Anthropic 上下文检索:利用上下文嵌入和 BM25 提升 RAG 准确率
上下文检索通过在检索过程中保留文档上下文,显著提升了检索增强生成(RAG)的准确率。
传统 RAG 解决方案常常无法检索到相关信息,因为将文档分块并创建嵌入的过程会丢失关键上下文。上下文检索通过在嵌入或索引每个分块之前,为每个分块添加分块专属的解释性上下文,从而解决了这一问题。
传统 RAG 系统的局限性
检索增强生成(RAG)是一种通过从知识库中检索相关信息并将其附加到用户提示中,来增强 AI 模型知识的标准方法。然而,传统 RAG 系统存在两个主要局限:上下文丢失和无法捕捉精确匹配。
当文档被拆分为较小的分块以便高效检索时,这些单独的分块往往缺乏足够的上下文。例如,一个分块写道“公司营收较上一季度增长了 3%”,如果不指明是哪家公司或哪个时间段,就会产生歧义。
此外,虽然语义嵌入擅长捕捉广泛的语义关系,但它们可能遗漏关键的精确匹配。诸如 BM25(最佳匹配 25)这类使用词法匹配的技术,对于查找精确的单词或短语匹配(例如“TS-999”这样的精确错误代码)是必要的。
传统 RAG 系统可以通过创建 TF-IDF 编码和语义嵌入来结合这些方法,使用 BM25 进行精确匹配,然后通过排名融合合并结果。然而,这种方法仍然面临上下文难题。
上下文检索:解决上下文问题的方案
上下文检索是一种预处理技术,通过解决标准 RAG 中固有的上下文丢失问题来提升检索准确率。它通过两种子技术实现:上下文嵌入和上下文 BM25。
上下文嵌入的工作原理是指导模型(如 Claude)根据整个文档为每个分块生成简洁、分块专属的解释性上下文。生成的上下文文本(通常为 50-100 个 token)会在嵌入或索引之前被添加到原始分块的前面。
这种转换使检索系统能够理解分块周围的上下文,确保即使是很小的分块在检索时也具有意义。
上下文检索的性能提升
实验结果表明,上下文检索在代码库、小说和科学论文等多种知识领域中都显著提升了检索准确率。
- 仅使用上下文嵌入即可将前 20 个分块检索失败率降低 35%(从 5.7% 降至 3.7%)。
- 结合上下文嵌入和上下文 BM25可将前 20 个分块检索失败率降低 49%(从 5.7% 降至 2.9%)。
使用 Claude 的提示缓存功能时,上下文检索可以以低成本进行部署。假设每个分块 800 个 token、每篇文档 8000 个 token、上下文指令 50 个 token、每个分块上下文 100 个 token,生成上下文分块的一次性成本为每百万文档 token 1.02 美元。
使用重排序进一步提升性能
通过将上下文检索与重排序步骤相结合,可以进一步优化检索准确率。重排序是一种过滤技术,确保只有最相关的分块被传递给生成模型,从而降低成本和延迟。
该过程包括:
- 初步检索大量可能相关的分块(例如前 150 个)。
- 将这些分块和用户查询传递给重排序模型。
- 根据相关性和重要性对每个分块进行评分。
- 选择前 K 个分块(例如前 20 个)作为上下文传递。
当使用重排序的上下文嵌入和上下文 BM25 时,前 20 个分块检索失败率降低了 67%(从 5.7% 降至 1.9%)。
实现注意事项
实现上下文检索的开发者应考虑以下几个因素以最大化性能:
- 分块边界: 分块大小、分块边界和分块重叠的选择会显著影响检索性能。
- 嵌入模型: 虽然上下文检索在所有测试的嵌入模型上都能提升性能,但 Gemini 和 Voyage 嵌入被发现特别有效。
- 自定义上下文生成提示: 虽然提供了通用提示,但针对特定领域或用例定制提示(例如包含关键术语表)可能会产生更好的结果。
- 分块数量: 虽然更多分块会增加包含相关信息的可能性,但添加过多信息可能会分散模型注意力。测试表明,在 5、10 和 20 个分块中,使用 20 个分块是性能最优的选择。
总之,最大化性能的最有效方法是结合上下文嵌入(来自 Voyage 或 Gemini)与上下文 BM25,然后进行重排序步骤,并将前 20 个分块传递给提示。
Sources
- OriginalIntroducing Contextual Retrieval