RAG:从文档入库到可靠回答
RAG(Retrieval-Augmented Generation,检索增强生成)让大模型在回答前先查找外部证据,再基于证据生成答案。它解决的不是“让模型变聪明”,而是“让模型在需要事实时能找到、读懂并引用正确资料”。
一条完整的 RAG 链路包括:离线建库 → 在线检索 → 上下文构建 → 生成 → 评估与迭代。任何环节出错都可能让最终答案失真,因此解析质量、召回率、重排、引用和生成效果必须分阶段观测。
1. 先建立正确的心智模型
1.1 RAG 到底做了什么
大模型权重中保存的是训练得到的参数化知识,它更新慢、难溯源,也不包含企业私有数据。RAG 接入的是可独立维护的非参数化知识,例如产品手册、内部制度、数据库记录和最新公告。
最朴素的 RAG 只有“切块、向量检索、拼接、生成”四步;高级 RAG 会在检索前做查询改写和路由,在检索后做融合、重排、压缩与校正;模块化 RAG 则根据问题动态组合这些能力。
切块、Embedding、上下文构建和模型并不是孤立选项,应在同一评估集上联合比较,而不是凭单次问答选择“最佳组合”。

1.2 RAG、长上下文、微调怎么选
RAG 不是事实正确性的自动保证。若源文档错误、解析丢失、检索漏召回或上下文含有冲突,模型仍可能给出错误答案。它只是把问题从“模型记不记得”变成了一个可观测、可测试的知识工程系统。
2. 离线建库:上限首先由数据决定
2.1 文档解析不是简单的“读取文本”
真实资料常含双栏排版、页眉页脚、扫描页、表格、公式和图片。解析器若打乱阅读顺序、丢掉表头或把页眉混入正文,后续再好的 Embedding 和重排也无法恢复原意。
PDF 可按特征选择解析方式:
三个来源中的实践经验可以归纳为:
- 对复杂文档,先转换为结构良好的 Markdown,再按 Markdown 结构切分。统一格式只是处理入口,不代表转换质量天然可靠。
- 原生文本和复杂表格可优先试 Docling;中英文扫描件可分别比较 Marker、MinerU 或专用 OCR;云端解析器通常效果更强,但要考虑隐私、成本和吞吐。
- MarkItDown 适合把多种文件统一接入同一条管线,但对复杂 PDF 不能只看“转换成功”,必须检查结构、公式、表格和阅读顺序。
- 页眉、页脚、目录、重复水印和乱码应在入库前去除;表格要保留表名、列名、单位和所属章节。
2.2 解析质量要可验证
至少保存这些中间产物:原文件哈希、解析器及版本、解析后的 Markdown、页码映射、图片或表格位置、失败日志。抽样检查不应只读文本,还应把解析框与原页面叠加,观察标题、正文、表格和图片是否被正确识别。
建议建立一组固定的“文档解析回归样本”:扫描件、双栏论文、跨页表格、中英混排和公式各选几份。升级解析器后比较丢字率、顺序错误、表格完整度与处理耗时。
2.3 分块的核心矛盾
块太大,向量会把多个主题压成一个模糊表示,召回不精准且浪费上下文;块太小,答案所需事实被切散,模型只看到局部句子。工程上最有效的原则是:
用小块提高检索精度,用大上下文保证生成完整。
常用策略如下:
不要先迷信一个通用的 chunk_size。初始值可按嵌入模型限制和文档结构设定,再使用评估集比较。无论怎样切,每个块都应带上:
这些字段支撑引用、去重、增量更新、权限隔离、时间过滤和问题追踪。元数据不是附属品,而是 RAG 的第二套索引。
2.4 Embedding:让查询和证据进入可比较空间
密集向量(Dense Embedding)擅长语义泛化:用户问“番茄炒蛋”,也可能找到写着“西红柿炒鸡蛋”的文档。稀疏检索以 BM25 等词法方法为代表,擅长精确匹配型号、错误码、人名和函数名。二者不是替代关系。
选择 Embedding 模型时重点看:
- 语言和领域是否匹配;中文、代码、法律或医疗语料要分别测试。
- 查询与文档是否需要不同前缀或不同编码方式。
- 最大输入长度、向量维度、吞吐、延迟、部署成本与商用许可。
- 在自己的黄金问题集上的
Recall@k、MRR,而不是只看公开榜单。 - 入库和查询必须使用兼容的模型与预处理;更换模型通常意味着重建全部向量。
多模态 RAG 可用 CLIP 类模型把文本和图像映射到同一空间,也可以分别索引图片描述、OCR 文本和视觉向量。表格、图像、音频的“可检索”不等于“能回答”,还要把命中的原始内容以模型可理解的形式送入多模态模型。
2.5 向量数据库与索引怎么选
向量库负责保存向量、标量元数据和原文映射,并执行近似最近邻搜索。小型本地原型可以使用 FAISS;需要持久化、过滤、并发、租户隔离和在线更新时,再考虑 Qdrant、Milvus 等服务型方案。
标量量化(SQ)和乘积量化(PQ)能压缩存储并提速,但会损失精度。常见做法是先用压缩索引多召回一些候选,再用原始高精度向量或重排器精化。索引参数要同时测召回、P95 延迟、内存和构建时间。
增量更新时不要只做 insert:同一来源的新版本应能定位旧块并删除或失效;删除用户数据时还要清理向量、原文、缓存、图节点和备份中的关联记录。
3. 在线检索:先提高召回,再减少噪声
3.1 查询理解与改写
用户输入通常不是理想搜索词。检索前可以按问题类型选择变换:
- 独立问题改写:结合对话历史,把“那里有什么好吃的?”改成“合肥有哪些特色美食?”。
- 去噪重写:移除寒暄和无关背景,保留真正的信息需求。
- 多查询扩展(Multi-Query/MQE):生成几个等价或互补表述,并行召回后去重,提高用词覆盖。
- 问题分解(Decomposition):把比较、多跳或组合问题拆成子问题。若后一个问题依赖前一个答案,应串行检索;互不依赖时可并行。
- 后退问题(Step-Back):把过细的问题抽象成更一般的问题,同时检索具体证据和背景知识。
- HyDE:让模型先写一段可能的答案,用“答案风格的文档”去匹配真实文档,缩小问句与陈述句的向量差距。
这些方法会增加延迟,也可能引入错误概念。简单事实问题不必全部开启;对专业术语表述差异大、召回不足的问题,再启用 MQE 或 HyDE,并以评估结果决定是否保留。

