上下文窗口大了,Agent 反而更笨:一份手工管理的「预算表」

📅 2026/4/26 ✍️ 小文 📖 约 1 分钟

窗口从 8K 涨到 1M,很多 Agent 的效果却在下滑。本文把上下文当成稀缺预算来管:四类内容的价值密度测算、压缩与驱逐的决策顺序、以及一份可直接照抄的上下文预算表。

一个反直觉的现象:把模型的上下文窗口从 128K 拉到 1M,很多 Agent 的任务成功率没涨,反而跌了。原因不在模型,在我们的用法。窗口变大之后,团队开始”什么都塞进去”——完整对话历史、全量工具返回、几十份文档原文。结果是信噪比崩塌:关键指令被淹没,模型开始忽略中间段落(lost in the middle),成本还翻了五倍。

把上下文当成一份有限的预算,问题就变得可解了。

先给每类内容算”价值密度”

不要凭感觉决定放什么。对每一类候选内容,估两个数:它对当前这一步决策有多大帮助(0-3 分),以及它占多少 token。价值除以 token,就是密度。

一份实测下来的排序(针对客服 / 运营类 Agent):

内容类型价值典型 token处理方式
系统指令与硬约束3500-1.5K永久驻留,不可驱逐
当前任务目标与验收标准3200-500永久驻留
最近 3 轮工具调用结果2-31-8K保留,成功后折叠成摘要
检索到的文档片段24-20K按分数截断,宁少勿滥
完整对话历史15-50K只留摘要 + 最近 3 轮原文
全部工具定义13-15K按需加载,别一次全给
中间思考过程0-1变化大单步结束即丢弃

表格里最容易被违反的是最后两条。工具定义一次全量下发,是新手最常见的浪费:50 个工具的 schema 能吃掉 10K token,而单步真正会用到的通常不超过 3 个。

压缩的顺序:先折叠,再摘要,最后才丢

很多团队一遇到超限就直接截断最老的消息,这会丢掉任务最初的目标,Agent 于是开始”目标漂移”。正确的顺序是三级:

  1. 折叠:把一次成功的工具调用压缩成”动作 + 结论 + 关键 ID”,去掉原始 JSON。一次搜索结果 6K token,折叠后通常 200 token 以内,信息损失很小。
  2. 摘要:把更早的多轮对话写成结构化摘要,只保留已确认的事实、已排除的假设、未完成的子任务三项。让模型自己写摘要比外部规则更准,但要用固定模板,否则摘要会越来越长。
  3. 驱逐:以上都不够时才删,且从”与当前子任务无关”的内容开始,而不是从时间最老的开始。

一个具体规则:任何一次工具调用返回后,立即判断它是否已经在后续步骤中被消费。已消费的,降级为一行结论。

一份可以直接照抄的预算表

给每一步设一个硬上限,超了就强制走压缩流程:

总预算:32K(即使模型支持 200K,也主动限制)
├─ 系统指令          ≤ 1.5K   固定
├─ 任务目标+验收标准  ≤ 500    固定
├─ 工具定义          ≤ 3K     只加载当前步骤所需
├─ 检索上下文        ≤ 8K     最多 5 个片段
├─ 历史摘要          ≤ 2K     结构化三段式
├─ 最近原文          ≤ 6K     最近 3 轮
└─ 余量(安全垫)    ≥ 11K    给工具返回和思考用

安全垫这一项常被砍掉,然后系统在复杂步骤上反复崩。留出 1/3 的余量,是让 Agent 有空间”边做边想”的前提。

长任务里的两个实操细节

第一,把”当前进度”外化为文件,而不是留在上下文里。 长任务每完成一个子目标,就往一个 progress.md 里写一行:完成了什么、产出在哪里、下一步是什么。上下文被压缩后,从文件里重新读回来——这比指望模型记住更可靠,也让中断恢复成为可能。

第二,子任务隔离。 需要读 20 份文档做汇总时,不要把它们都塞进主对话。开一个子 Agent,只回传 300 字的结论。主 Agent 的上下文只增长 300 token,而不是 20 份文档。

判断预算是否真的在起作用

两个监控信号:每步 token 的 P90 和任务完成率随步数衰减的斜率。如果 P90 持续贴着上限、完成率在第 8 步之后断崖下跌,说明预算太紧或压缩策略在丢关键信息;反过来,如果 P90 只有预算的三成,说明你在浪费窗口,该给的检索上下文没给够。

窗口大小是模型的参数,信噪比是你自己的责任。把这份表贴进团队文档,比订阅一个更大的模型便宜得多,也有效得多。

📤 分享到