概念科普 📅 2026-10-10 ✍️ MagicNetWorld 编辑部

上下文工程:为什么把上下文窗口做大,不等于让模型变聪明——注意力预算、Context Rot 与四类上下文手段

把模型的上下文窗口从 128K 扩到 1M、10M,很多人默认它会「更聪明」。近两年的实测给出了相反信号——严格说,是 2023 年以来的实测:Chroma 在 18 个模型上测出输入越长性能越不可靠;Lost in the Middle 发现关键信息落在中段时性能显著下滑;一份厂商技术报告记录的 Gemini 2.5 Pro 虽支持 1M 以上窗口,却在约 100K token 之后(该宝可梦 Agent 场景)更倾向于复读历史动作而非规划。根因在于 Transformer 的注意力要对 n 个 token 建立 n 平方级别的两两关系,窗口越长,每条关系分到的注意力预算越薄。本文用「工作台不是仓库」的类比讲清注意力预算,再把「窗口变大不等于变聪明」从直觉、形式化推到实测,最后给出上下文工程的四类手段:写入、选取、压缩、隔离。

上下文工程AI Agent注意力机制长上下文

过去两年,模型厂商每隔几个月就把上下文窗口往上翻一倍:128K、200K、1M,甚至 10M token。每一次发布,评论区里都会出现同一句话——「窗口这么大,以后直接把资料全塞进去就行了,RAG 该退休了」。这句话听起来很顺,但它把一件事搞反了:上下文窗口是「容量」,不是「能力」。一个能装一万升水的桶,不会因为桶变大就自己变聪明;真正决定模型在这桶水里能不能找到那根针的,是它每一步能「盯住」多少东西。

本文要回答的就是这个常被搞混的问题:为什么上下文窗口变大,不等于模型变聪明。我们会按「直觉 → 符号 → 形式化 → 推导 → 工程含义 → 边界」的顺序走一遍,全程只用一个例子穿起来:一个要在几十万 token 的历史里做决策的 AI Agent。凡引用他人结论处,一律标注一手来源(论文名 / 官方博客 + 编号或日期);凡本文自己算出来的数(例如注意力权重的量级、KV 缓存的显存估计),一律在文末「本文自行推导」一节单列,与官方数字分列,只作量级一致性检查,不得当作官方数值引用。

一、先给直觉:上下文是工作台,不是仓库

先做一个生活化的类比。你的书房里有一个仓库和一整面工作台。仓库可以很大,几万本书都塞得下;工作台只有一米宽,你此刻手上能摊开的书、笔、草稿纸,最多也就那么几样。

现在想象一个苛刻的规则:你每一步只能看一遍工作台,而且要在一瞬间决定下一步做什么。这时候会发生什么?如果把整个仓库的书都倒到工作台上,你并不会因此更博学——你反而找不到刚才那支笔了。桌面的面积变大了,但你「同一时刻能真正聚焦的东西」并没有变多,甚至被稀释了。

Transformer 做决策,遵守的正是这条规则。所谓上下文(context),就是这一步推理时喂给模型的那一串 token;所谓上下文窗口(context window),就是这串 token 的长度上限——它是仓库的容量。而注意力预算(attention budget),是模型在这一步里真正能「分给每个 token」的注意力总量——它更像你的目光,是有限且会被摊薄的。

Anthropic 在 2025 年 9 月的官方工程博客里把这个说法写得很直白:LLM 和人一样,有一笔「注意力预算」,每引入一个新 token 都会消耗掉一点,因此上下文必须被当作一种边际收益递减的有限资源来对待(Anthropic,“Effective context engineering for AI agents”,2025-09-29)。换句话说,窗口是仓库,注意力预算才是工作台;厂商在拼命扩的是仓库,而决定 Agent 表现好坏的,是它有没有把真正要紧的东西摆到那一米工作台上。

1.1 一个常见说法与本文立场

你可能听过这句话:「现在窗口都 1M 了,RAG 那套拼接检索该淘汰了。」它一半对、一半错:

  • 对的那半——「取回来」这件事确实变简单了,你不必再为了塞不下而精挑细选;
  • 错的那半——「塞进去之后模型能不能用好」是完全另一个问题,而且窗口越大,这个问题往往越严重。

本文的立场是:窗口是必要条件,不是充分条件。它买来的是「装得下」,买不来「看得清」。所以本文既不唱衰长窗口,也不鼓吹「无限塞」;它要给的是一个可操作的判据——在什么任务上、长上下文会从帮手变成负担。

这一节想让你记住的一件事: 上下文窗口是「能装多少」,注意力预算是「能同时看清多少」——前者翻倍,不代表后者变大。

二、符号与术语约定

后面要用到的记号和术语先约定清楚,免得读到公式时卡壳。凡是术语第一次出现,都顺手给一句人话定义。

记号 / 术语含义(人话版)
nn当前上下文里的 token 数。可以理解成工作台上摊开的「东西」个数。
dkd_k单个注意力头的维度,是张量形状参数,不是数据量。
LLTransformer 的层数。
aia_i对某一给定的 query,第 ii 个 token 分配到的注意力权重(每个 query 各自归一化,权重之和为 1);可理解为「模型看这一个 token 的目光占比」。
注意力预算模型在一步推理里可分配的总注意力;权重之和恒为 1,所以它是一块固定大小的蛋糕。
上下文腐化(context rot)输入 token 越多,模型从这段上下文里准确取用信息的能力越差的现象(Chroma 技术报告,2025-07-14)。
有效上下文模型真正能「稳定用上」的长度,通常远小于标称窗口。
KV 缓存推理时缓存每个 token 的 key/value 张量,避免重复计算;它随长度线性增长。
上下文工程(context engineering)在推理时动态挑选与维护「喂给模型哪一串 token」的一套策略,是提示工程(prompt engineering)的下一层(Anthropic,2025-09-29;LangChain,2025-06-23)。

这里有一个容易踩的坑先说破:「窗口大小」和「有效上下文」是两个不同的数。厂商宣传的是前者(例如 1M、10M),而在真实任务里你能稳定拿到的,往往是后者的量级——后面第五节会给出实测证据。

