这篇学完你能回答什么
- 什么是 context rot?为什么上下文越长模型反而变笨?
- 除了「记不住」,长上下文还有哪些具体的失败形态?
- 你怎么知道自己的系统已经开始腐烂了?
从一个真实故障讲起
一个法务问答 Agent。团队的想法很朴素:既然模型有 100 万 token 的窗口,那就把整本 200 页的合规手册(约 15 万 token)直接塞进 system,一劳永逸,还省掉一整个检索模块。
上线后三个结果:
- 单条问答成本是原设计的 20 倍——产品捏着鼻子认了;
- 首 token 延迟 8 秒——也勉强忍了;
- 真正把团队打懵的第三条:手册第 137 页白纸黑字写着的规定,模型答错了。 而把那一页单独拎出来、只给 800 token 时,它答得完全正确。
信息就在窗口里,模型「看不见」。
这不是模型没读,是它的注意力被稀释了。这个现象有个名字:context rot。理解它,你才会明白为什么 2026 年的主线是「策展」而不是「堆砌」。
200 页手册塞进 system
约 15 万 token,顺手省掉整个检索模块
成本涨到 20 倍
产品捏着鼻子认了
首 token 延迟 8 秒
也勉强忍了
第 137 页答错了断点
白纸黑字写着的规定,模型答不对
那一页单独拎出来
只给 800 token,它答得完全正确
核心概念:先打比方,再给定义
Context engineering(上下文工程)。官方定义的意思是:为模型的每一次推理策展并维护一组最优的 token,包括提示词之外所有可能落进上下文的信息——系统提示词、工具定义、检索结果、对话历史、外部记忆、按需加载的文档。
Context rot(上下文腐烂)。随着上下文里 token 数上升,模型从中准确召回信息的能力下降。所有模型都有这个特性,只是衰减快慢不同。
Attention budget(注意力预算)。本篇最重要的心智模型:上下文不是硬盘,是一份有限且边际递减的预算。
比喻:给你一张桌子和一叠资料。桌子再大,你能同时看清的纸也就那么几张。往桌上多摊 200 页,不会让你更懂,只会让你更难找到那一页。
桌子够大,一叠资料全摊得下
摊得下不等于看得清 —— 桌面大小只是必要条件
100 万 token 装得下整本手册
「窗口能装下」和「装进去还管用」是两回事,前者只是门槛
你能同时看清的纸就那么几张
多摊 200 页不会让你更懂,只会让你更难找到那一页
有限、且边际递减的一份预算
token 数一上升,模型从中准确召回信息的能力就下降 —— 这就是 context rot
原理拆解
- 有效召回接近 1.0那一页单独给 800 token,答得完全正确
- 开始往下掉注意力权重在全序列上被摊薄
- 干扰项开始抢语义相近但无关的内容混了进来
- 曲线最陡的一段15 万 token 全塞,第 137 页答错
四种失败形态,比「记不住」精确得多:污染(一次幻觉进了上下文,此后每轮都被当作事实,会自我强化)、干扰(历史太长后复读做过的动作,原地打转)、混淆(工具与检索太多,无关内容把信号挤掉)、冲突(系统提示词说简洁、技能文档说详尽,模型得先花力气仲裁)。
四个基本操作按代价从低到高:写出去(存到窗口之外的记忆)→ 挑进来(这一轮只放这一轮要的)→ 压缩(额外调用 + 信息损耗 + 前缀重写)→ 隔离(子代理各用各的窗口,代价最高)。不要跳级 —— 一遇上下文问题就上多 Agent 隔离,是最常见的错。
为什么会衰减? 几条统计性质叠加,不是某个 bug:
- 注意力权重是在全序列上归一化分配的。序列越长,单个位置能分到的权重越被稀释;
- 干扰项竞争。长上下文里必然混进大量语义相近但无关的内容,它们和正确内容抢注意力——这也是为什么「多塞一点也没坏处」是错的:多塞的每一段都是潜在干扰项;
- 长序列样本在训练分布里本来就稀疏,超长位置上的泛化天然更弱。
有效召回率
│
1.0┤●●●●●●
│ ●●●●
│ ●●●●
│ ●●●●●
│ ●●●●●●●
└────────────────────────────────────► 上下文长度
短 中 长 接近窗口上限
各家模型的曲线陡缓不同,但没有哪条是平的。
「窗口能装下」和「装进去还管用」是两回事。四种失败形态(比「记不住」精确得多,面试里很好用)
| 形态 | 表现 | 危险之处 |
|---|---|---|
| 污染 | 一次幻觉或一个错误的工具返回进了上下文,此后每一轮都被当作事实 | 会自我强化——模型基于错误结论继续推导,越走越远 |
| 干扰 | 历史太长后,模型开始复读历史里做过的动作,而不是根据当前状态决策 | 表现为「原地打转」,最终答案却看起来正常 |
| 混淆 | 工具太多、检索结果太多,无关内容把信号挤掉 | 选错工具、引用错文档,且看起来有理有据 |
| 冲突 | 不同来源的指令互相矛盾(系统提示词说简洁、技能文档说详尽) | 模型要先花力气仲裁,既慢又飘。官方在自家转录里就观察到过这类冲突 |
注意第四种:它把「上下文工程」和「提示词治理」连了起来——指令写得越多越严,冲突面越大。这正是官方为新一代模型删掉 80% 以上系统提示词、且编码评测无可测损失的直接背景。
四个基本操作(以及它们的代价排序)
写出去 (write) 把状态存到窗口之外的记忆 / 笔记里 代价:低,需要一套读写约定
挑进来 (select) 这一轮只放这一轮需要的 代价:低,需要检索或选择逻辑
压缩 (compress) 历史必然增长,到点做摘要式压缩 代价:中,额外调用 + 信息损耗 + 前缀重写
隔离 (isolate) 子代理各用各的窗口,互不污染 代价:高,引入交接损耗与编排复杂度
按代价从低到高上,不要跳级。 最常见的错误是一遇到上下文问题就上多 Agent 隔离——那是选择和压缩都做完之后才轮到的手段。
工程实践(截至 2026-08)
把窗口预算显式建模,不要让它自然生长:
| 分块 | 内容 | 建议 |
|---|---|---|
| 固定开销 | system + 工具定义 | 尽量薄;用渐进披露把冷门内容挪出去 |
| 状态块 | 关键约束、待办、已确认决定 | 每轮原样重新注入,不参与压缩 |
| 检索预算 | 本轮召回的资料 | 设硬上限,超了先降 top-k |
| 历史预算 | 对话与工具结果 | 设硬上限,超了触发清理或压缩 |
| 输出预留 | 思考 + 正文 | 高档位要留足,否则被截断 |
渐进披露(progressive disclosure)。官方的做法是把只在特定分支用得上的内容(代码审查流程、验证清单)拆成可被按需调用的技能文档,而不是全部前置塞进系统提示词。同样的思路也用在工具上:部分工具可以延迟加载,模型需要时才去检索完整定义,用不到就不占上下文。
对你的项目而言,这条翻译成一句可执行的话:别把「可能用得上」的东西放进每轮都带的位置。
怎么度量自己有没有腐烂——这是面试里的加分项,因为大多数人只会定性描述:
- 拆构成:把每轮进入窗口的 token 按来源分桶(system / 工具定义 / 工具结果 / 历史 / 检索),看占比随轮次怎么变。绝大多数 Agent 的答案是工具结果占了大头;
- 位置敏感性测试:拿一组已知答案的问题,把关键信息分别放在上下文的开头、中间、末尾,看准确率差异;
- 长度对照测试:同样的问题,分别在「精准注入 800 token」和「全量塞入 15 万 token」两种条件下跑,对比准确率——开头那个故障就是这么定位的;
- 轨迹指标:重复动作率、无效工具调用率。它们往往比最终答案更早暴露「干扰」这类问题。
避坑清单
- 别把「窗口装得下」当成「可以装」。 装得下只是必要条件。
- 别一遇到问题就上子代理隔离。 先清理、先选择、再压缩。
- 警惕污染的自我强化。 一个错误的工具返回如果没被清出去,后面每一轮都在给它背书;高风险场景要给工具结果做校验或加显式的「未验证」标记。
- 做冲突审计。 系统提示词、技能文档、用户指令之间打架时,模型先要仲裁,延迟和不稳定都会上升。
- 上下文治理的效果要用轨迹评测验证,不能只看最终答案对不对——路径变了,问题可能只是换了个地方冒头。
| 分块 | 内容 | 建议 |
|---|---|---|
| 固定开销 | system + 工具定义 | 尽量薄;用渐进披露把冷门内容挪出去 |
| 状态块最容易漏 | 关键约束、待办、已确认决定 | 每轮原样重新注入,不参与压缩 |
| 检索预算 | 本轮召回的资料 | 设硬上限,超了先降 top-k |
| 历史预算 | 对话与工具结果 | 设硬上限,超了触发清理或压缩 |
| 输出预留 | 思考 + 正文 | 高档位要留足,否则被截断 |
- 拆构成
- 每轮进窗口的 token 按来源分桶(system / 工具定义 / 工具结果 / 历史 / 检索),看占比随轮次怎么变
- 位置敏感性
- 一组已知答案的问题,把关键信息分别放开头、中间、末尾,看准确率差异
- 长度对照
- 同题分别在「精准注入 800 token」和「全量塞入 15 万 token」下跑 —— 开头那个故障就是这么定位的
- 轨迹指标
- 重复动作率、无效工具调用率,往往比最终答案更早暴露「干扰」这类问题
- 渐进披露
- 只在特定分支用得上的内容拆成按需调用的技能文档;部分工具也可延迟加载,用不到就不占上下文
- 冲突审计
- 系统提示词、技能文档、用户指令打架时,模型要先仲裁,延迟和不稳定都会上升
面试视角
- 先给心智模型上下文是注意力预算,有限且边际递减
- 再给机制注意力稀释 + 干扰项竞争 + 长序列样本稀疏
- 给失败形态污染 / 干扰 / 混淆 / 冲突,这是深度证据
- 落到代价排序写出去 → 挑进来 → 压缩 → 隔离,说自己项目做过哪一档
- 把 context rot 说成「上下文太长模型会忘」,说不出机制
- 认为大海捞针测试满分,就等于自己的系统没问题
- 能背四个操作,却说不出它们的代价差异
- 遇到上下文问题,第一反应是换个窗口更大的模型
- 被「有百万窗口为什么还要 RAG」问住 —— 只跟了口号
- 开口就区分「窗口大小」和「有效窗口」,不是一个东西
- 给得出可执行的度量:位置敏感性、长度对照,而非定性描述
- 知道治理要按代价排序,子代理隔离排在最后
- 报得出自己 Agent 上下文的构成占比,工具结果占了多少
- 举得出污染或干扰这类具体失败形态,并说明怎么发现的
面试官怎么问。 Q1-11 是概念入口,Q1-12 是机制追问。头部公司常用「既然有百万窗口,为什么还要 RAG」来做反向测试——这题答不好,说明你只跟了口号没跟机制。
答题结构建议
- 先给心智模型(上下文是注意力预算,有限且边际递减);
- 给机制(注意力稀释 + 干扰项竞争 + 长序列样本稀疏),不要只说「模型会忘」;
- 给失败形态(污染 / 干扰 / 混淆 / 冲突),这是深度证据;
- 给操作与代价排序,落到自己项目里做过什么。
分水岭信号
- 只读过:把 context rot 说成「上下文太长模型会忘」,说不出机制;认为大海捞针测试满分就等于没问题;能背四个操作但说不出代价差异;遇到上下文问题第一反应是换更大窗口的模型。
- 真做过:会主动区分「窗口大小」和「有效窗口」;能举出污染或干扰这类具体失败形态并说明怎么发现的;报得出自己 Agent 上下文的构成占比;知道治理要按代价排序、子代理隔离排最后;提得出可执行的度量方法而不只是定性描述。
小结与延伸
继续深入
本篇归属第 1 章「LLM 与 Prompt 基础」,去做这一章的题。