块优化对比:2025年顶级块优化工具测评

2026-06-22阅读 0热度 0
ai 人工智能

Modular RAG and RAG Flow: Part I
模块化 RAG 和 RAG 流程:第 I 部分

一个关于 RAG 的压缩且高级的总结。

在第一部分中,我们将聚焦于模块化 RAG 的概念和组件,包含 6 种模块类型、14 个模块和 40 多个运算符。

介绍

要说过去一年里最火的话题,检索增强生成(RAG) 绝对算一个,它已经成为实现 LLM 应用的核心方法论。我们之前撰写过一份关于 RAG 的综合调研,深入探讨了从 Naive RAG 到 Advanced RAG,再到 Modular RAG 的演进之路。不过,那份调研的侧重点在“增强”这个维度上,比如增强的来源、阶段和过程。

这一次,我们把目光完全聚焦在 模块化 RAG 这个范式上,并进一步定义了一个 三层架构模块类型模块操作符。在这个框架下,我们梳理了当前 RAG 系统中的核心技术,总计涵盖了 6 大模块类型、14 个模块和 40 多个操作符,希望能提供一个更全面的理解视角。

通过编排这些不同的操作符,就能衍生出各种各样的 RAG 流程(RAG Flow),这也是本文想要讲清楚的核心概念。基于大量的研究,我们提炼并总结了其中的典型模式、一些具体的实现案例,以及行业内的最佳实践(这部分内容比较多,我们放到第二部分详细展开)。

本文的目标是让大家对 RAG 的现状有一个更深刻的认识,并为未来的发展铺平道路。模块化 RAG 带来了巨大的想象空间,它允许我们定义新的操作符、新的模块,以及配置新的流程。

来自我们 RAG 调研中的图表

什么是模块化 RAG?

RAG 的进步带来了更灵活、更丰富的流程,具体体现在以下几个关键方面:

  1. 数据获取能力增强: RAG 的数据源已经超越了传统的非结构化数据,现在还包括半结构和结构化数据。重点在于如何预处理结构化数据,以提高检索效率,并减少模型对外部知识的依赖。
  2. 技术融合: RAG 正在与其他技术深度结合,比如微调、适配器模块和强化学习,这些都能显著增强其检索能力。
  3. 检索过程自适应: 检索过程已经进化到支持多轮检索增强,既能用检索到的内容指导生成,也能用生成的内容反过来改进检索。此外,通过自主判断和利用 LLM 的能力来判断是否需要检索,大大提高了回答问题的效率。

模块化 RAG 的定义

从上面可以看出,RAG 的发展速度之快,已经超越了传统的 链式高级 RAG 范式,呈现出明显的模块化特征。为了应对当前缺乏组织和抽象的问题,我们提出了模块化 RAG 的方法,它无缝地整合了 Naive RAG 和 Advanced RAG 的开发范式。

模块化 RAG 提供了一种高度可扩展的范式,将系统划分为模块类型、模块和操作符这三个层级。每个模块类型都代表 RAG 系统中的一个核心流程,包含多个功能模块;而每个功能模块又包含多个具体的操作符。整个 RAG 系统,本质上就是多个模块和对应操作符的组合,这就是我们所说的 RAG Flow。在一个流程中,你可以在每个模块类型下选择不同的功能模块,并在每个功能模块中选择一个或多个操作符。

与之前范式的关系

模块化 RAG 以多层模块化的形式组织 RAG 系统。可以说,Advanced RAG 是 RAG 的一种模块化形式,而 Naive RAG 则是 Advanced RAG 的一个特例。这三者之间,是一种继承与发展的关系。

模块化 RAG 的机会

模块化 RAG 的好处显而易见,它为现有的 RAG 相关工作提供了一个全新且全面的视角。通过模块化的组织方式,相关的技术和方法得以清晰地总结。

  • 研究视角: 模块化 RAG 的高度可扩展性,为研究人员在全面理解当前发展现状的基础上,提出新的模块类型、模块和操作符 创造了条件。
  • 应用视角: RAG 系统的设计和构建变得更加便捷。用户可以根据现有的数据、使用场景、下游任务等需求,灵活地定制自己的 RAG Flow。开发者也可以参考现有的流程构建方法,定义新的流程和模式,以适应不同的应用场景和领域。

模块化 RAG 的框架

模块类型 — 模块 — 操作符

在这一章,我们将深入探讨这个三层结构,并为 RAG 构建一个技术路线图。受限于篇幅,我们不会陷入技术细节的汪&洋大海,但会提供一些参考文献供大家深入阅读。

