构建 RAG(R etrieval Augmented Generation的缩写)来“与数据聊天”很容易:安装流行的 LLM 协调器,如LangChain或LlamaIndex,将数据转换为向量,在向量数据库中对其进行索引,并使用默认提示快速设置管道。
只需几行代码,您就可以完成一天的工作。
或者你会这么认为。
实际情况比这更复杂。专为 5 分钟演示而制作的 Vanilla RAG 实现并不适用于实际业务场景。
别误会我的意思,这些快速而粗略的演示对于理解基础知识非常有用。但在实践中,让 RAG 系统投入生产不仅仅是将一些代码串在一起。它是关于处理混乱的数据、不可预见的用户查询以及提供有形商业价值的持续压力的现实情况。
在这篇文章中,我们将首先探讨决定基于 RAG 的项目成败的业务要素。然后,我们将深入探讨常见的技术障碍(从数据处理到性能优化),并讨论克服这些障碍的策略。
免责声明:此处分享的见解不代表我的雇主,而是来自我的个人经历、研究和多次深夜编码会议。
1 — 从一开始就明确商业价值:背景、用户和数据
“我们为什么要费心建造 RAG 呢?”
照片由Mayukh Karmakar在Unsplash上拍摄
在编写任何代码之前,从业务角度理解为什么需要 RAG(检索增强生成)至关重要。这似乎很明显,但许多开发人员忽略了这一部分,在没有明确定义长期目标的情况下匆忙实施。
让我们防止您在未来浪费时间。以下是在开始基于 RAG/LLM 的项目之前需要考虑的一些业务要求。这些原则也适用于一般的 ML 项目:
→明确背景:了解您的用户及其行为。用简单的术语阐述他们的主要业务问题,设身处地为他们着想,分析他们所做的事情,然后讨论 RAG 和 LLM 如何提供帮助。提出示例问题并模拟系统如何处理这些问题。
→向非技术用户介绍生成式 AI 的功能和局限性。由于这是一个新领域,因此这一点非常有帮助。这可以通过使用 RAG 系统的研讨会、培训课程和实际演示来实现。例如,我发现内部制作的提示指南通常有助于开始与 LLM 互动。
→了解用户旅程:他们将使用 RAG 回答哪些类型的问题?这样的系统可以期待什么样的输出?生成的答案将如何使用?
最重要的是,您必须知道您的 RAG 将如何集成到现有的工作流程中。这种预见将预测进一步的发展,例如 RAG 是否会嵌入到浏览器扩展、API 端点或 Word 插件中。
使用 RAG 系统生成答案很简单。然而,复杂之处在于从中获取实际价值。
请记住这一点:除非企业改变并改善其工作方式,否则他们不会来找你并使用你花哨的模型。
→预测要索引的数据:对其进行鉴定,将其映射到用户,并了解在触发 RAG 管道时为何以及如何使用它来形成良好的答案。这将决定应实施哪些处理和元数据。鉴定后,您最终需要制定数据获取策略:购买、利用内部数据、丢弃不必要的数据或从开放资源(开放数据、GitHub 存储库等)获取数据。
如果某个流程严重依赖于业务需求,则必须在此步骤尽早识别。
→定义成功标准:正确答案是什么?关键成功因素是什么?我们如何建立一种计算投资回报率的清晰方法?这些指标不应仅在项目完成时进行评估。它们应该在整个项目中不断迭代,以发现早期错误、容易出现的缺陷和不一致之处。
个人说明:如果企业要求您构建 RAG,一个可能的原因是他们看到竞争对手在这样做(FOMO 是真实存在的,我的朋友)。在这种情况下,我的建议是先挑战这个请求。很多时候,企业的需求可能没有我们想象的那么复杂。
2 — 了解你正在索引的内容
在映射和限定构建 RAG 所需的数据源之后,您将快速识别将在与企业进一步讨论后被索引的不同类型的模式。
- 文本
- 图片和图表
- 表
- 代码片段
每种模态都会被以不同的方式处理,转换成向量,并用于检索。
组合多模式数据有不同的方法:这是一种处理文本,表格和图像的常见方法:
- 文本数据被分块并用嵌入模型嵌入
- 表格用 LLM 进行总结,其描述被嵌入并用于索引。检索后,表格按原样使用,采用原始表格格式。
- 代码片段以特殊方式分块(以避免不一致)并使用文本嵌入模型嵌入
- 使用多模态视觉和语言模型将图像转换为嵌入 - 执行检索时,相同的多模态 LLM 将在您的文本查询中将其转换为向量并在向量数据库中搜索相关图像。
作者绘制的图表
补充说明:
- 您索引的向量不一定是您检索到的向量:您可以做不同的事情:例如,您可以根据句子出现的段落、它们回答的问题或它们的摘要来索引句子。查看此帖子以了解更多信息。
- 关于多模式 RAG 有很多很棒的资源。查看LlamaIndex 的博客以深入了解。
3 — 提高块质量 — 垃圾进,垃圾出
在索引文本数据之前,您需要将其分解成更小的部分,称为块。块是向量数据库检索并作为上下文传递给 LLM 以生成答案的文本片段。
因此,很明显,块的质量会影响答案。
如果块:
- 脱离了周围的环境(例如从中间切开)
- 包含与问题无关的数据
- 互相矛盾
他们会给出一个糟糕的答案。
其他技术取决于数据类型(原始文本、markdown、代码)。
然而,通常最有效的方法是精确分析数据并得出从业务角度有意义的分块规则:
以下是一些提示:
- 利用文档元数据(如目录、标题或页眉)提供上下文相关的区块。例如,简介和第一章之间重叠的区块不一致,而且很少有意义
- 关于块大小没有经验法则。如果你的文档冗长,并且用相对较长的段落表达一个想法,那么块大小会比用项目符号编写的文档更长
- 有些数据不需要分块,因为它们相对较短且自成体系。想象一下在 JIRA 票证上构建基于 RAG 的系统:您不需要为此进行分块。
关于语义分块的注意事项:此方法生成语义相关的块。但是,由于它依赖于底层的嵌入模型,因此非常耗时。
有关分块的资源:
4 - 改进预检索
在查询到达 RAG 系统之前,您可以通过额外的处理步骤对其进行优化。
这些步骤称为预检索:它们优化输入查询,确保系统检索最相关和高质量的文档。
以下是一些需要考虑的关键预检索步骤⤵️
✍️ 查询重写
用户提问时,通常无法清晰地表达自己的想法。他们的意图可能含糊不清,表述不够清晰,重要细节可能缺失。问题也可能太短,系统无法提供相关答案。我见过只有单个单词的问题。
为了解决这个问题,您可以在将此查询发送到矢量数据库之前,使用 LLM 重新表述该查询。
您还可以让 LLM 在聊天中与用户互动并要求澄清(这里考虑代理)。
查看有关查询扩展的论文以了解更多信息。
💥使用假设文档嵌入(HyDE)进行查询扩展
HyDE 是一种增强检索的方法。它旨在生成一个假设答案,该答案可能看起来与真实答案相似,但可能存在误差。然后嵌入这个假答案,并用它来从数据库中检索真实向量(即块)。
实验表明,HyDE 的表现始终优于最先进的无监督密集检索器 Contriever,并且在各种任务(例如网络搜索、QA 和事实验证)和语言中表现出可与微调检索器相媲美的稳健性能。
类似地,Gao 等人(2023a)提出了假设文档嵌入(HyDE)方法,该方法指示 LLM 为给定查询生成假设文档。然后,将假设文档用作新查询进行嵌入,并使用密集检索器搜索邻居。
来源:HyDE论文
查询增强
Yu 等人(2023c)提出了查询增强,将原始查询和初步生成的输出组合为新查询,然后使用该查询从外部数据库中检索相关信息。检索到的结果可以启发语言模型重新思考和增强生成的结果。
与仅应用原始查询相比,这种增强可能有助于从语料库中检索到更多相关信息,以直接阐明查询-输出关系。在新查询中包含初始输出可进一步增强与给定问题要检索的支持文档之间的词汇和语义重叠。查询增强在这些查询增强策略中实现了总体更好的性能,因为它可以在生成答案的同时集体处理所有检索到的知识(Wang 等人,2024c)。
5 — 改进检索
检索步骤接受查询(无论是原始格式还是通过预检索步骤改变的格式)以从向量数据库中获取最相关的文档。
虽然可以使用向量相似性有效地执行此操作,但仍可以通过其他技术进行增强。
混合搜索
混合搜索是一种结合向量搜索和关键字搜索的方法。它允许您结合两种技术的优点,从而在匹配查询的精确术语的同时保持对语义的控制。
当您搜索嵌入模型未经过训练或无法与向量相似度匹配的特定关键字(例如产品名称、技术术语、字母数字代码等)时,此技术很重要。
多个数据库通过结合密集搜索(由向量上的相似性度量支持)和关键字搜索(由 BM25 算法支持)实现了此功能。
Pinecone 的实现方式如下。
作者绘制的图表
按元数据进行过滤
您索引的每个向量都可以具有我们称为元数据的附加属性。查询数据库时,您可以使用这些元数据预先过滤向量空间。
虽然计算起来非常便宜,但从商业角度来看它可以极大地提高结果的质量。
假设您已将位置作为元数据的一部分对客户评论进行索引。现在假设您想使用这些数据来了解有关美国特定产品(例如 iPhone)的更多信息。
你不必问“iPhone 产品在美国是如何被看待的?”,而是可以根据美国位置预先过滤结果,然后搜索这个查询“iPhone 在美国是如何被看待的?”
这更有效率:它保证针对明确定义的细分市场获得更好的搜索结果。
测试多个嵌入模型
嵌入模型是检索步骤中的关键组件:它将文本数据转换为固定大小的数值向量。
有多个嵌入模型可供使用,它们要么是专有的,要么是开源的。
如果您不确定使用哪一个,请参考海量文本嵌入基准 (MTEB)排行榜。
来源:MTEB排行榜
微调嵌入模型
嵌入模型通常基于一般知识进行训练,这限制了它们在公司或特定领域采用的有效性。针对特定领域数据(例如法律或金融)自定义嵌入可以显著提高 RAG 应用程序的检索性能。
如果您有相关句子的正对,如(查询,上下文)或(查询,答案),则可以使用它们来微调嵌入模型。
这是一篇博客文章,展示了如何为金融 RAG 应用程序微调嵌入模型。
6 — 改进检索后结果:
后检索技术的目标是提高文档从数据库提取后的相关性。
这里就有其中两个。
重新排名
一种流行的技术是重新排名,旨在根据文档与查询的一致性/相关性对其进行重新排序。
有多个开源和专有的重新排序模型可供选择:我使用 HuggingFace 的这个模型,但你也可以依赖像Cohere重新排序器这样的专有模型
删除不相关的内容
您还可以指示 LLM 对检索到的文档进行后期处理。这可以帮助对文档进行重新排序并过滤掉不重要的部分或块。由于此技术仅依赖于 LLM,因此请谨慎使用,因为它可能会产生高昂的成本或引起幻觉。
7 — 被忽视的部分:世代
一旦检索并处理文档以使其与查询尽可能相关,它们就会作为上下文传递给 LLM 以生成答案。
虽然这一步至关重要,但在 RAG 工作流程中,许多人并没有给予它足够的重视,而只关注检索部分。
以下是一些可以增强答案生成的实用技巧:
- 定义一个系统提示来指导您的 RAG,使其以特定方式“表现”,并以特定风格书写。这很容易实现,并且具有切实的业务影响。例如,“您是一位经验丰富的财务分析师。您的职责是向我解释财务报告,就像我 5 岁一样。尽可能准确。”
- 在系统提示中包含一些镜头示例。如果您指示 LLM 执行的任务很复杂,请添加一些输入/输出示例对。示例越真实,答案就越好。
- 只要结构化输出符合您的业务逻辑,就强制您的 LLM 生成结构化输出。结构化输出可让您将 LLM 集成到管道中。
- 有些生成任务需要推理、总结结果,甚至在生成文本时退后一步(这已被证明是有效的)。这就是Chain Of Thought发挥作用的地方。
有多个框架可以执行这些任务。我特别喜欢的是DSPY。它涵盖了所有这些功能,并提供了一个有趣的范例来优化提示工程。
结论
这不仅是一个结论,更是一个起点。
如果您的项目即将投入生产并被企业采用(恭喜!),那么构建 RAG 只是一个开始。与传统 ML 模型一样,RAG 在本地构建和测试后需要持续关注。
一旦部署,它们需要:
- 提供服务,无论是通过 REST API、Web 应用程序,还是集成到 WhatsApp 或 Teams 等平台。
- 进行监控,仔细跟踪成本和性能等关键指标。
- 定期更新,确保拥有强大的数据提取生命周期。