2.1 三组最容易混用的词

初学者最容易把下面三组词当成同义词,其实它们指的完全不是一回事:

  • 上下文窗口 vs 有效上下文:前者是模型的接收上限(硬指标),后者是它稳定用得上的长度(软指标)。厂商宣传前者,实践中你面对的是后者。
  • 提示工程 vs 上下文工程:前者关心「这句话怎么写」,后者关心「这一步到底该喂进哪些 token」(含工具定义、外部资料、历史消息)。LangChain 直接把提示工程归为上下文工程的子集(LangChain,2025-06-23)。
  • 注意力预算 vs 上下文长度:长度是「给了多少东西」,预算是「能分多少目光」。长度翻倍不等于预算翻倍——预算的总量几乎是恒定的(权重和为 1)。

把这三组分开,后面所有讨论都不会再绕。

2.2 把上下文拆成一本「预算账本」

上面这些记号合起来,可以写成一条很实用的「预算等式」。模型这一步能用的总长度,是被下面几项共享的:

n总=n系统提示词+n工具定义+n少样本示例+n对话历史+n检索文档+n输出预留n_{\text{总}}=n_{\text{系统提示词}}+n_{\text{工具定义}}+n_{\text{少样本示例}}+n_{\text{对话历史}}+n_{\text{检索文档}}+n_{\text{输出预留}}

把它读成一本账:左边是固定额度,右边是几笔必须分完的开支。于是「上下文管理」就变成一个很具体的动作——决定哪几笔该省、哪几笔该留。

账目经验量级该省还是该留
系统提示词小留,但别堆 if-else
工具定义中到大精简,工具越多越差
少样本示例中留少量「典范」,别堆边界情况
对话历史大且持续增长定期压缩、清理工具输出
检索文档波动大按需取、别预灌
输出预留小但关键必须留,别塞满

(表中「经验量级」是定性估计,不是实测值,仅供排产时参考。)

这一节想让你记住的一件事: 把「窗口」和「有效上下文」当成两个数来读,是本篇后面所有结论的前提。

三、把「预算」写成公式:注意力为什么天生受限

先看注意力的定义,这是所有讨论的起点。给定查询矩阵 QQ、键矩阵 KK、值矩阵 VV,一层自注意力是:

Attn(Q,K,V)=softmax ⁣(QK⊤dk)V\mathrm{Attn}(Q,K,V)=\mathrm{softmax}\!\left(\frac{QK^{\top}}{\sqrt{d_k}}\right)V

中间的 softmax\mathrm{softmax} 是关键:它把每一行的分数压成一组加起来恰好等于 1 的权重。也就是说,对序列里的第 ii 个位置,权重是

ai=exp⁡(si)∑j=1nexp⁡(sj),∑i=1nai=1a_i=\frac{\exp(s_i)}{\sum_{j=1}^{n}\exp(s_j)},\qquad \sum_{i=1}^{n}a_i=1

这条「权重和为 1」的约束,正是注意力预算的数学来源。想象你把 1 块钱(总预算)分给 nn 个人:nn 越大,平均每个人能拿到的就越少。若把各位置的分数近似看成独立同分布,权重的期望量级满足

E[ai]≈1n⟹ai=O ⁣(1n)\mathbb{E}[a_i]\approx\frac{1}{n}\quad\Longrightarrow\quad a_i=O\!\left(\frac{1}{n}\right)

这就是「注意力被稀释」最朴素的一行推导:上下文越长,模型分给单个 token 的平均注意力越小。当然,真实模型不是均匀分配——softmax 的指数会把少数高相关 token 的权重顶起来。但当 nn 从 4K 涨到 400K(差两个数量级)时,若没有任何机制补偿,同一对高相关 token 能分到的相对权重会被显著摊薄。Anthropic 的说法与此一致:LLM 基于 Transformer,每个 token 都要和其余所有 token 建立关系,于是 n 个 token 产生 n 平方级别的两两关系;上下文越长,这些关系被「拉伸得越薄」,形成了上下文长度与注意力聚焦之间的天然张力(Anthropic,2025-09-29)。

把计算代价也写出来,方便后面对照:

QK⊤⏟Θ(n2d)  +  softmax(⋅) V⏟Θ(n2d)  =  Θ(n2d)\underbrace{QK^{\top}}_{\Theta(n^{2}d)} \;+\; \underbrace{\mathrm{softmax}(\cdot)\,V}_{\Theta(n^{2}d)} \;=\; \Theta(n^{2}d)

即序列长度翻倍,注意力的计算量约变为 4 倍;而 KV 缓存的大小随长度线性增长(约变为 2 倍)。全部层合计大致是

MKV=2⋅L⋅n⋅nkv⋅dhead⋅bM_{\mathrm{KV}}=2\cdot L\cdot n\cdot n_{\mathrm{kv}}\cdot d_{\mathrm{head}}\cdot b

其中 nkvn_{\mathrm{kv}} 是 KV 头数、dheadd_{\mathrm{head}} 是头维度、bb 是每元素字节数,系数 2 对应 key 与 value 各一份。这条公式解释了为什么「窗口免费变大」是错觉——长度 n 每升一个量级,缓存的显存与搬运成本就跟着上一个量级。

3.1 一个手算例子:n 从 4K 涨到 400K

把上面的量级关系代进几个真实长度,能直观看出稀释有多快。取「分数近似独立同分布」这个简化假设:

上下文长度平均注意力权重约 1/n相对 4K 的稀释倍数
4,096(4K)约 2.4e-41 倍
32,768(32K)约 3.1e-5约 8 倍
131,072(128K)约 7.6e-6约 32 倍
400,000(约 400K)约 2.5e-6约 100 倍

读法:从 4K 到 400K,长度涨了约 100 倍,平均每个 token 能分到的注意力权重也掉了约 100 倍——这不是巧合,而是权重之和恒为 1 这条归一化约束的直接后果。