1. 索引

索引,简单来说,就是把文本切分成易于管理的块,这是组织系统的关键一步。当然,这一步也面临三个主要挑战:

  • 内容表示不完整: 分块方式会影响块的语义信息,可能导致一些重要信息在长文本中丢失或被淹没。
  • 块相似性搜索不准确: 随着数据量的增加,检索中的噪音也会增大,导致频繁匹配到错误数据,让检索系统变得脆弱且不可靠。
  • 引用轨迹不清晰: 检索到的块,其来源可能五花八门,缺乏清晰的引用路径。这可能会导致我们得到多个来自不同文档的块,它们虽然在语义上相似,但讲的却是完全不同的主题。

块优化

这里有个经典的权衡:块越大,能捕获的上下文就越多,但也会引入更多噪音,处理时间和成本也更高。块越小,噪音少了,但可能无法完整地传达所需的上下文。

  • 滑动窗口: 一个简单的平衡方法是使用重叠的块。通过滑动窗口,可以增强语义的连贯性。但这种方法也有局限,比如对上下文大小的控制不够精确,有截断单词或句子的风险,也缺乏对语义的考虑。
  • 从小到大: 核心思想是把用于检索的块和用于最终合成的块分开。用较小的块来提高检索精度,再用较大的块来提供更丰富的上下文信息。

具体来说,一种方法是先检索较小的子块,然后通过引用其父ID 来返回更大的父块。或者,也可以直接检索单个句子,然后返回该句子周边的文本窗口

  • 摘要: 这有点像“从小到大”概念的变体。先为较大的块生成摘要,然后在摘要上进行检索。之后,再根据检索到的摘要,去回找对应的大块。
  • 元数据附加: 可以给块附加元数据信息,比如页码、文件名、作者、时间戳、摘要,甚至这个块能回答的问题。这样,在检索时就能根据这些元数据先过滤一遍,缩小搜索范围。

结构组织

提升信息检索效率的一个有效方法,是为文档建立一个层级结构。通过构建有结构的块,RAG 系统可以更快地检索和处理相关数据。

  • 分层索引: 在文档的层级结构中,节点以父子关系排列,块就挂在这些节点下面。每个节点上存储着数据的摘要,这有助于快速遍历数据,辅助 RAG 系统判断需要提取哪些块。这种方法还能在一定程度上缓解由于块提取问题导致的幻觉。

构建结构化索引的方法主要有这么几种:

  • 结构感知: 比如,感知文档中的段落和句子边界。
  • 内容感知: 利用 PDF、HTML、LaTeX 等格式中自带的固有结构。
  • 语义感知: 基于 NLP 技术(比如 NLTK)进行文本的语义识别和分割。
  • 知识图谱组织文档: 利用知识图谱(KG)来构建文档的层级结构,有助于保持内容的一致性。它能清晰地描绘不同概念和实体之间的联系,大大降低产生幻觉的可能性。

另一个好处是,它能将信息检索的过程转化为 LLM 能够理解的指令,从而提高知识检索的准确性,让 LLM 生成上下文更连贯的响应,最终提升整个 RAG 系统的效率。

2. 预检索

Naive RAG 的一个主要问题在于,它直接拿用户的原始查询去检索。现实情况是,很多人提的问题本身就模棱两可,表述不清,这直接导致检索效果不佳。

这个阶段的主要挑战包括:

  • 查询措辞不当: 问题本身可能很复杂,语言组织得也不够好。
  • 语言复杂性与歧义性: 在处理专业术语或有多重含义的模糊缩写时,语言模型常常会栽跟头。比如,它可能分不清“LLM”到底是指 大语言模型,还是在法律语境下的 法学硕士

查询扩展

既然一个查询不够,那把单个查询扩展成多个查询如何?这样可以丰富查询的内容,弥补其在特定细节上的不足,从而保证生成的答案能更好地命中要点。

  • 多重查询: 通过提示工程,让 LLM 帮你扩展出多个查询,然后并行地去执行。查询的扩展可不是随意的,得经过精心设计。两个关键的设计标准是查询的多样性覆盖度

