5.3 RAG 检索增强生成:从朴素 RAG 到 Advanced RAG


5.3 RAG 检索增强生成:从朴素 RAG 到 Advanced RAG

RAG(Retrieval-Augmented Generation,检索增强生成)是连接短期与长期记忆的桥梁——它把「从档案柜里捞相关记忆,拼到工作台上让 LLM 用」这件事系统化、工程化。RAG 是 Agent 记忆系统最实用的形态,但「会写 RAG」与「写好 RAG」之间隔着一整代技术的距离。

5.3.1 为什么需要 RAG:LLM 的知识缺口

第 1.1 节讲过 LLM 的「知识截止」与「幻觉」两大短板。RAG 正是为这两条短板而生:

LLM 短板 RAG 的补齐方式
知识截止 实时检索外部知识库,把最新信息送进 Prompt
幻觉 让 LLM 基于「检索到的事实」生成,而非凭记忆编造
领域知识不足 接入企业内部文档库,补齐专业领域
私有数据不可见 接入用户私有数据,个性化回答

💡 RAG 的本质:把「记忆」与「生成」分离——记忆存在外部库,生成时按需检索拼进 Prompt。LLM 不再需要「记住一切」,只需「会用检索」。

5.3.2 朴素 RAG:最小流水线

最朴素的 RAG 流水线分三步:检索 → 拼接 → 生成

朴素 RAG 的 Prompt 结构

[系统] 你是一个问答助手。根据下面的「参考资料」回答问题。 如果参考资料没有答案,请说"我不知道"。 [参考资料] 1. (检索到的文档片段 1) 2. (检索到的文档片段 2) ... K. (检索到的文档片段 K) [用户问题] <用户原始问题>

朴素 RAG 的典型问题

朴素 RAG 看起来简单,但有一堆典型问题:

问题 表现
召回不准 检索到的文档不是最相关的
召回过多 Top-K 太大,噪声多、窗口爆
召回过少 Top-K 太小,漏掉关键信息
查询与文档不匹配 用户问「怎么报销」,文档写「费用申请流程」
多跳问题 答案需要跨多个文档拼接
过时信息 检索到的是旧文档
LLM 不忠于检索 给了资料 LLM 还是凭记忆编

这些问题催生了「Advanced RAG」——在朴素 RAG 的前后加各种增强环节。

5.3.3 Advanced RAG:三段式增强框架

Advanced RAG 把流水线分为三段Pre-Retrieval(检索前)→ Retrieval(检索)→ Post-Retrieval(检索后)。每段都可以增强。

目标 典型技术
Pre-Retrieval 优化查询,提升召回率 查询改写、查询扩展、查询分解
Retrieval 提升检索精度与召回 混合检索、多路检索
Post-Retrieval 过滤噪声、突出重点 重排序 Rerank、压缩、去重
Generation 让 LLM 忠于检索结果 提示工程、Self-RAG、引用约束

下面逐段展开。

5.3.4 Pre-Retrieval:查询改写与扩展

用户的问题往往不适合直接拿去检索——太短、太模糊、用词与文档不一致。Pre-Retrieval 的目标是把「用户语言」转成「检索友好的查询」。

技术一:查询改写(Query Rewriting)

让 LLM 把用户问题改写成更利于检索的形式。

原始: "怎么报销" 改写: "员工费用报销流程 报销申请 提交方式"

技术二:查询扩展(Query Expansion)

把一个查询扩展成多个相关查询,分别检索后合并。

原始: "苹果营收" 扩展: → "Apple revenue" → "苹果 财报 收入" → "Apple Inc fiscal year revenue" (分别检索,合并结果)

技术三:查询分解(Query Decomposition)

把复杂问题拆成子问题,分别检索。

原始: "对比苹果和微软 2024 年的营收增长率" 分解: → 苹果 2024 营收 → 苹果 2023 营收 → 微软 2024 营收 → 微软 2023 营收 (分别检索后,LLM 综合计算)

技术四:HyDE(Hypothetical Document Embedding)

让 LLM 先编一个假设性答案,用这个假答案去检索——因为「答案的语言」比「问题的语言」更接近文档。

问题: "苹果 2024 营收?" LLM 假设答案: "苹果公司 2024 财年总营收约 3910 亿美元..." 用假设答案 Embedding 去检索 → 召回真实财报文档

💡 HyDE 的妙处:问题与文档存在「语义鸿沟」——问题是疑问句,文档是陈述句。HyDE 让两者语言对齐,显著提升召回率。这是 Pre-Retrieval 里最巧妙的技术之一。

5.3.5 Retrieval:混合检索

单一的向量检索(语义检索)有局限——它对关键词精确匹配专有名词数字不敏感。生产系统常用混合检索(Hybrid Retrieval)

