对于无法在上下文窗口内容纳的大型知识库,RAG 是一种典型的解决方案。RAG 通过以下步骤预处理知识库:
1. 将知识库(文档的“语料库”)拆分成较小的文本块,通常不超过几百个标记;
2. 使用嵌入模型将这些文本块转换为向量嵌入,以编码其语义;
3. 将这些嵌入存储在一个向量数据库中,以便通过语义相似度进行搜索。
在运行时,当用户向模型输入查询时,向量数据库会根据查询的语义相似度找到最相关的文本块。然后,这些最相关的文本块会被添加到发送给生成模型的提示中。
尽管嵌入模型在捕捉语义关系方面表现出色,但它们可能会错过关键的精确匹配。幸运的是,有一种较老的方法可以在这些情况下提供帮助。BM25(最佳匹配25)是一种使用词汇匹配来找到精确词语或短语匹配的排名函数。对于包含唯一标识符或技术术语的查询,它尤其有效。
BM25 的工作原理基于 TF-IDF(词频-逆文档频率)的概念。TF-IDF 衡量一个词在文档集合中的重要性。BM25 通过考虑文档长度并将饱和函数应用于词频来完善这一点,这有助于防止常用词主导结果。
BM25 在语义嵌入失效之处的成功之处在于:假设用户在技术支持数据库中查询“错误代码 TS-999”。嵌入模型可能会找到有关错误代码的一般内容,但可能会错过“TS-999”的精确匹配。BM25 则会寻找这个特定的文本字符串来识别相关文档。
通过结合嵌入和 BM25 技术,RAG 解决方案可以更准确地检索到最适用的文本块,具体步骤如下:
1. 将知识库(文档的“语料库”)拆分成较小的文本块,通常不超过几百个标记;
2. 为这些文本块创建 TF-IDF 编码和语义嵌入;
3. 使用 BM25 查找基于精确匹配的顶级文本块;
4. 使用嵌入模型查找基于语义相似度的顶级文本块;
5. 使用排序融合技术合并和去重步骤 (3) 和 (4) 的结果;
6. 将 Top-K 的文本块添加到提示中以生成响应。
通过同时利用 BM25 和嵌入模型,传统的 RAG 系统能够提供更全面和准确的结果,既平衡了精确术语匹配,又兼顾了更广泛的语义理解。
一个标准的检索增强生成(RAG)系统结合了嵌入和最佳匹配25(BM25)技术来检索信息。TF-IDF(词频-逆文档频率)用于衡量词语的重要性,并构成了 BM25 的基础。
这种方法使您能够以经济高效的方式扩展到巨大的知识库,远远超出单个提示可以容纳的范围。但这些传统的 RAG 系统存在一个显著限制:它们常常破坏上下文。
在传统的 RAG 系统中,通常将文档拆分成较小的文本块以便于高效检索。虽然这种方法在许多应用中效果良好,但当单个文本块缺乏足够的上下文时,可能会导致问题。
例如,假设您的知识库中嵌入了一系列财务信息(比如,美国 SEC 文件),并且您收到以下问题:“2023 年第二季度 ACME 公司的收入增长是多少?”
一个相关的文本块可能包含这样的内容:“公司收入比上一季度增长了 3%。”然而,这个文本块本身并未具体说明它指的是哪家公司或相关的时间段,这使得很难检索到正确的信息或有效地使用这些信息。
上下文检索通过在嵌入之前为每个文本块添加特定的解释性上下文(“上下文嵌入”)以及创建 BM25 索引(“上下文 BM25”)来解决这个问题。
让我们回到 SEC 文件集合的例子。以下是如何转换一个文本块的示例:
original_chunk="Thecompany'srevenuegrewby3%overthepreviousquarter."
contextualized_chunk="ThischunkisfromanSECfilingonACMEcorp'sperformanceinQ22023;thepreviousquarter'srevenuewas$314million.Thecompany'srevenuegrewby3%overthepreviousquarter."值得注意的是,过去已经提出了其他使用上下文来改进检索的方法。其他提议包括:将通用文档摘要添加到文本块中(我们尝试过,但效果有限)、假设文档嵌入和基于摘要的索引(我们评估后发现性能较低)。这些方法与本文提出的方法有所不同。
当然,手动为知识库中的数千甚至数百万个文本块添加注释工作量过大。为了实现上下文检索,我们求助于 Claude。我们编写了一个提示,指导模型提供简洁的、针对文本块的上下文,使用整个文档的上下文来解释该文本块。我们使用了以下 Claude 3 Haiku 提示为每个文本块生成上下文:
<document>
{{WHOLE_DOCUMENT}}
</document>
Hereisthechunkwewanttosituatewithinthewholedocument
<chunk>
{{CHUNK_CONTENT}}
</chunk>
Pleasegiveashortsuccinctcontexttosituatethischunkwithintheoveralldocumentforthepurposesofimprovingsearchretrievalofthechunk.Answeronlywiththesuccinctcontextandnothingelse.将上下文文本(通常为 50-100 个标记)添加到文本块的前面,然后进行嵌入和创建 BM25 索引之前的处理。
这一预处理步骤确保了在生成嵌入和 BM25 索引时,文本块中包含了足够的上下文信息,从而提高了检索的准确性和相关性。通过这种方式,信息的语义和词汇匹配能力都能得到有效的提升。
在实际操作中,预处理流程看起来是这样的:
如果你对使用上下文检感兴趣,可以从我们的指南开始[3]。
由于我们之前提到的特殊提示缓存功能,使用Claude进行上下文检索可以以低成本实现。通过提示缓存功能,你不需要为每个数据块传递参考文档。只需将文档加载到缓存中一次,然后引用之前缓存的内容即可。假设每个数据块包含800个标记,文档包含8000个标记,50个标记用于上下文指令,每个数据块包含100个上下文标记,那么生成上下文化数据块的一次性成本仅为每百万文档标记1.02美元。
我们在不同的知识领域(代码库、小说、ArXiv论文、科学论文)、嵌入模型、检索策略和评估指标上进行了实验。在附录II[4]中,我们列出了每个领域中使用的一些问题和答案示例。
下方的图表展示了在所有知识领域中使用表现最佳的嵌入配置(Gemini Text 004)和检索前20个数据块时的平均表现。我们使用1减去召回率@20作为评估指标,该指标衡量在前20个数据块中未能检索到的相关文档的百分比。完整结果见附录——上下文化我们评估的每种嵌入来源组合中都提升了性能。
我们的实验表明:
• 上下文嵌入将前20个数据块的检索失败率降低了35%(从5.7%降至3.7%)。
• 结合上下文嵌入和上下文BM25,将前20个数据块的检索失败率降低了49%(从5.7%降至2.9%)。
在实施上下文检索时,有几个方面需要注意:
1. 数据块边界:考虑如何将文档划分为数据块。数据块的大小、边界和重叠选择会影响检索性能。
2.嵌入模型:虽然上下文检索提升了我们测试的所有嵌入模型的性能,但某些模型可能受益更多。我们发现Gemini和Voyage嵌入特别有效。
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的使用、上下文检索的使用、重新排序器的使用和检索的总前K个结果),涵盖了各种不同的数据集类型。以下是我们的发现总结:
• 嵌入+BM25优于单独使用嵌入;
• 在我们测试的嵌入中,Voyage和Gemini表现最佳;
• 向模型提供前20个块比仅提供前10或前5个块更有效;
• 为块添加上下文可以显著提高检索准确性;
• 重新排序优于不进行重新排序;
• 所有这些优势是可以叠加的:为最大化性能提升,可以结合使用上下文嵌入(来自Voyage或Gemini)和上下文BM25,再加上重新排序步骤,并在提示中加入20个块。
以下是跨数据集、嵌入提供商、在嵌入之外使用BM25、使用上下文检索和在前20个检索中使用重新排序的结果分析。
请参阅附录II,了解前10和前5个检索的结果分析以及每个数据集的示例问题和答案。
| 欢迎光临 链载Ai (https://www.lianzai.com/) | Powered by Discuz! X3.5 |