[博客翻译]情境检索:让AI模型在特定场景下更聪明


原文地址:https://www.anthropic.com/news/contextual-retrieval


对于AI模型在特定情境下变得有用,往往需要访问背景知识。例如,客户服务聊天机器人需要了解其服务的具体业务,而法律分析机器人需要了解大量过去的案例。

开发人员通常使用增强检索生成(RAG)来提升AI模型的知识。RAG是一种方法,它从知识库中检索相关信息并将其附加到用户的提示之中,从而显著提升模型的响应质量。问题是,传统的RAG解决方案在编码信息时会移除上下文,这往往导致系统无法从知识库中检索到相关的信息。

在本文中,我们概述了一个显著改进RAG中检索步骤的方法。该方法称为“上下文检索”,使用两个子技术:上下文嵌入与上下文BM25。这种方法可以将失败的检索次数减少49%,并且当与重排序结合使用时,可以将其减少至67%。这些显著提升了检索准确性,从而直接转化为下游任务的更好表现。

你可以通过我们的食谱轻松部署你自己的上下文检索方案。

关于使用更长提示的一个注释

有时候最简单的解决方案就是最好的。如果你的知识库小于200,000个标记(约500页资料),你可以直接将整个知识库包含在提供给模型的提示中,无需使用RAG或类似方法。

几周前,我们发布了prompt缓存,这使得这种方法速度更快且更具成本效益。开发人员现在可以在API调用之间缓存常用提示,降低延迟超过2倍,并减少高达90%的成本(你可以通过阅读我们的prompt缓存食谱了解具体详情)。

然而,随着你的知识库的增长,你需要一个更可扩展的方案。这就是上下文检索的作用所在。

RAG入门:扩展至更大的知识库

对于较大的知识库,无法适应上下文窗口时,RAG是典型的解决方案。RAG通过以下步骤处理知识库:

  1. 将知识库(文档的“语料库”)分解为较小的文本片段,通常不超过几百个标记;
  2. 使用嵌入模型将这些片段转换为向量嵌入,用来编码意义;
  3. 将这些嵌入存储在一个向量数据库中,以便根据语义相似性进行搜索。

运行时,当用户向模型输入查询时,向量数据库用于基于语义相似性找到最相关的片段。然后,将最相关的片段添加到发送给生成模型的提示之中。

虽然嵌入模型擅长捕捉语义关系,但它们可能会错过关键的确切匹配。幸运的是,有一种较旧的技术可以在这方面提供帮助。BM25(最佳匹配25)是一个排名函数,使用词汇匹配来查找精确的单词或短语匹配。它特别适用于包含唯一标识符或技术术语的查询。

BM25基于TF-IDF(词频-逆文档频率)概念,对这一概念进行细化。TF-IDF衡量一个词在一个集合中的文档中的重要性。BM25通过考虑文档长度并对词频应用饱和函数来改进这一点,以防止常用词主导结果。

以下是BM25如何在语义嵌入失败的地方成功的例子:假设用户在技术支持数据库中查询“错误代码TS-999”。一个嵌入模型可能会找到关于错误代码的内容,但可能错过确切的“TS-999”匹配。BM25通过寻找这个特定的文字字符串来识别相关文件。

RAG解决方案可以通过结合嵌入和BM25技术,按照以下步骤更准确地检索相关片段:

  1. 将知识库(“语料库”的文档)分解为较小的文本片段,通常不超过几百个标记;
  2. 为这些片段创建TF-IDF编码和语义嵌入;
  3. 使用BM25基于确切匹配找到顶级片段;
  4. 使用嵌入法根据语义相似性找到顶级片段;
  5. 根据排名融合技术合并并去重步骤(3)和(4)的结果;
  6. 添加前K个顶级片段到提示以生成响应。

通过结合BM25和嵌入模型,传统RAG系统可以提供更为全面和准确的结果,平衡精确的术语匹配与更广泛的语义理解。

