SSD Nodes Learn Hosting plans →
指南 Matt Connor作者: Matt Connor · 更新于 2026-08-23

如何控制常驻 AI agent 的 VPS API 费用

无人值守 agent 会在每次循环中持续计费。本文介绍硬上限、任务预算、提示缓存与批处理,并说明如何记录用量字段,找出实际耗费最多的任务。

如何防止常驻 AI agent 产生失控费用

在 VPS(虚拟专用服务器)上控制 AI agent 的成本,关键是在 agent 启动前设置上限,因为运行期间不会有人持续查看用量。使用 max_tokens 限制每次响应,​​在自己的代码中限制循环迭代次数,缓存提示中不会变化的部分,并记录每次响应的用量数据,以确定哪个任务消耗最多。服务器租用费是固定的月费。模型 API 按 token 计费,而无人值守的循环很容易在不易察觉的情况下持续消耗 token。

本文假设 agent 已经存在,并从您管理的服务器调用 Messages API。在 VPS 上使用 Claude 构建 AI agent介绍具体的实现过程。

Why an unattended agent is a different cost shape

An interactive session has a human in it. When the model goes down a wrong path or reads a 40,000-line log, the person watching stops it. An unattended agent has no such brake: it runs until the loop ends, then a timer starts it again.

Frequency is the multiplier people miss. A job on a five-minute schedule runs 288 times a day and about 8,640 times a month. Whatever one run costs, that is the figure you multiply. Many "always-on" agents do not need to be on. They need to answer within some number of minutes, which is a schedule.

An agent also pays for things a chat window does not.

  • Tool definitions ride along on every request. The tool-use system prompt costs 290 tokens on Claude Opus 4.8 with tool_choice of auto or none, and 410 with any or tool. The bash tool adds 325 more. Every MCP server you attach adds its schemas to that weight, MCP being the model context protocol.
  • Tool results are input tokens. A command that prints 8,000 lines puts 8,000 lines into the next request, and into every request after it in that turn.
  • Fetched pages are input tokens. An average 10 kB web page is roughly 2,500 tokens and a 500 kB research PDF roughly 125,000. max_content_tokens truncates the text ones only, because it "applies to text content, not to binary content such as PDFs". Bound a PDF with max_uses and allowed_domains instead.
  • Web search is priced per search, at $10 per 1,000 searches, however many results come back. A search that errors is not billed.

None of that is expensive once. All of it is expensive 8,640 times.

硬上限和软上限解决的是不同问题

max_tokens会强制执行。 它限制单个请求的总输出,包括思考和响应文本。Claude 不会超过此上限,并且模型无法看到该数值。达到上限后会返回 stop_reason: "max_tokens",响应也会被截断。对于 agent 而言,关键在于:工具调用循环中的每个请求都有自己的 max_tokens,因此它限制的是单次响应,而不是整个任务。一次包含 10 次工具调用、每次上限为 4,000 的流程,其本轮上限为 40,000 个 token。

任务预算仅供参考。 task_budget 位于 output_config 之内,用于告知模型整个 agent 流程可使用的 token 数量,其中包括思考、工具调用、工具结果和输出。

resp = client.beta.messages.create(
    model="claude-opus-4-8",
    max_tokens=4096,
    betas=["task-budgets-2026-03-13"],
    output_config={"task_budget": {"type": "tokens", "total": 64000}},
    messages=messages,
)

“任务预算是软提示,不是硬上限。”Claude 可能在一次操作中超过该预算,但输出仍受 max_tokens 强制限制。“只有模型可以看到倒计时”,响应中不会包含剩余预算字段。可接受的 task_budget.total 最小值为 20,000 个 token,设置更小的值会返回 400 错误。预算过小而无法完成任务时,模型会表现出类似拒绝的行为,因此会缩小任务范围或提前停止。

有一个细节不会节省费用,反而会增加费用。如果客户端在每次后续请求中递减 task_budget.remaining,更改后的值会使包含该值的缓存前缀失效。应在第一个请求中设置一次。

