AI Agent 成本失控怎么办?从真实账单看生产环境省钱之道

阅读时长:18分钟

有一天我检查 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 架构的思路都会不一样。

你看,省钱往往是理解系统最好的开始。

© 2026 softon.top

本站已稳定运行 271 天 1 小时 · 126 篇文章

使用 Hugo 构建 主题 Stack 由 Jimmy 设计 由 softon 魔改

最近构建时间:2026-09-29 09:47:50 CST