Claude:上下文检索(译文)

date
Sep 21, 2024
slug
Claude-contextual-retrieval-translate
status
Published
tags
RAG
翻译
Claude
summary
type
Post

引入上下文检索

为了让人工智能模型在特定场景下发挥作用,它通常需要访问背景知识。例如,客户支持聊天机器人需要了解其服务的具体业务知识,而法律分析机器人则需要了解大量的过往案例。
开发者通常使用检索增强生成(Retrieval-Augmented Generation, RAG)来增强AI模型的知识。RAG是一种从知识库中检索相关信息并将其附加到用户提示(prompt)中的方法,从而显著提升模型响应的质量。问题在于,传统的RAG解决方案在编码信息时会丢失上下文,这常常导致系统无法从知识库中检索到相关信息。
在这篇文章中,我们概述了一种能够显著改进RAG中检索步骤的方法。该方法被称为“上下文检索”(Contextual Retrieval),并使用了两种子技术:上下文嵌入(Contextual Embeddings)和上下文BM25(Contextual BM25)。这种方法可以将检索失败的次数减少49%,当与重排序(reranking)结合使用时,可以减少67%。这代表了检索准确性的显著提升,并直接转化为下游任务中更好的性能。
您可以使用我们的cookbook轻松部署自己的上下文检索解决方案。

关于直接使用更长提示的说明

有时候,最简单的解决方案是最好的。如果你的知识库小于200,000个token(约500页材料),你可以直接将整个知识库包含在给模型的提示中,无需使用RAG或类似方法。
几周前,我们发布了Claude的提示缓存(prompt caching)功能,这种方法因此变得更快、更具成本效益。开发者现在可以在API调用之间缓存常用的提示,将延迟降低超过2倍,成本降低高达90%。
然而,随着知识库的增长,您将需要一个更具扩展性的解决方案。这就是上下文检索发挥作用的地方。

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

对于无法容纳在上下文窗口中的更大型知识库,RAG是典型的解决方案。RAG通过以下步骤对知识库进行预处理:
  1. 将知识库(文档“语料库”)分解为更小的文本块(chunks),通常不超过几百个token。
  1. 使用嵌入模型(embedding model)将这些文本块转换为编码其含义的向量嵌入。
  1. 将这些嵌入存储在向量数据库中,以便按语义相似性进行搜索。
在运行时,当用户向模型输入查询时,系统会使用向量数据库根据与查询的语义相似性找到最相关的文本块。然后,将最相关的文本块添加到发送给生成模型的提示中。
虽然嵌入模型擅长捕捉语义关系,但它们可能会错过关键的精确匹配。幸运的是,有一种更早的技术可以应对这种情况。BM25(Best Matching 25)是一种排序函数,它使用词法匹配来查找精确的单词或短语匹配,对于包含唯一标识符或技术术语的查询尤其有效。
通过结合嵌入和BM25技术,RAG解决方案可以更准确地检索到最适用的文本块:
  1. 将知识库分解为小文本块。
  1. 为这些文本块创建TF-IDF编码和语义嵌入。
  1. 使用BM25根据精确匹配查找排名靠前的文本块。
  1. 使用嵌入根据语义相似性查找排名靠前的文本块。
  1. 使用排序融合技术合并和去重(3)和(4)的结果。
  1. 将排名最高的K个文本块添加到提示中以生成响应。
一个标准的检索增强生成 (RAG) 系统,该系统同时使用嵌入和BM25来检索信息
一个标准的检索增强生成 (RAG) 系统,该系统同时使用嵌入和BM25来检索信息
这种方法让您可以经济高效地扩展到庞大的知识库,但传统的RAG系统有一个显著的局限性:它们常常会破坏上下文。

传统RAG中的上下文难题

