摘要生成中...
AI 摘要
Hunyuan-lite
本文是在《Agent 设计模式》书摘基础上进行知识的整合。

最强大的 AI 不是知道一切,而是知道如何找到一切。知识不再是静态的库存,而是动态的流 [^ragpaper]。

RAG 模式的核心意图在于:通过动态检索外部知识库,将相关信息实时传入 LLM 的上下文。这样,不需要重新训练模型,即可解决模型知识老化、长尾知识缺失以及幻觉问题。

其最深刻的洞见在于将「推理能力」与「知识存储」解耦。

  • 模型(类似于计算机系统中的 CPU):负责推理、逻辑、语言组织等功能,可以不断升级(如从 GPT-3 到 GPT-4,再到 GPT-5)。
  • 知识库(类似于计算机系统中的磁盘):负责存储事实、数据、细节等内容,需要实时更新(包括添加、更新、删除操作)。

这种解耦使得我们能够以极低的成本保持系统的时效性和专业性,而不需要每次都重新训练昂贵的 LLM。这正是 AI 从「实验室玩具」走向「工程化落地」的基石。

模式架构与流程

RAG 的非对称架构:

  • 检索器(Retriever):系统的「海马体」,负责高通量、低延迟的记忆召回。它通常基于 Bi-Encoder 架构(如 BERT),通过牺牲深度理解来换取更高的处理速度。
  • 生成器(Generator):系统的「前额叶」,负责逻辑推理和语言组织。它基于 Decoder 架构(如 GPT),虽然算力需求较高,但具备强大的推理能力。

RAG 应用流程主要包含两个阶段:

  • 数据准备阶段(离线索引):
    • 数据提取。
      • 数据加载:包括多格式数据加载、不同数据源获取等,根据需要,将数据处理为同一个范式。
      • 数据处理:包括数据过滤、压缩、格式化等。
      • 元数据获取:提取数据中关键信息,例如文件名、Title、时间等 。
    • 文本分割。原始文档先经过切片处理(Chunking)。文本分割主要考虑 embedding 模型的 Tokens 限制情况以及语义完整性对整体的检索效果的影响。一些常见的文本分割方式如下:
      • 句分割:以「句」的粒度进行切分,保留一个句子的完整语义。常见切分符包括:句号、感叹号、问号、换行符等。
      • 固定长度分割:根据 embedding 模型的 token 长度限制,将文本分割为固定长度(如 1024/512 个 tokens),这种切分方式会损失很多语义信息,一般通过在头尾增加一定冗余量来缓解。
    • 向量化(embedding)。向量化是一个将文本数据转化为向量矩阵的过程,该过程会直接影响到后续检索的效果。
    • 写入向量数据库。数据向量化后构建索引,并写入数据库的过程可以概述为数据入库过程,适用于 RAG 场景的数据库包括:FAISS、Chromadb、ES、milvus 等。一般可以根据业务场景、硬件、性能需求等多因素综合考虑,选择合适的数据库。
  • 应用阶段(运行时):
    • 用户提问。
    • 数据在线检索。当用户发起查询时,系统会先将查询向量化,再进行向量 Top K 搜索,并通过重排序进行去噪与排序。常见的数据检索方法包括:相似性检索、全文检索等,根据检索效果,一般可以选择多种检索方式融合,提升召回率。
      • 相似性检索:即计算查询向量与所有存储向量的相似性得分,返回得分高的记录。常见的相似性计算方法包括:余弦相似性、欧氏距离、曼哈顿距离等。
      • 全文检索:全文检索是一种比较经典的检索方式,在数据存入时,通过关键词构建倒排索引;在检索时,通过关键词进行全文检索,找到对应的记录。
    • 增强生成:知识的综合。检索到的文档被组织成上下文,与 Prompt 一同传入大模型。
    • LLM 生成答案。最终,模型在检索到的证据的加持下,生成带有引用的可靠答案。

image.png

