精读笔记:Lost in the Middle: How Language Models Use Long Contexts


论文基本信息

项目 内容
论文标题 Lost in the Middle: How Language Models Use Long Contexts
中文标题 迷失在中间:语言模型如何利用长上下文
作者 Nelson F. Liu, Kevin Lin, John Hewitt, Ashwin Paranjape, Michele Bevilacqua, Fabio Petroni, Percy Liang
机构 Stanford University, Meta AI
发表期刊 Transactions of the Association for Computational Linguistics (TACL), 2024
arXiv ID 2307.03172(提交于 2023 年 7 月 6 日)
论文性质 实证分析论文(发现问题,非提出新方法)

阅读地图

这篇论文不提新方法,它做的事情是:揭示一个令人意外的缺陷

语言模型(比如 GPT-3.5、Claude)现在都支持处理很长的文本(几千甚至几万个词),大家默认"给的信息越多越好"。但这篇论文用严格的受控实验证明:模型对信息在上下文中的位置非常敏感——放在开头结尾效果好,放在中间效果明显变差,形成一条"U 形曲线"。

这个发现对所有做 RAG(检索增强生成)、长文档问答的人都有直接的实践意义。

本文结构:
1. Abstract(摘要)— 核心发现一句话概括
2. Introduction(引言)— 问题背景与研究动机
3. 多文档问答任务(Section 2)— 主要实验设计,重点精读
4. 键值检索任务(Section 3)— 辅助验证实验
5. 关键结果(U 形曲线)— 核心发现数据
6. 分析与讨论(Section 4)— 为什么会这样
7. 实践案例研究(Section 5)— RAG 应用启示
8. 结论
9. 对 RAG 实践者的启示(编者总结)


一、Abstract(摘要)

原文核心句

"We find that performance is often highest when relevant information occurs at the beginning or end of the input context, and significantly degrades when models must access relevant information in the middle of long contexts, even for explicitly long-context models."

翻译

我们发现,当相关信息出现在输入上下文的开头或结尾时,模型性能往往最高;而当模型必须访问位于长上下文中间的相关信息时,性能会显著下降——即使是专门为处理长上下文而设计的模型也不例外。

新手讲解

什么是"上下文(context)"?
你可以把它理解为模型每次处理时"能看到的全部文字"。比如你问模型一个问题,同时附上 20 篇参考文章,这 20 篇文章加上你的问题,合起来就是"上下文"。上下文的容量上限叫做 context window(上下文窗口),类似于人的工作记忆——你一次能记住的信息量是有限的。

摘要告诉我们什么?
这篇论文做了受控实验,把答案藏在不同位置,发现模型的表现形成 U 形:
- 藏在开头 → 模型容易找到,准确率高
- 藏在结尾 → 模型也容易找到,准确率还行
- 藏在中间 → 模型容易"看不见",准确率明显下降

这就是"Lost in the Middle(迷失在中间)"的含义。

类比: 想象你读一篇很长的文章,考试考文章细节。你往往记得开头读了什么、结尾读了什么,但中间段落的内容容易忘记或混淆——大模型也有类似的"注意力分布不均"问题。


二、Introduction(引言)

原文核心段落

"Language models have recently been extended to allow for longer input contexts, with many models now supporting context lengths of thousands of tokens. These extended-context models are being used in practice for a variety of tasks requiring long contexts, including document-level question answering and retrieval-augmented generation."

"Despite their widespread use, little is known about how these extended-context language models make use of their input contexts when performing downstream tasks."

翻译

语言模型近年来被扩展以支持更长的输入上下文,许多模型现在支持数千个 token 的上下文长度。这些扩展上下文模型在实践中被用于各种需要长上下文的任务,包括文档级问答和检索增强生成(RAG)。

尽管它们被广泛使用,但关于这些扩展上下文语言模型在执行下游任务时如何利用其输入上下文,我们几乎一无所知。

新手讲解

"token"是什么?
Token 是模型处理文本的最小单位,大致上一个英文单词是 1-2 个 token,一个中文字是 1-2 个 token。"支持 4000 个 token 的上下文"大约相当于支持 3000 个英文单词的输入。

