
在这篇文章中,我们将深入探讨检索增强生成 (RAG),并向您展示改进 RAG 管道各个部分的实用技巧和窍门! 我们将从一个实际示例开始:构建一个聊天机器人来模拟或协助人类医生。
考虑一下典型的北美医生。 在超过十年的教育和治疗约 10 万名患者之后,他们拥有相当庞大而复杂的知识库。 在诊断患者时,他们会从这丰富的经验中检索相关信息,以提供准确且特定于上下文的建议。
为了创建一个使用 RAG 模拟此过程的聊天机器人,我们需要复制人类医生的一些关键功能。 首先,我们必须建立一个相当于医生十年学习和患者互动经验的知识库。 该知识库应允许高效搜索,仅检索基于患者当前问题的最相关信息。
接下来,我们的系统必须能够对检索到的信息进行推理,类似于医生针对特定病例区分相关细节。 可解释性也很重要,尤其是在受监管的领域,在这些领域,理解诊断或治疗建议背后的推理与建议本身同样重要。
此外,整个过程必须实时运行。 系统应处理患者的查询,检索和推理相关知识,并及时提供可操作的建议或诊断。
最简单的方法可能是将患者信息输入到语言模型中,然后根据预训练的医学数据生成响应。 改进包括在专门的医学文献上微调模型,并采用高级提示工程技术来提高性能。
然而,更复杂的 RAG 方法涉及将全面的知识库(例如医疗记录和文献)集成到检索系统中。 通过索引和查询这个庞大的数据库,我们可以为语言模型提供精确、相关的信息,以增强其生成能力

这是简单的 RAG 框架,为了我们的目的,我们将将其分解为三个步骤:索引、检索和生成。