但这里必须补一句,否则会误读:真实模型不是均匀分配。softmax 是指数函数,高相关 token 的权重会被指数级放大,所以「平均权重掉 100 倍」不等于「关键 token 的权重也掉 100 倍」。真实情况是:模型靠「尖峰」把注意力抢给少数 token,而 n 越大,抢这一步的竞争越激烈,同时训练时见过长距离尖峰的机会越少。把这两件事合起来看,才能解释为什么长上下文「大多数时候还行、关键时刻掉链子」。

3.2 注意力预算的三种「花法」

注意力预算不会只被「长度」消耗。把它想成一笔钱,至少有三种花法:

  • 被长度花掉:nn 越大,平均每个 token 分到的越少——这是本节讨论的主线。
  • 被格式花掉:同样一段信息,写成一大坨 JSON 和写成一句简短错误信息,模型「读懂」的成本不同。LangChain 指出:一条简短但信息量足的错误信息,往往比一个大 JSON blob 更有用(LangChain,2025-06-23)。
  • 被无关内容花掉:塞进来的无关文档、多余工具定义,模型仍要为它们分配注意力——Berkeley 函数调用排行榜显示「工具越多越差」,GeoEngine 里「46 个工具失败、19 个成功」正是这条的极端例子(经 Breunig 转述)。

所以「少而准」不只是长度问题,格式与相关性同样在花钱。这也是为什么 Anthropic 把目标写成「最小的高信号 token 集合」,而不是「最短的集合」——短不等于好,冗余不等于安全。

3.3 三个约束不是一回事:算力、显存、注意力质量

初学者常把「长上下文的代价」笼统说成一个「贵」字,其实是三个互相独立的约束,必须分开看:

  • 算力约束:注意力是 Θ(n2d)\Theta(n^2 d),长度翻倍,计算量约四倍——这是「能不能算完」。
  • 显存与带宽约束:KV 缓存随 nn 线性增长,搬运量也线性上升——这是「装不装得下、搬不搬得动」。(FlashAttention 一类的动机正在于此:分块后中间矩阵不必写回显存,只把 Q/K/V 分块搬进片上内存——瓶颈常在搬运而非计算。)
  • 注意力质量约束:即便算力与显存都够,权重仍会被稀释、长距离关系仍不熟练——这是「就算跑得动,跑得好不好」。

前两个是工程问题,可以靠更好的内核、更省的缓存、更快的带宽缓解;第三个是模型问题,扩窗口并不能自动解决。把三者分开,你就不会再用「我们硬件很强」去回答「为什么模型在长上下文里变笨」——那是两个层面的问题。

这一节想让你记住的一件事: softmax 强制权重和为 1,所以注意力是一块固定大小的蛋糕;nn 越大,平均每块越小,这就是「注意力预算」的数学本质。

四、三条稀释机制:窗口变大为什么不等于变聪明

有了「预算是固定蛋糕」这个前提,「窗口变大 ≠ 变聪明」就可以拆成三条独立机制来理解。

flowchart TD
    N[上下文变长 n 增大] --> A[机制一 注意力稀释]
    N --> B[机制二 训练分布偏移]
    N --> C[机制三 位置编码外推退化]
    A --> R[中段信息更难被取用]
    B --> R
    C --> R
    R --> X[检索与长程推理精度下降]

这张图说明了什么:窗口变大之所以不等于变聪明,是因为它同时触发了三条各自独立、方向一致的稀释机制,最终都指向「检索与长程推理精度下降」这一个结果。

机制一:注意力稀释(attention dilution)。 就是上一节那行 E[ai]≈1/n\mathbb{E}[a_i]\approx 1/n。蛋糕还是那块蛋糕,分的人多了,每个人拿到的自然少。

机制二:训练分布偏移(train/inference length mismatch)。 模型是在训练数据上学「怎么分配注意力」的,而训练语料的序列长度分布偏向较短的一侧——长序列本来就少见。Anthropic 指出,这意味着模型对「跨越整个上下文的全局依赖」经验更少、专门参数更少(Anthropic,2025-09-29)。通俗说:你在训练时大多只见过「一页纸」的活儿,现在硬塞给它「一整柜档案」,它分配注意力的直觉是没被充分训练过的。

机制三:位置编码外推退化(position encoding extrapolation)。 模型原始能处理的长度是有限的,想让它吃更长的输入,就得靠位置编码插值把新长度「压」回它训练过的范围。Anthropic 明确说,这类做法虽然让模型能处理更长序列,但会带来token 位置理解的退化(Anthropic,2025-09-29)。

三条机制合起来,导出了这篇文里最重要的一句结论,也是 Anthropic 的原话意译:变长带来的是一条平滑的性能斜坡,而不是一道断崖——模型在长上下文下依然可用,只是相比短上下文,在信息检索与长程推理上会精度下降(Anthropic,2025-09-29)。这就是为什么很多人「感觉」大窗口很好用:在简单的检索任务上,它确实还行;一旦任务变成多步推理,斜坡就开始往下走了。

4.1 三条机制如何叠加:为什么是「斜坡」而不是「断崖」

把三条机制放在一起看,就能解释「斜坡」是怎么来的:

  • 只考虑机制一,注意力随长度平滑稀释,性能缓慢下滑;
  • 叠加机制二,模型对长距离依赖经验不足,长程推理额外吃亏;
  • 再叠加机制三,位置编码外推让位置分辨退化,越靠后的内容越难被精确定位。

三者方向一致、又都不是「到某个长度突然失效」,合起来就是 Anthropic 说的那条平滑下坡。这对工程有一个直接推论:任务的「难度类型」决定你落在斜坡的哪一段。单跳检索(大海捞针)落在平缓段,所以你「感觉能用」;多跳、跨段、需要保持全局一致性的推理落在陡峭段,于是「同一段长上下文,简单任务过、复杂任务崩」。这也解释了为什么用大海捞针测试「长上下文已解决」是危险的——它恰好在斜坡最平的地方取样。

4.2 一个小算例:同一段长上下文,为什么简单任务过、复杂任务崩

不必真的跑模型,用「预算 + 竞争」就能推出一个定性结论。设想一段 128K 的上下文,里面有两类任务:

  • 单跳检索:只要模型把注意力集中到一个关键片段上,其余的一百多个 K 全是干扰也问题不大——因为尖峰机制能把它顶起来。
  • 多跳推理:模型必须同时稳住好几个分散在不同位置的片段,串起来才能得出答案。这时稀释的代价被成倍放大——任何一个环节被削弱,整条链就断。

