04.04概念更新于 2026年9月17日

上下文腐化

上下文不是越长越好:注意力稀释、干扰信息与“中间遗忘”。

04.04 · 课时讲解

上下文腐化

窗口是容量,不是理解力;Token 越多,每条信息的利用往往越差。

1 / 11

一句话理解:上下文窗口是容量,不是理解力;放进去的 Token 越多,模型对每一条信息的利用往往越差,这就是上下文腐化(Context Rot)。

模型的上下文窗口这几年增长得很快。以 Claude 为例,官方文档显示多款当前模型已支持 1M Token 的上下文窗口。于是很自然地出现一种想法:既然装得下,何必费心筛选?把所有文档、所有历史、所有工具结果都放进去,让模型自己找。

这种做法在 Demo 里常常看起来可行,在生产环境里却会以一种很难排查的方式失败:Agent 没有报错,只是越跑越“笨”——忘记早先确认过的约束、重复调用已经调用过的工具、在长报告里漏掉关键的一行。这一课解释背后的原因,以及产品上应该怎么应对。

直觉:注意力是有预算的

Anthropic 在关于 Context Engineering 的文章里用了一个比喻:模型和人一样,有一个有限的“注意力预算”,每多放入一个 Token,就会消耗一点这个预算。

从机制上看,Transformer 需要在所有 Token 之间建立关联。上下文越长,需要处理的关系越多,模型能分给任何一条具体信息的“关注”就越稀薄。这不是某个模型的缺陷,而是一种普遍的趋势:上下文长度增加时,准确性与召回能力会逐渐下降。 Claude 的官方文档在介绍上下文窗口时也直接写明了这一点,并把它称为 context rot。

可以把它想象成开会:会议材料 3 页时,每个人都能记住关键数字;材料 300 页时,大家都“看过了”,但很少有人记得第 147 页那条例外条款。

同一条关键条款,放在长短不同的上下文里,处境完全不同:

注意力稀释:同一条关键信息在短上下文与长上下文中得到的关注对比 3 页材料 模型的注意力 300 页材料 模型的注意力 资料 A 关键条款 资料 C 块数少,每块都能被看清 关键条款被相似内容包围,分到的注意力变少
图 1 · 注意力稀释:材料越多,关键信息分到的关注越少

腐化的表现与研究证据

四种表现

表现 发生了什么 客服 / Coding 场景的例子
注意力稀释 关键信息被大量无关内容包围 3000 条支付流水里,“退款单已被驳回”那一条被忽略
干扰项误导 与问题 相似但不相关 的内容被当成答案依据 检索到了另一个订单号相近的订单的记录,Agent 用它下结论
中间遗忘 位于长上下文中部的信息更容易被忽略 会话初期用户说“只看企业版客户”,20 步之后被遗忘
错误累积 早期的错误假设留在上下文里,持续影响后续判断 Coding Agent 一开始误判 Bug 在前端,后面的探索都围绕这个方向打转

最后一种在 Agent 中尤其危险。Chatbot 的错误通常停留在一次回复里,而 Agent 的上下文会把错误的中间结论一路带下去,后续每一步都在“被污染的文件袋”上做判断。

研究怎么说

这里只列经过核实、且对产品设计有直接启发的两项研究。

“Lost in the Middle”(Liu 等,发表于 TACL,2023):研究者把回答问题所需的关键文档放在长输入的不同位置,发现当关键信息位于开头或结尾时模型表现最好,位于中间时表现明显下降。这项研究基于当时的模型,具体程度会随模型迭代而变化,但“位置会影响利用率”这个直觉至今仍有参考价值。

这项发现可以画成一条示意曲线:

Lost in the Middle 示意:关键信息位于开头或结尾时利用得最好,位于中间时明显下降 模型对它的利用 开头:表现最好 结尾:表现最好 中间:明显下降 开头 中间 结尾 关键信息在长输入中的位置(示意趋势,不代表具体数值)
图 2 · 位置影响利用率:中部的信息更容易被忽略(示意)

Chroma 的 Context Rot 报告(2025 年 7 月):测试了 18 个模型,得到几个反直觉的发现:

  • 即使只加入 一个 干扰项,表现也会下降,而且不同干扰项造成的影响不同。
  • 问题与答案之间的 语义相似度越低,输入变长时表现下降得越快。也就是说,需要“绕个弯”才能找到的信息,最怕长上下文。
  • 在对话记忆类任务上,只给相关片段(约 300 Token)的表现显著好于给出完整历史(约 11 万 Token)。