在传统的RAG中,文档通常被分割成小块以便高效检索。虽然这种方法在许多应用中效果很好,但当单个文本块缺乏足够上下文时,就会引发问题。
例如,假设您的知识库中嵌入了一系列财务信息(比如美国证券交易委员会SEC的文件),您收到了以下问题:“ACME公司在2023年第二季度的收入增长是多少?”
一个相关的文本块可能包含:“该公司本季度收入较上一季度增长了3%。” 然而,这个文本块本身没有指明是哪个公司或相关的时间段,这使得检索正确信息或有效使用信息变得困难。

引入上下文检索

上下文检索通过在嵌入和创建BM25索引之前,为每个文本块预先添加针对该块的解释性上下文来解决这个问题。这个过程包括“上下文嵌入上下文BM25”。
回到SEC文件的例子,以下是一个文本块如何被转换的示例:

实现上下文检索

当然,手动为知识库中成千上万甚至数百万的文本块添加注释工作量太大了。为了实现上下文检索,我们求助于Claude。我们编写了一个提示,指示模型提供简洁的、针对特定文本块的上下文,利用整个文档的背景来解释该文本块。我们使用以下Claude 3 Haiku提示为每个文本块生成上下文:
生成的上下文文本通常为50-100个token,在进行嵌入和创建BM25索引之前,它会被添加到原始文本块的前面。
上下文检索是一种提高检索准确性的预处理技术流程图
上下文检索是一种提高检索准确性的预处理技术流程图

性能提升

我们的实验表明:
  • 上下文嵌入将前20个文本块的检索失败率降低了35%(从5.7% → 3.7%)。
  • 结合上下文嵌入和上下文BM25,将前20个文本块的检索失败率降低了49%(从5.7% → 2.9%)。
结合上下文嵌入和上下文BM25,检索失败率降低49%
结合上下文嵌入和上下文BM25,检索失败率降低49%

实现注意事项

  • 文本块边界:如何将文档分割成块会影响检索性能。
  • 嵌入模型:虽然上下文检索对所有测试的模型都有提升,但我们发现Gemini和Voyage的嵌入模型尤其有效。
  • 自定义上下文生成提示:针对特定领域定制提示可能会获得更好的结果。
  • 文本块数量:我们发现检索20个文本块是性能最佳的选择,但这值得您在自己的用例上进行实验。

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

最后,我们可以将上下文检索与另一种技术——重排序(Reranking)——相结合,以获得更大的性能提升。重排序是一种常用的过滤技术,用于确保只有最相关的信息块被传递给模型。
关键步骤如下:
  1. 执行初步检索以获取大量可能相关的文本块(我们使用了前150个)。
  1. 使用重排序模型为每个文本块打分。
  1. 选择得分最高的K个文本块(我们使用了前20个)。
  1. 将这K个文本块作为上下文传递给模型以生成最终结果。
结合上下文检索和重排序以最大化检索准确性
结合上下文检索和重排序以最大化检索准确性
通过增加重排序步骤,我们将检索失败率总共降低了67%(从5.7% → 1.9%)。
经过重排序的上下文嵌入和上下文BM25,检索失败率降低67%
经过重排序的上下文嵌入和上下文BM25,检索失败率降低67%

结论

我们进行了大量测试,总结出以下几点:
  1. 嵌入+BM25优于单独使用嵌入。
  1. Voyage和Gemini在我们测试的模型中拥有最好的嵌入效果。
  1. 向模型传递前20个文本块比只传递前10或前5个更有效。
  1. 为文本块添加上下文能极大地提高检索准确性。
  1. 重排序优于不进行重排序。
  1. 所有这些好处都可以叠加:为了最大化性能,我们可以将上下文嵌入(来自Voyage或Gemini)与上下文BM25相结合,再加上重排序步骤,并将20个文本块添加到提示中。
我们鼓励所有使用知识库的开发者使用我们的cookbook来实验这些方法,以解锁新的性能水平。

附录I

在不同数据集、嵌入模型、是否使用BM25、是否使用上下文检索以及是否使用重排序等条件下,检索前20个结果(Retrievals @ 20)的1-recall@20指标的详细结果:
notion image

© Baiye 2022 - 2025