使用多查询有个潜在的问题:可能会稀释用户的初始意图。为了应对这个问题,可以在提示工程中指示模型,给原始查询分配更高的权重。

  • 子查询: 这个过程好比是问题规划:把原始问题分解成一系列必要的子问题,当把所有子问题的答案组合起来,就能完整地回答原始问题了。从原理上讲,这和添加相关上下文类似。具体来说,可以使用从最少到最多的提示方法,将复杂问题分解为一系列更简单的子问题。
  • CoVe(Chain-of-Verification): 另一个查询扩展的思路,是使用 Meta AI 提出的验证链。这种方法让 LLM 对扩展出来的查询进行自我验证,以达到减少幻觉的效果。经过验证的扩展查询,通常可靠性更高。

查询转换

有时候,我们不用用户的原始查询,而是用一个转换后的查询去检索和生成,效果可能更好。

  • 重写: 原始查询对 LLM 来说并不总是最优的,尤其在现实场景中。因此,我们可以让 LLM 来重写查询。除了用 LLM,也有专门的轻量级语言模型干这个活儿,比如 RRR(Rewrite-Retrieve-Read)。

淘宝促销系统中使用的查询重写方法(BEQUE)就是一个很好的例子,它显著提高了长尾查询的召回率,进而带动了 GMV 的增长。

  • HyDE(假设文档嵌入): 核心思路是,在响应查询时,让 LLM 先生成一个假设性的回答(假设文档),然后用这个假设文档的向量去检索,而不是直接用原始查询去向量数据库里搜。它强调的是答案到答案之间的嵌入相似性,而不是问题到答案的。同时,也有与之相反的 Reverse HyDE,专注于查询到查询的检索。

HyDE 和 Reverse HyDE 的核心思想,都是在查询和答案之间架起一座映射的桥梁。

  • Step-back Prompting: 使用谷歌 DeepMind 提出的这种方法,可以对原始查询进行抽象,生成一个更高层次的概念性问题(step-back question)。在 RAG 系统中,同时用 step-back 问题和原始查询去检索,把两个结果都作为生成答案的基础。

查询路由

针对不同的查询,路由到不同的 RAG 管道。这对于一个需要适应多种场景的通用 RAG 系统来说,非常实用。

  • 元数据路由器/过滤器: 第一步,从查询中提取出关键字(实体);然后,基于这些关键字和块中的元数据进行过滤,从而缩小搜索范围。
  • 语义路由器: 另一种路由方法,是充分利用查询的语义信息。当然,也可以把语义和元数据结合起来,采用一种混合路由的方法,效果更佳。

查询构造

简单说,就是把用户的自然语言查询,转换成另一种查询语言,以便访问其他类型的数据源。常见的方法包括:

  • Text-to-Cypher(文本转图查询语言)
  • Text-to-SQL(文本转SQL)

在很多场景下,结构化查询语言(如 SQL、Cypher)往往会和语义信息、元数据结合起来,用于构造更复杂的查询。

3. 检索

检索过程在 RAG 中扮演着核心角色。强大的预训练语言模型(PLM)能够有效地将查询和文本表示到潜在空间中,从而建立起问题和文档之间的语义相似度,支撑起整个检索过程。

这里有三个主要的考量点:

  • 检索效率
  • 嵌入质量
  • 任务、数据和模型之间的对齐程度

检索器选择

自 ChatGPT 发布以来,嵌入模型的发展可谓是日新月异。Hugging Face 的 MTEB 排行榜评估了几乎所有可用的嵌入模型,覆盖了 8 个任务和 58 个数据集。此外,C-MTEB 则专注于评估中文嵌入模型的能力。

在构建 RAG 应用时,对于“该用哪个嵌入模型”这个问题,没有放之四海而皆准的答案。但你会发现,某些特定的嵌入模型在某些特定场景下表现尤为出色。

  • 稀疏检索器: 虽然稀疏编码模型看起来有点“复古”,通常基于词频统计之类的统计方法,但它们编码效率高、稳定性好,所以至今仍占有一席之地。常见的代表有 BM25TF-IDF
  • 密集检索器: 基于神经网络的密集编码模型则更加多样,主要包含几种类型:
    • 基于 BERT 架构的编码器-解码器模型,比如 ColBERT。
    • 全面的多任务微调模型,例如 BGE 和 Baichuan-Text-Embedding。
    • 基于云 API 的模型,如 OpenAI-Ada-002 和 Cohere Embedding。
    • 为大规模数据应用设计的下一代加速编码框架 Dragon+。
  • 混合/混合检索: 稀疏和密集这两种嵌入方法捕获的是不同的相关性特征,正好可以互补。例如,可以用稀疏检索模型的结果来训练密集检索模型;PLM 也可以用来学习词汇权重,以增强稀疏检索。研究表明,稀疏检索能增强密集检索的零样本能力,并帮助密集检索器处理包含稀有实体的查询,从而提升整体鲁棒性。