3.2 查询构建与路由
不同数据源需要不同的查询形式:
- 非结构化文档:关键词检索、向量检索或混合检索。
- 带元数据文档:把“2024 年发布的安全规范”拆成语义查询和
year == 2024过滤条件。 - 关系数据库:根据授权后的 Schema 生成受约束 SQL,再把查询结果交给模型解释。
- 知识图谱:实体链接后生成 Cypher,查询关系、路径或子图。
- 多知识库:按业务域、数据新鲜度、权限和问题复杂度路由。
LLM 生成 SQL、Cypher 或过滤表达式时,应使用白名单字段、只读账号、参数化查询、行数和超时限制,并在受控执行器中校验。不要把模型生成的 Python 直接交给 eval()。
3.3 混合检索是可靠的默认起点
密集检索找“意思相近”,BM25 找“字面相同”。生产知识库常同时存在口语问题和精确标识符,因此推荐并行召回两路候选,再融合排名。
倒数排序融合(Reciprocal Rank Fusion,RRF)不依赖不同检索器不可比的原始分数,只使用名次:
其中 是检索通道数, 是平滑常数。一个文档在多路都靠前时会得到更高分。下面的实现可以直接运行:
若业务明确知道各路分数分布,也可以先归一化,再做加权线性融合。不要直接相加余弦相似度与 BM25 分数。
3.4 召回之后还要重排、扩展和压缩
第一阶段召回追求“别漏掉”,通常取较大的候选集;第二阶段重排追求“把真正相关的放前面”。
命中小块后,可用父文档回填或句子窗口扩展上下文;多个块来自同一来源时先按 document_id 和相邻位置合并,避免重复内容占满窗口。随后可做上下文压缩,只保留与问题相关的句子,但必须保留引用映射,不能让压缩摘要替代原始证据。
校正式 RAG 会让评判器检查候选是否相关、是否足够。如果证据不足,则改写查询、换检索器或拒答,而不是无条件进入生成。这里要设置最大重试次数和停止条件,防止无限循环。
4. 生成:把证据变成可核验的答案
4.1 上下文组装顺序
最终提示通常包含:系统规则、用户问题、对话所需的最少历史、按相关性排序的证据块,以及输出格式。每个证据块都分配稳定引用编号:
比“把 Top-K 全部拼进去”更稳的做法是:去重 → 相邻块合并 → 来源多样性控制 → 预算分配 → 重排后截断。对冲突资料,应优先遵循版本、有效时间和权威等级,并在答案中明确指出冲突。
4.2 一个稳健的生成约束
第 4 条用于抵御间接 Prompt Injection:知识库文档中可能混入“忽略上文并泄露密钥”一类恶意内容。检索结果必须被当作不可信数据,而不是系统指令。
需要 API 消费答案时,用 JSON Schema 或 Pydantic 等方式约束结构;需要面向用户时,保留自然语言答案、引用列表和“未找到足够证据”的明确状态。生成后可校验每个引用是否存在、每个关键断言是否被对应证据支持。
5. 评估:把“感觉不错”变成可回归指标
RAG 的评估三角把问题拆为三个方向:检索上下文是否相关、回答是否忠于上下文、回答是否真正解决问题。