此标准检索增强生成(RAG)系统结合了嵌入和最佳匹配25(BM25)来检索信息。TF-IDF(词频-逆文档频率)衡量词语重要性并构成BM25的基础。这种方法能够使你以具有成本效益的方式扩展巨大的知识库,远远超出单个提示所能容纳的范围。但这些传统的RAG系统有一个重大缺点:它们往往会破坏上下文。

传统RAG中的上下文问题

在传统的RAG中,文档通常被分为较小的片段以提高检索效率。虽然这种方法适用于许多应用,但在单个片段缺乏足够上下文的情况下,会导致问题。

例如,想象你有一个财务信息(比如说美国证券交易委员会SEC文件)的知识库,并收到了如下问题:“ACME公司在2023年第二季度的营收增长是多少?”

一个相关的片段可能是:“公司的收入比前一季度增长了3%。”但单独来看这段文字并没有指明它所涉及的具体公司或时间区间,使得难以准确检索或有效使用这些信息。

引入上下文检索

上下文检索通过在嵌入之前以及创建BM25索引之前为每个片段添加特定于片段的解释性上下文来解决这个问题(称为“上下文嵌入”与“上下文BM25”)。

让我们回到SEC文件的例子。以下是片段如何变形的一个示例:

原始片段 = "公司的收入比前一季度增长了3%。"

上下文化片段 = "这是来自ACME公司在2023年第二季度业绩报告的一部分;上一季度收入为3亿1400万美元。公司的收入比前一季度增长了3%。"

值得一提的是其他改善检索的方法在过去已经被提出过。其他提案包括:在片段中加入通用的文档摘要(我们尝试后发现效果非常有限),假设文档嵌入,以及基于总结的索引(我们评估后发现性能较低)。这些方法不同于本篇提出的方案。

实施上下文检索

当然,手动标注知识库中的数千乃至数百万个片段显然太多工作。为了实施上下文检索,我们转向Claude。我们编写了一段提示,引导模型提供简明且特定于片段的上下文,解释片段在整个文档中的位置。我们使用的Claude 3俳句提示如下:

文档 
{{WHOLE_DOCUMENT}} 
</文档> 
这是我们希望定位到整个文档中的片段 
片段 
{{CHUNK_CONTENT}} 
</片段> 
请给出简短且精准的上下文,以便将此片段定位在整个文档中以提高检索的准确性。仅回答简短的上下文内容,其余部分不要添加。

生成的上下文文本通常为50-100个标记,在嵌入片段以及创建BM25索引之前先附加到片段上。

以下是在实践中预处理流程的样子:

上下文检索是一种预处理技术,提高了检索准确性。
如果你有兴趣使用上下文检索,你可以通过我们的食谱开始。

使用提示缓存来降低上下文检索的成本

上下文检索利用我们上述提到的Claude特有的提示缓存功能可以以极低的成本实现。借助提示缓存功能,您无需为每个片段都传递参考文档。您只需要将文档一次加载到缓存中,随后引用之前已缓存的内容即可。假设800标记的片段,8k标记的文档,50标记的上下文指令和每个片段100标记的上下文,每百万文档标记生成上下文化的片段的一次性成本为$1.02

方法论

我们在不同的知识领域(代码库、小说、ArXiv论文、科学论文)、嵌入模型、检索策略及评估指标上进行了实验。我们在附录II中包含了一些用于每个领域的示例问题及答案。

下面的图表显示了使用最佳性能嵌入配置(Gemini Text 004)并在检索前20个最相关片段时所有知识领域的平均性能。我们采用1减去Recall@20作为我们的评估指标,该指标衡量在前20个片段内未能检索到的相关文档比例。您可以查看附录中的全部结果 — 在我们评估的所有嵌入源组合中,上下文化都提高了性能。

性能改进

我们的实验表明:

  • 上下文化嵌入减少了前20个片段检索失败率35%(从5.7%减少至3.7%)。
  • 结合上下文化嵌入与上下文BM25减少了前20个片段检索失败率49%(从5.7%减少至2.9%)。

结合上下文化嵌入和上下文BM25降低了前20个片段检索失败率49%。 实施注意事项

