Anthropic分享RAG最佳实践:Contextual Retrieval

先说结论,Anthropic提出了一种显著改进RAG中检索步骤的方法。这种方法被称为“上下文检索(Contextual Retrieval)”:

  • 它使用两种子技术:上下文嵌入(Contextual Embeddings)和上下文BM25

  • 这种方法可以将检索失败的次数减少49%

  • 并且当结合重排时,减少67%

上下文检索(Contextual Retrieval)的出发点:RAG是一种从知识库检索相关信息并将其附加到用户提示上的方法,显著提升了模型的响应。但是传统的RAG解决方案在编码信息时会移除上下文,这常常导致系统无法从知识库中检索到相关信息。

关于仅使用更长提示的说明

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

几周前,Anthropic为Claude发布了提示缓存,这使得这种方法显著更快且更具成本效益。开发者现在可以在API调用之间缓存经常使用的提示,减少延迟超过2倍,成本降低高达90%。

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

RAG简介:扩展到更大的知识库

对于不适合在上下文窗口内的知识库,RAG是典型的解决方案。RAG通过以下步骤预处理知识库:

  • 将知识库(文档的“语料库”)分解成较小的文本块,通常不超过几百个token;

  • 使用嵌入模型将这些块转换为编码意义的向量嵌入;

  • 将这些嵌入存储在允许按语义相似性搜索的向量数据库中。

标准检索增强生成 (RAG) 系统使用嵌入和BM25来检索信息。TF-IDF(词频-逆文档频率)衡量词语重要性并构成 BM25 的基础。

图片

虽然嵌入模型在捕获语义关系方面表现出色,但它们可能会错过关键的精确匹配。幸运的是,有一种较老的技术可以在这些情况下提供帮助。BM25使用词汇匹配来找到精确的单词或短语匹配。它特别适用于包含唯一标识符或技术术语的查询。

RAG解决方案可以通过以下步骤结合嵌入和BM25技术,更准确地检索最适用的块:

  • 将知识库(文档的“语料库”)分解成较小的文本块,通常不超过几百个token;

  • 为这些块创建TF-IDF编码和语义嵌入;

  • 使用BM25基于精确匹配找到顶部块;

  • 使用嵌入基于语义相似性找到顶部块;

  • 使用排名融合技术结合并去重(3)和(4)的结果;

  • 将顶部K块添加到提示中以生成响应。

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

这种方法允许你以成本效益的方式扩展到巨大的知识库,远远超出单个提示所能适应的范围。但这些传统的RAG系统有一个显著的限制:它们经常破坏上下文。

传统RAG中的上下文困境

在传统的RAG中,文档通常被分割成较小的块以便于检索。虽然这种方法对许多应用来说效果很好,但当单个块缺乏足够的上下文时,它可能会导致问题。

例如,想象你有一个金融信息集合(比如美国SEC文件)嵌入在你的知识库中,你收到了以下问题:“2023年第二季度ACME公司的收入增长是多少?

一个相关的块可能包含这样的文本:“公司的收入比上个季度增长了3%。”然而,这个块本身并没有指定它指的是哪家公司或相关的时间段,这使得检索正确信息或有效使用信息变得困难。

上下文检索技术(Contextual Retrieval)

上下文检索通过在嵌入之前将块特定的解释性上下文附加到每个块之前(“上下文嵌入”)和创建BM25索引(“上下文BM25”)来解决这个问题。

回到SEC文件集合示例。这里有一个块如何被转换的例子:

original_chunk = "The company's revenue grew by 3% over the previous quarter."
contextualized_chunk = "This chunk is from an SEC filing on ACME corp's performance in Q2 2023; the previous quarter's revenue was $314 million. The company's revenue grew by 3% over the previous quarter."

中文:

原始块 = "公司的收入比上个季度增长了3%。" 上下文化块 = "这个块来自关于ACME公司2023年第二季度表现的SEC文件;上个季度的收入为3.14亿美元。公司的收入比上个季度增长了3%。"

值得注意的是,过去曾提出过使用上下文来改进检索的其他方法。其他提议包括:向块添加通用文档摘要(实验看到非常有限的收益),假设性文档嵌入(HyDE)基于摘要的索引(进行了评估,效果不佳)。这些方法与上下文检索方法不同。

上下文检索实现

当然,手动注释知识库中的成千上万甚至数百万块会是太多工作。为了实施上下文检索,基于Claude模型,使用整个文档的上下文为每个块提供简洁的、块特定的上下文。使用了以下Claude 3 Haiku Prompt为每个块生成上下文:

<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,会在嵌入索引和BM25索引之前附加到块上。

Contextual Retrieval实际中的预处理流程:上下文检索是一种提高检索准确性的预处理技术。

图片

使用Prompt Caching降低上下文检索的成本

上面提到的特殊的提示缓存功能,上下文检索在Claude上是可能以低成本实现的。有了提示缓存,你不需要为每个块传入参考文档。你只需将文档加载到缓存中一次,然后引用先前缓存的内容。假设800 token的块,8k token的文档,50 token的上下文指令,每个块100 token的上下文,一次性生成上下文化块的成本是每百万文档token 1.02美元。

