一、上下文越长,Agent 未必越聪明
很多人调 Agent 的第一反应是「把能给的都给它」:整个仓库、十篇文档、二十轮历史,一股脑塞进 prompt。结果模型不是变强,是变糊涂------关键约束被埋在第三万个 token 的中间,注意力一衰减,它就在「该用 A 方案」和「上文提过 B 方案」之间反复横跳,还都能自圆其说。
我自己的判断是:上下文长度和决策质量不是单调关系,而是一条倒 U 曲线。真正管用的是「短而准」的系统提示加一份可检索的外部记忆,而不是把记忆全部内联进对话里。
二、成本账本:命中率决定这门生意能不能做
长上下文最贵的不是首 token,而是重复计费。假设一次任务输入 30k token、输出 1.5k,价格按输入 2.5 美元每百万、缓存读 0.3 美元每百万估:
- 完全无缓存:单轮输入成本约 0.075 美元,一个十步的 ReAct 循环就是 0.75 美元;一个重度用户一天跑 20 次,就是 15 美元。
- 前缀缓存命中:把稳定的 system prompt、工具定义、编码规范固化成不变前缀,让每次都变的内容只落在尾部。命中率做到 80% 时,同样的负载成本大约降到 0.22 美元一轮。
差的是一个数量级。很多团队的 Agent Demo 跑得欢,一上量发现毛利是负的,问题基本都出在这里。
工程上我守三条硬规矩:
- 前缀绝对稳定。日期、随机 ID、请求上下文这类每次都变的东西一律挪到尾部,别插在中间,否则缓存前缀直接断裂,前面几万字全按全价重新计费。
- 工具定义要精简。每多一个 function schema,每一轮都在付费。能合并的合并,能延迟加载的等真用到再注入,别为了「显得能干」挂三十个工具。
- 历史做摘要而不是截断。粗暴截断会丢掉约束条件,模型转头就违反规矩。滚动摘要加原始片段的引用编号,通常比「只留最近 N 轮」稳得多。
三、如果只能改一处
我会先把 system prompt 和工具定义变成不可变前缀。这是投入产出比最高的一刀,改动可能就十几行代码,换来的是成本直线下滑,而且完全不影响效果------模型看到的内容一个字都没少。
至于给整仓代码建向量索引,除非真的撞到检索瓶颈,否则我会再等等:索引的构建和失效维护成本,常常比它省下来的钱还贵。
一句话总结:上下文窗口是营销参数,缓存命中率才是工程参数。前者写在你抄的 benchmark 里,后者写在你月底的账单上。