RAG管道的盲点所在:将故障与智能体模式相对应
了解哪种代理式RAG模式适用于何种故障场景,涵盖查询重写与纠错回退、路由分配、答案评分、人工审核、监督机制以及规划等环节。
来源: Your RAG Pipeline Doesn’t Need More Retrieval, It Needs Better Decisions
标准的检索增强生成流程非常简单:检索、生成、回答。这种方式适合用于演示,但在实际应用中很快就会暴露出其缺陷。检索器可能返回无关内容,用户提出的问题可能是文档中从未出现过的表达方式,答案根本不在索引中,或者模型生成的内容并非检索到的文本所能支持。在提示词中加入更多文档也无法解决这些问题,因为问题不在于上下文的数量,而在于缺乏关于下一步该做什么的决策。
这种决策层正是人们所说的代理式RAG。本指南将其视为一组针对特定故障模式的针对性解决方案,而非单一的架构,这样你就可以审视自己的处理流程,找出当前出现盲目行为的环节,然后选择最合适的方案来解决它。
为何一次性处理流程会出问题
传统的RAG应用遵循固定的处理顺序:接收查询后,在向量数据库中执行相似度搜索,选取最佳结果,将其传递给大语言模型,然后返回模型的输出。这种设计隐含的假设是搜索步骤必定成功。
当这一假设不成立时,整个流程却毫无察觉:
- 质量低下的文档仍会被传递给模型,而模型会试图基于这些文档给出答案。
- 如果查询的词汇与文档不匹配,那么得到的结果几乎毫无价值。
- 若知识库中根本不存在相关答案,系统也没有其他处理路径。
一个有用的视角转变是,不再只思考如何提升检索效果,而是开始考虑当检索结果不够好时系统应该做些什么。以下的每种模式都是对这一第二个问题的不同回答。如果在详细研究各个具体模式之前希望先对检索架构进行更广泛的比较,可参阅RAG与代理式RAG及图结构RAG的对比。
对检索结果进行评分并重写查询
以“LangGraph是如何处理数据持久性的?”这样的问题为例。假设检索器返回了五个片段,其中只有一个相关。如果采用线性处理流程,会将这五个片段全部传递给模型让其自行排序,这样会削弱有用信息的价值并引发混淆。
基于智能体的工作流会首先插入评估步骤。评估者通常是一个带有是/否评分标准的小型大语言模型,负责判断检索到的文档是否足够相关以回答问题。如果不够相关,工作流不会简单地使用相同文本再次搜索,而是会根据第一次搜索的结果生成更优的查询语句,然后再次进行检索。这样的循环流程如下:
- 检索
- 评估结果
- 若结果不达标则重写查询语句
- 再次检索
循环本身并非关键所在,重要的是系统能够意识到第一次尝试并不充分。在实际应用中还需要设置停止条件,比如最大重写次数,以避免那些索引无法回答的问题无限循环。
当索引缺乏答案时的应对措施
只有当相关信息存在于你的语料库中时,重写才能发挥作用。但很多时候并非如此。想象一下,某个助手是基于一个月前收集的文档构建的,而用户却询问昨天才发布的功能。无论如何重新表述,那些从未被索引的文档都是无法找到的。
修正型RAG解决了这个问题。在对检索到的文档进行评分后,该工作流程会将结果不理想视为需要调整方向的信号,例如通过查询网页搜索等其他来源。原本“检索—生成”的线性流程变为:
- 检索
- 对文档进行评分
- 若评分不佳则进行修正
- 生成结果
“正确”的定义被刻意设定得较为宽泛。根据具体应用场景,它可能意味着需要重写查询语句、查阅其他资料或采取其他措施。其核心特征在于,当检索失败时,系统会触发不同的处理路径,而非给出不完善的答案。需注意,引入网络备用资源会改变你的信任模型:公共网络内容相比你自己的文档缺乏精心整理,因此你或许需要对依赖这些内容的答案进行标记或过滤。
将每个问题路由到合适的来源
基础RAG模型中还有一个隐含假设,即每个问题都应通过相同的检索工具处理。但实际上许多系统会同时使用多种知识来源:内部公司文档、公开的产品文档、一个或多个向量存储以及实时网络搜索。
这些数据源无法互相替代。关于内部人力资源政策的问题不应通过公开网络来解答,而关于上周发布的库版本的问题则不应仅依赖该版本发布之前构建的向量存储来处理。
自适应RAG在开始时会先进行路由决策。在检索任何内容之前,系统会先对问题进行分类,确定最适合回答该问题的数据源,然后再评估从该数据源获取的上下文信息。检索路径是针对每个问题单独确定的,并非对所有问题都固定不变。路由机制可以简单到只是一个分类提示或一组规则,无需过于复杂就能排除所有来自错误数据源的答案。
验证答案,而不仅仅是文档
一种更微妙的缺陷很容易被忽视:出色的信息检索并不能保证得到好的答案。模型即便获得了完全正确的段落,仍可能生成超出这些内容范围或偏离问题的回复。
解决办法是对输出结果进行评分。在生成答案后,可通过智能工作流来检查:
- 答案中的每个论点都有对应的检索到的上下文依据吗?
- 答案是否回应了用户实际提出的问题?
- 模型是否添加了上下文无法支持的信息?
如果答案出现错误,工作流可以对其进行修正或重新生成。这样就能进行两次独立的检查,且值得将它们区分开来:一是确认是否获取了正确的信息,二是确认这些信息是否被正确使用。将两者分开还能大大简化调试过程,因为故障原因可以归结为信息检索阶段还是生成阶段,而不仅仅是“机器人出错了”。按故障阶段评估RAG这篇文章进一步阐述了这一理念。
暂停等待人工决策
有些结果不应自动决定。需要人工审核的典型情况包括:
- 存在模糊或矛盾的证据
- 某些答案在使用前需要正式批准
- 系统自身的评分器给出较低置信度
在有人工干预的RAG系统中,工作流中会设置一个检查点,以便在继续执行之前由相关人员对结果进行审批、拒绝或修改。这并非放弃自动化,系统仍会自行处理常规案例,仅将真正需要判断的案例上报,这通常比逐一检查或完全不检查更能有效利用审核人员的时间。像LangGraph这样的基于图的编排框架非常适合这种场景,因为它们能够在检查点保存工作流状态,并在相关人员作出回应后继续执行。
将任务分配给专业代理
随着工作流规模的扩大,让一个智能体承担所有职责会导致其行为难以预测,也难以给出有效的提示。某些问题可以自然地分解为不同的角色:信息检索、研究分析、评估等等。
多智能体监督架构让其中一个智能体负责协调工作。监督者决定由哪位专家执行下一步任务,而各位专家则分别处理特定的子任务。增加智能体并非为了单纯的数量增长;每个额外的智能体都会带来延迟、成本以及更多的维护工作。只有当问题确实需要多个步骤或专业技能处理,且单个智能体的指令已变成难以管理的特殊案例列表时,增加智能体才有意义。
并行运行独立的检索任务
并非每一步都必须等待前一步完成。如果某个答案需要从多个独立来源获取信息,依次查询A、B、C后再给出答案,会浪费时间。
并行分发模式则同时发起这些查询:问题同时发送给A、B和C,各处的结果在生成答案之前被合并。独立的检索或处理任务可以并行运行,最后再统一整合。由于每个分支都是独立完整的,这种方式能让复杂的工作流程既更快又更易于组织。但相应的代价是,合并步骤必须处理可能重叠或冲突的结果,并且需要决定当某个分支出现故障或超时时应如何处理。
执行前的规划
有些问题根本无法通过单次查询来解决。它们需要多次搜索、中间转换或顺序至关重要的推理步骤。
计划与执行型RAG通过将思考过程与实际操作分开来解决这一问题。其流程如下:
- 接收问题
- 制定计划
- 执行计划中的步骤
- 评估结果
- 给出答案
计划制定者决定需要完成哪些任务,而执行部分则负责处理各个具体步骤。这种方法对于多部分问题尤为有用,比如需要在多份文档之间进行比较的情况,直接调用工具往往只能得到肤浅或不完整的答案。此外,当执行出错时,计划还能让开发者有东西可以检查,而那种每一步都即兴处理的智能体则很难做到这一点。
究竟是什么让RAG系统具备智能体特性?
仅仅调用大型语言模型或将某物称为智能体,并不能使系统真正具备智能体特性。其关键在于系统能够评估自身所处的状况并选择下一步行动。传统的处理流程是先检索信息再给出答案,而具备智能体特性的系统则可以自我提出一系列问题:
- 针对这个问题真的需要检索信息吗?
- 得到的结果是否有实际用处?
- 是否应该用不同的查询条件再次搜索?
- 是否有其他信息来源更合适?
- 该答案有证据支持吗?
- 是否需要人类介入决策?
- 是否应该让其他专业的智能体来处理?
- 先规划工作流程能否获得更好的结果?
每个问题都对应上述某种模式,正因如此,将代理式RAG视为由多个决策点构成的工具箱,而非单一的整体设计,会更有帮助。这些模式能与图式调度自然对应:评分与路由变为条件边,循环则变成带有状态计数器的环,人工审核成为中断机制,而分支扩展则表现为相互连接的并行分支。
将模式与故障对应起来
并非所有应用都需要这些模式,每增加一种模式都会带来延迟、成本以及更多需要维护的组件。应根据实际观察到的故障来选择:
- 如果检索质量是主要问题,使用相关性评分器对查询进行重写可能就足够了。
- 如果知识库存在缺失,可添加备用数据源。
- 如果需要使用多个知识源,应加入路由机制。
- 如果某些决策需要监督,可设置人工审核环节。
总结
能够带来实际改进的关键问题并非如何让RAG系统更具自主性,而是识别系统目前哪些地方仍在盲目操作:转发未经核实的文档、在错误的来源中搜索、轻信毫无依据的答案,或是强行做出本应由人决策的事情。通过对流程进行监控,找出最常出现的故障类型,添加最能解决这些问题的最小决策点,然后再进行下一步优化并重新评估。