面向质量工程师的 RAG

2024-06-28   出处: medium  作/译者:Blake Norrish/Yilia

RAG 对质量工程师的重要性

检索增强生成(RAG)已成为扩展大型语言模型(LLM)能力的一种常见模式。

从理论上讲,RAG 很简单(只需将数据添加到上下文窗口!),但实际上却非常复杂。隐藏在框图背后的是高级分块策略、重新排序、多查询检索器、小到大的检索、假设文档嵌入、预嵌入数据增强、动态路由、自定义嵌入模型等等。

虽然设置初始流水线可能很快也很容易,但达到生产级别的质量要复杂得多。如果不仔细考虑,RAG 系统可能会返回不正确、无关或不一致的信息;它们可能会遇到性能差、低效地消耗昂贵资源,或在扩展到生产规模的源数据时崩溃。

要有效且高效地评估 RAG 系统的质量,需要了解各个部分如何协同工作以创建完整的 RAG 流水线。每个部分的设计决策都会影响质量,尝试部署 RAG 应用程序的每个人都应该了解这些决策。

以下是从测试和质量的角度对 RAG 概念和模式的介绍。我们将从介绍 RAG 的价值开始,然后讨论从构建生产质量 RAG 所固有的众多设计决策中寻求如何改进它。这个介绍将为我们讨论 RAG 系统的具体评估方法和技术提供必要的基础。

LLM 的局限性

为了理解 RAG 流水线,我们应该首先回顾一下 RAG 试图解决的 LLM 的局限性。

在其核心,LLM 很简单:发送一个提示并获得一个响应。

为了返回响应,LLM 必须对模型运行推理计算。此计算涉及将输入项与定义模型的数百万甚至数千亿个参数结合起来。这是一项昂贵的计算。

调用 LLM 的成本如此之高,而训练 LLM 更是难上加难。训练是确定模型参数最佳值的过程。不同的算法用于计算最佳权重,但所有算法都涉及在给定输入上运行模型、计算误差,然后反向传播校正调整,使答案略有改善。这在许多输入上反复进行,最终得到一个训练好的模型。虽然模型推理可能需要几秒钟,但模型训练可能需要数周时间,即使在庞大的 GPU 集群上也是如此。

单个 NVIDIA H100 售价约 40,000 美元(2024 年第一季度)
巨大的训练成本是新信息或更新信息整合到 LLM 中的瓶颈。大多数公司没有资源来训练模型,不能通过使用私有数据进行训练来简单地“添加新信息”到 LLM 中。相反,大型资金充足的科技公司在大型公共数据集上训练通用基础模型,并通过诸如 RAG 等次要过程为这些模型增加新的能力和信息。

具体来说,RAG 旨在让 LLM 以一种避免高昂的新模型训练过程的方式访问大量额外知识。

RAG 基础

让我们了解一下 RAG 的实际工作原理。

发送到 LLM 的提示有长度限制,称为上下文窗口。上下文窗口以令牌(对我们来说,约等于单词)为单位测量。上下文窗口通常有 1K、4K 或更多令牌大小,尽管更大的上下文窗口变得越来越普遍(例如:Gemini 1.5 Pro,具有 128K 令牌)。

许多人直观地认为上下文窗口只是你能问的最长问题,但这是一种限制性的思维方式。由于 LLM 的工作方式,上下文窗口中提供的信息在生成响应时对 LLM 可用。因此,它可以用来提供额外的信息。这通常称为上下文学习。

因此,我们可以使用上下文窗口提供 LLM 回答问题所需的新知识。例如,我们可以创建一个询问公司关于丧假政策的提示,然后将整个公司手册(包括丧假部分)放入提示中,只要它不超过上下文窗口大小。这种方法可以让 LLM 使用提供的新信息作出响应。

当我们已经拥有相关信息并且这些信息可以放入上下文窗口时,这种解决方案很简单。不幸的是,情况并非总是如此。因此,我们需要一些机制来检索和选择与我们的提示相关的信息。

一种简单的方法是对提示中的术语在可能相关的所有数据中进行关键词搜索,复制命中的文本周围的文本,然后将这些文本添加到提示中。

这种简单的关键词搜索 RAG 可能会改进 LLM 的响应,并且在某些情况下可能有用,但也可能误报(在不同上下文中使用的关键词)。此外,我们也可以通过利用语义搜索而不是原始单词来匹配文本的含义,从而做得更好。

具体来说,可以利用嵌入模型从可能相关的数据块中创建嵌入,然后在这些嵌入中执行搜索以找到与我们的提示相关的数据。这种方法非常简化,但它开始看起来像真正的 RAG。