Claude Fable 5、Claude Opus 4.8 和 Claude Opus 4.7 支持处于 beta 阶段的任务预算。Claude Sonnet 5 和 Claude Haiku 4.5 被列为 Not supported,而任务预算不适用于 Claude Code。因此,在 tmux 中分离的 Claude Code 会话 取决于会话维护。

第三个上限位于 Claude Console 中:为 agent 分配独立工作区,然后为该工作区设置每月支出上限和每分钟速率限制。“无法为 Default Workspace 设置限制”,并且“组织范围的限制始终生效,即使各工作区限制的总和更高”。添加支出通知,以便在达到上限前通过阈值告警提醒您。

按作业选择模型,以及实际影响成本的因素

模型选择应按作业决定。截至2026年7月,每百万个 token 的输入和输出价格如下:Claude Fable 5 分别为 $10 和 $50,Claude Opus 4.8 与 Opus 4.7 分别为 $5 和 $25,Claude Sonnet 5 分别为 $3 和 $15,Claude Haiku 4.5 分别为 $1 和 $5。目前 Sonnet 5 的实际价格低于标价,因为“每百万个输入/输出 token $2/$10 的介绍性价格有效期截至2026年8月31日”。仅用于分类日志行的步骤不需要 Opus。忙碌的作业计划也无法依靠免费额度来抵扣,因为 Claude API 没有免费层级,注册时获得的小额额度除外。

Effort 是第二个调节因素。output_config.effort 接受 lowmediumhighxhighmax,默认值为 high,因此显式设置 high 等同于省略该设置。降低 effort 减少的不只是推理长度:文档说明,这会让 Claude 发起更少的工具调用,并将多个操作合并为一次。对于 agent,这项节省更大,因为每减少一次工具调用,就少产生一个完整请求。

问题在于,effort 会影响缓存。更改请求之间的该值会使提示缓存失效。在文档示例中,请求2报告了 cache_read_input_tokens: 3546;请求3 将 effort 从 high 改为 medium 后,报告了 cache_creation_input_tokens(共3546)和 cache_read_input_tokens(共0)。因此,应在不同工作负载之间调整 effort,不要在同一个已缓存的对话中调整。若要在不破坏缓存的情况下控制深度,请在提示中说明:在最新用户消息中加入类似“直接回答,不要展开推理。”的一行文字,可以保留之前的缓存断点。

思考 token 按输出价格计费,并计入 max_tokens,因此答案被截断通常意味着思考过程耗尽了预算。读取 usage.output_tokens_details.thinking_tokens 获取该数值。Claude token 费用究竟由什么组成 会拆解这一计量过程。

缓存稳定前缀,避免意外破坏它

在 5 分钟缓存中,写入缓存的费用是基础输入价格的 1.25 倍;在 1 小时缓存中,费用是 2 倍。读取缓存的费用是基础价格的 0.1 倍。因此,“5 分钟缓存只需读取一次即可开始节省成本(写入费用为 1.25 倍),1 小时缓存只需读取两次即可开始节省成本(写入费用为 2 倍)”。

下面这句话说明了它为什么适合持续运行的 agent:“每次使用缓存内容时,缓存都会免费刷新。”针对 5 分钟缓存每两分钟运行一次的任务,只需写入一次,就能让此前缀全天保持热状态。

以下 3 种情况会让缓存失效,而你可能不会立即发现。

前缀发生变化。“缓存前缀按以下顺序创建:toolssystem,然后是 messages。”此前缀顺序中较早位置的任何字节变化,都会使其后的全部内容失效;编辑工具定义则会使整个缓存失效。最常见的自我破坏方式,是在系统提示中加入时间戳或运行 ID:这样每个请求都会携带不同的前缀,以 1.25 倍价格写入新条目,却不会命中任何已有缓存。相同调用看起来完全一致,但 usage.cache_read_input_tokens 始终为 0,这就是明显信号。将易变文本移到最新的用户消息中。

前缀过短。每个模型都有可缓存长度下限。低于该长度时,请求会在不使用缓存的情况下处理,并且“不会返回错误”。例如,Claude Opus 4.8 和 Claude Sonnet 5 的下限为 1,024 个 token,Claude Haiku 4.5 的下限为 4,096 个 token。因此,将任务从 Sonnet 切换到 Haiku 可能会静默关闭缓存。