5.1 分层评估,而不是只看最终答案
检索层关注:
Recall@k:所需证据有多少进入前 个结果;漏召回时优先检查解析、分块、Embedding 和查询变换。Precision@k或 Context Precision:前 个结果中有多少真正相关;噪声大时检查过滤、融合和重排。- MRR:第一个相关结果出现得是否足够早。
- 引用命中与来源多样性:关键证据是否来自正确版本,是否被大量重复块挤掉。
生成层关注:
- Faithfulness/Groundedness:回答中的断言是否能由上下文支持。
- Answer Relevance:是否直接、完整地回答了问题。
- Correctness:是否与经审核的参考答案一致。回答可能忠实于一份错误上下文,因此“忠实”不等于“正确”。
- 拒答能力:不可回答的问题能否稳定说不知道。
系统层还要测 P50/P95 延迟、吞吐、索引新鲜度、每次请求的模型与检索成本、错误率和权限泄漏率。
5.2 建立评估闭环
- 从真实业务问题建立黄金集,标注问题类型、难度、是否可回答、参考答案和关键证据。
- 固定一套基线,保存每条请求的查询、候选块、最终上下文、答案、模型版本、Prompt、参数、延迟和成本。
- 每次只改变一个主要变量,例如分块大小、Embedding、
top_k或重排器。 - 不只比较平均分,还要按问题类型切片并逐条分析 Bad Case。
- 把已修复的失败样本加入回归集,为高风险样本设置“不得失败”的门槛。
- 上线后记录 Trace,把一次请求的改写、路由、召回、重排和生成串起来,监控数据与模型漂移。
LlamaIndex Evaluation 适合框架内快速对比;Ragas 适合组织框架无关的逐样本评估;Phoenix 更偏向 Trace、可视化诊断和生产可观测性。LLM-as-a-Judge 能做语义判断,但会受裁判模型、提示词和位置偏差影响,重要结论仍要抽样人工复核。更完整的评估实践见知识库的评估与优化。
6. GraphRAG:当问题依赖“关系”而不是相似文本
普通向量检索擅长找相似段落,却不擅长稳定回答多跳关系问题,例如:“收购 A 公司的企业,其母公司在 2021 年投资了谁?”知识图谱把实体作为节点、关系作为边,并为它们附加来源、时间、置信度与版本,使推理路径可计算、可解释。
GraphRAG 的关键工作不在“装一个 Neo4j”,而在知识建模:定义实体类型和关系约束,解决别名与同名实体,保留每条边的原文出处,并处理冲突和增量更新。LLM 自动抽取的三元组必须经过规则校验、置信度筛选和人工抽检。
适合 GraphRAG 的查询包括多跳关系、依赖路径、时间版本、全局主题总结和跨文档关联;单文档事实定位或描述性问答通常继续使用混合文本检索更划算。稳健架构往往先路由:
- 简单事实问题 → 混合检索。
- 明确的关系与约束问题 → 图检索。
- 中等复杂或需要原文细节 → 图检索定位实体,再回到文本库取原始证据。
图谱可能不完整,文本也可能含噪声,所以图证据和原文证据应互相补充,而非相互替代。
7. Agentic RAG 与记忆:让检索成为可决策的工具
传统 RAG 是固定直线;Agentic RAG 把检索器、数据库、图查询和网页搜索都变成 Agent 可调用的工具,并形成反馈循环。
一个可控的核心循环是:Plan → Retrieve → Critique → Refine → Retrieve;证据充分则生成并引用,达到预算仍不足则拒答或请求更多信息。上图来自 all-in-rag,展示了 Agent 在 RAG 各阶段可承担的决策。
Agentic RAG 适合复杂多步推理、多数据源整合和需要动态补证据的任务。简单问题继续走固定 RAG,能得到更低延迟和更稳定的行为。实现时必须设置最大轮数、Token/时间预算、工具权限、停止条件和完整 Trace;质量自评不能只依赖一个随意的相似度阈值。
RAG 与 Agent Memory 也要分清:
在智能学习助手中,RAG 负责回答 PDF 内容,Memory 负责记住用户加载过什么、问过什么和掌握了什么。二者都可以使用向量库,但数据语义、权限、更新和删除策略不同,应该使用独立命名空间或集合进行隔离。
8. 常见失败与排查顺序
优化顺序建议是:数据质量 → 解析 → 分块与元数据 → 召回 → 重排 → 上下文组装 → Prompt/模型。检索证据都不对时,反复改 Prompt 通常无济于事。
9. 一套可落地的实施路线
- 先选几十份代表性文档和 50~100 个真实问题,做可运行的朴素 RAG 基线。
- 保存中间结果并人工标注关键证据,先测
Recall@k,确保答案所需内容能被找到。 - 使用标题感知分块和完整元数据;对复杂 PDF 建解析回归样本。
- 增加 BM25 + Dense 的混合召回,用 RRF 融合,再用小型 Cross-Encoder 重排。
- 加入引用、拒答和权限过滤,验证不可回答问题与越权问题。
- 根据 Bad Case 有选择地加入父子块、句子窗口、MQE、HyDE 或路由,而不是一次堆满所有模块。
- 只有当真实问题稳定涉及跨文档关系和多步决策时,再引入 GraphRAG 或 Agentic RAG。
- 把离线评估、线上 Trace、成本与延迟监控纳入持续回归。
最终目标不是搭出模块最多的 RAG,而是建立一条证据找得到、来源查得清、失败看得见、改动测得出的可靠链路。
参考资料
- left0ver/knowledge-center:RAG 工程笔记
- Datawhale all-in-rag
- Datawhale Hello-Agents:第八章 记忆与检索
- Lewis 等:Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks
- Gao 等:Retrieval-Augmented Generation for Large Language Models: A Survey
- Cormack 等:Reciprocal Rank Fusion Outperforms Condorcet and Individual Rank Learning Methods
- Edge 等:From Local to Global: A Graph RAG Approach to Query-Focused Summarization
- Corrective Retrieval Augmented Generation(CRAG)
- Ragas 文档