在本文中,我们将探讨 RAG 堆栈的每个组件,并讨论如何使用开源库和资源来优化和增强它们。 无论您是为医疗保健或其他应用开发聊天机器人,这些技术通常都适用,并且将有助于改进大多数 RAG 设置!
让我们开始吧!🚀
索引
有效的索引对于任何 RAG 系统都至关重要。 第一步涉及我们如何摄取、分块和存储数据。 让我们探讨一些将数据索引到数据库中的技术,重点介绍各种文本分块方法和利用元数据的方法。
文本分块
1. 简单分块:
- 概述:此方法涉及将文档分解为固定大小的分块,并留有一些重叠。 这确保了每个分块保留来自前一个分块的上下文。
- 实现:您可以指定分块大小(例如,35 个字符)和重叠大小以在分块之间保持上下文。 这种方法适用于简单的文档,但可能不适用于更复杂的文本,并且完全不利用文档结构。
- 优点和缺点:易于实现,但可能会破坏语义单元,导致不连贯的分块和较差的检索性能。
Greg Kamradt (Data Indy) - 文本分块
2. 语义分块:
概述:语义分块涉及基于含义而不是固定大小来划分文本。 这种技术确保每个分块代表一个连贯的信息片段。
实现:计算句子嵌入的余弦距离。 如果两个句子在语义上相似(低于某个阈值),则它们属于同一个分块。 这会创建基于内容语义结构的变长分块。
优点和缺点:产生更连贯和上下文相关的分块,提高检索准确性,但需要通过基于 BERT 的编码器模型进行前向传递,这在计算上比简单分块更密集。
Greg Kamradt (Data Indy) - 语义分块
3. 基于语言模型的分块:
- 概述:这种高级方法使用语言模型从文本中创建自包含的命题,确保每个分块在语义上是完整的。
- 实现:语言模型(例如,70 亿参数的模型)处理文本,将其分解为独立的命题。 然后,该模型将这些命题组合成分块,平衡语义完整性和上下文。 这种方法在计算上密集,但提供最高的准确性。
- 优点和缺点:适应文本细微之处并产生高质量的分块,但计算密集型,可能需要针对特定应用进行微调。
Dense X Retrieval: What Retrieval Granularity Should We Use?
模型:https://hugging-face.cn/chentong00/propositionizer-wiki-flan-t5-large
利用元数据
1. 添加和基于元数据进行过滤:
概述:元数据提供了可以显着提高检索准确性的额外上下文。 通过合并诸如日期、患者年龄和先决条件之类的元数据,可以在搜索期间过滤掉不相关的信息。 过滤有助于缩小搜索范围,使检索过程更有效和相关。
实现:在索引数据时,将元数据与向量化文本一起存储。 例如,如果索引患者记录,请包括诸如年龄、就诊日期和特定条件之类的元数据。 使用此元数据来过滤搜索结果,确保系统仅检索相关信息。
例如,如果查询与儿科患者相关,则在执行语义搜索之前,过滤掉 18 岁以上患者的记录。 这可以减少检索结果中的噪声并提高输出的相关性。
2. 使用 GLiNER 为分块生成元数据
您可能并不总是拥有大量的元数据来增强分块,但使用 GLiNER(广义线性命名实体识别器)模型,您可以在摄取阶段为分块生成元数据! GLiNER 是一个强大的基于 BERT 的模型,可用于标记和标记分块,从而在摄取阶段创建元数据。 这可以显着提高检索过程。
使用 GLiNER 进行自动标记:
实现:您可以简单地将每个分块输入到 GLiNER,以及您想要在分块中识别的标签。 如果在分块文本中找到标签,它将识别它们,如果没有找到具有高置信度的匹配项,则不会生成标签,从而减少误报!
优点和缺点:对于通用用途效果很好,但可能需要针对特定领域和特定应用的数据集进行微调。
查询解析和过滤:
实现:GLiNER 的另一个用途是解析传入的查询并将其与标记的元数据匹配,以过滤结果。
优点和缺点:通过确保上下文相关性来提高检索准确性,但增加了一个额外的处理步骤。
GLiNER: Generalist Model for Named Entity Recognition using Bidirectional Transformer 演示:https://hugging-face.cn/spaces/urchade/gliner_multiv2.1
这些技术为强大的 RAG 系统奠定了基础,能够从大型数据集中进行高效检索。 分块方法和元数据的使用取决于数据集的特定要求和特征。
检索
现在让我们讨论 RAG 设置的 R 部分! 如何增强向量数据库的检索召回率? 这个过程是检索与查询相关的尽可能多的文档,从而大大提高 LLM 能够产生高质量结果的机会。 以下是一些实现此目的的技术
1. 混合搜索
向量搜索捕获查询的语义含义,关键字搜索识别特定术语的精确匹配。 混合搜索结合了向量搜索和关键字搜索的优势,以提高检索准确性。 在医学等领域,许多术语和概念并非语义上理解,而是特定的关键字,例如药物名称、解剖术语、疾病名称和诊断。
纯向量搜索可能会错过这些关键关键词,而基于关键词的搜索则确保考虑特定的重要术语。通过整合这两种方法,混合搜索能够实现更全面的检索过程。
这些搜索方法,向量搜索和关键词搜索,并行运行,然后将结果合并并根据加权系统进行排序。例如,使用 Weaviate,您可以调整 alpha 参数来平衡向量搜索和关键词搜索结果的重要性,从而创建一个组合的、排序后的文档列表。这平衡了精确率和召回率,提高了整体检索质量,但需要仔细调整权重参数。

