构建高级检索扩充生成系统
上 一篇文章 讨论了构建“数据聊天”应用程序的两个选项,这是企业中生成 AI 的首屈一指的用例之一:
- 检索扩充生成(RAG),它补充了大型语言模型(LLM)训练,其中包含一个可搜索文章的数据库,这些文章可以基于用户查询的相似性进行检索,并传递给 LLM 以完成。
- 微调,这扩展了 LLM 的培训,以了解有关问题域的详细信息。
上一篇文章还讨论了何时使用每个方法、每个方法的优缺点和其他几个注意事项。
本文更深入地探讨 RAG,特别是创建生产就绪解决方案所需的所有工作。
上一篇文章描述了使用下图的 RAG 的步骤或阶段。
这种描述被称为“天真 RAG”,是首先了解实现基于 RAG 的聊天系统所需的机制、角色和责任的有用方法。
但是,更真实的实现有更多的预处理和后期处理步骤,用于准备文章、查询和响应以供使用。 下图是对 RAG 的更现实的描述,有时称为“高级 RAG”。
本文提供了一个概念框架,用于了解基于 RAG 的实际聊天系统中的预处理和后处理问题的类型,如下所示:
- 引入阶段
- 推理管道阶段
- 评估阶段
作为概念性概述,关键字和想法作为上下文和起点提供,用于进一步探索和研究。
引流
引入主要涉及以这样一种方式存储组织的文档,以便可以轻松检索这些文档来回答用户的问题。 挑战是确保与用户查询最匹配的文档部分在推理期间找到和使用。 匹配主要通过矢量化嵌入和余弦相似性搜索来实现。 但是,它通过了解内容(模式、形式等)的性质以及数据组织策略(在矢量数据库中存储时的数据结构)来促进它。
为此,开发人员需要考虑以下步骤:
- 内容预处理和提取
- 分块策略
- 分块组织
- 更新策略
内容预处理和提取
干净准确的内容是提高基于 RAG 的聊天系统的整体质量的最佳方法之一。 为此,开发人员需要首先分析要编制索引的文档的形状和形式。 文档是否符合指定的内容模式(如文档)? 如果没有,文档可能会回答哪些类型的问题?
开发人员至少应在引入管道中创建步骤以:
- 标准化文本格式
- 处理特殊字符
- 删除不相关的过时内容
- 用于版本控制的内容的帐户
- 考虑内容体验(选项卡、图像、表)
- 提取元数据
在推理管道中检索和评估过程中使用的文档,或与文本区块结合使用以说服区块的矢量嵌入时,某些信息(例如元数据)可能很有用。
分块策略
开发人员必须决定如何将较长的文档拆分为较小的区块。 这可以提高发送到 LLM 的补充内容的相关性,以准确回答用户的查询。 此外,开发人员需要考虑如何在检索时利用区块。 这是一个领域,系统设计人员应该对行业中使用的技术进行一些研究,并进行一些试验,甚至以有限的能力在其组织中对其进行测试。
开发人员必须考虑:
- 区块大小优化 - 确定区块的理想大小,以及如何指定区块。 按节? 按段落? 按句子?
- 重叠和滑动窗口区块 - 确定如何将内容划分为离散区块。 还是区块重叠? 还是两者(滑动窗口)?
- Small2Big - 在粒度级别(如单个句子)进行分块时,内容将以这样一种方式进行组织,以便很容易找到相邻句子或包含段落? (请参阅“分块组织”。检索此附加信息并将其提供给 LLM 可以在回答用户的查询时提供更多上下文。
分块组织
在 RAG 系统中,矢量数据库中的数据组织对于有效检索相关信息以增强生成过程至关重要。 下面是开发人员可以考虑的索引和检索策略的类型:
- 分层索引 - 此方法涉及创建多个索引层,其中顶级索引(摘要索引)将搜索空间快速缩小到潜在相关区块的子集,二级索引(区块索引)提供了指向实际数据的更详细的指针。 此方法可以显著加快检索过程,因为它通过先筛选摘要索引来减少在详细索引中扫描的条目数。
- 专用索引 - 可以使用专用索引 ,例如基于图形的数据库或关系数据库,具体取决于数据的性质和区块之间的关系。 例如:
- 当区块具有可增强检索的互连信息或关系(例如引文网络或知识图)时,基于图形的索引 非常有用。
- 如果区块采用表格格式构建,则关系数据库 可能有效,其中 SQL 查询可用于基于特定属性或关系筛选和检索数据。
- 混合索引 - 混合方法结合了多个索引策略来应用每个索引的优势。 例如,开发人员可以使用分层索引进行初始筛选和基于图形的索引来在检索期间动态浏览区块之间的关系。
对齐优化
为了增强检索区块的相关性和准确性,请将它们与要回答的问题或查询类型紧密对齐。 实现此目的的一种策略是为每个区块生成并插入一个假设问题,该区块表示该区块最适合回答的问题。 这有助于通过多种方式:
- 改进了匹配:在检索期间,系统可以将传入查询与这些假设问题进行比较,以找到最佳匹配项,从而改善提取的区块的相关性。
- 机器学习模型的训练数据:这些问题和区块配对可用作训练数据,以改进 RAG 系统基础的机器学习模型,帮助它了解哪些类型的问题是哪些区块的最佳答案。
- 直接查询处理:如果真实用户查询与假设问题密切相关,则系统可以快速检索和使用相应的区块,从而加快响应时间。
每个区块的假设问题就像一个指导检索算法的“标签”,使其更加专注和上下文感知。 在区块涵盖各种信息主题或类型的方案中,这非常有用。
更新策略
如果你的组织需要为经常更新的文档编制索引,请务必维护更新的料库,以确保检索器组件(负责对向量数据库执行查询并返回结果的系统中的逻辑)可以访问最新的信息。 下面是用于更新此类系统中矢量数据库的一些策略:
- 增量更新:
- 定期间隔:根据文档更改的频率,定期计划更新(例如每日、每周)。 此方法可确保定期刷新数据库。
- 基于触发器的更新:实现更新触发重新索引的系统。 例如,任何修改或添加文档都可以自动启动受影响部分的重新编制索引。
- 部分更新:
- 选择性重新编制索引:而不是整个数据库重新编制索引,而是有选择地仅更新已更改的库部分。 此方法比完全重新编制索引更有效,尤其是对于大型数据集。
- 增量编码:仅存储现有文档与其更新版本之间的差异。 此方法通过避免处理未更改的数据来减少数据处理负载。
- 版本控制:
- 快照:在不同的时间点维护文档库版本。 此方法提供备份机制,并允许系统还原或引用以前的版本。
- 文档版本控制:使用版本控制系统系统系统跟踪文档更改,以维护更改历史记录并简化更新过程。
- 实时更新:
- 流处理:当信息时间线至关重要时,在进行文档更改时,利用流处理技术进行实时矢量数据库更新。
- 实时查询:不只依赖于预编制索引的矢量,而是实现实时数据查询机制以实现最新的响应,并结合缓存的结果提高效率。
- 优化技术:
批处理:批处理为资源优化和开销减少而累积的更改,而不是频繁更新。
混合方法:组合各种策略,例如:
- 对次要更改使用增量更新。
- 针对主要更新的完整重新编制索引。
- 文档库结构更改。
选择正确的更新策略或组合取决于特定要求,例如:
文档料库大小。
更新频率。
实时数据需求。
资源可用性。
根据特定的应用程序需求评估这些因素,因为每种方法都有复杂性、成本和更新延迟权衡。
推理管道
现在,文章分块、向量化和存储到向量数据库中,焦点将转向完成挑战。
- 用户的查询是否以这种方式写入,以从用户查找的系统获取结果?
- 用户的查询是否违反了我们的任何策略?
- 如何重写用户的查询,以提高在向量数据库中查找最接近匹配项的机会?
- 如何评估查询结果,以确保项目区块与查询保持一致?
- 在将查询结果传递到 LLM 之前,如何评估和修改查询结果,以确保 LLM 完成中包括最相关的详细信息?
- 如何评估 LLM 的响应,以确保 LLM 的完成回答用户的原始查询?
- 如何确保 LLM 的响应符合我们的策略?
正如你所看到的,开发人员必须考虑的许多任务,主要采用以下形式:
- 预处理输入以优化获得所需结果的可能性
- 处理后输出以确保所需的结果
整个推理管道实时运行。 虽然前和后处理步骤设计没有一种正确的方法,但它可能是编程逻辑和其他 LLM 调用的组合。 然后,最重要的注意事项之一是尽可能生成最准确且合规的管道,以及实现管道所需的成本和延迟之间的权衡。
让我们确定每个阶段的特定策略。
查询预处理步骤
在用户提交查询后立即发生查询预处理,如下图所示:
这些步骤的目标是确保用户在我们的系统范围内提出问题(而不是试图“越狱”系统以使其执行意外操作),并准备用户的查询,以增加它使用余弦相似性/“最近的邻居”搜索找到最佳项目区块的可能性。
策略检查 - 此步骤涉及标识、删除、标志或拒绝特定内容的逻辑。 一些示例可能包括删除个人数据、删除驱逐和识别“越狱”尝试。 越 狱是指用户可能用来规避或操纵模型的内置安全、道德或操作准则的方法。
查询重新编写 - 此步骤可能来自扩展首字母缩略词和删除俚语来重述问题,以更抽象地要求它提取高级概念和原则(“后退提示”)。
退步提示的变体是 假想的文档嵌入 (HyDE),它使用 LLM 回答用户的问题,为该响应(假设的文档嵌入)创建嵌入,并使用嵌入对向量数据库执行搜索。
子查询
此处理步骤涉及原始查询。 如果原始查询很长且复杂,则以编程方式将其分解为几个较小的查询非常有用,然后合并所有响应。
例如,关于物理学科学发现的问题可能是:“谁对现代物理、阿尔伯特·爱因斯坦或尼尔斯·布尔做出了更重要的贡献?
将复杂查询分解为子查询可使其更易于管理:
- 子查询 1: “阿尔伯特·爱因斯坦对现代物理学的关键贡献是什么?
- 子查询 2: “尼尔斯·布尔对现代物理学的关键贡献是什么?
这些子查询的结果将详细介绍每个物理学家的主要理论和发现。 例如:
- 对于爱因斯坦,贡献可能包括相对论、光电效应和E=mc^2理论。
- 对布尔来说,贡献可能包括他的氢原子模型、他关于量子力学的工作以及他的互补原则。
概述这些贡献后,可以评估它们以确定:
子查询 3: “爱因斯坦的理论如何影响现代物理学的发展?
子查询 4: “布尔的理论如何影响现代物理的发展?
这些子查询探索每个科学家对物理的影响,例如:
- 爱因斯坦的理论如何导致宇宙学和量子理论的进步
- 布尔的工作如何有助于理解原子结构和量子力学。
结合这些子查询的结果,有助于语言模型根据他们的理论进步,对谁对现代物理做出更重大的贡献形成更全面的响应。 此方法通过处理更具体、可应答的组件,然后将这些结果合成成一致的答案来简化原始复杂查询。
查询路由器
组织可能决定将其内容库划分为多个矢量存储或整个检索系统。 在这种情况下,开发人员可以使用查询 路由器,该路由器是一种机制,可智能地根据提供的查询确定要使用的索引或检索引擎。 查询路由器的主要功能是通过选择最适当的数据库或索引来优化信息的检索,该数据库或索引可以提供特定查询的最佳答案。
查询路由器通常在用户表述查询之后的某个时间点运行,但在发送到检索系统之前。 下面是简化的工作流:
- 查询分析:LLM 或其他组件分析传入的查询,以了解其内容、上下文和可能需要的信息类型。
- 索引选择:根据分析,查询路由器从可能有多个可用索引中选择一个或多个。 每个索引都可以针对不同类型的数据或查询进行优化,例如,有些索引可能更适合事实查询,而另一些索引可能擅长提供意见或主观内容。
- 查询调度:然后将查询调度到所选索引。
- 结果聚合:检索所选索引的响应,并可能聚合或进一步处理以形成全面的答案。
- 答案生成:最后一步是基于检索到的信息生成一致的响应,可能集成或合成来自多个源的内容。
你的组织可能会对以下用例使用多个检索引擎或索引:
- 数据类型专用化:某些索引可能专门从事新闻文章、学术论文中的其他索引,以及其他一般 Web 内容或特定数据库,例如医疗或法律信息。
- 查询类型优化:某些索引可能针对快速事实查找(例如日期、事件)进行优化,而其他索引可能更适合需要深入域知识的复杂推理任务或查询。
- 算法差异:不同的检索算法可用于不同的引擎,例如基于矢量的相似性搜索、传统的基于关键字的搜索或更高级的语义理解模型。
假设在医疗咨询环境中使用基于 RAG 的系统。 系统有权访问多个索引:
- 针对详细和技术说明进行了优化的医学研究论文索引。
- 临床案例研究索引,提供症状和治疗的实际示例。
- 基本查询和公共卫生信息的一般运行状况信息索引。
如果用户询问有关新药生化效果的技术问题,查询路由器可能会根据其深度和技术重点确定医学研究论文索引的优先级。 然而,对于常见疾病的典型症状的问题,可能会为其广泛且易于理解的内容选择一般健康指数。
检索后处理步骤
检索后处理发生在检索器组件从向量数据库中检索相关内容区块后,如下图所示:
检索候选内容区块后,后续步骤是在准备要呈现给 LLM 的提示之前,在扩充 LLM 提示符时验证文章区块有用性。
开发人员必须考虑几个提示方面:
- 包括过多的补充信息可能会导致忽略最重要的信息。
- 包括无关的信息可能会对答案产生负面影响。
另一个考虑因素是 草袋 问题的针头,一个术语指的是一些 LLM 的已知怪癖,其中提示的开头和结尾的内容比中间的内容具有更大的权重。
最后,必须考虑 LLM 的最大上下文窗口长度和完成异常长提示所需的令牌数(尤其是在大规模处理查询时)。
若要处理这些问题,检索后处理管道可能包括以下步骤:
- 筛选结果 - 在此步骤中,开发人员确保矢量数据库返回的文章区块与查询相关。 否则,在撰写 LLM 提示符时,将忽略结果。
- 重新排名 - 对从向量存储中检索到的项目区块进行排名 ,以确保相关详细信息位于提示的边缘(开始和结束)附近。
- 提示压缩 - 在发送到 LLM 之前,使用小型、廉价的模型将多个项目区块压缩并汇总到单个压缩提示中。
完成后处理步骤
完成后处理在用户查询后发生,所有内容区块都发送到 LLM,如下图所示:
LLM 在提示完成之后进行准确性验证。 完成后处理管道可能包括以下步骤:
- 事实检查 - 目的是识别在文章中呈现为事实的特定声明,然后检查这些事实的准确性。 如果事实检查步骤失败,则可能适合重新查询 LLM,希望获得更好的答案或向用户返回错误消息。
- 策略检查 - 最后一道防线,以确保答案不包含有害内容,无论是对用户还是组织。
计算
评估非确定性系统的结果并不像大多数开发人员熟悉的单元或集成测试那样简单。 需要考虑以下几个因素:
- 用户是否对获得的结果感到满意?
- 用户是否获得对其问题的准确回复?
- 如何捕获用户反馈? 我们是否有任何策略来限制我们可以收集哪些有关用户数据的数据?
- 为了诊断不尽如人意的响应,我们是否能够了解回答问题的所有工作? 是否在输入和输出的推理管道中保留每个阶段的日志,以便我们可以执行根本原因分析?
- 如何在不回归或降级结果的情况下对系统进行更改?
捕获和操作来自用户的反馈
如前所述,开发人员可能需要与其组织的隐私团队合作,设计反馈捕获机制和遥测、日志记录等,以便对给定的查询会话启用取证和根本原因分析。
下一步是开发 评估管道。 评估管道的需求源于分析逐字反馈的复杂性和时间密集型性质,以及 AI 系统提供的响应的根本原因。 此分析至关重要,因为它涉及调查每个响应,以了解 AI 查询如何生成结果、检查文档使用的内容区块的合适性以及划分这些文档时采用的策略。
此外,它还涉及考虑任何可以增强结果的额外预处理或后期处理步骤。 此详细检查通常会发现内容差距,尤其是在响应用户查询时不存在合适的文档时。
因此,构建评估管道对于有效管理这些任务的规模至关重要。 高效的管道将利用自定义工具来评估近似于 AI 提供的答案质量的指标。 此系统将简化确定为用户的问题提供特定答案的原因、用于生成答案的文档以及处理查询的推理管道的有效性的过程。
黄金数据集
评估非确定性系统(如 RAG 聊天系统)的结果的一种策略是实现“黄金数据集”。 黄金数据集是一组精选的问题,其中包含已批准的答案、元数据(如主题和问题类型)、对源文档的引用,这些文档可用作答案的基础真相,甚至变体(用于捕获用户如何提出相同问题的多样性的不同措辞)。
“黄金数据集”表示“最佳案例方案”,使开发人员能够评估系统,以了解其性能,并在实现新功能或更新时执行回归测试。
评估损害
危害建模是一种旨在预测潜在危害的方法,发现产品中可能存在风险的产品缺陷,并制定主动策略来缓解此类风险。
为评估技术(尤其是 AI 系统)的影响而设计的工具,将根据所提供的资源中概述的危害建模原则来提供几个关键组件。
危害评估工具的主要功能可能包括:
利益干系人识别:该工具将帮助用户识别和分类受技术影响的各种利益干系人,包括直接用户、间接受影响的各方和其他实体,如后代或非人因素(如环境问题)。
伤害类别和说明:它将包括潜在的伤害的综合列表,如隐私损失、情感痛苦或经济剥削。 该工具可以指导用户完成各种方案,说明技术如何造成这些伤害,帮助评估预期和意外的后果。
严重性和概率评估:该工具使用户能够评估每个已识别的伤害的严重性和概率,使他们能够优先处理哪些问题。 示例包括数据在可用的情况下支持的定性评估。
缓解策略:该工具在识别和评估危害后建议潜在的缓解策略。 示例包括对系统设计的更改、更多的安全措施或替代技术解决方案,以最大程度地减少识别的风险。
反馈机制:该工具应包含从利益干系人那里收集反馈的机制,确保危害评估过程是动态的,响应新的信息和观点。
文档和报告:为了提高透明度和问责制,该工具可能会促进详细报告,这些报告记录了危害评估过程、发现和潜在风险缓解措施。
这些功能不仅有助于识别和缓解风险,还有助于设计更道德和负责任的 AI 系统,从一开始就考虑广泛的影响。
有关详细信息,请参阅:
测试和验证安全措施
本文概述了一些旨在缓解基于 RAG 的聊天系统可能被利用或泄露的可能性的过程。 红队在 确保缓解措施有效方面发挥了重要作用。 红队涉及模拟攻击者针对应用程序的行动,以发现潜在的弱点或漏洞。 这种方法对于解决重大越狱风险尤其重要。
开发人员需要在各种准则方案中严格评估基于 RAG 的聊天系统安全措施,以有效测试和验证它们。 这不仅可确保稳健性,而且有助于微调系统的响应,严格遵循定义的道德标准和操作程序。
可能影响应用程序设计决策的最终注意事项
下面是本文中要考虑的事项和其他要点的简短列表,这些内容会影响应用程序设计决策:
- 在设计中确认生成 AI 的非确定性性质,规划输出中的可变性,并设置机制以确保响应中的一致性和相关性。
- 根据延迟和成本的潜在增加,评估预处理用户提示的好处。 在提交之前简化或修改提示可能会提高响应质量,但可能会增加响应周期的复杂性和时间。
- 调查并行化 LLM 请求以提高性能的策略。 此方法可能会降低延迟,但需要仔细管理,以避免增加复杂性和潜在的成本影响。
如果想要立即开始尝试生成生成 AI 解决方案,建议使用自己的 Python 数据示例来了解聊天入门。 .NET、Java 和 JavaScript 中还提供了本教程的版本。