RAG 架构面临的挑战在于如何让检索器和生成器这两个组件实现对齐:检索器必须能够理解生成器的需求,而生成器则必须能够容忍检索器产生的噪声。

RAG 核心机制

分块与向量化:把世界切片

模型无法处理整本书,只能处理片段(Chunk)。好的切片策略不仅要按字符切分,更要按语义切分。一个 Chunk 应该包含一个完整的知识点。Anthropic 提出的上下文检索(Contextual Retrieval)技术指出,单独的 Chunk 容易丢失上下文(例如,Chunk 中仅保留了「它上涨了」,但无法确定「它」指代什么)。具体解决方法是,在索引阶段,通过模型为每个 Chunk 生成一段约 50 字的「上下文说明」,并将其拼接到 Chunk 的头部,然后进行向量化处理,即通过嵌入模型将文本转换为向量。

将原始文档分成更小片段的过程包括两个重要步骤:

  1. 在保持内容语义边界的同时将文档分成多个部分。
  2. 将文档的各个部分进一步分割成大小仅占 AI 模型 token 限制一小部分的部分。

分块要点:

  • 对于包含段落和表格的文档,应避免在段落或表格中间分割文档。对于代码,应避免在方法实现中间分割代码。
  • 语义分块:先把文档按句子拆开,计算相邻句子的 embedding 相似度,当相似度突然下降时,说明话题变了,就分块,尽量保证每个句子的语义都是完整的。但是这个做法成本较大,而且相似度阈值非常难调,所以它比较适合结构松散、话题变化比较快的文档,像会议纪要、访谈记录。对于本身就有清晰章节结构的技术手册、产品说明文档,直接按标题切效果也不差,还更便宜。

检索:大海捞针

image.png

最原始的实现是使用平面索引——查询向量和所有块向量之间的暴力计算距离。我们还可以使用元数据过滤器来按照日期或来源等条件进行信息检索。

image.png

在大型数据库的情况下,一个有效的方法是创建两个索引——一个由摘要组成,另一个由文档块组成,然后分两步进行搜索,首先通过摘要过滤掉相关文档,然后只在这个相关组内搜索。

另一种方法是让 LLM 为每个块生成一个问题,并将这些问题嵌入到向量中,在运行时对这个问题向量的索引执行查询搜索(将块向量替换为索引中的问题向量),然后在检索后路由到原始文本块并将它们作为 LLM 获取答案的上下文发送。这种方法提高了搜索质量,因为与实际块相比,查询和假设问题之间的语义相似性更高。

还有一种叫做 HyDE 的反向逻辑方法——要求 LLM 在给定查询的情况下生成一个假设的响应,然后将其向量与查询向量一起使用来提高搜索质量。

语句窗口检索

为了在获取最相关的单个句子后更好地推理找到的上下文,将上下文窗口扩展为检索到的句子前后的 k 个句子,然后将这个扩展的上下文发送到 LLM。

image.png

层级索引

这里的思路与语句窗口检索器非常相似——搜索更精细的信息片段,然后在在 LLM 进行推理之前扩展上下文窗口。文档被拆分为较小的子块,这些子块和较大的父块有引用关系。

image.png

首先在检索过程中获取较小的块,然后如果前 k 个检索到的块中有超过 n 个块链接到同一个父节点(较大的块),将这个父节点替换成给 LLM 的上下文——工作原理类似于自动将一些检索到的块合并到一个更大的父块中,因此得名。请注意,搜索仅在子节点索引中执行。

这种方案就很适合长文档场景,比如技术手册、法律合同、产品文档这些内容,往往需要连带上下文一起看才能理解。

向量检索擅长处理模糊语义,但不擅长精确匹配(如精准查找产品型号 iPhone 15 Pro Max)。而混合检索(Hybrid Search)是一种常见且更精确的策略:向量检索用于查找与语义相关的文本(如「苹果」和「水果」);关键词检索用于查找精确匹配的文本(如「苹果」及其产品型号「iPhone 15 Pro」)。