把机制二、机制三叠上去更糟:多跳依赖的恰好是长距离关系(训练时见得最少)与精确位置分辨(外推最易退化)这两块。于是同一段 128K 上下文里,单跳任务轻松通过,多跳任务频繁失败——这与窗口标称值无关,与任务对「同时聚焦」的要求有关。

这一节想让你记住的一件事: 稀释不是一道墙,是一条斜坡——这就是「感觉能用」却「关键时刻掉链子」的来源。

五、实测证据:从 Lost in the Middle 到 Context Rot

直觉和公式之外,还有三组可复现的实测,性质各不相同,正好互为补充。

证据一:Lost in the Middle(关键信息的位置效应)。 Liu 等人(arXiv:2307.03172,arXiv 2023;TACL 2024)在一项「多文档问答」和一项「键值检索」任务上发现:当相关信息的位置改变时,模型性能会显著波动;性能往往在信息位于上下文的开头或结尾时最高,而当模型必须取用中段的信息时明显下滑——即便是宣称支持长上下文的模型也如此。他们的原话结论是:当前语言模型并不能稳健地利用长输入上下文(Liu 等,arXiv:2307.03172)。这条证据说明:即使总长度一样,信息放在哪都会改变结果。

证据二:Context Rot(输入越长,性能越不可靠)。 Chroma 的技术报告(Hong、Troynikov、Huber,2025-07-14)用18 个模型(含 GPT-4.1、Claude 4、Gemini 2.5、Qwen3)做了受控实验,特意固定任务复杂度、只改变输入长度,以便把「长度」这个变量单独隔离出来。结论是:模型并非均匀地使用上下文,性能随着输入变长越来越不可靠,而且不同模型退化的方式并不一致(Chroma,2025-07-14)。报告还专门指出:常用的「大海捞针」(needle-in-a-haystack)基准只是字面检索,过于简单,会让人误以为长上下文「已经解决」;一旦针与问句之间需要语义联想(NoLiMa 一类的非字面匹配),性能会明显下挫(Chroma,2025-07-14)。

证据三:四种「上下文变脏」的方式。 Drew Breunig 在《How Long Contexts Fail》(2025-06-22)里把长上下文的失败归纳为四类,并引了各自的来源:

  • 上下文中毒(poisoning):一个幻觉写进上下文后被反复引用,越滚越错。他引 Gemini 2.5 技术报告里玩《宝可梦》的 Agent 为例:一旦目标或被污染,模型会执着于不可能完成的目标。
  • 上下文分心(distraction):上下文长到一定程度,模型过度依赖上下文、忽略训练学到的能力,表现为复读历史动作而非规划。同一份报告中提到,Gemini 2.5 Pro 虽支持 1M 以上窗口,但在该 Agent 场景里,上下文显著超过 100K token 后它更倾向于复读历史动作;Breunig 另外引用一项 Databricks 的研究指出,Llama 3.1 405B 的正确率在约 32K 附近开始下降,更小的模型更早。
  • 上下文混淆(confusion):无关内容也会干扰输出。他引用 Berkeley 函数调用排行榜的做法指出,给模型的工具越多,每一个模型都表现更差;并引一项评测:在含 46 个工具的 GeoEngine 场景里,量化的 Llama 3.1 8B 给全部 46 个工具时失败,只给 19 个工具时反而成功——而此时上下文远未撑满其 16K 窗口。
  • 上下文冲突(clash):上下文自相矛盾。他引一个 Microsoft/Salesforce 团队的工作:把同一题的信息拆成多轮对话喂入后,模型平均成绩掉约 39%,其中 o3 的分数从 98.1 掉到 64.1——原因是早轮里「半懂不懂就抢答」的错误答案留在了上下文里,把最终答案带偏。

把三组证据并排,得到一张对照:

现象一手来源关键量 / 结论
中段信息更难取用Liu 等,arXiv:2307.03172性能呈「两头高、中间低」,长上下文模型亦然
输入越长越不可靠Chroma,2025-07-14受控实验覆盖 18 个模型,退化方式因模型而异
超长后转为复读Gemini 2.5 技术报告(经 Breunig 转述)该场景约在 100K token 后转向复读历史动作
正确率提前下降Databricks 研究(经 Breunig 转述)Llama 3.1 405B 约 32K 起下降,小模型更早
工具越多越差Berkeley 函数调用排行榜(经 Breunig 转述)每个模型在工具数 > 1 后都下滑
多轮拆解即失分Microsoft/Salesforce(经 Breunig 转述)平均掉约 39%,o3 由 98.1 跌至 64.1

5.1 怎么判断你的 Agent 是不是「上下文病了」

把上面的机制倒过来用,就是一份排障清单。当 Agent 表现异常时,先别急着换模型,先按症状对号入座:

症状最可能的机制对应手段
反复执行相似动作、不推进分心 distraction压缩历史 + 重写待办清单,把目标「念」到末尾
一直引用某条早期错误结论中毒 poisoning压缩切断传播;把该子任务隔离到干净窗口重做
调用了明显无关的工具混淆 confusion精简工具集、删无关文档
多轮拼凑后答案反而更差冲突 clash保持单一线性上下文、共享完整 trace
找不到几十步前的重要结论中段失焦写入外部记忆 + 即时检索,别指望它自己记住

除了对号入座,还可以做两个受控实验:① 固定任务、只改输入长度(像 Chroma 那样),看性能是否随长度单调下滑——若是,说明是「长度」在作祟,而不是任务本身变难;② 把关键信息从开头移到中段(像 Lost in the Middle 那样),看结果是否变化——若变差,说明模型在用「位置」而非「语义」找信息。第三个可观测信号是成本与延迟:记录每步的输入 token 数与首字延迟,一旦输入 token 数随轮次线性膨胀而输出始终很短,就该考虑压缩与选取了。