混合检索 = 语义 + 关键词

检索方式 擅长 弱项
语义检索(向量) 概念、近义、跨语言 精确词、数字、专名
关键词检索(BM25) 精确词、专名、代码 同义、概念扩展
混合检索 两者优势互补 实现复杂度略高

融合排序:RRF

两路检索结果如何合并?常用倒数排名融合(Reciprocal Rank Fusion, RRF)

\text{RRF}(d) = \sum_{r \in R} \frac{1}{k + r(d)}

其中 r(d) 是文档 d 在某路检索中的排名,k 是常数(通常 60)。RRF 不依赖原始分数(语义与关键词的分数不可比),只看排名,简单有效。

⚠️ 混合检索的成本:它要维护两套索引(向量 + 关键词),检索时间也加倍。生产中常先用一路粗筛,再另一路精排——而非每路都全量。

5.3.6 Post-Retrieval:重排序 Rerank

检索回来的 Top-K 文档里,常有噪声(不相关的)。Post-Retrieval 的核心动作是重排序(Rerank)——用一个更精确的模型对 Top-K 重新打分。

两阶段检索:召回-精排

<svg viewBox="0 0 720 280" xmlns="http://www.w3.org/2000/svg"> <rect x="40" y="100" width="120" height="80" fill="#dbeafe" stroke="#2563eb" rx="6"/> <text x="100" y="130" font-size="13" fill="#1e3a8a" text-anchor="middle" font-weight="bold">查询</text> <text x="100" y="150" font-size="11" fill="#1e3a8a" text-anchor="middle">Embedding</text> <rect x="200" y="60" width="160" height="160" fill="#fef9c3" stroke="#ca8a04" rx="6"/> <text x="280" y="90" font-size="13" fill="#713f12" text-anchor="middle" font-weight="bold">第一阶段:召回</text> <text x="280" y="115" font-size="11" fill="#713f12" text-anchor="middle">向量检索</text> <text x="280" y="140" font-size="11" fill="#713f12" text-anchor="middle">快速粗筛</text> <text x="280" y="170" font-size="11" fill="#713f12" text-anchor="middle">Top-100</text> <text x="280" y="195" font-size="10" fill="#713f12" text-anchor="middle">(高召回,低精度)</text> <rect x="400" y="60" width="160" height="160" fill="#fce7f3" stroke="#db2777" rx="6"/> <text x="480" y="90" font-size="13" fill="#831843" text-anchor="middle" font-weight="bold">第二阶段:精排</text> <text x="480" y="115" font-size="11" fill="#831843" text-anchor="middle">Rerank 模型</text> <text x="480" y="140" font-size="11" fill="#831843" text-anchor="middle">逐对打分</text> <text x="480" y="170" font-size="11" fill="#831843" text-anchor="middle">Top-5</text> <text x="480" y="195" font-size="10" fill="#831843" text-anchor="middle">(高精度,慢)</text> <rect x="600" y="100" width="100" height="80" fill="#dcfce7" stroke="#16a34a" rx="6"/> <text x="650" y="135" font-size="13" fill="#14532d" text-anchor="middle" font-weight="bold">最终</text> <text x="650" y="158" font-size="11" fill="#14532d" text-anchor="middle">拼进 Prompt</text> <line x1="160" y1="140" x2="200" y2="140" stroke="#475569" stroke-width="2" marker-end="url(#a)"/> <line x1="360" y1="140" x2="400" y2="140" stroke="#475569" stroke-width="2" marker-end="url(#a)"/> <line x1="560" y1="140" x2="600" y2="140" stroke="#475569" stroke-width="2" marker-end="url(#a)"/> <defs> <marker id="a" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto"> <path d="M0,0 L0,6 L9,3 z" fill="#475569"/> </marker> </defs> </svg>

为什么需要两阶段

  • 召回阶段(向量):快,从百万文档里捞 100 个候选。追求高召回率(别漏)。
  • 精排阶段(Rerank):慢,对 100 个候选用更强模型逐对打分,选 5 个。追求高精度(别错)。

Rerank 模型

Rerank 模型(如 Cohere Rerank、BGE Reranker)与 Embedding 模型不同——它输入查询+文档对,输出相关性分数,比单纯向量相似度精确得多。

维度 Embedding Rerank
输入 单文本 查询+文档对
输出 向量 相关性分数
速度
精度
用途 大规模召回 少量精排

💡 Rerank 是 RAG 性价比最高的优化。它在 Top-5 的最终质量上能带来 10-30% 的提升,成本只增加一次小模型调用。几乎所有生产 RAG 都用 Rerank——它是「写了 RAG 但没用 Rerank」与「专业 RAG」的分水岭。

