LLM 系列 (十三):RAG,大模型如何连接外部知识
大模型在预训练阶段已经学到了大量通用知识,但这些知识本质上是“写进参数里的静态记忆”。模型训练完成后,参数不会自动更新;而真实世界中的知识却在不断变化:产品文档会迭代,业务规则会调整,代码仓库会更新,企业内部知识也往往是私有的、动态的、需要权限控制的。
对于企业知识问答、客服助手、代码助手、法律合规、金融研报分析这类场景来说,答案不能只是“看起来合理”,还必须能够基于明确证据,说明来自哪份文档、哪个版本、哪个段落。换句话说,大模型不仅要会回答,还要会查资料、用资料、引用资料。
这就是 RAG 诞生的背景。RAG,全称 Retrieval-Augmented Generation,即“检索增强生成”。它的核心思想很直接:不要让模型只依赖参数中的静态知识,而是在回答问题之前,先从外部知识库中检索相关资料,再把这些资料放入上下文,让模型基于证据生成答案。
为什么需要 RAG
RAG 要解决的核心问题,不是让模型“变得更聪明”,而是让模型能够连接外部知识,并基于可追溯的证据回答问题。可以从四个角度理解它的价值:
- 补充最新知识:模型参数有时间边界,而外部知识库可以持续更新。
- 连接私有知识:企业文档、内部代码、工单记录、数据库说明等信息,通常不在公开预训练语料中。
- 降低更新成本:相比重新训练模型,更新知识库、重建索引和增量同步要现实得多。
- 提供证据来源:业务场景往往要求答案可解释、可引用、可审计,而不是只给出一个看似合理的结论。
所以,RAG 可以理解成大模型系统里的“外部知识访问层”:
- 模型参数:提供通用语言能力、推理能力和任务理解能力;
- 外部知识库:保存可更新、可治理、可权限控制的业务知识;
- RAG 系统:负责在两者之间完成检索、排序、上下文组装和基于证据的生成。

简单说,RAG 不是让模型记住一切,而是让模型在需要时能够找到正确资料,并基于资料回答问题。
RAG 工程链路
一个完整的 RAG 系统,不能简单理解成“把文档丢进向量库,然后让模型查询”。真正可用的 RAG,通常是一条从离线知识入库到在线检索生成的工程链路。
离线链路负责把原始资料加工成可检索、可过滤、可追踪的知识库;在线链路负责理解用户问题,通过多路召回和重排找到可靠证据,再把证据组织成模型可以理解的上下文。