这是一个很早以前的思路:结合传统的基于关键字的搜索(稀疏检索算法,如 tf-idf 或搜索行业标准 BM25)和现代语义或向量搜索,并将其结果组合在一个检索结果中。

image.png

这里唯一的关键是如何组合不同相似度分数的检索结果。这个问题通常通过 Reciprocal Rank Fusion (倒数排序融合)算法来解决,该算法能有效地对检索结果进行重新排序,以得到最终的输出结果。

混合或融合搜索通常能提供更优秀的检索结果,因为它结合了两种互补的搜索算法——既考虑了查询和存储文档之间的语义相似性,也考虑了关键词匹配。几乎所有生产环境都建议用 Hybrid Search 替代纯向量搜索,尤其是像技术文档、医疗、法律等术语密集的领域。

重排序与过滤:选择最佳

重排序的方式有很多,Cross-Encoder 是其中一种。它将用户查询和文档拼接在一起并输入 BERT,输出一个 0 到 1 的相关性分数。与向量检索(双塔模型)相比,Cross-Encoder 速度较慢,但它能捕捉用户查询和文档之间的细粒度交互,因此准确率更高。

具体应用时,一般会采用级联检索方案,分层筛选。

  • 可以先使用向量检索进行粗筛(如筛选出 Top 100 上下文)
  • 再使用 Cross-Encoder 进行精排(如从 Top 100 上下文中筛选出 Top 5 上下文)。

生成:基于已有资料的回答

RAG 的生成过程就是将检索到的内容注入 Prompt,此时的 Prompt 不再是简单的「请回答」,而是融合了具体上下文和针对性知识的信息载体。当 AI 模型需要回答用户问题时,问题和所有「相似」的文档片段都会被放入发送给 AI 模型的提示中。

有两种选择:一种是围绕较小的检索块的句子扩展上下文,另一种是递归地将文档拆分为多个较大的父块,其中包含较小的子块。

RAG 工程实践

RAG 的落地项目极为常见,几乎每个企业在 LLM 出现之后都开始考虑搭建自己的企业级知识库。以下是一些具有特色的相关产品和项目:

  • Perplexity.ai 展示了 RAG 的一种先进形态。它将 RAG 从简单的「搜」和「答」管道,提升为包含「理解 - 多步搜索 - 阅读 - 综合」的复杂过程。它还通过引用来源,让用户能够追溯信息的出处,从而有效缓解用户对 AI「幻觉」的担忧。
  • Glean 是企业级 RAG 的优秀代表。它解决了 RAG 在企业落地时的关键痛点——权限控制问题。Glean 在检索层严格执行数据权限过滤,从而确保数据安全。
  • Microsoft 在 2024 年推出的 Graph RAG 是另一种突破性的 RAG 应用范式。传统的 RAG 擅长回答「局部」问题(如「A 的电话是多少」),但在回答「全局」问题(如「这批邮件主要讨论了哪些隐患」)时表现不佳。Graph RAG 通过 LLM 提取实体构建知识图谱,并通过图聚类生成摘要,让 RAG 拥有了「鸟瞰视角」。
  • Self-RAG 和 Agentic RAG 等应用范式代表着 RAG 从被动进化为主动。在被动 RAG 中,无论问题多简单,每句话都需要查询数据库;而主动 RAG(如 Agentic RAG)则由 LLM 自行决定是否需要查询数据库。例如,遇到「你好」时直接回复;遇到「2024 年财报」时输出一个 <Retrieval> 标记以触发检索工具。它们甚至会反思检索结果:「查到的资料不足以回答这个问题,需要换个关键词再查一次。」这标志着 RAG 成为一个真正的 Agent,实现了从「查找」到「思考」的进化。

RAG 的不同模式