一个值得注意的推论:常见的“大海捞针”测试通常是在无关文本里找一句字面高度相似的话,这是最简单的情形。模型在这类测试里表现很好,不代表 它在真实业务的长上下文里同样可靠。

对产品设计的五条启发

1. 以“最小充分”为目标,而不是“尽量完整”。 好的上下文是能支撑判断的最小信息集。多出来的部分不是免费的,它会拉低准确率。

2. 让工具返回“可用的结果”,而不是“全部的数据”。 支付流水查询默认返回程序计算好的摘要和异常点,需要时再取原文。这比让模型在几千行里自己找可靠得多。

3. 重要的东西放在显眼的位置,并在关键时刻重申。 固定规则放在系统指令里;当前目标和约束,可以通过持续更新的任务清单(Todo)让它们反复出现在上下文靠后的位置。很多 Coding Agent 在长任务中维护 Todo 列表,一部分作用就在于此。

4. 及时清理已经没用的内容。 旧的工具结果、被推翻的假设、失败的尝试,在完成使命后应当被清理或压缩成一句结论。具体方法见 长任务的上下文管理。

5. 相似但无关的内容比完全无关的内容更危险。 检索时召回了 10 份“看起来相关”的文档,其中 7 份是干扰项,效果可能不如只给 3 份准确的。这正是后面 混合检索与重排序 要解决的问题。

如何发现腐化

腐化很少直接报错,需要在评测和 Trace 里刻意寻找:

发现上下文腐化的四个信号及其含义 信号 1 上下文越长,同一问题正确率越低 做长度梯度测试:同一用例在第 1、10、30 步分别提问 信号 2 Agent 重复调用相同参数的工具 它“忘了”已经查过,或没从之前的结果里读到答案 信号 3 后期回复违反早期确认过的约束 例:用户说“不要发通知”,长任务末尾却建议发送通知 信号 4 结论引用了相似但不相关的实体 订单号、客户名、工单号张冠李戴 这些信号都可以转化为评测用例,放进评测集持续回归
图 3 · 腐化很少报错:四个要在评测与 Trace 里刻意寻找的信号

这些信号都可以转化为评测用例,放进评测集持续回归(参见 构建评测集)。

常见误区

  • “窗口到了百万级,就不需要做上下文管理。” 窗口决定上限,不决定质量。长上下文还意味着更高的成本和延迟。
  • “大海捞针测试满分,说明长上下文没问题。” 那是最简单的检索情形。真实任务需要推理、需要处理干扰项,难度高得多。
  • “信息多给了,模型自己会忽略无关部分。” 研究显示,哪怕一个干扰项都可能降低表现。与其指望模型忽略,不如一开始就不放进去。

设计要点

  • 评审方案时,问每一块大体积上下文:“去掉它,判断会变差吗?”答不上来就先去掉,用评测验证。
  • 为长任务 Agent 设计“长度梯度”评测,而不仅是单步评测。
  • 工具默认返回摘要与异常点,原文通过 ID 按需获取。
  • 当前目标、关键约束、已排除项放进持续更新的任务状态,而不是只留在早期对话里。
  • 检索宁缺毋滥:召回之后要重排与截断,不要把 Top 20 全塞进去。

练习

用你能调用的任意一个模型,做一个 30 分钟的小实验:

  1. 准备一个知识库问题,例如“根据以下资料,订单 ORD-1024 的退款为什么没有到账?”,以及 3 段真正相关的资料。
  2. 版本 A:只给 3 段相关资料。版本 B:3 段相关资料 + 20 段相似但无关的资料(例如其他订单的记录、旧版政策),并把相关资料放在中间。
  3. 各跑 5 次,记录正确率和答案中是否出现了“张冠李戴”。写一段话总结你观察到的差异。

延伸阅读

下一步

既然上下文不能无限累积,长任务怎么办?下一课「长任务的上下文管理」会讲摘要压缩、外置笔记、清理旧工具结果与子任务隔离。

试试:上下文、MCP、沙箱、Prompt 注入、外链