验完症状,还要问一句:这些结论在你手上的模型上成立吗? 下一节给出一张速查表,但请把它当「当时的观测点」,而不是「永久常数」。

5.2 为什么「有效上下文」常被高估:基准的三个偏差

如果「长上下文已解决」是错的,那它是怎么被广泛相信的?答案在测法。三个系统性偏差:

  • 偏差一:只测字面检索。 大海捞针(NIAH)里针与问句字面重合,模型只要字符串匹配就能答对,几乎不考验「语义理解」。Chroma 特意指出,这类基准低估了真实任务的难度(Chroma,2025-07-14)。
  • 偏差二:不带干扰物。 真实上下文里满是主题相关但不回答问题的干扰句;Chroma 报告专门区分并研究了「干扰物 vs 无关内容」的不同影响(Chroma,2025-07-14)。只测「干净的海」会高估能力。
  • 偏差三:只测单跳。 大海捞针是「找一处、答一句」,而 Agent 的真实任务往往是多跳、跨来源、要保持一致——恰恰落在 4.2 节说的陡峭段。

结论:看到「某模型通过 1M 大海捞针」,先问它测的是哪一种。这不是否定该基准的价值,而是提醒你——它测的那件事,未必是你关心的事。

5.3 三组证据为什么互相补位

细看会发现,三组证据的「自变量」各不一样,正好覆盖三个维度,谁都不能替代谁:

  • Lost in the Middle 变的是「位置」:长度固定,只挪动关键信息的位次——测出的是位置敏感。
  • Chroma 变的是「长度」:任务复杂度固定,只拉长输入——测出的是长度敏感。
  • Breunig 归纳的是「内容」:错误、无关、冲突的内容混进来会怎样——测出的是内容敏感。

三者合起来才是完整的画面:长上下文的问题不在「够不够长」,而在位置、长度、内容三者一起作用。这也是为什么只报一个「通过 1M 测试」的结论不足以说明问题——它只是在某一个维度上取样。

这一节想让你记住的一件事: 三组独立实验指向同一件事——长上下文下「掉链子」是可复现的,不是个别模型的毛病。

六、上下文工程的四类手段

既然「把东西全塞进去」行不通,正确的姿势就是主动管理摆到工作台上的东西。业界把这套做法叫上下文工程。可以把它归成四类手段:写入(write)、选取(select)、压缩(compress)、隔离(isolate)。

flowchart TD
    A[Agent 循环] --> B[写入 把要点写到外部记忆与笔记]
    A --> C[选取 按需检索与即时加载]
    A --> D[压缩 摘要历史与清理工具输出]
    A --> E[隔离 用子智能体跑独立窗口]
    B --> A
    C --> A
    D --> A
    E --> A

这张图说明了什么:四类手段不是四个孤立动作,而是围绕同一个 Agent 循环运转的四条回路——写入把状态外置、选取按需取回、压缩给历史瘦身、隔离把脏活挪到别的窗口里。

写入(write)。 让 Agent 把关键状态写到上下文之外的持久存储里,需要时再拉回来。Anthropic 把它叫「结构化笔记 / 代理式记忆」,举例说 Claude Code 维护一个待办清单、自定义 Agent 维护一个 NOTES 文件,就能跨几十次工具调用记住进度(Anthropic,2025-09-29;这一思路可上溯到把 LLM 当作操作系统的 MemGPT,Packer 等,arXiv:2310.08560)。Manus 团队的观察更传神:它发现 Agent 处理复杂任务时会自发地写一个 todo 文件并逐步勾掉——这不是可爱,而是把目标「念」到上下文末尾,借重写清单来操纵注意力,规避中段失焦(Manus,“Context Engineering for AI Agents”,2025-07;他们报告单个任务平均约需 50 次工具调用)。

选取(select)。 不预先塞满,而是保留轻量指针(文件路径、查询、链接),运行时再按需即时加载。Anthropic 称其为「just-in-time」策略,并说这模仿了人的认知——我们并不背下整座图书馆,而是靠文件系统、收件箱、书签在需要时取回(Anthropic,2025-09-29)。LangChain 给的例子是「短期记忆」(给长对话做摘要)与「长期记忆」(跨会话取回用户偏好)(LangChain,2025-06-23)。

压缩(compress)。 把逼近上限的历史摘要成高保真要点,再开一个新窗口继续——Anthropic 叫它 compaction,说它「保留架构决策、未解决的 bug 与实现细节,丢弃冗余的工具输出」,Claude Code 的做法是「压缩后的上下文 + 最近访问的五个文件」;他们提醒别压得太狠,否则会丢掉「后来才显出重要」的细节,并建议从高召回开始,再迭代提高精度(Anthropic,2025-09-29)。Manus 的配套实践则强调:压缩必须可还原——网页正文可以丢,但URL 要留(Manus,2025-07)。这里还有一笔很实用的账:Manus 说他们 Agent 的平均输入/输出 token 比约 100:1,于是KV 缓存命中率成了生产环境最关键的一个指标,并以 Claude Sonnet 为例:命中缓存的输入约 0.30 美元/百万 token,未命中的约 3 美元/百万 token,差 10 倍(Manus,2025-07);对应的工程纪律是保持前缀稳定、上下文只追加不修改。

隔离(isolate)。 把「会污染主窗口的活」挪进独立窗口。Anthropic 描述子智能体架构:主智能体拿高层计划,子智能体各自用干净的窗口深挖,可能跑掉数万 token,但只回传一份约 1000 到 2000 token 的浓缩摘要,于是「细节搜索的脏上下文被关在子窗口里」(Anthropic,2025-09-29;agent 与工作流的区分见同团队《Building effective agents》)。

这里必须补一条反直觉但重要的边界,来自 Cognition 的《Don’t Build Multi-Agents》(Walden Yan,2025-06-12)。他们主张两条原则:共享完整上下文、别只共享单条消息;以及每个动作都隐含决策,互相冲突的决策会带来坏结果。据此他们认为多智能体协作在今天很脆弱,理由是决策被分散、上下文无法充分共享;他们观察到(截至 2025 年 6 月)Claude Code 的子智能体从不与主智能体并行,通常只负责回答一个定义清晰的问题,而不写代码(Yan,Cognition,2025-06-12)。所以「隔离」不等于「万灵药」——它擅长「一问一答式」的脏活隔离,不擅长「并行分工再合并」这种高风险协作。

