有一天我检查 Claude Code 的账单,发现一夜之间多了 120 万的输入 token。而那天晚上,我明明只是在睡觉。
排查后真相大白:我写的一个定时 cron 作业触发了 Agent 自动分析日志的流程,结果日志量比预期大了 10 倍,Agent 被塞进了 80 万 token 的日志上下文,然后它"认真"地分析了每一行——花了大约 $4.8。
不是一笔大钱,但如果这种场景每个月发生 10 次呢?如果有 5 个 Agent 同时跑呢?如果团队 20 个人都用呢?
AI Agent 最大的谎言不是"它们会取代程序员",而是"每次调用才几分钱"。
成本不是线性增长的——它是指数跳变的
先给一个残酷的数字:我用一个三 Agent 架构(调度 Agent + 编码 Agent + 审查 Agent)处理日常代码维护任务,三个月的账单趋势是这样的:
| 月份 | Agent 调用次数 | 总 Token 用量(M) | 费用($) | 环比增长 |
|---|---|---|---|---|
| 第 1 月 | 632 | 8.2 | ~$24 | — |
| 第 2 月 | 1,847 | 31.5 | ~$95 | 296% |
| 第 3 月 | 4,326 | 89.7 | ~$269 | 183% |
不是线性 3 倍,是指数跳变。第二个月增长了约 3 倍,第三个月又翻了约 2.8 倍——看数字和增长可以理解为 Agent 数量没变、调用场景没变,但每个 Agent 每轮对话的上下文越来越胖了。
这就是 AI Agent 成本失控的典型模式:调用频率线性增长,但 Token 用量指数膨胀。
原因很简单——Agent 是有记忆的。每次对话它都会追加历史记录,上下文窗口越来越胖。你从"单个 prompt/response 对话"进入了"Agent 自主决策 + 多轮工具调用 + 长上下文积累"的新模式,成本的数学规律完全变了。
元凶 1:无限制的日志和调试输出
上面我那个"睡觉烧掉 $4.8"的故事就是活例子。cron 作业启动 Agent 分析日志 → 日志文件 80 万 token → Agent 全部读进去分析 → Token 直接爆表。
为什么容易发生:
大多数 Agent 框架的默认行为是"先理解上下文再行动"。当你的日志文件、调试输出、API 响应被 Agent 捕获时,它不会说"这些重复了、跳过",它会老老实实地读完每一行。
解决:限制输入上下文上限
# Claude Code 的 tokens 配置
export CLAUDE_CODE_MAX_INPUT_TOKENS=100000
# 或者在项目配置中设置
claude config set max_input_tokens 100000
这个配置的意思是:无论 Agent 遇到多大的输入,只截取前 10 万 token 处理。配合 truncate 策略,10 万 token 以上的数据直接丢弃。
但光截取不够,更好的方案是给 Agent 装一个"护栏":
# Agent 的护栏规则(在 agent 配置中定义)
rules:
input_limits:
max_file_size_mb: 5 # 拒绝 >5MB 的文件
max_log_lines: 500 # 只读取日志前 500 行
skip_generated: true # 跳过 dist/、.next/、build/ 等目录
skip_binary: true # 不读二进制文件
实操中用了这组规则后,那个 cron 作业的 Token 开销从 80 万降到了约 1.2 万——减少了 98.5%。
元凶 2:循环递归——Agent 自己调用自己
这是最隐蔽的成本陷阱。你写了一个 Agent A,让它去调用 Agent B,Agent B 发现问题回头找 Agent A 确认,Agent A 再派 Agent C……这就是一个递归循环,而且没有 break 条件。
一条真实的循环链:
Agent A(调度)→ 分发给 Agent B(代码审查)→ B 发现代码问题 → 调用 A 确认规则 → A 让 B 参考 C(规则解析器)→ C 的输出又返回给 A → A 再次分发给 B → B 发现 C 的规则和之前冲突 → 再次调用 A……
这条链实际跑了 47 轮对话、21.3 万 token、花费约 $0.64。最终结果?没有一个代码变更。全部是"协调"。
根因:没有限定最大协调深度。
解决:设定协调树的最大深度
# 多 Agent 协调配置
agent_coordination:
max_depth: 3 # 协调链最多 3 层
max_rounds_per_depth: 2 # 每层最多 2 轮对话
escalation_mode: "human" # 超出后交给人类
timeout_minutes: 10 # 每轮超时 10 分钟
加了这些限制后,类似场景的 Token 消耗从 21.3 万降到了 约 1.8 万,更重要的是——Agent 不会再无限循环下去了。
元凶 3:对话上下文肥胖症
这是最常见但最容易被忽略的成本陷阱。看一个典型场景:
你让 Agent 重构一个函数的命名。Agent 打开文件,读取了上下文,修改了 3 行代码,告诉你"已完成"。这个交互可能只消耗了 2,000 tokens。合理。
但第二天你又让 Agent 处理同一个文件的另一个函数。此时 Agent 说:“让我先看看项目背景”。它读取了昨天的对话历史、项目 README、package.json、tsconfig.json……这一轮下来可能已经 8,000 tokens 起跳。
第三周,这个 Agent 的默认上下文已经膨胀到了 30,000+ tokens——而其中 80% 是三个星期前的对话历史。
这就是"上下文肥胖症":Agent 的对话越长,它启动时需要携带的历史上下文就越重,然后对话又变得更长——死亡螺旋。
Vercel 的 AI SDK 团队在 2025 年的一个分享中提到,他们的生产环境 Agent 有 60% 的 Token 消耗来自历史上下文而非当前交互。
解决:对话上下文分页 + 滚动窗口
简单的思路是这样的:
# Agent 对话管理配置
conversation:
strategy: "sliding_window" # 滑动窗口策略
max_context_tokens: 12000 # 最大上下文 12k tokens
recent_window: 4000 # 保留最近 4k tokens 的详细对话
summary_budget: 2000 # 之前的内容压缩成 2k tokens 摘要
archive_older_than: 7 # 超过 7 天的对话自动归档
核心思想:不保留所有历史,只保留"当前窗口 + 历史摘要"。 具体到实现:
- 最近 N 轮对话:完整保留
- 旧对话:Agent 自己生成摘要,压缩成原大小的 1/10
- 天级过期:超过 T 天的对话自动归档到外部队存储
我在 OpenClaw 的 Agent 配置中用了类似的策略,效果显著:
| 指标 | 优化前 | 优化后 | 变化 |
|---|---|---|---|
| 平均每轮上下文 | 24,800 tokens | 8,300 tokens | -66.5% |
| 对话框回复质量 | 正常 | 正常 | 未下降 |
| 旧决策召回率 | 100%(记忆完整) | 92%(依靠摘要) | 可接受 |
一个平衡点:上下文压缩到 66% 以内时,质量下降几乎不可感知;超过 80% 的压缩才会影响决策准确性。
元凶 4:毫无节制的重试和退火
这个模式很常见:Agent 调用 API 失败 → 自动重试 → 又失败 → 退火等待再重试 → 成功。看起来没问题。
但如果"失败"是因为 Agent 自己的 prompt 写错了呢?
我踩过这个坑:让一个代码审查 Agent 每天凌晨分析当天的代码变更并生成报告。因为逻辑复杂,Agent 偶尔会输出不完整的 JSON 导致解析失败。框架的设计是自动重试 5 次,每次退火 30-60 秒。
5 次重试 × 每次消耗 8,000 tokens(重新分析)+ 60 秒退火时间 = 40,000 tokens + 5 分钟延迟,最后生成了一份"第 5 次重试成功"的报告——和第一次的输出几乎没有区别。
核心问题不在于重试,而在于重试时重新分析了相同的数据。
解决:失败缓存 + 退火上限
# Agent 重试策略
retry:
max_attempts: 2 # 最多重试 1 次(共 2 次尝试)
backoff_strategy: "fixed" # 固定退火(不用指数,避免无意义等待)
backoff_seconds: 5 # 5 秒
cache_intermediate: true # 缓存中间计算结果
on_parse_error: "notify" # 解析错误不重试,直接通知人类
关键变化:on_parse_error: "notify"。遇到解析错误时,不自动重试,而是给人发一个通知。这额外的好处是——你很快会注意到 Agent 的 prompt 有问题,而不是让它默默重试 5 次浪费时间和钱。
元凶 5:多 Agent 间的冗余上下文广播
在多 Agent 架构中,另一个常见的成本坑是"信息广播"。
调度 Agent 从项目管理工具拉取了 50 个用户故事的详细描述,然后将这 50 个故事的上下文全部注入到每个子 Agent 的 prompt 中——即使每个子 Agent 只负责其中的 3-5 个。
我亲眼见过一个场景:调度 Agent 往 3 个子 Agent 各发了 15 万 token 的"项目上下文",结果子 Agent A 需要其中 1.2 万 token,B 需要 8,000 token,C 需要 2 万 token。浪费率 92%。
解决:按需注入 + 引用策略
# 上下文分发策略
context_distribution:
strategy: "lazy_on_demand" # 延迟按需注入
default_ref: "path" # 默认引用方式是文件路径
add_full_context: false # 不自动注入全量上下文
context_resolution: "agent" # 子 Agent 自主决定需要什么上下文
“延迟按需注入"的实操方式:
调度 Agent 不再发送全量上下文,而是发送"引用”:
任务:重构 items.ts 中的 calcTotalPrice 函数
上下文引用:
- 项目路径:src/utils/items.ts
- 相关类型:src/types/order.ts
- 依赖函数:src/utils/price.ts
相关用户故事:US-1023, US-1025(完整描述见项目管理系统 task-1023)
子 Agent 接收到引用后,按需读取相关文件——数据总量减少了 85-95%。
实战组合拳:一个可复用的成本控制飞轮
上面 5 个元凶各自有解法,但最有效的是把它们组合成一个持续运行的成本控制飞轮:
[监控] → [分析] → [限制] → [反馈] → [优化] → [再次监控]
第一步:监控
用机器不可靠,必须有可量化的监控指标:
# 关键指标(每个 Agent 实例)
metrics_to_track:
- "tokens_per_call" # 每次调用的 Token 消耗
- "calls_per_session" # 每轮对话的 API 调用次数
- "context_size_growth" # 上下文大小的增长趋势
- "retry_rate" # 重试率
- "cost_per_task" # 每个任务的实际成本
可以每天跑一个脚本拉取这些指标,或者用现成的工具(如 CodexBar 或 codeburn)监控。
第二步:分析
设定告警阈值:
| 指标 | 告警线 | 警告 | 严重 |
|---|---|---|---|
| 单任务 token 消耗 | >50k token | 黄色 | — |
| >200k token | — | 红色 | |
| 上下文增长率 | >20%/轮 | 黄色 | — |
| >50%/轮 | — | 红色 | |
| 重试率 | >15% | 黄色 | — |
| >30% | — | 红色 |
第三步:限制
上面提到的所有限制策略汇总成一个"护栏":
# Agent 成本护栏(生产环境配置)
cost_guardrails:
# 输入限制
max_input_tokens: 100000
max_file_size: "5MB"
max_log_lines: 500
# 重试限制
max_retries: 2
retry_backoff: "fixed 5s"
# 协调限制
agent_coordination:
max_depth: 3
max_rounds: 6
# 上下文管理
context_strategy: "sliding_window"
max_context_tokens: 12000
# 预算限制
budget_per_session: 0.50 # 每轮对话预算上限 $0.5
budget_per_day: 5.00 # 每日预算上限 $5
budget_alert: "notify" # 超预算时通知人类
注意 budget_per_session 和 budget_per_day——给 Agent 设预算,这和给你的信用卡设额度一样重要。
第四步:反馈
成本数据是信号,不是噪声。每周末花 5 分钟看一下账单:
- 哪些 Agent 最贵?→ 检查上下文是否在膨胀
- 哪些任务 Token 消耗异常?→ 检查是否有循环/重试
- 成本是否持平/下降?→ 是的话维持;增长的话排查
从"先烧再说"到"预算即架构"
这三个月的经历让我对 AI Agent 成本有了新的认识。以前的想法是"先让 Agent 跑起来,成本后面再说",现在回头看,那时真是天真。没有成本意识的设计,迟早会被账单教育。
更本质的变化: 过去三个月里,设计 Agent 架构时最费劲的部分不是功能逻辑,而是成本预算分配。
——这个 Agent 的任务平均 Token 消耗多少?会不会循环调用别的 Agent?它的上下文会膨胀到什么程度?这些问题的答案,直接决定了架构的稳定性和可维护性。
生产环境 AI Agent 的成熟度,不在于它多能搞定复杂问题,而在于它多大程度上是可控的。 可以大胆地假设未来,成本控制意识会成为 Agent 工程师的基本素养——就像后端工程师必须懂数据库索引和缓存策略一样。
回头再看最初那个"睡觉烧掉 $4.8"的故事,现在当然不会发生了。但这不仅仅是省了几块钱的问题——而是当你知道成本是如何构成的,你设计 Agent 架构的思路都会不一样。
你看,省钱往往是理解系统最好的开始。