5.3.7 Generation:让 LLM 忠于检索

Post-Retrieval 之后,要把检索结果交给 LLM 生成。这一段也有坑——LLM 可能不忠于检索资料,依然凭记忆编造。

忠于检索的提示工程

[系统] 严格根据下面的「参考资料」回答。 - 资料中有答案才回答,引用资料编号 [1] [2] - 资料不足时回答"根据现有资料无法确定" - 不得使用资料外的知识

Self-RAG:让 LLM 自我反思

Self-RAG(Asai et al. 2023)让 LLM 在生成过程中自我判断

反思点 LLM 自问
是否需要检索 「这个问题需要查资料吗?」
检索是否相关 「召回的资料与问题相关吗?」
生成是否忠于 「我的回答有资料支撑吗?」
回答是否完整 「资料是否支持完整回答?」

⚠️ Self-RAG 的代价:每次生成要多调几次 LLM 做反思。它的价值在「关键场景」——医疗、法律、金融等不容幻觉的领域。对一般问答,过于昂贵。

5.3.8 RAG 的工程化挑战

把 RAG 推到生产,要面对几个工程挑战:

挑战一:文档切分(Chunking)

文档太长不能整篇检索,要切成片段(Chunk)。切多大、怎么切,直接影响召回质量。

切分策略 做法
固定长度 每 N 个 Token 一段
按句/段 不切断句子
按结构 按标题/章节
滑动重叠 相邻片段有重叠(如每段含上段末尾 20%)

💡 切分是 RAG 最被低估的优化点。同样模型同样数据,切得好与切得差,召回质量差 30% 以上。生产 RAG 必须为不同文档类型设计不同切分策略

挑战二:增量更新

文档会变(更新、删除、新增),索引也要跟着变。

做法 说明
全量重建 定期重建索引(简单但慢)
增量更新 只对变更文档重新 Embedding(高效)
版本管理 保留历史版本支持回溯

挑战三:评估

RAG 怎么知道好不好?要建立评估指标:

指标 衡量
召回率 Recall 相关文档有没有被检索到
精度 Precision 检索到的相关不相关
忠实度 Faithfulness 回答是否忠于检索
答案相关性 回答是否切题

业界有 RAGAS、TruLens 等 RAG 评估框架,专门量化这些指标。

5.3.9 RAG vs 微调:两大范式之争

补齐 LLM 知识,除了 RAG 还可以微调(Fine-tuning)。两者常被混淆,要分清:

维度 RAG 微调
知识来源 外部库(动态) 模型权重(静态)
更新成本 低(改库即可) 高(重新训练)
实时性
私密性 数据不进模型 数据进模型
适合 事实知识、动态数据 风格、能力、领域推理

💡 生产实践常组合用:RAG 补「事实知识」,微调补「能力与风格」。例如一个法律 Agent:用法律领域数据微调让模型「会法律推理」,再用 RAG 接入最新法条让它「知道当下法律」。两者不是二选一。

5.3.10 RAG 的反模式

反模式 表现 后果 正确做法
只做朴素 RAG 检索完直接拼 召回差、噪声多 三段式增强
无 Rerank 召回完直接用 Top-K 质量低 加 Rerank 精排
切分不合理 固定 512 Token 硬切 召回质量差 按文档类型切分
查询不改写 用户原话直接检索 召回不全 Pre-Retrieval 改写
不评估 凭感觉调参 黑盒优化 用 RAGAS 量化
不更新索引 文档变了不重建 过时信息 增量更新

本节小结

  • RAG 是连接短期与长期记忆的桥梁,本质是「记忆与生成分离」——记忆存外部库,生成时按需检索拼进 Prompt。它补齐 LLM 的知识截止与幻觉短板。
  • 朴素 RAG = 检索 → 拼接 → 生成,简单但有召回不准、噪声多、LLM 不忠等问题。
  • Advanced RAG 三段式:Pre-Retrieval(查询改写/扩展/分解/HyDE)→ Retrieval(混合检索:语义+关键词)→ Post-Retrieval(Rerank 精排)→ Generation(提示工程/Self-RAG)。
  • Rerank 是性价比最高的优化——两阶段检索(召回粗筛 + Rerank 精排)是生产 RAG 的标配。
  • 工程挑战:文档切分(最被低估)、增量更新、评估(RAGAS)。RAG 与微调不是二选一,常组合使用。

下一节《5.4 记忆的检索、更新与遗忘》把视角拉到记忆的全生命周期,讨论何时检索、何时更新、何时遗忘,并连接 Generative Agents 的经典架构。


作者与出处
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 会发光的石头的小龙虾 转发
评论区 (0)
U