窗口变长之后,随之而来的是一种特定的诱惑:不再做选择。既然都放得下,那就全放进去,让注意力自己去分辨。

我们试过,在试错成本最低的那几条检索路径上。它站不住。容量和可用容量是两个不同的量,而且窗口填得越满,两者的差距越大。

调用链显示了什么

在我们测过的路径上,这个形状是一致的,而且它不是一道出现在极限处的悬崖。质量在窗口填满之前很久就开始移动 —— 先是同一条输入在多次运行之间的方差略微变大,然后是一种具体的失败:模型用”在场的、看上去相关的”材料作答,而不是用真正能定案的那份材料。

有三个效应可以拆开看,它们重要的原因各不相同。

位置。 处在长上下文中段的证据,比同一份证据放在两端时被使用得更不可靠。这一点在别处已有充分记录,而且它扛过了我们试过的每一种 prompt 层面的绕法。它是一个要围绕它做设计的性质,不是一个能靠措辞绕过去的 bug。

竞争。 加进一段与正确材料主题相近、但并不回答问题的文字,比不加更糟。“差一点命中”比”完全无关”昂贵,因为无关材料容易被忽略,而差一点命中的不会。

累积。 在多轮和 agentic 路径里,上下文是靠追加长大的 —— 历史轮次、工具输出、中间摘要 —— 而累积下来的东西,到了真正要用的时候大多已经过期。一个已被取代却仍留在上下文里的中间结果,不会惰性地待在那儿。它会参与竞争。

这些都不是在说长上下文没用。它们说的是:更大的窗口改变的是什么负担得起,不是什么是正确的。

我们移除了什么

在生产里活下来的规则,按我们施加的顺序:

  1. 为问题检索,而不是为主题检索。 检索的单位是”一条可能给问题定案的论断”,不是”一篇提到了这个主题的文档”。这一个改动消除的”差一点命中”,比我们后来叠上去的任何重排都多。
  2. 被取代的状态要丢弃,而不是继续追加。 当一个中间结果被替换,旧的那个就离开上下文。那些把完整历史一路追加下去的 agentic 路径,正是长程运行中行为会漂移的那些。
  3. 决定性的材料靠近两端。 既然位置效应无法靠 prompt 绕开,排序就是一个设计参数:决定答案的那份材料,要放在模型可靠地读到的地方。
  4. 压缩叙述,永不压缩证据。 历史轮次变成简短的事实摘要;而答案必须可被核对的那些原文段落,保持逐字保留。被压缩过的证据会产出无法审计的答案 —— 因为被引用的东西,已经不再以被引用时的形式存在了。
  5. 在窗口半满的状态下做测量。 只跑短上下文的 eval 套件,认证的是一个没有人在运行的系统。我们用真实的上下文长度跑同一批用例,而两者之间的偏离本身就是一个指标。

经济性变了,纪律没变

现在多发 token 很便宜,所以”多放”的成本基本上不再是一个预算问题。这恰恰是纪律必须来自别处的原因。当”全放进去”很贵时,账单在替你执行取舍。现在没有任何东西在执行了 —— 除了继续取舍这个决定本身。

有用的重新表述是:上下文窗口不是存储,是工作集。问题从来不是放得下什么,而是这一个具体答案要正确需要什么、以及什么会与它竞争。窗口还很小的时候,这个问题的答案是一样的。