RAG 和嵌入

了解 RAG 提供的好处需要了解嵌入模型的目的和性质。这是一个深刻的话题,但对于理解 RAG 至关重要。

嵌入模型类似于我们原始的 LLM,但不是生成新内容,而是将输入减少为向量(仅是一个数字列表)。对于嵌入模型,它们是非常大的数字列表。嵌入模型创建的向量通常有 768 或 1536 个数字(维度),但也存在其他大小的向量。

嵌入模型创建的向量不仅仅是随机数集合;它是根据模型对输入数据意义的提炼。向量对其他模型没有意义,但相似的文本在同一模型中会创建相似的向量。相似不仅仅是“具有相同的关键词”——嵌入模型专门训练以从非结构化数据中提炼更深层次的语义。例如,“Guy horses do not fly”和“A fly guy horsing around”尽管有相似的词,但不会是接近的向量。

向量的一个伟大之处在于你可以对它们进行数学运算。快速数学运算。可以在相对较短的时间内搜索数百万个向量以找到相似的向量。(这里是一些使用的算法。)

现在我们有了 RAG 管道的各个部分,让我们走过这些步骤。

前四个步骤只做一次,或者一次并随着源数据的变化更新。步骤五到八在每次推理请求时完成:

  1. 我们收集所有可能相关的数据——如此多的数据,我们不可能将其全部放入提示的上下文窗口中。
  2. 我们将这些数据分块为更小的部分(稍后详细介绍)。
  3. 然后我们将每个块运行通过嵌入模型以创建一个封装该块意义的向量。
  4. 我们将向量保存到向量数据库中。
  5. 在每次推理请求时:当我们得到一个提示时,我们将该提示通过与块状源数据相同的嵌入模型运行以生成另一个向量(称为提示向量或查询向量)。
  6. 我们在向量数据库中搜索与提示向量相似的向量。返回的向量将比我们仅对原始数据进行关键词搜索获得更好的匹配。
  7. 我们(可选)重新排序识别到的相关向量,然后返回每个顶级向量的原始数据。
  8. 将原始数据与初始提示结合并发送到 LLM。

基础 RAG:绿色为预处理步骤,蓝色为每次推理时完成的步骤
瞧——我们的 LLM 现在的行为就像是对我们通过向量搜索提供的所有新的专有数据进行了训练,而不必执行昂贵的基础模型训练。

至少,理论上是这样的。实际上,这种过于简化的管道可能无法满足您的生产需求,您需要适应、改进、交换或扩展不同部分,以满足您的特定应用需求,才能达到质量、生产准备好的 RAG 管道。

RAG 设计与质量

上文介绍了 RAG,但正如我们之前所说,实际中的 RAG 可能要复杂得多,而这些现实世界的复杂性会影响应用质量。让我们逐步了解每个步骤,了解一些实现挑战、质量风险和 RAG 管道中的可能替代方案。

1—收集相关数据、摄取和丰富

从头开始,我们必须找到所有“可能相关的数据”。