flowchart LR
    P[上下文变脏] --> Q[中毒 错误被反复引用]
    P --> R[分心 只顾复读历史]
    P --> S[混淆 无关内容干扰]
    P --> T[冲突 上下文自相矛盾]

这张图说明了什么:四类「变脏」的方式各有对应手段——中毒靠压缩与隔离切断传播、分心靠选取与重写清单重新聚焦、混淆靠精简工具与无关内容、冲突靠保持单一线性上下文(共享完整 trace)。

6.1 RAG 与长上下文不是二选一

长窗口一出来,「RAG 要退休」的声音就起来了。但把两件事摆正位置,会发现它们根本不冲突:

  • RAG 解决的是「取什么进来」——从海量资料里把相关的部分找出来,降低污染与混淆的机会;
  • 上下文工程解决的是「进来之后怎么摆、怎么删」——即便你只取了几段,它们仍可能相互冲突、过长、格式糟糕。

长窗口没有取消这两个问题,只是把「取」的一部分负担转成了「摆」。Breunig 说得直接:长上下文让大海捞针变容易,却没解决「放错了东西照样干扰你」(Breunig,2025-06-22);Chroma 也强调真实任务比大海捞针复杂得多(Chroma,2025-07-14)。所以更准确的说法是:窗口越大,检索与筛选的价值越高,而不是越低——因为你要在一堆「能塞进去」的东西里,主动决定「哪些不该塞进去」。

6.2 四个动词怎么选:一张取舍表

四类手段没有优劣,只有「适合什么任务」。下面这张表把 Anthropic 与 Manus 的经验并起来,供排产时对照:

手段最适合代价 / 风险代表实践
写入有明确里程碑的迭代开发笔记自身可能过时待办清单、NOTES 文件
选取资料动态、易变(网页 / 代码库)运行时探索更慢即时加载、只保留指针
压缩需要大量来回对话的长任务压太狠会丢「后来才重要」的细节摘要 + 保留最近文件
隔离「一问一答」式的脏活并行分工易冲突子智能体只回答、不并行写

一个实用的起点是 Anthropic 给的那句原则:找到「最小的高信号 token 集合」(Anthropic,2025-09-29)。翻译成动作就是——先问「这一步真的需要它吗」,再决定写、选、压还是隔。

6.3 「隔离」的两个真实边界

隔离很好用,但 Cognition 的观察提醒了两个容易被忽略的边界(Yan,2025-06-12):

  • 边界一:子智能体若要和主智能体「并行分工再合并」,很容易出问题。 他们举了一个生动的失败:把「做一个 Flappy Bird」拆成「画背景」与「做鸟」两个子任务,结果一个子智能体做成了超级马里奥风格的背景,另一个做的鸟完全不像游戏素材——两边各自基于冲突的隐含假设行事,最后合并出四不像。原话结论是:动作隐含决策,冲突的决策带来坏结果。
  • 边界二:解法不是「多传点上下文」那么简单。 他们指出,真实生产系统的对话多是多轮的、中间夹着工具调用,哪些细节会影响子任务的理解,事前很难穷举。所以他们主张两条原则:共享完整上下文(而非单条消息)、并默认排除不遵守这两条的架构。

对工程的含义很直接:隔离适合「脏活外包」,不适合「并行分权」。想把长上下文拆开跑,最稳的起点仍是单线程线性 Agent(Yan,2025-06-12),再按需要引入「一问一答式」的子智能体。

6.4 一个编码 Agent 的上下文流水账

把四个动词串起来,看一个编码 Agent 跑一天会怎么用:

  • 起步:系统提示词 + 工具定义(精简到必要的那几个)+ 少量示例,把「任务定义」摆到工作台上。
  • 探索:用 glob / grep 一类工具按需把相关文件拉进来,而不是把整个仓库塞进去(选取)。
  • 动手:改完一个文件、跑完一次测试,把结果摘要留在历史里,原始输出(一屏编译日志)清掉(压缩)。Anthropic 把这一步叫「工具结果清理」,并说这是最轻、最安全的一种压缩(Anthropic,2025-09-29)。
  • 跨天:把「已完成、待办、踩过的坑」写进一个 NOTES 文件(写入),下次开工先读它,而不是让模型背下整段历史。
  • 卡住:把「去某个大库里找证据」这类脏活外包给一个只回答问题的子智能体(隔离),它跑完只回一段浓缩摘要(Anthropic 说子智能体常把数万 token 压成约一千到两千 token)。

这一串动作里,没有一步是「把窗口做大」,但每一步都在决定模型「这一步看得清不清」。

这一节想让你记住的一件事: 上下文工程不是「少写点提示词」,而是四个动词——写出去、按需取、摘要瘦身、脏活隔离。

七、对照表:窗口大小 ≠ 有效上下文

把公开来源里能查到的「标称窗口」和「有效上下文」的证据并排,结论一目了然。下表只用于对照口径,不代表本文实测。

口径典型值 / 证据来源
标称窗口(示例)Gemini 1.5 Pro 早期即引入 1M;GPT-4.1 为 1M;Llama 4 宣称 10MChroma,2025-07-14
标称窗口(示例)Gemini 2.5 与 GPT-4.1 均为 1M tokenBreunig,2025-06-22
有效上下文(分心阈值)该 Agent 场景约 100K token 后转向复读Gemini 2.5 技术报告(经 Breunig 转述)
有效上下文(正确率拐点)Llama 3.1 405B 约 32K 起下降,小模型更早Databricks(经 Breunig 转述)
位置效应关键信息在开头/结尾最好,中段明显变差Liu 等,arXiv:2307.03172
字面 vs 语义检索大海捞针偏简单;语义匹配下性能显著下挫Chroma,2025-07-14
工具数量效应46 个工具时失败,19 个时成功(远未填满窗口)GeoEngine(经 Breunig 转述)
多轮拆解效应平均掉约 39%,o3 由 98.1 跌至 64.1Microsoft/Salesforce(经 Breunig 转述)
成本效应缓存命中约 0.30 vs 未命中约 3 美元/百万 tokenManus,2025-07