在工程实践中,我们见证了它从最初的简单向量相似度匹配,逐步发展为高度优化的复杂流水线,最终深度融入 Agent 的认知循环,成为 Agentic RAG 的核心组件。基本分层:

  • Naive RAG:最基础的实现方式,「检索一次,再让模型回答」
  • Advanced RAG:在 Naive RAG 基础上进行了优化,都叫 Advanced RAG。
  • Modular RAG:不再把 RAG 视为一条固定不变的流水线,而是把它看作一套可以灵活组合的功能模块。Modular RAG 的重点并不是模块越多越好,而是让系统能够根据问题特点,调用合适的模块完成合适的工作。RAG 系统中常见的一些核心模块包括:
    • Rewrite:对用户问题进行改写或补充,使查询表达更清晰;
    • Retrieve:从知识库、向量数据库或其他数据源中召回相关内容;
    • Read:让大模型对召回内容进行阅读理解,并提取关键信息;
    • Rerank:对检索结果重新排序,把最相关的内容优先保留下来。
    • Routing(路由):先判断问题属于哪一类,再决定走哪一套处理流程;
    • Search(搜索):支持从多个来源获取信息,而不局限于单一向量库;
    • Predict(预测):提前判断任务类型或信息需求,帮助系统决定后续步骤;
    • Demonstrate(演示):给模型提供示例,帮助其更好地完成复杂任务;
    • Fusion(融合):将来自不同来源的结果整合起来,形成更完整的上下文;
    • Memory(记忆):保存历史对话或检索信息,支持多轮问答与持续上下文理解。

Naive RAG

这可以视为 RAG 的原始阶段的代表。其机制为简单的「查询→向量检索→生成」。其主要痛点在于精度低、召回率差,面对复杂问题时,检索到的片段往往存在断章取义的情况,或因关键词不匹配而遗漏关键信息,最终导致「Garbage In,Garbage Out」。

image.png

Advanced RAG

这是一个笼统的说法。凡是对最简单「向量召回 + 直接拼接」的优化,全都可以叫 Advanced RAG。这些优化大致可以分为两类:

  • 检索前优化(Pre-retrieval):就是在「查资料之前」先做优化,让系统更容易搜对内容。比如把文档切得更合理、给文本加上标题和标签,或者先把用户的问题改写得更清楚。这样做以后,检索结果通常会更准。
  • 检索后优化(Post-retrieval):就是在「查到资料之后」先做整理,而不是直接把所有结果都丢给模型。因为搜出来的内容可能有重复、有噪声,也可能并不是最相关的。所以要先筛选、排序、压缩,再交给模型使用,这样最终回答的质量会更高。

image.png

Multi-Query RAG

Multi-Query 的思路就是:既然一种问法搜不全,那就让大模型把原始问题改成多种不同的表述,分别去搜,最后把结果合并去重。这种方法的代价就是每次提问要多调用一次 LLM 做改写,再多跑 N 次向量检索,延迟和成本都会增加。而且如果 LLM 改写出的问题方向跑偏,会把无关文档也带进来,影响答案质量。所以它比较适合面向普通用户的客服、电商等场景,用户表述口语化、和文档术语差距大。

HyDE

AI 回复的效果不好,可能不是因为用户的问法不好,而是用户的问题和文档的语义空间不一致。用户的提问往往很短,比如「KV Cache 是什么?」但文档里关于 KV Cache 的描述可能是一大段技术解释。一短一长,在 embedding 空间中可能离得很远,就检索不到了。

HyDE 的做法就是让大模型凭空写一个答案(不必完全准确),然后用这段假答案的向量去检索。因为假答案和真文档的文体更接近,两者在向量空间中离得也更近。

不过 HyDE 也有一个风险,如果 LLM 编的假答案方向完全跑偏了(比如把 KV Cache 理解成了 Redis 缓存),那检索结果就会更差。所以它比较适合 LLM 对问题领域有基本认知的场景,冷门领域或企业私有术语慎用。

Corrective RAG(CRAG)

RAG 就是把搜到的资料过滤一遍。具体做法就是在检索和生成之间插一个质检员,逐个审查检索到的文档是否和问题相关,然后根据审查结果走不同的分支:

  • 打分高的,说明资料靠谱,直接喂给大模型生成答案;
  • 打分低的,说明内部知识库里压根没找着相关内容,干脆回退到 Web 搜索兜底;
  • 打分模糊的,就两边的结果合一起送进去。