离线入库:先把资料变成可检索知识
RAG 的第一步不是 Embedding,而是文档解析。真实业务里的知识通常不是干净的纯文本,而是 PDF、Word、Markdown、HTML、飞书文档、代码仓库、数据库表结构、日志、工单、PPT、图片和扫描件。
解析阶段的目标不是“提取文字”这么简单,而是尽量保留结构信息:
- 标题 / 章节层级 / 段落 / 列表 / 表格
- 代码块 / 文件路径 / 图片说明 / 文档来源
- 更新时间 / 版本号 / 作者 / 权限信息
如果这一层把表格打散、标题丢掉、代码缩进破坏,后面的检索和生成都会变差。很多 RAG 效果不好,并不是模型不行,而是知识在入库前就已经被处理坏了。
Chunk 切分:决定检索粒度
文档解析后,系统通常不会直接把整篇文档作为检索单元,而是切成多个 Chunk。Chunk 是 RAG 的基础检索单元,它决定系统召回的是“一句话”“一段内容”“一个章节”,还是“一块结构化信息”。
| 切分方式 | 适合场景 | 关键问题 |
|---|---|---|
| 固定长度切分 | 大规模通用文档 | 简单但容易切断语义 |
| 滑动窗口切分 | 连续文本 | 通过 overlap 缓解边界丢失 |
| 按标题切分 | 技术文档、产品手册 | 保留章节结构 |
| 语义切分 | 长文章、知识库 | 按主题边界切分 |
| 结构化切分 | 表格、代码、FAQ、API 文档 | 保留原始结构 |
| Parent-Child Chunk | 企业知识问答 | 小 chunk 检索,父章节返回 |
Chunk 太小,模型缺少上下文;Chunk 太大,召回不精确,还会浪费上下文窗口。所以生产系统常用一个原则:
- 检索粒度要足够小,便于命中关键内容;
- 返回上下文要足够完整,便于模型理解语义。
这也是 小 chunk 召回 + 父文档扩展 常见的原因:先用小 chunk 精确命中,再把相邻段落、标题层级或父章节一起带回。
索引构建:不只有向量索引
Embedding 的作用,是把文本转换成向量:
- chunk text -> embedding vector
- query text -> embedding vector
- similarity(query_embedding, chunk_embedding)
常见相似度包括 Cosine Similarity、Inner Product 和 L2 Distance。大规模检索不会暴力扫描所有向量,而是使用 ANN 近似最近邻索引,例如 HNSW、IVF、PQ / SQ 量化、DiskANN,工程上可以落到 FAISS、Milvus、Elasticsearch、OpenSearch、pgvector 等系统。
但生产级 RAG 通常不会只有向量索引,还会同时维护三类索引:
- 向量索引:解决语义召回;
- 倒排索引:解决关键词、错误码、接口名、专有名词;
- 元数据索引:解决权限、时间、版本、业务线过滤。
元数据非常关键。一个 chunk 不应该只有文本,还应该有:
1 | { |
没有元数据,RAG 很快会变成一个“能搜但不可控”的向量仓库。
在线召回:从 Query 改写到 Hybrid Search
在线链路的第一步,是把用户问题转换成更适合检索系统理解的 Query。
真实用户的问题往往很短、很口语,甚至缺少上下文。如果直接拿原问题去检索,很容易召回不到关键资料。例如:
- 用户问题:为什么支付失败?
- 改写后:支付失败可能涉及哪些错误码、风控拒绝、账户余额不足、渠道超时、回调异常或订单状态异常?
这一步通常会用到几类 Query 处理方法:
- Query Rewrite:把口语化问题改写成更适合检索的表达。
- Query Expansion:扩展同义词、缩写、产品名、错误码别名。
- Multi-Query Retrieval:从多个角度生成查询,并行召回候选结果。
- HyDE:先生成一个假设性答案或文档,再用它做语义检索。
- Query Decomposition:把复杂问题拆成多个子问题分别检索。
Query 处理之后,召回阶段通常不会只依赖一种检索方式。生产系统里更常见的是 Hybrid Search:
- Sparse Search:基于 BM25 / 倒排索引,擅长精确匹配关键词、错误码、接口名、专有名词。
- Dense Search:基于 Embedding / 向量检索,擅长语义匹配,能找到表达不同但含义接近的内容。
- Metadata Filter:基于权限、时间、版本、业务线、文档类型等元数据过滤候选范围。
- Structured Search:针对数据库、表格、代码符号、API schema 等结构化信息做精确查询。
比如用户问:
1 | ERR-7782 是什么原因? |
这里最关键的是 ERR-7782 这个精确错误码,BM25 或倒排索引往往比向量检索更稳。但如果用户问:
1 | 为什么服务启动后马上退出? |
这类问题不一定和文档里的原始表述完全一致,Dense Search 更容易找到“进程 crash”“健康检查失败”“启动异常退出”等语义相关内容。所以,更合理的召回方式通常是:
1 | 关键词召回 + 向量召回 + 元数据过滤 + 结构化检索 |
不过,多路召回之后还不能直接进入生成。因为 BM25、向量检索和结构化检索来自不同系统,分数体系并不一致,不能简单把原始分数直接相加。工程上通常还需要做一次候选融合:
- RRF:根据结果在不同召回通道中的排名进行融合,不直接依赖原始分数,简单且稳定。
- 分数归一化:把 BM25 分、向量相似度、时间权重等拉到同一尺度,再进行加权。
- 规则加权:根据来源权威性、更新时间、业务线匹配、关键词精确命中等因素调整排序。
候选融合的目标不是完成最终排序,而是先得到一个覆盖较全、质量较高的候选池。随后,再交给 Rerank 模型做更精细的相关性判断。
Rerank 与上下文组装:把候选证据整理给模型
第一阶段召回通常追求“别漏”,可能会返回 top 50 或 top 100 个候选片段。接下来需要通过 Rerank,把真正相关的内容排到前面。常见 Rerank 方案包括:
- Cross-Encoder Reranker:把 query 和 document pair 一起输入模型,相关性判断更准,但成本较高。
- Late Interaction Reranker:代表思路是 ColBERT,query 和文档分别编码,再做 token 级交互。
- LLM Reranker:让大模型判断哪些片段最相关,适合复杂问题,但延迟和成本更高。
- 规则融合排序:结合 BM25 分、向量分、时间、文档质量、来源权威性等信号。
Rerank 之后,系统还需要做一次上下文组装。这里的目标不是治理证据,而是把最相关的候选内容整理成模型能够读取的输入:
- 去掉重复 chunk;
- 合并相邻片段;
- 补充标题、章节、来源和更新时间;
- 按相关性和文档结构重新排序;
- 控制 token 长度,避免上下文过长;
- 给片段添加编号,方便后续引用。
可以简单理解为:
- 召回结果 -> 候选融合 -> Rerank -> 去重 -> 结构补全 -> 上下文组装 -> LLM 生成
这一层解决的是“如何把检索结果送到模型面前”。至于这些证据是否可信、是否冲突、能否被追溯,则属于后面的生产治理问题。
小结
这一章可以总结为:
1 | 离线链路: |
真正决定 RAG 效果的,不只是 embedding 模型好不好,而是整条链路是否能做到:
- 文档解析保留结构;
- Chunk 粒度合理;
- 元数据足够完整;
- Sparse、Dense、Metadata 多路召回互补;
- Rerank 能把关键证据排前面;
- 上下文组织清晰、可引用、可追溯;
- 模型最终基于证据回答,而不是凭空补全。
工程实践:从能用到可靠
一个 RAG demo 很容易做:文档切块、向量化、检索、拼 prompt、生成答案。但企业级 RAG 要解决的问题远不止这些。真正上线后,系统要面对权限、版本、引用、评估、延迟、成本和幻觉治理。
证据治理:引用、冲突与可追溯
企业级 RAG 不能只追求“答出来”,还要追求“答得有依据”。模型最终输出的答案,最好能回答三个问题:
- 这个结论来自哪里?
- 引用的资料是否足够支持答案?
- 如果资料之间冲突,系统有没有说明?
所以生产级 RAG 通常会把证据治理作为独立能力来做。首先,每个进入上下文的片段都应该带上稳定的证据标识,例如:
1 | [证据 1] |
这样模型生成答案时,才能明确引用来源,而不是泛泛地说“根据文档”。更进一步,系统还可以要求答案按 claim 级别引用证据:
- 结论 A -> 来自证据 1
- 结论 B -> 来自证据 2、证据 3
- 结论 C -> 当前资料不足,无法确认
其次,RAG 系统要处理资料冲突。真实业务里,不同文档可能版本不一致,旧文档和新文档可能说法不同,FAQ、代码注释、接口文档之间也可能互相矛盾。这时模型不应该强行选择一个答案,而应该说明:
- 哪些资料存在冲突;
- 哪份资料更新时间更晚;
- 哪个来源更权威;
- 当前结论是否需要人工确认。
最后,证据需要可追溯。一个成熟的 RAG 系统通常会记录:
- 用户问题;
- Query 改写结果;
- 召回了哪些 chunk;
- Rerank 后的排序;
- 最终进入上下文的证据;
- 模型答案引用了哪些证据;
- 哪些证据没有被使用。
这些信息对调试、审计和持续优化都很重要。否则当用户发现答案错误时,系统很难判断问题出在解析、切分、召回、排序、上下文组装,还是模型生成阶段。
简单说,证据治理解决的是:
- 不仅要回答,还要知道为什么这样回答;
- 不仅要引用,还要引用得准确;
- 不仅要检索,还要能追溯整个证据链。
权限与版本:企业 RAG 的底线
企业 RAG 最重要的问题之一是:相关不代表可见。检索系统不能只判断“哪些内容和问题相关”,还必须判断:
1 | 这个用户有没有权限看这些内容? |
否则,RAG 可能把无权限文档召回给模型,造成信息泄露。工程上通常需要:
- 文档级 ACL:文档本身有访问控制;
- Chunk 权限继承:切块后不能丢失原文档权限;
- 用户身份过滤:根据用户、部门、项目、租户过滤;
- 检索前过滤:先限制候选范围,再召回;
- 检索后校验:召回后再次检查权限;
- 权限变更同步:文档权限变化后,索引权限也要更新。
除了权限,版本也很关键。知识库不是静态的,文档会更新、删除、迁移,规则会过期,embedding 模型也会升级。一个成熟 RAG 系统通常要支持:
- 增量文档更新;
- 文档删除后的索引清理;
- embedding 版本升级;
- chunk 策略变更后的重建;
- 文档版本追踪;
- 旧文档降权;
- 引用来源可回溯。
这也是为什么元数据不是可选项,而是 RAG 的治理基础。一个 chunk 至少应该有这些信息:
1 | doc_id |
没有元数据,RAG 很快会变成一个无法治理的向量仓库。
评估体系:不要只看最终答案
RAG 的评估不能只问“答案看起来对不对”。因为一个答案可能看起来很流畅,但底层检索是错的;也可能检索到了正确资料,但模型生成时没有用上。更合理的做法,是把 RAG 拆成四层评估:

常见指标包括:
| 层次 | 指标 | 说明 |
|---|---|---|
| 检索 | Recall@K | 正确证据是否被召回 |
| 检索 | MRR | 正确证据是否排在前面 |
| 检索 | nDCG | 排序整体质量 |
| 上下文 | Context Precision | 放进上下文的内容是否相关 |
| 上下文 | Context Recall | 必要证据是否都在上下文里 |
| 生成 | Faithfulness | 答案是否忠于证据 |
| 生成 | Answer Correctness | 答案是否正确回答问题 |
| 生成 | Citation Accuracy | 引用是否准确 |
| 系统 | Latency | 端到端响应时间 |
| 系统 | Cost | 检索、rerank、生成整体成本 |
| 安全 | Permission Accuracy | 是否发生越权召回 |
可以看到,RAG 的评估不是一个分数,而是一组指标。不同问题要定位到不同层:
1 | 没召回到证据 -> 检索问题 |
幻觉治理:RAG 只能降低幻觉,不能消灭幻觉
RAG 能降低幻觉,但不能保证没有幻觉。原因很简单:
- 检索可能错;
- 检索可能漏;
- 文档本身可能过期;
- 多个文档可能冲突;
- 模型可能误读材料;
- 模型可能在证据不足时强行回答。
所以生产级 RAG 通常要加入回答约束:
1 | 如果资料不足,必须回答“不确定” |
更强的系统还会加入 Answer Verification,也就是答案验证:

答案验证可以做得很轻,也可以做得很重:
- 轻量方式:检查答案是否包含引用,引用文档是否在上下文里;
- 中等方式:把答案拆成多个 claim,逐条检查是否有证据支持;
- 重型方式:使用另一个 verifier 模型或规则系统,对答案做事实一致性校验。
这一步的目标不是让系统永远不犯错,而是让错误更容易被发现、被解释、被拦截。
常见问题与治理方式
RAG 系统常见问题可以按链路拆开看:
| 问题 | 表现 | 治理方向 |
|---|---|---|
| 文档解析差 | 表格、代码、标题丢失 | 优化解析器,保留结构 |
| Chunk 不合理 | 检索太碎或太粗 | 调整 chunk size、overlap、语义切分 |
| 召回失败 | 答案依据不存在 | Hybrid Search、Query Rewrite、多路召回 |
| 排序错误 | 正确证据排在后面 | Rerank、RRF、规则加权 |
| 上下文噪声多 | 模型忽略关键内容 | 去重、压缩、父章节扩展 |
| 引用不准确 | 答案和来源对不上 | 证据编号、claim-level citation |
| 知识过期 | 回答旧规则 | 版本管理、更新时间降权 |
| 权限泄露 | 召回无权限文档 | ACL filter、租户隔离、权限同步 |
| 成本过高 | 延迟高、token 多 | 缓存、压缩、分层检索、轻量 rerank |
| 幻觉 | 证据不足仍强答 | 拒答策略、答案验证、引用约束 |
未来演进:从检索插件到知识系统
早期 RAG 的形态很简单:
1 | 向量库检索 -> 拼接上下文 -> LLM 回答 |
但随着应用场景变复杂,RAG 正在从一个“检索插件”,演进成大模型系统中的知识访问层。它不再只是负责找几段文本,而是要连接文档、数据库、图谱、多模态资料、工具系统和长期记忆。

未来 RAG 主要会沿着四个方向演进,如下表所示:
| 演进方向 | 核心变化 | 解决的问题 | 典型场景 |
|---|---|---|---|
| GraphRAG | 从“检索文本片段”走向“检索实体关系” | 普通 RAG 不擅长全局结构、多跳关系和复杂关联推理 | 组织架构、企业知识网络、法律条款关系、论文引用网络、代码模块依赖、金融实体关系 |
| Agentic RAG | 从“单次检索”走向“模型主动规划多步检索” | 复杂问题一次检索不够,需要拆解问题、选择数据源、多次查找和验证证据 | 多文档调研、代码仓库分析、故障排查、法律/财务审阅、数据库问答、企业知识助手 |
| 多模态 RAG | 从“文本检索”走向“图片、表格、视频、代码等多模态信息检索” | 企业知识不只存在于文本中,还分布在 PPT、截图、设计稿、视频、日志和监控图表里 | 图片问答、表格分析、会议内容检索、设计稿理解、日志分析、代码知识库 |
| RAG + 长上下文 | 从“找少量片段”走向“检索后阅读更多资料” | RAG 负责找资料,长上下文负责读资料,两者结合提升复杂资料理解能力 | 长文档问答、合同审阅、代码仓库分析、研究报告分析、Agent 长程任务 |
总结
RAG 的本质,不是给大模型接一个向量数据库,而是构建一套外部知识访问系统。它要解决的问题包括:
- 如何把文档解析成高质量知识单元;
- 如何切分、标注、embedding 和索引;
- 如何通过 sparse、dense、hybrid search 找到证据;
- 如何通过 query rewrite、rerank、多路召回提升检索质量;
- 如何组装上下文,让模型基于证据回答;
- 如何处理权限、版本、更新、引用和评估;
- 如何在复杂任务中走向 GraphRAG、Agentic RAG 和多模态 RAG。
一句话概括:RAG 让大模型不再只依赖参数里的静态知识,而是能够在回答问题时连接外部知识、引用真实证据,并把企业知识、实时信息和复杂资料纳入推理过程。
这也是大模型从“通用聊天模型”走向“企业知识系统”和“智能工作流”的关键一步。