一个诚实的结论:标称窗口可以到 1M、10M,但在真实任务里能稳定拿到的「有效上下文」,往往要小一到两个数量级。这不是反对大窗口——而是提醒你,大窗口买来的是「容量」;「取用能力」得靠上下文工程去挣。

再补一句关于「怎么读厂商数字」的:标称窗口是硬指标(模型能接收多少 token),而「有效上下文」是软指标,它随任务、模型、提示结构而变,没有一个官方数字。所以你几乎不可能在厂商文档里找到「有效上下文 = X」——要得到它在你的任务上的值,只能自己测(见 5.1 的两个受控实验)。

还有一点常被忽略:窗口与输出共享同一块预算。模型的总长度额度里,输入与输出用的是同一块,输入越多,留给「思考与回答」的空间越少。所以「把绝大多数窗口都用来塞资料」往往不是优化,而是在压缩模型的输出空间——对需要长推理的任务,这一点比想象中更贵。

7.1 怎么自己测「有效上下文」

既然「有效上下文」没有官方数字,想用到它就只能自测。一套不依赖昂贵基础设施的做法:

  1. 造受控任务:固定任务复杂度,只让输入长度从短到长分档(例如 4K、16K、64K、256K),每档跑同一批样本。
  2. 同时上两种任务:一种单跳检索(对照「大海捞针」),一种多跳推理(跨多个片段综合)。两者若分叉——单跳仍高、多跳下滑——就说明你撞上了斜坡。
  3. 变化关键信息的位置:把答案从开头移到中段再移到结尾,看结果是否呈「两头高、中间低」。若是,你的模型在用「位置」找信息。
  4. 记录成本曲线:把输入 token 数与首字延迟、单位成本一起画出来。若性能已平而成本仍涨,说明继续加长已无收益。

四条做完,你会得到一条只属于你的任务与模型的有效上下文曲线——它比任何排行榜都可靠。

7.2 「多长算太长」:几条经验判据

在没有自家测量之前,可以先借几条公开观测当经验红线(都来自特定模型与任务,仅作起点,不是精确阈值):

  • 若任务以多跳推理为主:公开观测里出现「约 32K 起正确率下降」「约 100K 后转为复读」这类信号——先把注意力放在 10 万 token 以下,别默认能吃满标称窗口。
  • 若是单跳检索:长窗口通常还能用,但一旦工具很多或干扰文档很多,混淆与冲突会先于「长度」发作。
  • 只要看到输入 token 数随轮次线性膨胀、而输出一直很短,就说明上下文在「净增长」——该压缩了。

这些数字不是要你照抄,而是提醒你去做 7.1 的测量。红线会随模型版本漂移,唯一稳定的是「自己测出来的那条曲线」。

这一节想让你记住的一件事: 把「窗口」这个词在你脑子里自动替换成「容量」,很多困惑会立刻消失。

八、边界、未解与常见误区

任何结论都有边界,这一节把该说清的一次说全,并按重要性编号。

① 三个常见误区,先点名。

  • 误区一:窗口够大,就万事大吉。 上文三组实验都是反例;Anthropic 直接说,在可预见的未来,各种大小的窗口都会受「上下文污染」与「信息相关性」的困扰(Anthropic,2025-09-29)。
  • 误区二:RAG 要退休了。 恰恰相反——Breunig 说长上下文让「大海捞针」变简单,却没解决「放错了东西也照样干扰你」;而 Chroma 也强调真实任务的复杂度高于大海捞针(Breunig,2025-06-22;Chroma,2025-07-14)。「找得准」反而更依赖检索与筛选。
  • 误区三:多智能体一定更强。 Cognition 明确反对把多智能体当默认解,主张先考虑单线程线性 Agent(Yan,2025-06-12)。隔离是手段,不是目标。

② 因果尚未完全厘清。「输入变长」与「性能下降」的相关性已被多组实验证实,但具体到某一个模型、某一层,究竟是什么导致退化,学界仍在争论;本文只报告「现象 + 来源」,不下「机制已定论」的判断。

③ 基准的局限。 大海捞针这类基准是字面检索,会系统性高估长上下文能力;在这一点上,Chroma 报告做了受控扩展,NoLiMa 则是一个独立的第三方基准(Chroma,2025-07-14)。引用任何「长上下文已解决」的说法前,先问它用的是哪种基准。

④ 转述与一手的区分。 本文的间接引用(标「经 Breunig 转述」者)没有逐条打开其原始论文核对,只核了 Breunig 原文的表述;读者若要写进正式材料,应回到 Gemini 2.5 技术报告、Databricks 与 Microsoft/Salesforce 的原始出处。

⑤ 本文自己的限度。 本文所有公式都是教科书级的量级推导,用于建立直觉;E[ai]≈1/n\mathbb{E}[a_i]\approx 1/n 假设分数近似独立同分布,这与真实模型(softmax 是尖峰分布)不完全一致,只作量级一致性检查。少数「窗口/成本」数字来自厂商或第三方转述,未做本文实测。

⑥ 什么情况下「堆长上下文」仍然合理。 并非所有长上下文都是坏主意。Anthropic 也承认,对资料不常变的领域(例如法律、金融的静态材料),把内容预先放进上下文更省事(Anthropic,2025-09-29)。判据是:任务以「检索 + 复述」为主、且资料相对静态时,长窗口是划算的;一旦任务变成多步推理或跨来源综合,稀释与冲突就会重新占上风。

⑦ 适用边界(哪些结论不该外推)。 本文引用的实验覆盖的是 2023–2025 年的模型与基准;模型与推理栈在持续变化,具体阈值(如 32K、100K)会随模型不同而漂移,请把表格里的数字当「当时的观测点」,而不是「永久常数」。本文也不主张「窗口无用论」——恰恰相反,没有足够长的窗口,很多 Agent 任务根本无从谈起;本文要说的是「窗口是必要条件,不是充分条件」。