对话超出回溯范围。“回溯窗口为 20 个块。”系统在每个断点最多检查 20 个位置,然后停止。在文档示例中,一轮包含 35 个块,并在第 35 个块设置断点时,系统会检查第 35 到第 16 个块;上一轮位于第 15 个块的条目超出窗口,因此不会命中。agent 每轮追加多个工具调用块和工具结果块时,只需 2 或 3 轮就会超过 20。每个请求有 4 个断点,因此应将其中一个用于最近的消息。

将所有可以延迟的任务提交到 Batches API

输入和输出均按标准 API 价格的 50% 计费。批处理采用异步方式,“大多数批次会在 1 小时内完成”。结果会在所有请求完成后返回,或在 24 小时后返回,以先到者为准。这是通常情况,并非保证。

轮询 processing_status,直到其值为 ended。返回 erroredcanceledexpired 的请求不会计费。如果您依赖支出上限,还需注意一个例外:“批次的支出可能会略微超过 Workspace 配置的支出上限。”

这些折扣可以叠加。由于批次处理时间可能超过 5 分钟,文档建议对共享上下文的批次使用 1 小时缓存。因此应拆分任务:用户或 webhook 需要等待的内容保留在实时路径上,夜间摘要或前一天的日志分类则提交到批次中,以半价处理。

将每次响应的用量字段记录到自己的存储中

未记录的支出无法归属。每次响应都会告诉您产生了多少成本。

u = resp.usage
row = {
    "job": job_name,
    "model": resp.model,
    "uncached_input": u.input_tokens,
    "cache_write": u.cache_creation_input_tokens,
    "cache_read": u.cache_read_input_tokens,
    "output": u.output_tokens,
    "stop_reason": resp.stop_reason,
}

每次 API 调用向 JSON-lines 文件追加一行,并标记作业名称。一周后,您就能知道哪些作业产生了支出,哪些只是看起来繁忙。请监控 cache_read:全是 0 的列是自托管代理中最常见的成本统计错误。

有一个字段很容易误读。input_tokens只统计最后一个缓存断点之后的 token,因此实际提示词大小是 total_input_tokens = cache_read_input_tokens + cache_creation_input_tokens + input_tokens。大型提示词上报告 input_tokens: 400 的代理并不表示成本低:其余内容来自缓存。

发送前先计数。Token 计数不收费,且其速率限制独立于消息创建,因此应使用 count_tokens 拒绝过大的附件,而不是付费后才发现附件超限。结果只是估算值,因此应针对每个模型重新测量,绝不要复用其他供应商 tokenizer 得出的计数。Claude Opus 4.7 及更高版本的 Opus 模型、Claude Fable 5 和 Claude Sonnet 5 使用较新的 tokenizer,该 tokenizer “对相同文本生成的 token 数大约多 30%”。Claude Sonnet 4.6 及更早版本(包括 Claude Haiku 4.5)使用旧版 tokenizer。

如需查看权威数据,Admin API 会在 https://api.anthropic.com/v1/organizations/usage_report/messages 报告用量,并在 https://api.anthropic.com/v1/organizations/cost_report 报告成本。两者都需要将管理员密钥(sk-ant-admin01-...)作为 x-api-key: $ANTHROPIC_ADMIN_KEY,并配合 anthropic-version: 2023-06-01 使用,同时接受 bucket_width=1dgroup_by[]=modelapi_key_ids[]=。有一项限制:“Admin API 不适用于个人账户。”

最后一个参数提供了一种低成本的归属方法:为每个作业分配独立的 API key,使用 api_key_ids[] 进行筛选,再使用 group_by[]=api_key_id 按 key 拆分报告。筛选器是复数,分组维度是单数。请将这些 key 保存在环境变量中,而不是代码中,正如 在 VPS 上创建第一个 Claude API 应用时的做法。

限制循环次数,因为没有其他机制会替你限制

这里必须设置有上限的迭代次数。循环由您编写,因此计数器也由您控制:

for step in range(MAX_STEPS):          # MAX_STEPS = 12, never "while True"
    resp = client.messages.create(...)
    if resp.stop_reason != "tool_use":
        break
else:
    log.warning("job %s hit MAX_STEPS=%d, giving up", job_name, MAX_STEPS)

上面的两个上限都不能替您完成这项工作:max_tokens限制单次响应,而模型只会获知任务预算。托管产品会在这里停止,就像Claude 对单轮工具调用次数的上限会终止调用次数过多的会话一样;但您自行编写的循环不会自动提供这种保护,必须手动添加。

在进程外再设置一道限制。不要运行永久进程,而应通过 systemd timer 运行任务,并在其 service unit 中设置 RuntimeMaxSec=。设置 RuntimeMaxSec=600 后,运行卡住时会在 10 分钟后终止,而不是一直运行到您发现问题为止。将程序作为 systemd 服务和计时器运行介绍了 unit file 的具体配置。使用 journalctl -u triage-agent.service --since "1 hour ago" 查看某次运行执行了哪些操作。

同时限制重试次数,因为无限重试的处理程序会为每次尝试计费。对于 429 或 500 错误,可以结合退避策略重试几次。对于 400 错误,不应重试,因为相同请求会以相同方式失败。

AI agent 成本控制始于读取自己的数据

没人能直接告诉您常驻 agent 的成本,因为成本等于每次运行消耗的 token 数乘以每天运行次数,而这两项都由您决定。先运行一次,读取您记录的用量行,再乘以计划运行次数。两天后,将成本报告与该计算结果进行核对。如果两者不一致,差值几乎总是由缓存失效或运行时间超出预期的循环造成。

这里假设您使用 API key,因为 agent 是调用 Messages API 的自有程序。对于您自己的交互式工作,哪种 Claude 方案适合您的工作方式介绍了订阅方面的选择。这里的所有价格和限额均已根据 Anthropic 在 July 2026 发布的文档进行核对,因此在制定预算前,请重新查看定价页面。

FAQ

运行持续在线的 VPS AI agent 需要多少成本?

费用分为两部分,只有一部分可以准确预测。服务器按月收取固定费用。模型 API 按 token 计费,因此成本取决于单次运行消耗的 token 数量,以及运行频率。Anthropic 没有公布自托管持续在线 agent 的具体费用,因此任何引用的金额都只能视为估算值。记录一次真实运行产生的 usage,再根据运行计划计算总成本。

max_tokens 和任务预算有什么区别?

max_tokens 由系统强制执行,模型无法看到。它限制单次请求的输出量,其中包括思考内容;达到限制后会返回 stop_reason: "max_tokens"。任务预算则相反:模型会获知预算值,并据此控制 agent 循环,但“任务预算只是软提示,不是硬限制”,真正强制执行的限制仍然是 max_tokens

为什么我的 agent 的 cache_read_input_tokens 始终为 0?

因为连续调用之间的前缀发生了变化,或者前缀太短,无法进行缓存。常见原因是将时间戳或运行 ID 插入了系统提示词:缓存以此前缀为键,因此任何字节变化都会使其后的全部内容失效。修改工具定义或 effort 值也会产生相同结果。否则问题可能是提示词长度,因为较短的提示词不会被缓存,而且系统不会返回错误。

如何阻止 AI agent 无限循环?

在循环代码中统计迭代次数,并在达到固定上限时停止,因为 max_tokens 只限制单次响应,而 agent 可能生成多次响应。在进程外部添加 wall-clock 时间限制:使用 systemd timer 启动任务,并设置 RuntimeMaxSec=,这样卡住的运行会按计划终止。同时限制重试次数,因为每次重试都会产生费用。

能否为单个 Claude API key 设置支出上限?

文档规定的支出上限按 workspace 设置,而不是按 key 设置。因此,应为该 agent 创建独立的 workspace,并在那里限制月度支出。“无法为 Default Workspace 设置限制”。添加支出通知,以便在达到阈值时先收到提醒。为便于归因,为每个任务分配独立的 key,然后使用 group_by[]=api_key_id 汇总使用情况报告。