构建 RAG 系统的高级技术

上一篇文章中,您学习了如何构建一个简单的检索增强生成(RAG)系统。RAG是一种强大的方法,可以利用外部知识增强大型语言模型,并且有许多变体可以使其更好地工作。接下来,您将看到一些高级特性和技术,以提高RAG系统的性能。特别是,您将学习到:

  • 如何改进RAG中使用的提示词
  • 如何使用混合检索来提高检索文档的质量
  • 如何使用带有重排序的多阶段检索来提高生成响应的质量

通过我的书籍《Hugging Face Transformers中的NLP》快速启动您的项目。它提供了带有工作代码的自学教程

让我们开始吧。

构建 RAG 系统的高级技术
图片来源:Limonovich。保留部分权利。

概述

这篇博文分为三部分;它们是:

  • 查询扩展和重构
  • 混合检索:密集和稀疏方法
  • 带有重排序的多阶段检索

查询扩展和重构

RAG系统面临的挑战之一是用户的查询可能与知识库中使用的术语不匹配。如果使用一个好的模型来生成嵌入,这不是问题,因为查询的上下文很重要。但是,您永远不知道特定查询是否如此。

查询扩展和重构可以通过生成查询的多个版本来弥补这一差距。其假设是,通过同一查询的几种变体,至少其中之一可以帮助检索RAG最相关的文档。

要进行查询扩展,您需要一个能够生成输入变体的模型。BART就是一个例子。让我们看看如何使用它进行查询扩展。

在此代码中,您加载了一个预训练的BART模型和分词器。它被创建为一个`BartForConditionalGeneration`对象,这是一个用于文本生成的序列到序列模型。与您在Hugging Face transformers库中使用模型的方式相同,您将输入进行分词并将其传递给`reformulate_query()`函数中的模型。您要求模型对一个输入生成`n`个输出。

为了创建更多变体,您将温度略高于1,您甚至可以尝试更高的值。使用BART生成实际上是要求模型读取您的输入并记住其在“隐藏状态”中的含义,然后将隐藏状态解码回文本,并可能出现变体。使用束搜索创建多个变体,如果您愿意,可以添加更多生成参数。

使用分词器将多个输出逐个解码成文本。然后您可以在代码的末尾打印出来。如果您运行此代码,您可能会看到:

原始查询的歧义越大,您将获得的变体就越多。

混合检索:密集和稀疏方法

RAG的理念是用知识库中最相关的文档来补充查询的上下文。这些额外的信息可以帮助模型生成更好的响应。您可以使用不同的方法来查找相关文档。

密集向量检索意味着将知识库中的文档表示为高维向量。此向量中的所有维度都很重要,但没有具体原因来确定每个维度代表什么。通常,密集向量是一个看起来随机的浮点数向量。

然而,稀疏向量有许多零。它通常具有更高的维度,并且是整数向量。一个例子是独热向量,其中每个位置代表词汇表中的一个单词,并且只有当该单词存在于文档中时,其值才为1。

密集向量和稀疏向量都没有绝对的优劣。如果您使用嵌入模型生成密集向量,它擅长捕捉语义相似性。另一方面,稀疏向量通常擅长捕捉关键词。对稀疏向量进行操作可能会消耗大量内存,但您可以通过使用Okapi BM25等技术来减少工作量。

在下面的代码中,您需要安装库来计算BM25分数。您可以使用pip完成此操作

让我们看看如何结合稀疏向量和密集向量来构建检索系统

 

当你运行这段代码时,你会看到:

首先,您为集合中的所有文档创建了一个Okapi BM25索引。Okapi BM25是一种基于TF-IDF的评分方法,这意味着它通过检查精确单词的交集来比较两个文本。从这个意义上说,大小写不重要。因此,在使用BM25时,您将文档转换为小写。

然后,您使用预训练的句子Transformer模型为文档集合生成密集向量。您将这些密集向量存储在FAISS索引中,以便使用L2距离进行高效的相似性搜索。