如果内部知识库完全搜不到有用信息,CRAG 会自动回退到 Web 搜索(当然也可以是其他策略)。

Self-RAG

大模型可能在生成阶段产生幻觉。Self-RAG 的思路是在整个流程中设置四个检查点,每一步都让模型自我审视:

  • 这个问题需要检索吗(Retrieve)?
  • 检索到的文档相关吗(IsRel)?
  • 我的回答有文档支撑吗(IsSup)?一般来说这个检查点的价值相对较高,能在一定程度上避免 AI 的幻觉。
  • 这个答案对用户有用吗(IsUse)?

Adaptive RAG

Adaptive RAG 在最前面加了一个路由器(分类器),先判断问题的复杂度,然后决定走哪条路线。

这个分类器可以是一个微调的小模型,也可以用 LLM 的 few-shot 少样本提示来实现,关键是让简单问题和复杂问题分别处理。

这种方案适合流量混杂的场景,比如既有「公司地址在哪」这种一句话能答的问题,又有「对比 A 和 B 两个方案的优缺点」这种需要多文档综合分析的复杂问题。

Graph RAG

但现实里经常有一类问题:答案散落在多个文档中,需要串起来推理。传统向量检索大概率只能搜到文档 A,但要回答这个问题,必须把 A 和 B 连起来推理。

GraphRAG 就是用来解决这种问题的,这是 Microsoft Research 在 2024 年提出的方法。Graph RAG 利用知识图谱建模文档间的语义关联,擅长解决全局性任务,如「总结整个知识库的主题」。

它的思路是先把文档变成知识图谱,再基于图谱来检索和推理。具体做法分为 3 步:

  1. 用 LLM 逐篇读文档,抽取里面的实体(人、部门、产品等)和关系,构建成一张图谱;
  2. 用 Leiden 算法对图谱做社区划分,把关联紧密的实体聚成一团,然后让 LLM 为每个社区生成一段摘要;
  3. 提问时先定位到相关实体,沿着关系拿到子图。

根据微软的评测,在全局语义理解类问题上,GraphRAG 答案的全面性和多样性显著优于传统向量 RAG。但对于简单的事实查询,两者效果差不多,就没必要用了。

需要注意的是,GraphRAG 要用 LLM 逐篇抽实体关系,图谱构建成本比向量索引高得多,查询延迟也更大,所以使用 GraphRAG 之前一定要评估是否必要。

Text-to-SQL RAG

如果我们的数据本身就是结构化的表格,比如销售数据、用户行为日志、财务报表这些,就不合适传统的 RAG 了,因为对表格数据做 embedding 是非常低效的。

用户问:「上个月销售额最高的产品是哪个?」

这本质上就是一条 SQL,向量搜索对这种聚合、排序、筛选类的需求完全没招。

Text-to-SQL RAG 的做法是让 LLM 直接把自然语言翻译成 SQL,执行查询,再把查询结果作为上下文来回答。这个方案适合所有数据分析类需求,比如 BI 看板问答、数据库运维助手、财务报表查询等等,本质上是用 LLM 替代了手写 SQL。

不过要特别提醒,生产环境中绝对不能让 LLM 生成的 SQL 直接执行,必须配备只读权限控制、SQL 语法审计、沙盒隔离等安全措施,防止 SQL 注入。

Agentic RAG

前面每种方法都有自己擅长的场景:Hybrid Search 擅长术语密集的文档,GraphRAG 擅长多跳推理,Text-to-SQL 擅长结构化数据。但在一个真实的系统中,这些场景可能同时存在。

Agentic RAG 的做法是让一个 AI Agent 来自动调度,根据问题自主决定每一步该怎么做。Agentic RAG 则将检索视为 Agent 可调用的工具,由 Agent 自主决定何时检索、检索什么,并能评估检索结果是否满足需求。这一设计标志着 RAG 从「局部片段检索」迈向「全局知识理解」的关键跨越。