引言提出了什么问题?
作者说:大家都在扩展模型的上下文窗口,也都在用这些模型处理长文档,但没人认真测过——模型真的能用好这么长的上下文吗? 还是说只是"看起来能用",实际上有盲区?

这个问题的研究价值在于:如果模型不能均匀地利用整个上下文,那么我们在设计 RAG 系统时,就不能简单地"堆叠更多文档",而需要考虑信息的摆放位置。


引言的研究贡献声明

"We find that current language models are not robust to changes in the position of relevant information in the input context and tend to perform best when relevant information is positioned at the very beginning or end of the context."

翻译: 我们发现,当前语言模型对相关信息在输入上下文中位置的变化缺乏鲁棒性,倾向于在相关信息位于上下文开头或结尾时表现最佳。

新手讲解: "鲁棒性(robustness)"是工程术语,意思是"在各种条件下都稳定表现"。这里说的是:如果一个模型是"鲁棒的",那么不管答案放在第 1 篇文档还是第 20 篇文档,准确率应该差不多。但实验发现根本不是这样——位置会严重影响准确率,说明模型的长上下文利用能力不稳定、不可靠


三、实验设计:多文档问答任务(Section 2)

精读重点:这是全文最核心的实验,理解它才能理解所有结果。

3.1 任务定义

原文:

"We study multi-document question answering, where a model must answer a question given k documents in its input context, exactly one of which contains the answer."

翻译: 我们研究多文档问答任务:模型必须根据输入上下文中的 k 篇文档来回答问题,其中恰好有一篇包含答案。

新手讲解: 这是一个人为设计的"受控实验"场景。想象一下:
- 你提问:"北京是哪年成为中国首都的?"
- 给你 20 篇维基百科文章,其中只有 1 篇包含答案
- 剩下 19 篇是"干扰文档"(关于北京的其他内容,但没有那个具体答案)
- 研究者把那篇有答案的文章放在不同位置(第 1 篇、第 10 篇、第 20 篇),看模型每次能否答对

这就是"位置受控实验"的设计核心。


3.2 数据来源

原文:

"We use 2,655 queries from NaturalQuestions-Open with paragraph-level answers."

翻译: 我们使用了来自 NaturalQuestions-Open 数据集的 2,655 条查询,这些查询都有段落级别的答案。

新手讲解: NaturalQuestions-Open 是谷歌发布的真实用户问题数据集,问题来自真实的谷歌搜索,答案来自维基百科。使用真实数据集而非人工构造问题,保证了实验的生态效度(即实验结果在现实中也有参考价值)。


3.3 干扰文档的获取方式

原文:

"To collect k−1 distractor documents that do not contain the answer, we use a retrieval system (Contriever, fine-tuned on MS-MARCO) to retrieve the k−1 Wikipedia chunks that are most relevant to the query. The distractors were presented in order of decreasing relevance."

翻译: 为了收集 k-1 篇不包含答案的干扰文档,我们使用检索系统(在 MS-MARCO 上微调的 Contriever)检索与问题最相关的 k-1 个维基百科段落。这些干扰文档按相关性从高到低排列

新手讲解: 这里有一个很巧妙的设计细节:干扰文档不是随机的,而是"最相关但没有答案"的文档。这样做的好处是:
1. 模拟真实 RAG 场景(检索系统返回的文档往往都和问题相关)
2. 增加了实验难度(避免模型通过简单的关键词匹配就找到答案)


3.4 实验变量的控制

原文(概括): 研究者系统地控制了两个变量:
- 文档总数 k:测试了 k = 10、20、30 的情况
- 答案文档的位置:从位置 0(最开头)到位置 k-1(最末尾)逐一测试

位置索引说明: 位置 0 表示答案文档放在上下文的最开头;位置 k-1 表示放在最末尾;中间的位置索引(如位置 4、5、...)依次对应中间区域。

新手讲解: 这就是"受控实验"的精髓:除了被测变量(答案位置),其他一切保持不变。这样,如果准确率随位置变化,就可以排除其他干扰因素,直接归因于"位置效应"。


3.5 评测的模型

研究测试了当时(2023 年中)主流的大语言模型:

模型 上下文窗口 类型
GPT-3.5-Turbo 4K tokens 闭源,OpenAI
GPT-3.5-Turbo (16K) 16K tokens 闭源,扩展版
Claude-1.3 8K tokens 闭源,Anthropic
Claude-1.3 (100K) 100K tokens 闭源,超长上下文版
MPT-30B-Instruct 8K tokens 开源
LongChat-13B (16K) 16K tokens 开源,扩展上下文
Llama-2(7B/13B/70B) 开源,对比分析
Flan-T5-XXL 512 tokens 编码器-解码器架构
Flan-UL2 2048 tokens 编码器-解码器架构

新手讲解: 测试多个不同类型、不同大小的模型,是为了验证发现的普遍性——如果只有一个模型表现出 U 形曲线,可能只是那个模型的特殊问题;如果所有主流模型都表现出这个规律,说明这是语言模型的系统性缺陷


3.6 三种评测设置

闭卷(Closed-book): 只给问题,不给任何文档。测试模型凭自身记忆能答出多少。

Oracle(神谕)设置: 只给那一篇包含答案的文档,不给干扰文档。测试模型在理想情况下(答案就在面前)能达到的上限准确率。

实验设置(多文档): 给 k 篇文档(1 篇有答案 + k-1 篇干扰),答案文档放在不同位置,看模型实际表现。

新手讲解: 这三种设置形成了一个比较框架:
- 闭卷分数 = 模型的"背景知识下限"
- Oracle 分数 = 模型的"理解能力上限"
- 实验分数 = 模型在有干扰时的"实际能力"

如果实验分数低于闭卷分数,就说明给了更多信息反而帮了倒忙——这正是后来发现的惊人结果。


四、实验设计:键值检索任务(Section 3)

原文:

"Inputs are (i) a string-serialized JSON object with k key-value pairs, where each of the keys and values are unique, randomly-generated UUIDs. The model's goal is retrieving the value associated with the specified key."

翻译: 输入是一个字符串化的 JSON 对象,包含 k 个键值对,所有键和值都是随机生成的 UUID(通用唯一标识符,类似 3f2504e0-4f89-11d3-9a0c-0305e82c3301)。模型的目标是检索指定键所对应的值。

实验规模: 测试了 k = 75、140、300 个键值对的情况。

新手讲解:

为什么要设计这个"合成任务"?

多文档问答毕竟涉及语义理解——模型可能通过"感觉这段文字像是答案"来作弊,而不是真正依靠位置信息检索。键值检索任务排除了语义,让每个键值都是没有意义的随机字符串,这样模型唯一的检索线索就是位置

类比: 类似于在一本随机字母组成的"字典"里查找某个随机字母串——没有任何意义可以借助,只能靠"位置感"。

这个任务的作用是: 验证"U 形曲线"不是语义理解问题,而是更底层的"位置利用"问题。


五、关键信息位置的控制方式

这是方法论的核心,新手理解这部分才能看懂实验图表。

如何精确控制答案位置

在 k 篇文档的序列中,实验者把有答案的那篇文档逐一放到每个可能的位置(从第 1 篇到第 k 篇),然后分别记录模型的准确率。

例如,k=20 时:
- 位置 0(最开头):[答案文档, 干扰1, 干扰2, ..., 干扰19]
- 位置 9(正中间):[干扰1, ..., 干扰9, 答案文档, 干扰10, ..., 干扰19]
- 位置 19(最末尾):[干扰1, ..., 干扰19, 答案文档]

然后画出"位置 → 准确率"曲线,就能看出性能随位置的变化规律。

位置索引说明(原文)

"Index n indicates performance when the document with the answer occurs at position n+1, where lower indices are closer to the start of the input context."

翻译: 索引 n 表示答案文档在第 n+1 个位置时的性能,较小的索引对应上下文开头的位置。

新手讲解: 索引从 0 开始,索引 0 = 第 1 篇(最开头),索引 19 = 第 20 篇(最末尾,当 k=20 时)。实验图表的 X 轴就是这个位置索引,Y 轴是准确率,看图就能直观地看到 U 形。


六、关键结果:U 形性能曲线

这是全文最重要的发现,请重点理解。