图片来自 IVAN ILIN:高级 RAG 技术图解概述

检索器微调

当你的上下文和预训练模型在嵌入空间中认为“相似”的东西不太一样时,尤其是在医疗、法律这些高度专业化的领域,调整嵌入模型本身就能很好地解决问题。虽然这需要额外的努力,但能显著提升检索效率和领域对齐度。

  • SFT(监督微调): 你可以基于特定领域的数据,自己构建一个微调数据集,然后微调模型。这个过程用 LlamaIndex 可以很快完成。
  • LSR(LM 监督检索器): 与直接构建微调数据集不同,LSR 巧妙地利用语言模型生成的结果作为监督信号,在 RAG 的进行过程中动态微调嵌入模型。
  • RL(强化学习): 受 RLHF 的启发,利用语言模型的反馈,通过强化学习来进一步强化检索器。
  • 适配器: 有时,微调整个检索器成本太高,特别是对于那些基于 API、无法直接微调的检索器。这时,我们可以通过添加一个适配器模块来进行微调。这样做还有一个额外的好处:能更好地对齐特定的下游任务。

4. 检索后处理

直接把检索到的整个文档块一股脑塞进 LLM 的上下文环境,并不是最佳选择。对检索到的文档做些后处理,能帮助 LLM 更好地利用上下文信息。

这个阶段的主要挑战包括:

  • 迷失在中间: 和人类一样,LLM 也倾向于只记住长文本的开头和结尾,而忘记中间的内容。
  • 噪音/矛盾块: 检索到的噪音文档或事实性矛盾的文档,会严重影响最终的生成质量。
  • 上下文窗口限制: 尽管我们可能检索到大量相关内容,但大模型的上下文窗口长度有限,无法容纳所有这些信息。

重新排序

在不改变文档块内容和长度的情况下,对它们重新排序,目的是让 LLM 能优先关注到更重要的信息。

  • 基于规则的重新排序: 根据一些预设的规则,计算指标来重新排序。常见的指标包括:
    • 多样性
    • 相关性
    • MMR(最大边际相关性):这个方法的初衷是减少冗余、增加结果的多样性,后来也被用在文本摘要中。MMR 基于查询相关性和信息新颖性的组合标准,在最终列表中挑选出最佳短语。
  • 基于模型的重新排序: 利用一个语言模型来重新排序。可选的模型包括:
    • BERT 系列的编码器-解码器模型,比如 SpanBERT。
    • 专门的重新排序模型,例如 Cohere rerank 或 bge-raranker-large。
    • 通用的大型语言模型,比如 GPT-4。

压缩与选择

RAG 流程中有一个常见的误区:认为检索到越多相关文档越好,把它们全连起来形成长长的提示词就够了。然而,过多的上下文会引入更多噪音,反而会削弱 LLM 对关键信息的感知,导致“迷失在中间”等问题。一个常见的解决方案是对检索到的内容进行压缩和筛选。

  • (Long)LLMLingua: 通过使用对齐且经过训练的小语言模型(比如 GPT-2 Small 或 LLaMA-7B),可以检测并删除提示词中不重要的 tokens,将其压缩乘人类难以读懂但 LLM 却很了解的形式。这是一种直接而实用的提示压缩方法,无需额外训练 LLM,同时还能平衡语言完整性和压缩率。
  • Recomp: 引入了两种类型的压缩器:抽取式压缩器,从检索到的文档中挑选相关句子;抽象式压缩器,则整合多个文档的信息生成简洁的摘要。这两个压缩器都经过专门训练,目的是在生成的摘要被附加到 LLM 输入之前,能提升其在最终任务上的性能,同时确保摘要本身简洁。如果检索到的文档与输入无关,或者无法提供额外信息,压缩器可以返回空字符串,从而实现选择性增强。
  • 选择性上下文: 通过识别并移除输入上下文中的冗余内容,可以精简输入,从而提高语言模型的推理效率。可以把它理解为一种“停用词清除”策略。在实践中,该方法根据基础语言模型计算出的自信息,来评估词汇单元的信息量。通过保留自信息较高的内容,它为语言模型处理提供了更简洁的文本表示,而不会影响其在各种应用场景下的性能。
  • 标签过滤: 一个比较直观直接的方法。先给文档打上标签,然后根据查询的元数据信息进行过滤。
  • LLM 批判: 另一个简单高效的方法:在生成最终答案之前,先让 LLM 自己评估一下检索到的内容。通过 LLM 的自我批判,可以过滤掉相关性差的文档。比如在 Chatlaw 项目中,LLM 会被提示对自己引用的法律条文进行评估。