Multi-Agent RAG

单个 Agent 处理复杂任务时,可能有个问题:当它要同时兼顾理解意图、选择策略、验证质量、生成答案时,Prompt 变得又长又复杂,决策质量就会下降。这就像一个人又当程序员、又教人打篮球、又当说唱歌手,忙不过来。

Multi-Agent RAG 的做法是拆分为多个专职 Agent,各自负责一些任务。

比如 Router Agent 负责分发、各 RAG Agent 负责对应领域的检索和推理、Verification Agent 负责质检、Generation Agent 负责润色输出。

这种方案适合数据源多、权限复杂、语言多样的企业级知识库。每个环节可以独立优化和扩展,不会牵一发而动全身。

多模态 RAG(Multimodal RAG)

传统 RAG 只处理文本,但现实中的企业文档里面充斥着大量的图表、流程图、架构图、产品照片等。

如果用纯文本 RAG 去处理一份真实文档,那些流程图、架构图里的信息就全丢了。

多模态 RAG 的做法是把图片、表格和文本统一到一个向量空间里,这样检索时就能跨模态匹配:

最后一步生成阶段,需要用视觉语言模型来处理混合模态的上下文,因为普通的纯文本 LLM 看不懂图片。

Speculative RAG

普通的 RAG 还有一个问题:如果把检索到的所有文档都塞进同一个 Prompt,不仅增加了推理延迟、响应速度,而且如果某个文档是噪声,整个生成都会被带偏。

Speculative RAG(假设性检索增强生成)借鉴了推测性解码(Speculative Decoding)的思想,核心目标是降低延迟,把检索到的文档分成多个子集,用多个专家小模型从每个子集 并行 生成候选草稿,最后由一个更强的大模型做一次验证,选出最佳答案。

这就有点像团队共同做个大项目,多位前端和后端开发一起干活和仔细验证,最后产品经理只需要简单验证就好,能大幅缩短工作总时长,有问题也更容易发现。

模式组合

本章节是对《Agent 设计模式》的联动。

RAG 不再是一个独立的处理管道,而是正在演变为 Agent 大脑中的「海马体」,与感知、推理、记忆等其他认知模块深度协同工作。

  • 思维链模式。该组合将一次性的大规模检索拆解为一系列微检索,在推理的每一步动态引入外部知识,持续校准内部逻辑,有效抑制知识性幻觉。该组合适用于需要多跳推理的复杂问答场景(如问「马斯克收购 Twitter 时的股价是多少」)。具体机制如下:
    • 传统 RAG:采用「先检索,再推理」的模式。
    • 检索增强思维:在思维链的每一步都嵌入检索:第 1 步,推理出「需要先查询马斯克收购 Twitter 的日期」→执行检索;第 2 步,基于结果推理「需要查询该日期 Twitter 的股价」→再次执行检索……
  • 站内文章主动感知模式。该组合将检索从「硬编码的固定流程」升级为「按需调用的认知能力」,赋予 Agent 拒绝回答或主动求知的主体性。具体机制如下:
    • 不再被动执行「每问必查」。
    • 主动感知模块实时评估当前信息的不确定性或置信度。
    • 如果置信度低,则主动触发检索工具;如果检索结果不相关或不足以支持回答,则触发反思模块,重新生成更精准的查询并再次检索。
  • 站内文章分层记忆模式。RAG 模块为分层记忆模块提供了非结构化知识的存储介质(如向量数据库)和标准化访问协议(基于嵌入的检索)。具体机制如下:
    • 分层记忆模块定义了记忆的整体架构,包括 L1 缓存、L2 缓存和 L3 缓存。
    • RAG 作为 L3 长期存储中处理非结构化文档(如 PDF、Wiki 页面等)的核心实现技术,负责将外部知识高效地存入并按需检索,使 Agent 能够持久化并复用语义信息。

本文参考