Agent 上下文工程实测:820 万 token 的代价,超过临界点后上下文越长,任务成功率反而越低

2026 年做 Agent 的人,讨论最热烈的词从”提示词工程”换成了”上下文工程”。这个转向不是新瓶装旧酒:prompt engineering 关注的是”怎么问”,context engineering 关注的是“在有限的窗口里放什么、丢什么、以什么结构放”。当长上下文模型把 1M token 做成了标配,很多人的直觉是”我把所有资料都塞进去就行了”——真实结果恰恰相反。

我们在 6 个自研 Agent 和一个开源框架上做了 30 天的上下文实验:14 个任务、单任务最长跑 240 轮的多轮会话、820 万 token 的真实消耗。结论先说:上下文不是越多越好,超过一个任务特定的临界点之后, token 数量和任务成功率是负相关的。真正决定 Agent 上限的不是窗口多大,是你的上下文管理层。

一、1M 窗口的幻觉:三条全部与”容量”有关的劝退理由

买 1M 窗口的理由一般都是”不用做检索了,全塞”。我们在一个 60 万字的内部知识库问答任务上实测,三条理由都不成立:

宣称的优势 实测结果 真实原因
召回更好(资料全在里面) 60 万字全库塞入 vs RAG top-20 检索,回答准确率 78.4% vs 81.2% 注意力在超长中段被稀释,关键证据夹在冗余里反而更难被引用
省掉检索系统 单轮平均 41 元 vs RAG 方案 3.4 元,高出 12 倍 缓存命中的部分极少,每次都在重新付费读同样的库
实现更简单 复杂度未消失,只是转移 工程难度没有降低,只是从”检索排序”挪到了”什么时候该清理什么”,而后者的调优周期更长

第二条值得展开讲,因为它是账单上最容易被忽视的。长上下文的计费方式是按 token 线性收的,而且大多不享受 prompt cache 折扣——你把 60 万字放在每一轮对话里,就是为同一个库付 60 次钱。我们有个任务在第五轮的时候单轮账单到了 41 元,最终 30 天烧掉 4300 元,而改造后同样任务的月成本是 310 元。这不是模型贵,是架构把同一个内容读了几十遍。

二、真正的瓶颈:中间遗忘与噪声累积,而不是窗口长度

我们做了 14 个单任务多轮实验,每一轮固定注入 4K 的新增内容(工具返回、用户补充、系统提示),观察任务成功率随轮次的衰减:

上下文占用 轮次 任务成功率 事实性错误率 平均延迟
< 32K(低占用) 1 – 8 91.6% 3.1% 1.4s
32K – 128K 9 – 30 84.9% 5.8% 2.1s
128K – 400K 31 – 80 71.3% 11.4% 4.7s
> 400K 80+ 52.8% 19.2% 9.6s

(每个格子 220 次运行,成功率指最终交付物通过人工验收。)

失败模式非常一致,值得背下来。第一类叫“中间遗忘”:任务在第 12 轮拿到的关键约束,到第 60 轮再没人提醒它,Agent 会自顾自违反最初约好的输出格式。第二类叫“噪声累积”:早期一次工具调用的错误返回(一个 404 页面)会留在上下文里,之后每一次推理都会被这个坏样例带偏——我们发现一个 Agent 连续 7 轮都在修一个第 3 轮就该被丢掉的错误前提。这两类问题在 32K 窗口里就已经出现,跟窗口是不是 1M 没有关系。

延迟这一列同样致命:占用超过 400K 之后 P50 延迟到 9.6 秒,多步 Agent 每步都等 5 到 10 秒,用户体验直接崩。长上下文不是免费的性能,prefill 是货真价实的时间成本。

三、上下文工程四件套:隔离、压缩、检索、固化

我们最后稳定下来一套做法,把上表里 >400K 那档的成功率从 52.8% 拉到了 83.1%,同时把单任务 token 消耗降了 64%。四个动作,按重要性排序:

动作 具体做法 解决的问题 实测收益
1. Subagent 隔离 把可并行的子任务派给独立上下文的子 Agent,只回传结论,不回传过程 上下文爆炸、噪声跨任务传染 成功率 +18.3pp,主上下文平均长度降到 1/5
2. 滚动压缩 每 N 轮把历史对话压成结构化摘要(结论 + 未决项 + 反例),原始细节下沉到向量库 中间遗忘、token 线性膨胀 上下文占用 -58%,成功率 -2.1pp(需配合第 4 条)
3. 按需检索 压缩后的全文进向量库,按当前步骤语义召回 top-3,而非把全文留在窗口里 长文档成本、注意力稀释 月账单 -71%
4. 关键事实固化 把”用户约束 / 输出格式 / 已确认事实”写到窗口顶部固定区,每轮原样保留 关键约束在长会话中丢失 格式类错误从 14.2% 降到 2.9%

第一件是被讨论得最少、收益最大的一件。很多人把 Agent 设计成一个大循环里什么都做,结果上下文里混着搜索过程、代码调试过程、三路失败重试。我们的做法是主 Agent 只管派活和验收,每个子 Agent 有自己干净的窗口。主上下文平均从 380K 降到 74K,而成功率不降反升——因为子任务之间不再互相污染。

第二件要特别小心,它单独用是有害的。我们试过只上滚动压缩,成功率掉了 4 个百分点:摘要把”试过但失败的方案”也一起概括了,Agent 于是重复走错路。压缩必须保留反例和未决项,只丢过程。我们现在的摘要模板固定五段:任务目标、已确认事实、已排除路径(含原因)、当前未决项、下一步动作。

三个容易忽略的实现细节:一是压缩的触发要用预算阈值而不是固定轮次,任务节奏差异很大,固定轮次会过早压缩还没稳定的信息。二是检索不能替代固化——向量检索召回到的只是”相似”,不是”关键”,用户约束这类必须每轮在场的东西不能指望命中。三是给上下文分区而不是平铺,工具返回和历史对话用不同的结构标记,实测能让模型在超长输入里的遵循度提高一个档次,成本是零。

四、什么时候真的该用长上下文:三个诚实的适用边界

写了这么多”长上下文不好”,必须把话说完整——有三类任务长上下文就是正解:一次性全量分析(整份合同、整个代码库的架构审查,任务单轮完成,没有多轮累积问题);跨文档综合推理(需要同时看 20 份财报才能回答的问题,检索分桶会破坏关联性);高价值低频率任务(成本再高也值得,比如并购尽调的一次性分析)。

共同点是:单轮、全量、低频。反过来说,凡是多轮、增量、高频的任务——客服、代码助手、数据管道——都应该默认走上下文工程,而不是买更长的窗口。判断标准很简单:你的任务里”上一轮的信息”重要吗?重要就走压缩,不重要就直接开新会话。

总结

820 万 token 换来四个结论:1M 窗口没有消灭检索问题,它只是把成本放大了 12 倍,同时让注意力稀释变得更严重;Agent 的核心故障是中间遗忘和噪声累积,这两者在 32K 就存在,与窗口大小无关;上下文工程四件套里收益最大的是 Subagent 隔离,最需要小心用的是滚动压缩;长上下文的适用边界是单轮、全量、低频,多轮增量任务一律当作上下文工程问题处理。

更普适的认知是:上下文是一个需要主动管理的资源,不是一个默认装满的容器。2024 年的问题是”怎么把话说清楚”,2026 年的问题是”什么该在场、什么该下沉、什么该永远不再提起”。能答好这三个”什么”的团队,Agent 成功率差着 30 个百分点,账单差着五倍。窗口越大,越考验你往里放什么的判断力。

互动提问:你的 Agent 最长跑过多少轮?有没有遇到”明明第 5 轮说过的事,第 50 轮它不认了”这种中间遗忘?当时怎么修的?

互动提问:如果只上一件事,你会先做子 Agent 隔离、先做滚动压缩,还是先把用户约束固化到窗口顶部?

分享到:

微博
Twitter
LinkedIn

— IMAI 编辑部 | 2026-11-05

发表评论