5. 生成

这一步就是利用 LLM,基于用户查询和检索到的上下文信息来生成最终答案。

生成器选择

根据应用场景的不同,LLM 的选择大致可以分为两类:

  • 基于云 API 的生成器: 通过调用第三方 API 来使用,比如 OpenAI 的 ChatGPT、GPT-4,或者 Anthropic 的 Claude 等。
    • 优点: 没有服务器压力,支持高并发,能使用更强大的模型。
    • 缺点: 数据经过第三方,有隐私泄露的风险;绝大多数情况下无法调整模型。
  • 本地部署: 在本地部署开源或自研的 LLM,比如 Llama 系列、GLM 等。优缺点正好和云 API 模式相反:更灵活,隐私保护更好,但需要较高的计算资源。

生成器微调

除了直接拿来用,根据具体场景和数据特征进行针对性的微调,往往能取得更好的效果。这也是部署本地模型的最大优势之一。

  • SFT(监督微调): 当 LLM 缺乏特定领域的数据时,可以通过微调向模型注入额外知识。微调的另一个好处是能调整模型的输入输出格式,比如让模型适应特定的数据格式,或者按照指示生成特定风格的回复。
  • RL(强化学习): 通过强化学习,让 LLM 的输出与人类偏好或检索器的偏好对齐。除了人类偏好,理论上也可以与微调模型或检索器的偏好对齐。
  • 蒸馏: 当你无法使用强大的专有模型或更大的开源模型时,一个简单有效的方法是对更强大的模型(如 GPT-4)进行知识蒸馏。
  • 双重微调(Dual FT): 同时微调生成器和检索器,让它们的偏好对齐。一个典型的方法是 RA-DIT,它使用 KL 散度来对齐检索器和生成器的评分函数。

6. 编排

编排是指用来控制 RAG 流程的模块。与 Naive RAG 的固定流程不同,现在 RAG 需要在关键节点做出决策,并根据结果动态选择下一步的行动。这正是模块化 RAG 的关键特征之一。

调度

Judge 模块负责评估 RAG 流程中的关键节点,判断是否需要检索外部知识库、当前答案是否满足要求,以及是否需要进一步探索。它通常应用在递归、迭代和自适应检索中。主要包含两个操作符:

  • 基于规则: 根据预设规则决定下一步。通常,会对生成的答案进行打分,然后根据分数是否达到预设阈值(比如 tokens 的置信度水平)来决定是继续还是停止。
  • 基于提示: 让 LLM 自主决定下一步。主要有两种方式:
    • 提示基础: 通过提示,让 LLM 基于对话历史进行反思或判断,比如 ReACT 框架。好处是不需要微调模型,但判断的输出格式取决于 LLM 对指令的遵循程度。一个例子是 FLARE。
    • 微调基础: 让 LLM 生成特定的 token 来触发特定的动作。这个方法可以追溯到 Toolformer,在 RAG 中的应用有 Self-RAG。

融合

这个概念源自 RAG Fusion。正如我们在“查询扩展”部分提到的,现在的 RAG 流程不再是单一的管道。它通常需要通过多个分支来扩展检索范围或多样性。因此,当扩展到多个分支后,就需要 Fusion 模块来合并多个答案。

  • 可能性集成: 基于多个分支生成的不同 token 的权重值,综合选择最终的输出。主要采用加权平均的方法。
  • RRF(倒数秩融合): 这是一种将多个搜索结果列表的排名组合起来,生成一个统一排名的技术。实践表明,RRF 产生的结果比在任何单个分支下重新排序得到的块更有效。

结论

关于 RAG Flow 的更多内容,我们会在即将发布的第二部分中详细展开。

由于这是笔者第一次尝试这种形式的文章,还有许多不成熟之处,欢迎各位批评指正。

免责声明

本网站新闻资讯均来自公开渠道,力求准确但不保证绝对无误,内容观点仅代表作者本人,与本站无关。若涉及侵权,请联系我们处理。本站保留对声明的修改权,最终解释权归本站所有。

相关阅读

更多
欢迎回来 登录或注册后,可保存提示词和历史记录
登录后可同步收藏、历史记录和常用模板
注册即表示同意服务条款与隐私政策