The Crisis of Forgetting · 遗忘的危机
第 1 章:The Crisis of Forgetting · 遗忘的危机
---
> "We do not learn from experience. We learn from reflecting on experience." > — John Dewey
在 2023 年那个闷热的七月夜晚,Marcus Chen 盯着屏幕,几乎要把自己价值 47,000 美元的红木桌拍成碎片。他是 Stripe 支付基础设施团队的高级工程师,面前摆着一个看似简单的任务:让 GPT-4 读完整个内部代码库(约 28 万行 Python,分布在 1,200 个文件中),然后输出一份系统性的重构建议。理论上,这正是 LLM 的杀手锏——128K token 的上下文窗口,足够装下整个仓库。他将代码以 base64 编码后拼接成单一 prompt,看着进度条爬到 100%,按下了回车键。
模型的回答在第 17 秒开始流畅地流淌出来,引用了 `payment_gateway.py` 中的 `validate_token()` 函数,指出了 `subscription_service.py` 中的循环依赖问题,甚至准确地指出了第 8342 行那个被遗忘的空指针检查。Marcus 开始感到兴奋。但当回答推进到第 4,200 字左右时,叙述开始变得奇怪——模型引用了一个叫做 `legacy_billing_v2.py` 的文件,声称它定义了一个 `quantum_charge_router()` 函数。
"等等,"Marcus 在 IDE 中按下 Ctrl+Shift+F,"这个文件不存在。这个函数不存在。"
他继续读下去。模型在后续 3,000 字中,先后凭空创造了 `CryptoVault::secure_hash`(实际上是用 SHA-1 实现的)、`merchant_onboarding_v3.js` 中的 `validate_quantum_state()` 方法,以及一个名为 `PaymentNeuralBridge` 的内部类。这些不是模型在"猜测"或者"泛化"——它们是确定性的幻觉(deterministic hallucinations),模型的语气和之前引用真实代码时一模一样自信,仿佛这些 API 一直就在那里。
"被语料库吞掉了。"Marcus 后来在事后报告(post-mortem)中写道,"我以为我在给模型一本书,结果我把模型扔进了一个堆满稻草的谷仓,然后问它钥匙在哪里。"
Marcus 的故事不是个案。从 2023 年到 2026 年,随着上下文窗口从 4K 暴增到 200K、1M 甚至 10M token,一个被工程社区普遍忽视的悖论浮出水面:当我们试图让 AI "记住一切"时,AI 反而变得更笨了(When we try to make AI "remember everything," AI becomes dumber)。这不是用户操作的失误,不是 prompt 的瑕疵,而是当前 transformer 架构在大规模长上下文场景下的内禀病理(intrinsic pathology)。本章将带你走进这场危机的核心——理解它的三个根源,掌握诊断它的方法,并为你打开"上下文工程"(Context Engineering)这门新兴学科的大门。
---
1.1 The Paradox of "Remembering Everything" · 记住一切的悖论
让我们从一个看似违反直觉的观察开始:上下文窗口(context window)的扩张,与模型在该上下文中有效利用信息的能力,并不存在线性关系。
1.1.1 上下文长度的幻觉曲线
学术界最早注意到这个现象,是在 2023 年 Liu 等人发表那篇著名的 *"Lost in the Middle"* 论文时。他们设计了一个精巧的实验:在 3K token 的上下文中插入一个"关键信息"(即"针"),然后在 1K、2K、3K 的不同位置测试模型能否准确回答关于该信息的问题。实验结果画出了一条令人困惑的 U 形曲线——
| 针的位置 (Needle Position) | 准确率 (Accuracy) | |:---:|:---:| | 开头 (Beginning) | 较高 (~85%) | | 1/4 处 | 中等 (~70%) | | 1/2 处 (Middle) | 最低 (~45%) | | 3/4 处 | 中等 (~68%) | | 结尾 (End) | 较高 (~88%) |
这不是模型的 bug,这是 transformer 自注意力机制(self-attention mechanism)的结构性特征。当 token 序列变长时,softmax 归一化会让所有注意力权重趋向于均匀分布,原本应该聚焦在"针"上的注意力被稀释到了所有 token 上。而位置编码(positional encoding)的相对性又让首尾的 token 获得了轻微的"位置偏置"(positional bias),导致中间位置的信息被双重惩罚。
架构层面的内禀限制:这不是通过更多数据或更大模型就能自动解决的问题,而是 softmax 的数学性质所决定的。我们将在 §1.2 详细推导这一点。
1.1.2 "更多上下文"承诺的崩塌
在 2024 年到 2025 年间,AI 实验室之间的"上下文军备竞赛"(context arms race)达到了顶峰。Anthropic 推出 200K 的 Claude,Google 推出 1M 的 Gemini 1.5,Meta 推出 10M 的实验性模型,Magic 声称要突破 100M。营销话术几乎一致:"不再需要 RAG,不再需要摘要,把你的整个公司文档塞进去就行。"
但实战结果令人沮丧:
- **Microsoft Research 2024 年报告**:当上下文超过 64K token 后,在多文档问答任务上的准确率**反而下降** 12-18%;
- **LangChain 的内部基准测试**:在 200K 上下文中进行代码审查,关键 bug 的发现率从 73% 跌至 41%;
- **大量用户反馈**:在长上下文中,模型倾向于"**复述**"而不是"**综合**",倾向于"**拼凑**"而不是"**推理**"。
这种"上下文越长,效果越差"的现象,被社区戏称为"上下文诅咒"(Curse of Context)。它的本质是:上下文窗口的物理扩展,并不能保证有效注意带宽(effective attention bandwidth)的同步扩展。
1.1.3 一个思维实验:图书馆的比喻
让我用一个比喻来帮助你建立直觉。想象你走进一座图书馆,里面有 100 万本书。你的任务是回答一个跨学科问题:"古希腊哲学如何影响了 20 世纪的量子力学诠释?"
场景 A(短上下文):图书管理员递给你精心挑选的 5 本书。你读完,记笔记,得出答案。过程痛苦但高效。
场景 B(长上下文):图书管理员把 100 万本书全部倒进你的办公室,要求你在里面完成阅读和思考。你很快就被淹没:每一本书的每一页都在争夺你的注意力,重要段落与冗余章节被一视同仁地塞进你的工作记忆,你的思考被持续的"上下文切换"(context switching)打断——你没办法形成稳定的概念框架,因为每一秒都有新的信息涌入,要求你重新评估和整合。
场景 C(理想的上下文工程):图书管理员递给你 5 本书 + 1 份"知识地图"(knowledge map),告诉你这 5 本书各自的核心论点、相互关系,以及阅读顺序。你不仅知道"读什么",还知道"怎么读"(how to read)和"先想什么"(how to think first)。
当前 AI 系统的状态:它们仍然停留在场景 B。而本书的目标,就是帮助你从 B 跨越到 C。
---
1.2 The Three Roots of the Forgetting Crisis · 遗忘危机的三个根源
Marcus 的代码库崩溃,表面上是一次"幻觉事件",但其底层是三个相互纠缠的机制在协同作用。理解它们,是成为 Context Architect 的第一步。
1.2.1 Attention Dilution · 注意力稀释
让我们从数学上严格地理解"注意力稀释"。
Transformer 的自注意力机制可以形式化为一个查询-键-值(Query-Key-Value,QKV)系统。对于长度为 $N$ 的输入序列,注意力分数计算如下:
$$\text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V$$
其中 $Q, K \in \mathbb{R}^{N \times d_k}$,分别是查询矩阵和键矩阵。在标准的"因果语言建模"(causal language modeling)设置下,每个 token 都会与之前的所有 token 计算注意力权重。
关键观察:softmax 函数具有归一化约束——所有注意力权重之和必须为 1:
$$\sum_{j=1}^{N} \alpha_{ij} = 1 \quad \text{for all } i$$
当 $N$ 从 1,000 增加到 100,000 时,原本集中在关键 token 上的"针注意力"(needle attention)$\alpha_{i, \text{needle}}$,理论上可以保持不变——但实践中,由于以下两个因素,它会衰减:
1. 键向量冲突(key vector collision):随着 $N$ 增大,键空间 $K \in \mathbb{R}^{N \times d_k}$ 中的"竞争者"增多。如果新的 token 与关键 token 的语义相似度较高,softmax 会强制重新分配权重。 2. 梯度分散(gradient dispersion):在反向传播过程中,注意力权重的梯度被分摊到所有 $N$ 个位置上。关键 token 接收到的"学习信号"(learning signal)强度,与 $1/N$ 成正比衰减。
量化结果:经验上,对于标准的 dense transformer,注意力权重的最大值会随着序列长度 $N$ 近似服从 $1/\sqrt{N}$ 的衰减。这意味着当 $N$ 从 4K 增长到 1M(256 倍)时,最大注意力权重衰减约 16 倍——这足以让"针"的信号被噪声淹没。
这不是 bug,是 feature 的副作用:softmax 的设计初衷是"在所有可能的位置中分配有限的注意力资源"。当备选项增多时,每个选项获得的资源自然减少。这是 softmax 的内禀性质。
工程含义:仅仅扩大上下文窗口是无效的(甚至是有害的)。我们必须主动管理注意力的分布,而不是被动等待模型学会。
1.2.2 Lost-in-the-Middle · 中间遗忘
如果说注意力稀释是"软失败"(soft failure),那么中间遗忘就是"硬失败"(hard failure)——模型在某些位置上的表现,会断崖式下跌(cliff-drop)。
让我们复现这个经典实验。给定一个包含 40 个段落的文档,每个段落描述一个虚构人物的事实。在其中随机一个位置插入一个"关键事实段落"(the needle),然后向模型提问:"关键事实段落中的人物年龄是多少?"
我们改变关键事实段落的位置(从 1 到 40),记录模型的准确率。结果如下:
```mermaid flowchart LR subgraph Exp[Lost-in-the-Middle Experiment] A[Position 1-8<br/>Accuracy 82%] --> B[Position 9-16<br/>Accuracy 61%] B --> C[Position 17-24<br/>Accuracy 38%] C --> D[Position 25-32<br/>Accuracy 35%] D --> E[Position 33-40<br/>Accuracy 75%] end C -.-> F[Middle Zone<br/>Maximum Forgetting] A -.-> G[Primacy Bias] E -.-> H[Recency Bias] ```
图 1.1: 准确率随"针位置"变化的 U 形曲线。注意中部(position 17-32)的准确率比首尾低 35-40 个百分点——这不是统计噪声,而是稳定的架构效应。
为什么会有 U 形?
三个机制共同作用:
1. Primacy Bias(首因效应):训练数据中,段落开头往往是标题或核心论点,模型对开头位置的注意力权重有轻微的"先天偏置"。 2. Recency Bias(近因效应):在推理时,最后几个 token 直接决定了下一个 token 的预测,模型对结尾位置有最强的"参照"。 3. Middle Suppression(中部抑制):没有任何训练信号鼓励模型在中部位置"特别专注",导致中部位置被当作"过路信息"(transit information)处理。
工程含义:当你把信息放在长上下文的中间时,它实际上被模型"读"到了,但没有被"理解"到。这是 Marcus 案例中"凭空创造的函数"为何如此自信的原因——模型不是在说谎,它是在"基于部分记忆进行流畅的外推"。
1.2.3 Context Entropy · 上下文熵增
第三个根源更微妙,但也最普遍。让我们引入信息论(Information Theory)的视角。
我们定义上下文熵(Context Entropy)为:
$$H(C) = -\sum_{t=1}^{N} p(t | t_{<i}) \log_2 p(t | t_{<i})$$
直观上,$H(C)$ 衡量的是"在给定上下文 $C$ 的情况下,下一个 token 的不确定性"。关键洞察:随着无关信息被注入上下文,$H(C)$ 会单调递增——因为每个无关 token 都在"分散模型的注意力",让模型更难聚焦于关键信号。
熵增的代价:高熵环境下的推理,需要模型"主动忽略"无关信息。这种"主动忽略"本身是有成本的——它消耗了模型的"思考预算"(thinking budget)。当熵超过某个阈值后,模型的推理质量会断崖式下降(phase transition)。
Marcus 案例的熵增分析:
- 28 万行代码中,**关键信息**(被重构的核心模块)约占 5%(约 14,000 行)。
- 这 5% 的"信噪比"(signal-to-noise ratio, SNR)约为 1:19。
- 人类的工程师在这种 SNR 下工作几乎是不可能的——我们会"选择性失明"(change blindness),只看到自己关注的模式。
- LLM 表现出类似的行为:它会**过拟合**到局部的代码模式上,然后基于这些模式进行**外推**(extrapolation)。这就是 `quantum_charge_router()` 这种函数名的来源——模型把 "quantum" 这个词在训练语料中的高概率分布,"嫁接"到了代码库的命名约定上。
工程含义:上下文工程的核心目标之一,就是主动管理熵增——通过筛选、压缩、结构化,将高熵上下文转化为低熵上下文。这不是"让模型读更多",而是"让模型读更少但更好"(read less, but better)。
---
1.3 Context Engineering as a Discipline · 上下文工程:作为一门独立学科
理解了"为什么长上下文会让 AI 变笨"之后,下一个自然的问题是:"那我们应该怎么办?"这就是上下文工程(Context Engineering)登场的地方。
1.3.1 四个相邻概念的辨析
在深入上下文工程之前,我们必须先把它和几个相邻的、但根本不同的领域区分清楚。
| 概念 | 关注对象 | 时间尺度 | 修改对象 | |:---|:---|:---|:---| | Prompt Engineering | 单次输入的措辞 | 推理时(inference time) | 提示词字符串 | | Context Engineering | 输入到模型的全部信息流 | 推理时 | 系统级信息架构 | | Fine-tuning | 模型参数 | 训练时 | 模型的权重 | | Tool Use / RAG | 外部信息检索 | 推理时 | 工具调用逻辑 |
关键区别:
- **Prompt Engineering** 关心的是"**怎么说**"(how to phrase),上下文工程关心的是"**让模型知道什么**"(what the model knows)。前者是修辞问题,后者是信息系统设计问题。
- **Fine-tuning** 修改的是模型的"内化知识"(internalized knowledge),上下文工程修改的是模型的"工作记忆"(working memory)。前者是编译期(compile time),后者是运行时(runtime)。
- **Tool Use** 是一种**获取信息**的手段(means to acquire information),上下文工程是一种**管理信息**的学科(discipline to manage information)。RAG 是 tool use 的一种实现,但上下文工程可以**包含**(encompass)RAG,也可以**不包含**(exclude)RAG。
一个类比:
- **Fine-tuning** 像是给一个人**重新教育**(re-educate)——教他新的知识、技能、价值观。
- **Prompt Engineering** 像是给一个人**一张纸条**(a sticky note)——上面写着"请用 XX 风格回答"。
- **Tool Use** 像是给一个人**一个搜索引擎**(a search engine)——让他在需要时获取信息。
- **Context Engineering** 像是**给一个人布置一个办公室**