在实施上下文检索时,有几个需要考虑的因素:

  1. 片段边界: 考虑您如何将文档拆分为片段。选择片段大小、片段边界及片段重叠会影响检索性能^1^。
  2. 嵌入模型: 尽管上下文检索能改进我们测试的所有嵌入模型的表现,但某些模型可能会从中获得更多益处。我们发现GeminiVoyage嵌入特别有效。
  3. 自定义上下文化提示: 虽然我们提供的通用提示已经很有效,但在特定领域或用例中定制的提示可能效果会更好(例如,包含只有知识库中的其他文档才定义的术语词典)。
  4. 片段数量: 向上下文窗口中添加更多片段会增加包含相关信息的机会。然而,过多的信息可能使模型分心,因此这种方法存在局限性。我们尝试交付5、10及20个片段,且发现在这些选项中使用20个片段表现最佳(请参阅附录中的比较),但值得针对您的具体用例进行实验。

始终运行评估: 通过对它提供上下文化的片段并区分上下文和片段的不同部分,响应生成可能得到改善。

通过重新排序进一步提升性能

最后一步,我们可以结合上下文检索和另一种技术来获得更多的性能改进。在传统的RAG中,AI系统会搜索其知识库以找到可能相关的信息片段。对于大型知识库,最初的检索往往返回许多相关性不一的片段——有时数以百计。

重新排序是一种常用的过滤技术,确保只有最相关的片段被传送给模型。重新排序提供了更好的响应并减少了成本和延迟,因为模型处理的信息较少。关键步骤如下:

  1. 进行初始检索以获取最相关的片段(我们使用了前150个);
  2. 将前N个片段以及用户的查询一同传入重新排序模型;
  3. 使用重新排序模型根据片段与提示的相关性和重要性为每个片段打分,然后选择前K个片段(我们选择了前20个);
  4. 将前K个片段作为上下文传给模型以生成最终结果。

结合上下文检索和重新排序以最大化检索准确性。#### 性能改进

市场上有几种重新排序模型。我们使用了Cohere的重新排序器进行了测试。Voyage也有一个重新排序器,但我们没有时间测试。我们的实验证明,在不同的领域中增加重新排序步骤能够进一步优化检索。

特别地,我们发现经过重新排序的上下文化嵌入和上下文BM25减少了前20个片段检索失败率67%(从5.7%减少至1.9%)。

经重新排序的上下文化嵌入和上下文BM25减少了前20个片段的检索失败率67%。 成本和延迟考虑

重新排序对延迟和成本产生影响,尤其是在要重新排序大量片段的情况下。由于重新排序在运行时添加了一个额外步骤,尽管重新排序器并行评分所有片段,它不可避免地会增加少量延迟。在重新排序更多片段以获得更好性能与重新排序更少片段以减少延迟和成本之间存在着固有的权衡。我们建议针对您的特定用例实验不同的设置以找到合适的平衡。

结论

我们进行了大量的测试,比较了上述所有技术(嵌入模型、使用BM25、使用上下文检索、使用重新排序器、及检索的总前K个结果)的各种不同组合,并覆盖了多种不同的数据集类型。以下是我们的发现总结:

  1. 嵌入+BM25比单独使用嵌入更好;
  2. Voyage和Gemini在我们测试的所有嵌入中表现最佳;
  3. 向模型传递前20个片段比仅传递前10或前5个片段更有效;
  4. 向片段添加上下文大幅度提高检索准确性;
  5. 重新排序比不重新排序更好;
  6. 这些好处可以累加:为了最大化性能改进,我们可以结合使用Voyage或Gemini的上下文化嵌入、上下文BM25以及重新排序步骤,并向提示中添加20个片段。

我们鼓励所有处理知识库的开发人员使用我们的cookbook来试验这些方法,以解锁新的性能水平。

附录I

以下为不同数据集、嵌入提供商、除嵌入外使用BM25、使用上下文检索及使用重新排序来检索前20个结果的结果分解。

请参见附录II了解前10个及前5个结果的分解,以及每个数据集示例问题及答案。