6.1 核心发现原文

"Performance is often highest when relevant information occurs at the beginning or end of the input context, and significantly degrades when models must access relevant information in the middle of long contexts."

翻译: 当相关信息出现在输入上下文的开头或结尾时,性能往往最高;当模型必须访问位于长上下文中间的相关信息时,性能会显著下降。


6.2 具体数字:GPT-3.5-Turbo(20 篇文档设置)

答案位置 准确率
开头(位置 0) 75.8%
中间(位置 9) 57.2%
结尾(位置 19) 63.2%
闭卷(无文档) 56.1%

惊人发现: 当答案放在中间位置时,GPT-3.5-Turbo 的准确率(57.2%)几乎等同于它不看任何文档时的准确率(56.1%)!

这意味着:给了 20 篇文档,还不如没有文档——额外的信息不仅没有帮助,反而可能形成干扰。


6.3 三种上下文长度的对比

10 篇文档时:
- GPT-3.5-Turbo:开头 76.8% → 中间 61.2% → 结尾 62.4%

20 篇文档时:
- GPT-3.5-Turbo:开头 75.8% → 中间 57.2% → 结尾 63.2%

30 篇文档时(GPT-3.5-Turbo 16K 版本):
- 开头 73.4% → 中间 55.1% → 结尾 63.7%

规律: 文档越多(上下文越长),中间位置的性能下降越明显,U 形越"深"。


6.4 Claude-1.3 的对比

文档数 开头 中间 结尾
10 篇 62.9% 58.3% 59.7%
20 篇 59.9% 55.9% 60.1%
30 篇 59.1% 55.1% 59.9%

新手讲解: Claude-1.3 也表现出 U 形,但相对 GPT-3.5-Turbo 更"平坦"一些——这说明不同模型的程度有差异,但所有主流模型都表现出这个规律


6.5 两种偏差:首因效应 vs 近因效应

原文:

"Models are better at using relevant information that occurs at the very beginning (primacy bias) or end of its input context (recency bias)."

翻译: 模型更擅长利用出现在输入上下文最开头(首因效应 / primacy bias)或结尾(近因效应 / recency bias)的相关信息。

新手讲解:
- 首因效应(primacy bias):记住最先接触的信息。人类心理学中早有记录,比如面试中第一印象很重要。
- 近因效应(recency bias):记住最近接触的信息。比如你今天最后做的一件事比中午做的事印象更深。

大模型同时表现出这两种效应,结合起来就形成了 U 形曲线:首尾都比中间好。


6.6 键值检索任务的结果

原文:

"Claude-1.3 and Claude-1.3 (100K) do nearly perfectly on all evaluated input context lengths."

翻译: Claude-1.3 和 Claude-1.3 (100K) 在所有测试的输入上下文长度上都几乎完美完成了任务。

新手讲解: 键值检索是一个纯机械性的任务,Claude 系列接近完美,但其他模型在键值对增多时(尤其是 300 个键值对)在中间位置的检索准确率会明显下降。这说明不同模型的上下文利用能力存在差异,Claude 在这个纯检索任务上明显更强。


七、分析与讨论(Section 4)

7.1 扩展上下文模型并不更强

原文:

"Performance between them is nearly identical, indicating that extended-context models are not necessarily better than their non-extended counterparts."

翻译: 扩展上下文版本和标准版本的性能几乎相同,这说明扩展上下文模型并不必然优于其非扩展版本

具体对比:
- GPT-3.5-Turbo (4K) vs GPT-3.5-Turbo (16K):在相同的 10/20 篇文档设置下,两者准确率几乎相同
- Claude-1.3 (8K) vs Claude-1.3 (100K):同样几乎没有差距

新手讲解: 这个发现很重要,也很令人失望。你可能以为"支持 100K token 的 Claude 肯定比 8K 版本更擅长利用长上下文",但实验证明:在重叠的上下文长度范围内,扩展版和标准版表现一样。仅仅扩大了窗口容量,不等于提升了模型实际利用长上下文的能力。这就好比给书桌加宽了,但人的注意力范围没有变大。


7.2 指令微调不是根本原因

原文:

"Both models have a U-shaped performance curve, where performance is much higher when relevant information occurs at the start or end of the input context, indicating that instruction fine-tuning process itself is not necessarily responsible for these performance trends."

翻译: 两种模型(基础版和指令微调版)都呈现 U 形性能曲线,这说明指令微调过程本身未必是造成这一性能趋势的原因

新手讲解: 有人可能猜测:也许是因为指令微调阶段的训练数据偏向短文本,所以模型在中间位置表现差?但实验对比了基础模型(MPT-30B)和指令微调版本(MPT-30B-Instruct),两者都显示出 U 形,说明这个问题不是微调阶段引入的,而是更根本的架构或训练问题。


7.3 编码器-解码器架构更鲁棒(有条件)

原文:

"When Flan-UL2 operates within training-length sequences, it shows relatively robust performance with 1.9% absolute difference between best- and worst-case performance."

翻译: 当 Flan-UL2 在训练长度范围内的序列上运行时,其性能相对鲁棒,最好和最差情况之间的绝对差距仅为 1.9%。

背景知识: GPT 系列是"解码器-only"架构,处理文本是从左到右单向进行的。而 Flan-T5、Flan-UL2 是"编码器-解码器"架构,编码器可以双向看整个输入,理论上对位置应该更不敏感。

新手讲解: 实验发现编码器-解码器架构确实更鲁棒——但只在训练时见过的序列长度范围内。一旦超过训练长度,它也会出现类似的 U 形性能下降。这说明:双向注意力有帮助,但训练数据的长度分布同样重要。


7.4 查询感知上下文化(Query-Aware Contextualization)

原文:

"This technique—placing queries before and after documents—dramatically improves performance on the key-value retrieval task—all models achieve near-perfect performance. However, query-aware contextualization minimally affects performance trends in the multi-document question answering task."

翻译: 这种技术——在文档前后都放置查询——在键值检索任务上显著提升了性能,所有模型都接近完美。然而,查询感知上下文化对多文档问答任务的性能趋势影响甚微。

什么是"查询感知上下文化"?
标准做法是:[查询] [文档1] [文档2] ... [文档k]
查询感知做法是:[查询] [文档1] [文档2] ... [文档k] [查询](在末尾重复一次查询)

新手讲解: 这是一个实用小技巧:把问题放在文档序列的前面和后面各一次,模型在生成答案前刚好看到了问题,可以"提醒"自己要找什么。这在纯机械检索任务上有显著效果,但对真实的问答任务效果有限。对 RAG 工程师来说,这个技巧值得在键值式查找场景中尝试。


八、实践案例研究:开放域问答(Section 5)

8.1 发现:模型性能饱和比检索回召饱和得更早

原文:

"Reader model performance saturates long before retriever performance saturates. Using 50 documents instead of 20 retrieved documents only marginally improves performance (∼1.5% for GPT-3.5-Turbo and ∼1% for Claude-1.3)."

翻译: 阅读器模型的性能饱和时间远早于检索器性能的饱和时间。从 20 篇文档增加到 50 篇文档,性能仅有边际提升(GPT-3.5-Turbo 约提升 1.5%,Claude-1.3 约提升 1%)。

新手讲解:

在真实 RAG 系统中,流程是:
1. 检索器(Retriever):从知识库里找出 k 篇相关文档
2. 阅读器(Reader,即语言模型):读这 k 篇文档,生成答案

这里发现了一个不匹配
- 检索器:返回 50 篇文档的效果明显好于 20 篇(找到答案的概率更高)
- 阅读器:但即使给了 50 篇,模型的答题准确率和给 20 篇差不多

这说明瓶颈不在于"有没有找到答案文档",而在于"找到了但模型看不到"


8.2 实践建议

原文:

"Effective reranking of retrieved documents (pushing relevant information closer to the start of the input context) or ranked list truncation (retrieving fewer documents when appropriate) may be promising improvements for language-model-based retrieval systems."

翻译: 对检索文档进行有效的重排序(将相关信息推到输入上下文的靠前位置)或排名列表截断(在适当时候检索更少的文档),可能是改善基于语言模型的检索系统的有效途径。

新手讲解:

作者给出了两条具体建议:

  1. 重排序(Reranking):检索出 50 篇文档后,用一个更精准的模型再次排序,把最相关的那篇排到最前面(位置 0)。根据实验,这能显著提升准确率。

  2. 截断(Truncation):别傻傻地把 50 篇都塞给模型。如果检索质量够好,截断到 10-20 篇效果反而更好,因为答案文档更有可能落在靠前位置,而不是被淹没在中间。


九、结论

原文:

"We empirically study how language models use long input contexts via a series of controlled experiments. We show that language model performance degrades significantly when changing the position of relevant information, indicating that models struggle to robustly access and use information in long input contexts. In particular, performance is often lowest when models must use information in the middle of long input contexts."

翻译: 我们通过一系列受控实验,对语言模型如何利用长输入上下文进行了实证研究。我们发现,当改变相关信息的位置时,语言模型的性能会显著下降,这说明模型在鲁棒地访问和利用长输入上下文中的信息方面存在困难。特别是,当模型必须利用长上下文中间的信息时,性能往往最低。

新手讲解: 这篇论文的贡献不是"提出了新方法",而是发现并量化了一个之前被忽视的系统性缺陷。它告诉研究者:评测长上下文模型时,不能只测"能处理多长的上下文",还要测"处理长上下文时有没有位置盲区"。它也给从业者提供了可操作的建议:关键信息要放在开头,而不是中间。


十、对 RAG 与长文档应用实践者的启示

编者按:这是本文发现对工程实践的直接指导意义。

核心教训

"Lost in the Middle"现象的实质是:当你给语言模型很长的上下文时,它并不是均匀地"读"每一部分,而是对开头和结尾的信息更加敏感,对中间的信息容易"失明"。

具体操作建议

场景 建议 原理
RAG 检索后排序 把最相关的文档排在最前面(而非中间) 首因效应,位置 0 性能最高
文档数量控制 不要堆砌过多文档,10-20 篇通常已足够 文档越多,中间文档被"遗忘"的概率越高
重要信息摆放 关键上下文放在 Prompt 的开头或结尾 U 形曲线证明,中间位置是"死角"
系统提示词位置 关键指令放在 System Prompt 开头,或在 User Turn 末尾重复 同样遵循近因/首因效应
不要依赖"大窗口" 100K 上下文窗口不代表能均匀利用 100K 内容 扩展版模型与标准版表现几乎相同
重排序优先于扩容 用重排序模型提升文档质量,比增加文档数更有效 检索回召和阅读器性能不匹配

一句话总结

不要把关键信息埋在中间。当你用 RAG 或长文档应用时,把最重要的内容放在开头,这是目前最简单、最有效的工程实践改进。


十一、相关工作与附录

相关工作(一句话带过):该节回顾了长文档理解、检索增强生成、注意力机制效率等相关工作,为本文研究定位提供背景。

附录(一句话带过):包含了各模型在不同任务上的详细结果图表、Llama-2 系列的额外实验、以及更多消融实验数据,感兴趣的读者可参阅原文。


十二、核心概念速查表

术语 英文 解释
上下文窗口 Context Window 模型每次处理时能"看到"的最大文本长度
多文档问答 Multi-Document QA 给模型多篇文档,要求它从中找出问题的答案
键值检索 Key-Value Retrieval 给模型一组键值对,要求它找出指定键对应的值
U 形曲线 U-shaped Curve 性能随位置变化的图形:两端高、中间低
首因效应 Primacy Bias 模型更擅长利用上下文开头的信息
近因效应 Recency Bias 模型更擅长利用上下文结尾的信息
鲁棒性 Robustness 在各种条件下都能稳定表现的能力
检索增强生成 RAG 先用检索器找相关文档,再让模型基于文档生成回答
Oracle 设置 Oracle Setting 只给一篇有答案的文档,测试理解能力上限
闭卷 Closed-book 不给任何文档,只靠模型自身记忆回答
重排序 Reranking 对检索结果按相关性再次精细排序
查询感知上下文化 Query-Aware Contextualization 在文档序列的前后都放置查询语句

精读完成。本文基于 ar5iv.labs.arxiv.org 提供的原文内容整理,准确性以原文为准。