本文自行推导(仅作量级一致性检查,不得作为官方数值引用)

  • 平均注意力权重: 在「分数近似独立同分布」下,由 ∑iai=1\sum_i a_i=1 得 E[ai]≈1/n\mathbb{E}[a_i]\approx 1/n,故 ai=O(1/n)a_i=O(1/n);这是量级估计,不是精确值。
  • KV 缓存显存: MKV=2⋅L⋅n⋅nkv⋅dhead⋅bM_{\mathrm{KV}}=2\cdot L\cdot n\cdot n_{\mathrm{kv}}\cdot d_{\mathrm{head}}\cdot b(key 与 value 各一份,LL 为层数,算的是全部层合计)。以 L=32L=32、nkv=8n_{\mathrm{kv}}=8、dhead=128d_{\mathrm{head}}=128、b=2b=2 字节(FP16)估算,n=100,000n=100{,}000 时全部 32 层合计约 2×32×100000×8×128×2≈1.3×10102\times32\times100000\times8\times128\times2\approx 1.3\times10^{10} 字节量级(约 13 GB),而单层仅约 2×100000×8×128×2≈4.1×1082\times100000\times8\times128\times2\approx 4.1\times10^{8} 字节(约 0.4 GB)——随配置浮动很大,数量级而已,切勿当官方值。
  • 注意力计算量: 由 Θ(n2d)\Theta(n^{2}d),长度翻倍则计算量约变为 4 倍(×4\times 4)、KV 缓存大小约变为 2 倍(×2\times 2)。

这一节想让你记住的一件事: 承认「相关性已证、因果待定、基准有偏」,比背一个漂亮结论更接近工程真实。

九、小结

把全文压缩成四句话:

  1. 上下文窗口是容量,注意力预算是能力。 softmax 让权重和为 1,nn 越大,平均分给每个 token 的注意力越小。
  2. 窗口变大 ≠ 变聪明,有三条机制: 注意力稀释、训练分布偏移、位置编码外推退化——它们合力把「断崖」变成一条平滑下坡。
  3. 实测站在同一侧: Lost in the Middle(位置效应)、Chroma 的 18 模型 context rot(长度效应)、Breunig 归纳的四种变脏(poisoning/distraction/confusion/clash),都说明长上下文下「掉链子」可复现。
  4. 对策是上下文工程四动词: 写入、选取、压缩、隔离;并且记住隔离不是万灵药,多智能体要慎用。

9.1 给三类人的一句话

  • 做 Agent 的工程读者:把「上下文工程」当成一个每日维护的活,而不是一次性写提示词——记录 token 曲线、定期压缩、按需检索。
  • 做评测的读者:别只跑大海捞针;至少加上「语义针」与「多跳」两类,并把关键信息在位置维度上打乱。
  • 做产品的读者:把「我们支持 1M 窗口」当容量来宣传可以,但别把它当保证;真正决定体验的是你有没有做好选取、压缩与隔离。

9.2 一页速查:读到什么,该做什么

你遇到的情况含义建议动作
单跳检索没问题,多跳就崩落在斜坡陡段拆分任务、减少同屏片段数、外部记忆兜底
长历史里找不到旧结论中段失焦写入外部记忆 + 按需检索
反复做相似动作分心压缩历史 + 重写目标到末尾
答案被早期错误带偏中毒或冲突压缩切断传播、隔离重做
工具一多就乱混淆精简工具集
性能已平、成本还涨长上下文已无收益停止加长,转做压缩与选取

这张表不替代你自己的测量,只是给你一个从症状到动作的快速索引。

这一节想让你记住的一件事: 真正稀缺的从来不是「能装多少 token」,而是「每一步能把注意力放在对的地方」。

十、📋 来源与核验记录

以下均为本轮实际打开过的一手或原始出处(访问日期:2026-10-10)。第三方转述项已在正文中就标注。

一手论文与官方工程博客

  1. Anthropic,《Effective context engineering for AI agents》,2025-09-29。https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents
  2. Anthropic,《Building effective agents》。https://www.anthropic.com/engineering/building-effective-agents
  3. Nelson F. Liu 等,《Lost in the Middle: How Language Models Use Long Contexts》,arXiv:2307.03172(arXiv 2023;TACL 2024)。https://arxiv.org/abs/2307.03172
  4. Charles Packer 等,《MemGPT: Towards LLMs as Operating Systems》,arXiv:2310.08560。https://arxiv.org/abs/2310.08560
  5. Kelly Hong、Anton Troynikov、Jeff Huber,《Context Rot: How Increasing Input Tokens Impacts LLM Performance》,Chroma Technical Report,2025-07-14。https://research.trychroma.com/context-rot
  6. Yichao ‘Peak’ Ji / Manus,《Context Engineering for AI Agents: Lessons from Building Manus》,2025-07。https://manus.im/blog/Context-Engineering-for-AI-Agents-Lessons-from-Building-Manus
  7. Harrison Chase / LangChain,《The rise of “context engineering”》,2025-06-23。https://blog.langchain.com/the-rise-of-context-engineering/

第三方分析与转述

  1. Drew Breunig,《How Long Contexts Fail》,2025-06-22。 https://www.dbreunig.com/2025/06/22/how-contexts-fail-and-how-to-fix-them.html (其转述的 Gemini 2.5 技术报告、Databricks 研究、Berkeley 函数调用排行榜、Microsoft/Salesforce 工作,本文未逐一打开原始论文)
  2. Walden Yan / Cognition,《Don’t Build Multi-Agents》,2025-06-12。https://cognition.ai/blog/dont-build-multi-agents

本文自行推导

  1. 平均注意力权重 ai=O(1/n)a_i=O(1/n)、KV 缓存显存估计、注意力计算量 Θ(n2d)\Theta(n^2 d) 的量级推导,均见第八节「本文自行推导」清单,不得作为官方数值引用。

数据截至 2026-10-10。文中标注「经 Breunig 转述」的数字(约 100K、约 32K、46 vs 19、约 39%、98.1→64.1)来自该文对原始研究的转述,尚未由本文回到原始出处置信;涉及口径判断请以原始论文为准。