学习笔记 | 11 月 3 日 · Agent 的成本账
- 2026-11-06 22:02:10
同一个任务,为什么有人花 2 分,有人花 2 块
单次问答的成本很好算:输入长度乘以单价,一眼就能估出来。
Agent 不是一次请求,是 n 次请求。而且第 n 次请求,要把前面 n-1 次的历史重新读一遍。
这带来一个不太直觉的结果:步数翻倍,成本接近翻四倍。
所以「贵」通常不是单价贵,是结构贵。今天把账拆开算,再说三处最该省的地方。
先把账算明白:成本 ≈ 步数 × 每步上下文
拿一组假设数(只是量级演示,不是任何一家的报价):基础上下文 2000 token,每步新增 800 token。
第 1 步输入 2,800第 10 步输入 9,200第 20 步输入 17,200累计输入 192,000一次性问答 2,800倍数 约 69 倍
同一个任务,如果步数从 20 变成 40:
20 步累计 192,00040 步累计 704,000步数 ×2,成本 ×3.7
结论很清楚:成本对「步数」是平方敏感的,对「每步新增多少」是线性敏感的。
由此得到一个优化顺序的判断:加步数省钱最快,但也最容易牺牲成功率;压上下文慢一些,但更安全。所以先压上下文,再谨慎砍步数。
第一处:重复的前缀,别每次都付全价
系统提示、工具定义、固定示例,这几样在每一步里都一模一样,通常占每步输入的 30%-50%。
也就是说,你有一半的钱,花在「把同一段话重复读二十遍」上。
现在的模型基本都支持提示缓存(prefix caching):前缀不变的部分,命中缓存后按大幅折扣计费。
用好的关键只有一句话:让前缀稳定。
不变的放前面:系统提示、工具清单、格式要求。 会变的放后面:用户这次的问题、检索结果、时间戳。 - 时间戳、随机 id、用户昵称不要放在开头——它们每轮都变,会让整段缓存直接失效。
一个真实事故:有人在系统提示第一行写了「现在是 2026-11-03 14:22」,缓存命中率从此归零,成本翻了三倍,而他从头到尾没觉得那句话有什么问题。
第二处:能一次做完的,别放进循环
判断标准只有一条:这一步需不需要「看上一步的结果」才能决定?
不需要,就不要进循环。三个具体做法:
并行:没有依赖的工具调用,一次性发出去,不要排队。
批量:十个小请求合成一个大请求,往返次数立刻降一个数量级。
路由:先分类,再决定走哪条链路,避免让主链路做它不该做的事。
反例很常见:让 Agent 一步一步读二十个文件。如果总量放得下,一次调用全部读进来就行——二十轮对话的开销,比一次大输入贵得多。
还有一条容易忽略:早停。
模型有过度确认的倾向,做完之后总想「再检查一遍」。检查本身没错,但每检查一轮,就是把全部历史再读一遍。给一个明确的完成判据,比让它自己感觉「差不多了」便宜得多。
第三处:不是所有步骤都值得用最贵的模型
一个任务里的步骤,难度分布是很不均匀的:八成是机械活(分类、抽取、格式转换),两成需要判断(规划、取舍、异常处理)。
全都用最贵的模型,等于给那八成机械活付了溢价。
分级思路:
路由与分类:最便宜的模型,甚至规则。
规划与难例:强模型,只在真正需要的时候用。
校验:规则优先,规则覆盖不到的再上模型。
还有一个成本陷阱:重试。
一次失败重试,约等于把这一段再跑一遍。失败率高的步骤,先修它,别急着换更贵的模型——换个模型可能只是把失败变成「更贵的失败」。
最后别忘了延迟:用户等 40 秒和等 4 秒,是两种产品。
给周报 Agent 记一笔账
不记账就没法优化。最少记三个字段:每步的输入、输出、耗时。
一行一步,追加到 runs.jsonl:
step 7 read_filein 4120 out 260 cached 3600 830ms
跑完统计三个数:
总 token:这次任务到底花了多少。
最贵的一步:通常不是最后一步,而是某次检索把八千字塞进了上下文。
缓存命中率:低于 50% 就说明前缀不稳定,先修这个,收益最大。
优化顺序固定成三步,不要跳:
最贵的那一步,是不是必要的?能不能并进别的步骤? 缓存命中率够不够高?前缀里有没有会变的东西? 最后才考虑换模型、降规格。
验收标准也只有一条:成本降下来,成功率没掉。 掉点的优化不算优化,只是把成本换成了返工。
今日三句话
Agent 的成本是平方量级——每一步都要把前面的历史重新读一遍。 最该省的三处:稳定的前缀(缓存)、不必要的步数(并行与早停)、机械活用便宜模型(分级)。 先记账再优化;没有每步 token 统计的优化,都是猜。
明日预告:从 demo 到上线——权限、审计、灰度,三件上线前必须补的事。