为什么它在几百页材料里找错了地方

「营收环比增长 3%」——这句话被切出来单独存进检索库之后,没人知道它说的是哪家公司、哪个季度。Anthropic 给了一个便宜的修法:先让小模型给每一块补一句上下文,检索失败率降了 49%。

2024/09/19约 7 分钟HiBridge 编译
译文本文是英文原文的中文翻译,原作者与原文链接如下。
原作者
Anthropic
原文标题
Introducing Contextual Retrieval
原发布平台
Anthropic
原发布日期
2024/09/19

译者说明:本文译自 Anthropic 官方博客。原文面向开发者,讲的是检索增强生成(RAG)系统的构建。 但它诊断的那个毛病,任何一个用 AI 处理大批材料的人都撞过——所以本文保留了方法,重点翻译「为什么会错」这一段,并在文末给出不写代码的替代方案。

问题:切块的时候,上下文被切掉了

传统的检索增强生成(RAG)系统有一个结构性的毛病:它们在编码信息的时候把上下文移除了。

当文档被切成小块时,单独的一块常常缺少足以被正确理解或被正确检索的周边信息。

举个例子。假设你有一堆财报文件在知识库里,收到这样一个问题:

「ACME 公司 2023 年第二季度的营收增长是多少?」

某一个块可能正好包含这句话:

公司的营收比上一季度增长了 3%。

但这一块本身没有说明是哪家公司,也没有说明是哪个时间段。 这让检索几乎不可能准确命中,也让答案不可能可靠。

解法:给每一块补一句上下文再存

这个方法叫上下文检索(Contextual Retrieval),它由两个动作组成:

  • 上下文嵌入(Contextual Embeddings):在把块转成向量之前,先在块前面加上一段解释性的上下文
  • 上下文 BM25:在建立 BM25 词法索引之前,同样把上下文加在前面

那段上下文由 Claude Haiku 用下面这个提示词生成——原文照录,不译

<document>
{{WHOLE_DOCUMENT}}
</document>
Here is the chunk we want to situate within the whole document
<chunk>
{{CHUNK_CONTENT}}
</chunk>
Please give a short succinct context to situate this chunk within the overall
document for the purposes of improving search retrieval of the chunk. Answer
only with the succinct context and nothing else.

生成的上下文通常在 50–100 个 token,加在每一块的前面。

回到刚才那个例子,处理之后那一块会变成类似这样:

「本节摘自 ACME 公司 2023 年第二季度的 SEC 财报,上一季度营收为 3.14 亿美元。公司的营收比上一季度增长了 3%。」

现在它可以被检索到了。

效果

做法 前 20 块检索失败率 相对降幅
基线 5.7%
只加上下文嵌入 3.7% ↓ 35%
上下文嵌入 + 上下文 BM25 2.9% ↓ 49%
再加重排序 1.9% ↓ 67%

**重排序(Reranking)**是在初步检索出的前 150 块中,再筛出最相关的 20 块。它进一步提高了准确率,但开发者需要在性能收益与增加的延迟和成本之间权衡。

实践建议

原文给出的建议:

  1. 认真考虑分块的边界和大小
  2. 嵌入模型上,Gemini 和 Voyage 在测试中表现最好
  3. 针对你所在的具体领域,定制那段生成上下文的提示词
  4. 检索并传入 20 块,而不是 5 块或 10 块
  5. 在你自己的用例上跑评测
  6. 在重排序的阈值上做实验,找到延迟与准确率的平衡点

但如果你的材料不到 20 万 token,别做这些

原文里有一句容易被跳过、但对多数人最重要的话:

对于小于 20 万 token 的知识库(大约 500 页材料),最简单的办法是把整个知识库直接放进提示词里,用提示词缓存的话,成本大约是每百万 token 1.02 美元。

换句话说:上面那一整套只在材料多到装不下的时候才需要。


译后附记:不写代码的话,这篇怎么用

这篇文章的价值不在于让你去搭一套检索系统,而在于它解释了一个你一定遇到过的现象:你把五十份访谈稿一起丢进去,问「谁提到了价格敏感」,它漏了一半。

原因就是原文说的那个:每一段被切开之后,它自己不知道自己是谁说的。

三条可以直接用:

① 先算一下材料有多大。 20 万 token 大约是 500 页 / 15 万个汉字。低于这个量,就别搞检索——直接全文喂进去,今天的模型窗口装得下,而且不会漏。这是这篇文章给非开发者最有用的一条。

② 装不下的话,动手在每份材料开头补一行「身份行」。 这就是原文那套方法的手工版:

【来源】华东区经销商 A / 2026-06-12 / 深访 / 访谈员:李

一行字,写在每份稿子最上面。它让任何一段被单独抽出来时都还知道自己是谁。成本几乎为零,效果和原文那套自动化处理是同一个方向。

③ 别信「它没找到就是没有」。 原文的基线失败率是 5.7%,那还是精心构建的检索系统。你在对话框里做的那种粗放检索,漏得只会更多。 涉及关键结论时,回原文核对一遍。

配套阅读:从超长文档里提取关键信息材料该用什么格式喂给模型


出处

本文译自 Anthropic 官方博客,原文 Introducing Contextual Retrieval。 译文与译后附记由 HiBridge 撰写。