此代码的关键部分在`hybrid_retrieval()`函数中。在准备好Okapi BM25和FAISS索引后,您将查找最适合您的查询字符串的文档。获得的BM25分数是与每个文档对应的TF-IDF分数。您还计算了每个文档的FAISS的L2距离度量。然后将此距离转换为分数,以匹配BM25的分数:更高的分数应该意味着更好的匹配。为了确保两种方法可比较,您将分数归一化到[0, 1]范围。

根据您的选择,您可以通过更改参数`alpha`来更强调密集检索或稀疏检索。然后使用组合分数来查找要返回的top-k文档。正如您从上面的输出中看到的那样。

这种混合方法通常优于任何单一方法,特别是对于同时需要语义理解和特定术语的复杂查询。

带有重排序的多阶段检索

如果您有一个完美的模型来评估文档与您的查询的相关性,那么一个简单的检索系统就足够了。然而,没有模型是完美的。实际上,通常质量越高的模型计算强度也越大。这就是多阶段检索的用武之地。

混合检索擅长快速挑选文档。特别是如果您使用快速模型,您可以轻松计算大量文档的分数。然而,挑选并不总是好的。但是您可以使用更慢但更准确的模型重新计算分数。这次,并非所有文档都考虑在内,而只考虑混合检索挑选的文档。只要第一阶段使用的模型大致正确,第二阶段计算密集度更高的模型将为您提供准确的选择。

这就是多阶段检索技术的作用。让我们看看如何实现它。

此代码是在上一节的基础上构建的。它使用了与之前相同的`hybrid_retrieval()`函数。

在`multi_stage_retrieval()`函数中,您首先使用混合检索获取文档列表。然后,您使用重排序模型对这些文档进行重排序。

重排序模型是一个交叉编码器模型,一种可用于排序任务的Transformer模型。简而言之,它接受两个序列作为输入,以`[CLS] query [SEP] document [SEP]`的格式连接。模型的输出是一个分数,显示文档与查询的相关性。这是一个慢模型,但比L2距离或BM25更准确。

在`rerank()`函数中,您在混合检索筛选出的查询和文档上运行重排序模型。然后,您根据重排序模型提供的分数选择top-k文档。`multi_stage_retrieval()`函数中的参数`initial_k`和`final_k`允许您控制召回率(检索所有相关文档)和准确率(确保检索到的文档相关)之间的权衡。较大的`initial_k`会增加召回率,但需要更多的重排序计算,而较小的`final_k`则侧重于最相关的文档。

进一步阅读

以下是一些您可能觉得有用的进一步阅读资料:

总结

在本教程中,您探索了几种增强RAG系统的高级技术。对于给定的生成模型,RAG系统的成功在很大程度上取决于您是否能提供有用的上下文,以及在提示中准确描述您期望的输出。您学习了如何改进检索器并创建更好的提示。特别是,您学习了:

  • 使用查询扩展来尝试不同的方式来指导模型
  • 使用混合检索结合密集和稀疏检索,以便检索更多相关的文档
  • 使用带重排序的多阶段检索来提高检索文档的质量

这些高级功能可以显著提高RAG系统的性能和能力,使其在各种应用中更有效。

想在您的NLP项目中使用强大的语言模型吗?

NLP with Hugging Face Transformers

在您自己的机器上运行最先进的模型

...只需几行Python代码

在我的新电子书中探索如何实现
使用 Hugging Face Transformers 进行自然语言处理

它涵盖了在以下任务上的实践示例实际用例文本分类、摘要、翻译、问答等等...

最终将高级NLP带入
您自己的项目

没有理论。只有实用的工作代码。

查看内容

对《构建RAG系统的进阶技术》的2条回复

  1. dim_SK+82 2025年8月10日下午6:03 #

    哇,我不敢相信你们从零开始构建了这个,并免费提供。我觉得你们可能不知道你们帮了像我这样的人多大的忙。愿上帝保佑您、您的家人和您的团队。非常感谢!

    • James Carmichael 2025年8月11日上午4:01 #

      感谢您的反馈和支持!请在您学习内容时随时向我们汇报您的进展!

发表评论

Machine Learning Mastery 是 Guiding Tech Media 的一部分,Guiding Tech Media 是一家领先的数字媒体出版商,专注于帮助人们了解技术。访问我们的公司网站以了解更多关于我们的使命和团队的信息。