上下文检索性能提升

在各种知识领域(代码库、小说、ArXiv论文、科学论文)进行了实验,嵌入模型、检索策略和评估指标,实验表明:

  • 上下文嵌入将Top20个块的检索失败率降低了35%(5.7% → 3.7%)。

  • 结合上下文嵌入和上下文BM25将Top20个块的检索失败率降低了49%(5.7% → 2.9%)。

使用表现最佳的嵌入配置(Gemini Text 004)检索前20个块时所有知识领域的平均性能

图片

通过重排(Reranking)进一步提高性能

在最后一步中,可以结合上下文检索和另一种技术来获得更多的性能改进。在传统的RAG中,AI系统搜索其知识库以找到可能相关的信息块。对于大型知识库,初始检索通常会返回大量(有时是数百个)具有不同相关性和重要性的块。

Reranking是一种常用的过滤技术,确保只有最相关的块被传递到模型。重新排名提供了更好的响应,并降低了成本和延迟,因为模型处理的信息更少。关键步骤是:

  • 执行初始检索以获取Top潜在相关的块(使用了Top150个);

  • 将TopN块和用户的查询一起通过重新排名模型;

  • 使用重新排名模型,根据其与提示的相关性和重要性给每个块打分,然后选择TopK块(使用了Top20个);

  • 将TopK块作为上下文传递到模型以生成最终结果。

结合上下文检索和重新排序来最大化检索准确性

图片

上下文检索性能进一步改进

使用Cohere重新排名器进行了测试,实验表明,在各个领域,添加重新排序步骤可以进一步优化检索。

具体来说,发现重新排名的上下文嵌入和上下文BM25将Top20块的检索失败率降低了67%  (5.7% → 1.9%)。

图片

结论

Anthropic进行了大量的测试,比较了上述所有技术的不同组合(嵌入模型、使用BM25、使用上下文检索、使用重新排名器和检索的TopK结果),所有这些都在不同类型的数据集上进行了测试,总结如下:

  • 嵌入+BM25比单独使用嵌入更好;

  • Voyage和Gemini具有最好的嵌入;

  • 将Top20块传递给模型比仅Top10或5更有效;

  • 向块添加上下文大大提高了检索准确性;

  • 重新排名比不重新排名更好;

  • 所有这些好处都是叠加的:为了最大化性能改进,可以结合上下文嵌入(来自Voyage或Gemini)、上下文BM25,加上重新排名步骤,并添加20个块到提示中。

附录I

以下是跨数据集、嵌入提供商、使用BM25+嵌入、使用上下文检索以及对检索@20的重新排名的使用结果细分。

图片

向块中添加通用文档摘要:https://aclanthology.org/W02-0405.pdfHyDE:https://arxiv.org/abs/2212.10496Summary-based indexing:https://www.llamaindex.ai/blog/a-new-document-summary-index-for-llm-powered-qa-systems-9a32ece2f9ec记得

大模型51

大模型 · 目录

上一篇2024年新书-《掌握大语言模型》免费pdf分享

### 配置和使用 ANTHROPIC_API_KEY 的方法 要在 LangGraph 中配置和使用 `ANTHROPIC_API_KEY`,需要遵循一系列标准操作来确保 Anthropic 模型能够正常运行。以下是具体说明: #### 1. 设置环境变量 为了使 Anthropic 功能生效,必须先定义 `ANTHROPIC_API_KEY` 环境变量。此步骤是访问 Anthropic 提供的服务的基础[^2]。 ```bash export ANTHROPIC_API_KEY=<your-anthropic-api-key> ``` 上述命令应在终端执行,其中 `<your-anthropic-api-key>` 是由 Anthropic 提供给用户的唯一密钥字符串。如果希望该设置永久化,则可将其添加至 `.bashrc` 或 `.zshrc` 文件中。 #### 2. 安装必要的依赖项 在使用 Anthropic 和 LangChain 结合的功能之前,需安装 LangChain CLI 工具以及 Python 库。可以通过以下命令完成安装过程[^3]: ```bash pip install langchain anthropic ``` 这一步骤将下载并安装所需的所有库文件,从而支持后续的开发工作。 #### 3. 整合到 LangGraph 中 当完成了前两步之后,在实际项目代码里初始化 LangChain 并加载 Anthropic 模型变得简单明了。下面是一个简单的例子展示如何实现这一点: ```python from langchain.llms import Anthropic import os os.environ["ANTHROPIC_API_KEY"] = "<your-anthropic-api-key>" llm = Anthropic() response = llm.predict("What is the capital of France?") print(response) ``` 在此脚本中,首先导入了所需的模块,并设置了环境变量以匹配先前所提到的方法。接着实例化了一个基于 Anthropic 的 LLM 对象,并调用了预测函数来进行测试查询。 --- ### 总结 通过以上三个主要部分的操作——即正确设定 API 密钥作为环境变量、安装必需软件包以及编写适当的应用程序逻辑——就可以顺利地在 LangGraph 上面利用 Anthropic 提供的语言处理能力[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值