2. 查询重写
查询重写认识到人类的查询可能未针对向量数据库或语言模型进行优化。通过利用语言模型来重写查询,可以显著改善检索过程。
- 针对向量数据库的查询重写:患者的初始查询被转换为更适合数据库的格式。例如,“我的左肩疼痛,拇指和食指麻木”可能会被重写为“疼痛 左肩。麻木。麻木 食指。”
- 针对语言模型的提示重写:这涉及自动且交互式地构建提示,以优化与语言模型的交互,提高生成结果的质量和准确性。像 DSPy 这样的框架可以帮助完成这个过程。
这些重写的查询和提示确保搜索过程更好地理解和检索相关文档,并且语言模型能够被优化地提示。查询重写可以按照以下方式实现。
3. 微调嵌入模型
虽然预训练的嵌入模型提供了一个良好的起点,但在您的特定数据集上微调这些模型可以显著提高检索性能。这包括
选择合适的模型:对于医学等专业领域,选择在相关数据上预训练的模型。对于这个特定的例子,我选择使用 MedCPT 系列的查询和文档编码器,它们由 PubMed 搜索日志中前所未有的 2.55 亿个查询-文章对进行预训练。
使用正负对象对进行微调:您可以通过收集自己的数据并创建相似(正)和不相似(负)示例对来进一步提高这些模型的性能,并微调模型以更好地理解这些区别。这有助于模型学习特定领域的关联和语义,提高检索性能,但需要精心策划的训练数据。
这些技术结合起来,可以创建一个强大的检索系统,从而增强对象的整体相关性,最终提供给 LLM 时可以提高生成质量。
生成
最后,让我们讨论如何改进语言模型 (LLM) 的生成质量控制。这里的关键在于确保您提供给 LLM 的上下文与提示尽可能相关,不相关的数据可能会引发幻觉。以下是一些实现更好生成结果的技巧
1. 自动截断以删除不相关信息
自动截断是一种过滤从数据库检索到的不相关信息的方法,否则这些信息可能会误导 LLM 并导致幻觉。其工作原理如下
检索和评分相似度:当发出查询时,会检索多个对象以及它们的相似度分数。
识别和截断:使用相似度分数,识别分数显著下降的截断点。该点之后的对象被认为不太相关,并自动排除。
例如,如果您检索到六个对象,相似度分数在第四个对象之后可能会急剧下降。通过检查相似度分数的变化率,您可以确定要排除哪些对象,确保只有最相关的信息被提供给 LLM。
2. 重新排序检索到的对象
重新排序涉及使用第二个、更复杂的模型来重新评估和重新排序最初检索到的对象,基于它们与查询的相关性。这个过程提高了最终检索集的质量。其工作原理如下
- 过度检索:最初检索比需要的多对象。
- 应用排序模型:使用高延迟、大型模型,通常是交叉编码器,来重新评估每个检索到的对象的相关性。该模型成对地考虑查询和每个检索到的对象,以重新评估它们的相似性。
- 重新排序结果:基于新的评估,重新排序对象以反映最相关的结果位于顶部。
这种方法确保最相关的文档被优先排序,从而提高提供给 LLM 的数据的整体质量。
3. 微调 LLM
在特定领域的数据上微调 LLM 可以显著提高其在该领域的性能。例如,使用 Meditron 70B 这样的模型,它是 LLaMA 2 70b 的一个微调版本,专门针对医学数据,使用以下方法进行微调
- 无监督微调:继续在大量的特定领域文本(例如,PubMed 文献)上预训练模型。
- 监督微调:使用特定领域的任务(例如,医学多项选择题)上的监督学习进一步完善模型。
这种专门的训练有助于模型在目标领域表现出色,在特定任务中优于其基础模型和更大的、不太专业的模型(如 GPT-3.5)。
总结
改进检索增强生成 (RAG) 系统中的检索和生成对于增强人工智能应用程序的性能和可靠性至关重要。
上述技术范围从低投入、高回报的方法(如查询重写和重新排序),到更密集的流程(如嵌入和 LLM 微调)。技术的选择取决于应用程序的具体要求和约束。
为了使这些技术更易于访问,我们开发了 Verba,一个开源聊天机器人,它集成了许多这些改进。请在 GitHub 上查看它。您可以通过使用自己的数据自定义和索引来进一步扩展它。您还可以观看下面的视频,了解 Verba 的最新动态!
准备开始构建了吗?
请查看 快速入门教程,或使用 Weaviate Cloud (WCD) 的免费试用版构建令人惊叹的应用程序。