返回博客

AI 入门指南

为什么 AI agent 会消耗这么多 token(一个 20 步示例)

AI agent 在每一步都会重新发送它的历史记录、工具列表和工具输出。通过一个 20 步的完整示例,看看 token 都去了哪里。

作者:CheapTokens Team发布于 5 分钟阅读

聊天卡片:一个问题,几十万个 token?每一步都会重新发送整段历史记录。
本页内容
  1. 一张图看懂 agent 是什么
  2. 每一步都随行的三样东西
  3. 一次 20 步的运行,算一算
  4. 从哪里削减:四个习惯
  5. 统计你自己的运行

你向 agent 提一个问题,它运行几分钟,用量页面就显示几十万个 token。这并没有出故障。Agent 是一个循环,循环的每一轮都会把此前说过的所有内容(工具列表、历史记录、工具返回的任何东西)作为输入 token 重新发送。它写出的答案很小,但它反复读取的内容可不小。

一张图看懂 agent 是什么#

聊天模型只回答一次。Agent 是同一个模型处在带工具的循环中:读文件、搜索网页、运行命令。而且模型在两次调用之间不记得任何东西。想象一个每次挂断电话都会忘掉一切的助手:每次他再打来,你都要从头念一遍笔记,然后再加上一行。API 就是这么工作的。

Anthropic 的工具使用文档(2026 年 10 月 26 日查阅)这样描述这个循环:

  1. 你的应用发送用户消息和工具列表。
  2. 模型回复 stop_reason: "tool_use" 和一个 tool_use 块:用哪个工具,带哪些参数。
  3. 你的应用运行该工具并发送第二个请求。它包含之前的消息、模型的工具调用、一个 tool_result 块以及同样的工具列表。
  4. 模型给出回答,或请求另一个工具,循环再次转起来。

同一页面还说明,工具使用请求按发送的总输入计费,包括 tools 参数,再加上输出。所以第 3 步从来不是“只有新增的部分”:而是整段对话再来一遍。

text
Request 1  tools + system + task
Request 2  tools + system + task + call 1 + result 1
Request 3  tools + system + task + call 1 + result 1 + call 2 + result 2
...

这和为什么长对话更贵是同一个机制,只是更快。聊天在你打字时每次增加一条消息。Agent 在每一步增加两个块,而且没人打字。

每一步都随行的三样东西#

工具列表。 每个工具的名称、描述和参数 schema 都会进入每一个请求,即使模型这一轮一个都没用。文档还补充了一个小细节:开启工具后,API 会加入自己的工具使用提示,在 Claude Sonnet 5.5、Opus 5.5 和 Haiku 5.5 上是 286 个 token,其他模型则有其他数量。

历史记录。 你的任务、模型之前的工具调用、它的笔记。

工具输出。 这才是隐蔽的那个。Agent 读过的文件、一页搜索结果、一份测试日志:一旦落入历史记录,之后每一步都要再为它付费。

一个 token 是一小段文本,大致是一个短词或词的一部分,这三样东西都按 token 计数。

一次 20 步的运行,算一算#

假设你运行一个小型编码 agent,带三个工具(读文件、搜索、运行测试),并给它一个需要 20 步的任务。采用以下假设:

  • 工具定义:1,500 个 token,系统提示:500,你的任务:200,所以每个请求从 2,200 个 token 起步;
  • 每一步模型写一个 150 个 token 的工具调用,工具返回 800 个 token;
  • 两者都加入历史记录,所以每一步给下一个请求增加 950 个 token。
agent 运行第 1、5、10 和 20 步时单个请求的输入规模:2,200、6,000、10,750 和 20,250 个 token,而输出保持每步 150
每个请求的输入 token 随每一步增长;输出保持每步 150 个 token(假设如上)

要得到整次运行的总量,把全部 20 个请求加起来。2,200 的基础部分被发送 20 次,而各轮内容由后续步骤携带:第 1 步不携带,第 2 步携带一轮,依此类推直到第 19 步,总共 190 轮。

20 × 2,200 = 44,000

950 × 190 = 180,500

44,000 + 180,500 = 224,500 个输入 token,以及 20 × 150 = 3,000 个输出 token。

Agent 写了 3,000 个 token,读了 224,500 个。输出 token 的单价高于输入 token(见输入与输出 token),但它们的数量太少,所以账单仍由输入侧决定。以下是按当前价格计算的这次运行:

模型 费用 OpenRouter
GLM-5.3-Flash $0.0046 $0.0095
DeepSeek-V4-Flash $0.0037 $0.0111
MiniMax-M2.7 $0.0117 $0.071

总计 224,500 个输入 token 和 3,000 个输出 token。每 100 万 token 的价格为当前价格,会随我们的资费一同变动;OpenRouter 列显示相同工作负载的参考价格。

在 DeepSeek-V4-Flash 上,这样一次运行是 $0.0037,在 GLM-5.3-Flash 上是 $0.0046。一百次运行就是 22,450,000 个输入和 300,000 个输出 token:在 DeepSeek-V4-Flash 上是 $0.367。上表把输入和输出合在一起计算,总体来看表中的模型比 OpenRouter 更便宜。

步数的影响比看起来更大。在相同假设下的一次 5 步运行:

5 × 2,200 = 11,000

950 × 10 = 9,500

11,000 + 9,500 = 20,500 个输入 token。步数变为四倍,输入却变成约十一倍,因为每个新步骤还会重读所有旧步骤。

从哪里削减:四个习惯#

一个工具结果是最容易节省的地方。假设第 3 步的一次测试运行返回 4,000 个 token 的日志。它随后会被接下来的 17 个请求重新发送:

  • 之前:4,000 × 17 = 68,000 个输入 token 由这一份日志携带;
  • 之后,如果工具只返回相关的 40 行(约 400 个 token):400 × 17 = 6,800。

同样的任务,同样的答案,来自那一个结果的输入只有十分之一。由此得出四个习惯:

  • 让工具返回更少。 只返回错误附近的几行,而不是整份日志;只返回那个函数,而不是整个文件。更长的讨论见让工具输出远离上下文。
  • 给 agent 更少的工具。 每个定义都会随每个请求同行。
  • 限制步数,当旧历史不再重要时就开始一个新任务。
  • 把每一步的用量加起来,并在你事先选定的预算处停止运行。关于估算方面,见如何估算 AI agent 的成本。

统计你自己的运行#

每个响应都会在其 usage 字段中报告它接收和输出了多少 token。把所有步骤的这些数字加起来,你就得到了自己 agent 的真实数据,而不是我的假设。下面是一个使用 OpenAI Python SDK 指向 CheapTokens 的示例(messages 和 tools 是你自己 agent 的):

python
from openai import OpenAI

client = OpenAI(base_url="https://api.cheaptokens.dev/v1", api_key="YOUR_API_KEY")

total_in = total_out = 0
for step in range(20):  # your agent loop
    resp = client.chat.completions.create(
        model="deepseek-ai/DeepSeek-V4-Flash-0731",
        messages=messages,
        tools=tools,
    )
    total_in += resp.usage.prompt_tokens
    total_out += resp.usage.completion_tokens
    # ...run the tool, append the result to messages

print(total_in, total_out)

这两个总数可以直接代入上面的成本表。对于这样的长历史,DeepSeek-V4-Flash 提供 380K 上下文窗口,每次回答最多 32,768 个输出 token,且任何时段都是同一价格;GLM-5.3-Flash 有 390K 上下文,最多 8,192 个输出 token。设置方法见文档,每个模型的当前价格在定价页面上,该模型也有自己的页面:便宜的 DeepSeek。