长上下文退化是指:模型虽然支持很大的上下文窗口,但当输入变长、信息位置变远、噪声变多或任务需要跨段推理时,模型未必能稳定利用全部上下文,输出质量可能下降。

这不是“上下文窗口不够大”的问题,而是“有效利用上下文”的问题。

Context window 是模型最多能接收多少 token。
Effective context length 是模型在真实任务里能可靠使用多少 token。

以常见 coding agent 的默认配置为例,上下文往往不会一上来就拉满模型标称的上限(例如 1M)。

标称 32K、128K、1M token,并不等于模型能以同等质量使用每一个位置的信息。

例如关键信息位于中间、存在大量干扰信息、需要多跳推理、需要理解隐含关系时,性能常会下降。

为什么会发生

1. 注意力不是“均匀阅读全文”

Transformer 的 self-attention 会为当前 token 计算它应该看前面哪些 token。

但这不等于模型会像人一样稳定读完整篇文章。每个 query 对前文 token 的注意力权重会经过 softmax 归一化,很多 token 在同一层、同一头里竞争有限的注意力质量。输入越长,候选 token 越多,噪声、重复内容、过期信息和无关段落也越容易参与竞争。

所以长上下文里的难点不是“模型看不见”,而是“模型看见了也未必选对、记住、整合并用于生成”。

2. 模型有位置偏置

很多模型对上下文位置的利用呈现不均匀模式:开头和结尾更容易被利用,中间更容易被忽略。

Lost in the Middle(Liu et al.)指出长上下文里中间位置的信息更容易被用不好。后续关于 positional attention bias 的研究进一步把它解释为一种位置注意力偏置:模型不只是按语义重要性分配注意力,也会受位置影响。

直观理解:

text
开头通常包含系统提示、任务说明、文章开头、标题或元信息,训练中经常很重要。
结尾离当前生成位置最近,天然更容易被自回归模型利用。
中间位置既不占开头优势,也不占近因优势,容易被大量内容淹没。

3. 位置编码存在长距离泛化问题

RoPE、绝对位置编码、相对位置编码等机制让模型知道 token 的顺序和距离。

但如果训练时主要见到较短序列,推理时突然给很长序列,模型需要在训练分布之外处理位置关系。

以 RoPE 为例,它通过旋转 Query 和 Key 的方式编码相对位置。长上下文扩展时,如果位置范围远超训练长度,旋转频率、距离关系和注意力分数分布可能进入模型不熟悉的区域。因此很多长上下文方法会做位置插值、RoPE scaling(如 NTK-aware、YaRN、PI 等思路)、继续训练或专门的长上下文数据训练,而不是只把窗口参数调大。

4. 训练目标和数据分布更偏短程依赖

语言模型主要通过 next-token prediction 训练。很多训练样本里的预测线索来自局部上下文:前一句、当前段落、最近几段。

这会让模型天然更擅长短程依赖,而不是稳定处理几十万 token 之外的证据。即使模型架构允许长距离注意力,训练数据中是否有足够多高质量长文档、多跳依赖、跨段推理样本,仍然决定它能否真的学会长上下文利用。

5. 检索成功不等于推理成功

“needle in a haystack” 任务通常把一条答案句藏进长文本里,让模型找出来。这类任务能测一部分长上下文检索能力,但不能代表所有长上下文理解。

真实任务更复杂:

text
证据可能分散在多个位置。
问题和证据可能没有相同关键词。
文档里可能有相互冲突的旧信息和新信息。
模型需要先判断哪些内容相关,再组合推理。

所以长上下文评估不能只看“能不能找到一句原文”,还要看跨文档推理、抗干扰、位置鲁棒性、引用准确性和任务成功率。

6. Agent 场景会出现 context rot

在场景比如coding agent 中,上下文会不断积累:

text
用户的新要求。
工具调用结果。
搜索结果。
文件片段。
测试日志。
失败尝试。
过期计划。
历史对话。

如果这些内容都原样塞回模型,模型可能被旧错误日志、重复信息或已经废弃的假设影响。工程上常把这种“上下文越积越乱,模型越难稳定工作”的现象叫 context rot。

So

  1. 不要把“能塞进去”当成“能用得好”

  2. 关键信息要放在模型容易利用的位置

  3. 控制噪声比单纯拉长上下文更重要

  4. 长任务要用压缩和状态管理

  5. 评估要做位置扫描和干扰测试