RAG 图中的单个图标(#1)更可能是一个完整的数据管道(或一组管道!),从多个来源摄取数据;进行分阶段处理;策划;可能进行转换、匿名化和标记化;并执行数据管道中常见的其他处理操作。

其中一些管道可能非常复杂,尤其是当原始数据不是文本格式时。例如,一些管道广泛使用 OCR 技术来摄取大量扫描

的物理文档。

随着数据管道的复杂性而来的是测试数据管道的所有挑战。

即使是最完善的 RAG 管道,如果源数据没有进入向量数据库也会惨败,且根据这些数据的多样性、速度和数量,这个摄取阶段可能会很复杂,并且是许多应用质量问题的根源。

除了常规的数据管道活动,RAG 还可以从数据丰富中受益。通常,其他系统(或人)对源数据有上下文,这对于评估其意义非常有利。例如,客户数据库可以通过其他系统的标签或注释来丰富,添加相关信息。通常,其他生成模型或 NLP 用于创建更干净或摘要的元数据。将这些视为嵌入生成前的“预处理”,如果做得正确,可以显著提高检索质量。

如果您在评估 RAG 检索系统的质量,了解数据在进入 RAG 管道的花哨 AI 部分之前是如何被获取和摄取的,这一点非常值得。

2—分块

在数据被摄取之后但在运行嵌入模型之前,必须将其分成离散的部分。那么,您如何决定如何分割数据呢?这称为您的分块策略。

多大或多小的块是最佳的?块是否应重叠?是否有比按页、段落或固定长度划分更聪明的分块方法?如何分块非标准格式的数据(代码、JSON 等)?

这些是分块策略试图回答的问题,没有完美的解决方案。不同的策略有不同的权衡。某些方法简单且实施迅速,结果尚可。某些方法则更复杂,可能提供更好的命中率和 LLM 响应质量。将数据分块过于粗糙,可能会用无关数据填满上下文窗口,挤掉其他相关块,或创建过于通用的嵌入,无法获得有意义的匹配。分块过于细致,可能会“剪断”相关数据。

这篇文章探讨了五种分块方法:固定大小、递归、基于文档、语义和代理(使用 AI 进行分块,很有趣!)。

还有许多其他方法可以用来优化分块。例如,在小到大检索中,使用小块进行搜索,但每个块链接到一个较大的父块,该块被检索以插入上下文模型。上下文感知分块使用关于文档性质的现有知识来智能地将它们分割成逻辑块。

这个列表可能并不详尽,但展示了 RAG 实施者可用的多样化选择,以及适当和调整的分块策略对应用整体质量的重要性。Pinecone 博客有关于这些策略的更多详细信息。

3—嵌入模型选择和配置

有许多模型可用于生成嵌入,不同模型在不同情况下的表现会更好或更差。某些模型经过预训练以供一般使用,而某些则针对特定领域(如医疗记录)进行了微调。也可以针对您的应用处理的特定数据微调自己的嵌入模型。

此外,许多模型有不同的大小(这影响嵌入生成的成本和时间)、不同的输入长度(它能处理的最大块大小)和不同的输出向量维度(维度越高=越准确,但空间需求和速度越慢)。

某些嵌入模型只能通过 API 访问(例如 OpenAI 嵌入端点),而其他则是完全开源的,可以下载并在本地运行或在云提供商中托管。

也可以为应用中的不同数据路径使用不同的嵌入模型。

虽然一般良好的嵌入模型可能适用于许多 RAG 应用程序,但其他应用程序可能受益于特定嵌入模型或自定义训练的模型。

了解嵌入策略中的设计考虑因素及其选择的质量特征,将为您的应用评估需求和方法提供见解。额外阅读,以下是评估嵌入模型选择的深入讨论。

5—查询处理和嵌入

没有规则规定必须按原样对传入查询运行嵌入模型。事实上,有很多方法可以优化查询和结果嵌入搜索,以提高应用的整体质量。如果查询直接来自人类用户,尤其如此,他们可能会写出含糊、不切实际、模棱两可的查询。

有了关于应用性质或意图的额外知识,可以使用 LLM 或传统逻辑将查询简化或重写为更紧凑和明确的方式,即将查询重写为意图而非实际问的问题。

查询处理的一种高级形式是 HyDE,创建一个答案的假设文档,并进行类似文档的向量搜索(答案对答案),而不是对查询进行嵌入和搜索(问题对答案)。

另一个选择是将查询拆分为多个相关查询并并行运行每个查询,结合结果——多重检索器模式。显然,这种选择带来了处理成本,但可以提高检索质量。

根据具体的用例,可能需要自定义查询处理,并且可以显著影响应用的质量和行为。

4 , 6—向量数据库和向量搜索

虽然向量搜索很快,但在向量数据库中搜索与查询相似的嵌入仍然有时间(和可能的金钱)成本。一种最小化这种成本的方法是语义缓存。在语义缓存中,嵌入首次检索后,响应被缓存,因此将来相似的搜索将直接从缓存中返回数据。

当然,缓存增加了复杂性(这是计算机科学中两个难题之一——我记不起另一个名字了)。虽然缓存可以提高性能,但在数据源变化频繁的环境中,过时的缓存会对响应质量产生不利影响。

7—重新排序

在我们上面的描述中,我们简单地假设我们可以将上下文窗口填满向量搜索返回的所有相关数据。显然这是一个简化,必须有一些过程来确定所有返回向量中哪些应该优先放入上下文窗口。

即使我们可以将搜索结果装入上下文窗口,许多研究表明上下文填充(填满上下文窗口)可以通过引入“中间丢失”问题而对 LLM 的回忆产生负面影响,从而影响响应质量(回忆是 LLM 使用上下文窗口中信息的能力)。

解决方案是在初始向量搜索后添加重新排序步骤。

重新排序的 TLDR(太长不看):嵌入模型针对速度进行了优化,因为它们需要针对大量文档运行。另一种称为重新排序模型(或交叉编码器)的模型速度较慢,但针对准确性进行了优化。因此,使用快速但不准确的嵌入模型生成嵌入(保存在向量数据库中),然后使用慢速但准确的模型在这个较小的集合中找到质量最高的文档。来自慢速但准确搜索的最佳匹配在上下文窗口中优先。

当然,这比这复杂得多,但这是重新排序的本质。Pinecone 博客有一个关于这个过程的更详细的描述。

重新排序可以显著提高 RAG 返回数据的相关性,这是检索质量的一个度量。上下文窗口中更相关(或更少无关)的数据将提高响应质量。虽然它增加了复杂性和延迟,但在许多 RAG 应用程序中,质量权衡可能是有价值的。

大上下文窗口与 RAG

我们终于到了调用 LLM 的时候,但在讨论提示工程之前,我们应该花点时间提及 RAG 和大上下文窗口之间的关系。

LLM 技术正在迅速发展,其中一个改进维度是上下文窗口的大小。一个典型的例子是 2024 年 2 月发布的 Gemini 1.5 Pro,具有 128K 上下文窗口,并且(未公开发布)选项可达到一百万(!!!)个令牌。

一些人最初猜测百万令牌上下文窗口会使 RAG 管道过时,但事实并非如此。这篇博客解释了为什么 RAG 在使用大上下文窗口模型时仍然有价值(甚至是必要的)(剧透:成本、延迟和回忆质量)。

大上下文模型是有价值的,可以帮助 LLM 回应需要综合大量事实的查询(这些事实可能已经通过 RAG 被选择下来)。

大上下文窗口和 RAG 之间的关系将继续发展,RAG 实施者和测试人员应了解这些权衡及其对应用质量的影响。

8—提示生成

您从向量数据库中获得了一些相关数据,重新排序,并最终得到一组适合 LLM 上下文窗口的相关数据。现在怎么办?您是否只是将这些数据塞入提示的末尾并称其为好?

任何与 LLM 打交道的人都可以告诉您,比这要复杂得多。LLM 可以非常强大,但也可能非常挑剔和令人沮丧。事实证明,提示中的小细节可以显著影响响应质量

。提示的措辞、数据的顺序、使用的语气、“慢慢来”的建议,甚至使用情感语言都可能影响 LLM 的响应质量。有一些策略可以使用专门训练生成提示的其他模型自动生成最佳提示。这都是快速发展的提示工程领域的一部分。

生成最高质量响应的精确提示模板通常是模型和应用特定的,通常需要一些反复试验。鉴于 RAG 这一看似微小细节对质量的影响,特定提示工程应像系统的任何其他部分一样得到严格评估和审查。

测量和评估 RAG 系统

我们已经走过了 RAG 管道的主要部分,并(简要)讨论了它们对应用质量的影响。这是一个介绍,但应该为您提供这些类型应用程序的内部工作和质量挑战的见解。有很多很棒的文章、博客和论文深入探讨了 RAG。如果您只从一个开始阅读,请阅读《大型语言模型的检索增强生成——一项调查》。

关键要点:实现 RAG 时有大量选择和选项,每个都有权衡和质量影响。有些选择可以直接评估,有些则影响整体检索或响应质量。了解这些选择以及它们可能对您的 RAG 系统的影响,对于实现整体应用的生产质量至关重要。

显然的下一个问题是:好吧,但我如何评估 RAG?我如何衡量开放式自由响应的质量?我可以使用什么指标实际测量?这些评估可以在什么级别上自动化?在 LLM 本质上不确定且它们消耗的数据本质上不稳定的情况下,我如何确保质量?

这些都是有趣的问题,有趣的答案。我们需要深入研究诸如 ARC 和 HellaSwag 等框架的模型评估、LLM-as-a-judge 等方法、针在干草堆测试等测试、困惑度、可信度和相关性等指标,以及 Ragas 和 LlamaIndex 等工具。


声明:本文为本站编辑转载,文章版权归原作者所有。文章内容为作者个人观点,本站只提供转载参考(依行业惯例严格标明出处和作译者),目的在于传递更多专业信息,普惠测试相关从业者,开源分享,推动行业交流和进步。 如涉及作品内容、版权和其它问题,请原作者及时与本站联系(QQ:1017718740),我们将第一时间进行处理。本站拥有对此声明的最终解释权!欢迎大家通过新浪微博(@测试窝)或微信公众号(测试窝)关注我们,与我们的编辑和其他窝友交流。
121° /1213 人阅读/0 条评论 发表评论

登录 后发表评论