Skip to content

RAG 知识库 · 知识点

RAG(Retrieval-Augmented Generation)= 先检索再生成:把和问题相关的证据放进上下文,再让模型作答。模型负责理解和组织,知识库负责提供可更新、可引用、带权限的事实。


0. 总图

text
离线(索引)
  文档 → 解析清洗 → 切片(chunk) → Embedding → 向量库 + 元数据
                                              ↘ 可选:倒排/BM25、图谱

在线(查询)
  用户问题 → 权限过滤范围 → 查询改写
           → 检索(向量 / 关键词 / 混合) → 精排(rerank) → 组装上下文
           → 生成(必须引用 / 无证据则拒答)→ 返回答案 + 来源

一次问答里,RAG 真正做的是给生成模型补上 它参数里没有、或不该写死在权重里的证据

效果差时,先分清坏在哪一层:

坏了会怎样先查什么
解析/切片表被拆碎、标题和正文分离chunk 原文是否还像人话
召回答案不在 top-k 里Recall@k、黄金问题能否命中
精排命中了但排在后面被截掉rerank 前后顺序
组装证据在,模型没看见/看错顺序、长度、Lost in the Middle
生成看见了仍编造或拒答不当提示词、温度、引用约束

重点 1. 为什么用 RAG(和相邻方案的边界)

手段解决什么不适合
塞进 System Prompt极少、几乎不变的硬规则会更新的知识、大量文档
长窗口全文单份不太长的材料全集、权限隔离、成本
RAG私有知识、常更新、要引用实时计算、下单、精确数值运算
微调稳定口径、格式、风格当知识库用(易过期、难引用、难权限)
工具/API库存、订单、精确查询非结构化长文档的语义问答

怎么选:

  • 知识会变、要出处 → RAG
  • 要算、要查库表、要执行 → 工具
  • 只是口吻/JSON 格式不稳 → 先改 prompt
  • 样本极多、输入分布固定、要极稳分类 → 才考虑微调

Naive RAG 只做「切一刀 + 向量 top-k + 塞进 prompt」。上线系统通常还要:混合检索、元数据过滤、精排、引用、评测、增量更新


2. 离线:解析与切片

2.1 解析

先保证「进切片器的文本是干净、有结构的」,否则后面全是垃圾。

  • PDF:注意双栏、页眉页脚、页码、扫描件(要 OCR)。文本层用 PyPDF 一类库即可;双栏、公式、扫描件再上 MinerU(OpenDataLab):版面检测 + OCR,抽出带结构的 Markdown / JSON。
  • HTML:去导航/广告,保留标题层级
  • Markdown / 语雀 / Confluence:尽量保住标题树
  • 表格:不要按字数拦腰切;能转 Markdown 表或「一行一个事实」
  • 代码/API:按函数/章节切,保留签名
  • 图片/架构图:需要的话走多模态或先出 caption,再索引 caption

元数据建议一开始就带上:doc_idtitlesectionsource_urlupdated_atacl(权限)、type(faq/手册/changelog)。

重点 2.2 切片(Chunking)—— RAG 里最常见的设计题

目标:每个 chunk 语义完整、长度适中、能被独立理解(必要时带上标题路径)。

策略做法适用
固定长度按 token/字数切,带 overlap实现简单,结构弱的纯文本
递归/结构切按标题 → 段 → 句,超长再切手册、Markdown,优先用
语义切按embedding 相似度找边界结构乱的长文,成本更高
父子切片(small-to-big)小块检索,大块(父文档)送给模型检索要准、生成要上下文
句子窗口检索中心句,扩展前后句精确问答
按文档类型分策略FAQ 一条一块;法规按条;代码按函数生产里几乎必做

经验范围(不是标准答案,要能说出「看文档类型调」):

  • 通用说明:约 300–800 token,overlap 10%–20%
  • FAQ:一问一 chunk,不要把两个问题粘在一起
  • overlap 用来避免「答案正好跨边界」;过大则重复、噪声、费用升

切片原则:

  1. 不拆表格、代码块、列表中的一条完整规则
  2. chunk 内带 标题路径(如 安装 / Linux / 依赖),否则检索到一段「再执行上面的命令」会失忆
  3. 一块只表达一个主题,便于精排和引用
  4. 切完抽查:拿 10 个真实问题,看答案是否完整落在某个/某几个 chunk 里

重点 2.3 索引更新与过期数据

  • 文档变更:按 doc_id 删旧 chunk 再写入,避免重复召回两版政策
  • 删除:向量库要真删或 tombstone,不能只删对象存储
  • 版本:chunk 带 rev / updated_at,生成时可提示「以最新为准」
  • 增量:只重嵌变更文件;embedding 模型升级则要 全量重嵌

3. Embedding 与检索

3.1 向量检索在算什么

把 query 和 chunk 打到同一向量空间,用近似最近邻(ANN)找近邻。

  • 常用相似度:cosine(方向);很多模型向量已归一化,此时内积 ≈ cosine
  • ANN 索引:HNSW(召回高、吃内存)、IVF(可扩展)—— 应用岗能说到「近似检索,有召回/延迟折中」即可
  • 维度、模型要 query 和文档同一套 embedding 模型(或官方成对的双塔)

选型要点:

  • 中文/领域词:用在目标语言上表现好的模型,不要只看英文 MTEB
  • 长度:超长 chunk 被模型截断等于白切
  • 指令型 embedding:有的模型 query 要加指令。BGE-M3 通常免指令;Qwen3-Embedding 查询侧要加 Instruct 才发挥。图文同一空间用 CLIP 一类,才能以文搜图。
  • embedding 只改模型、不重嵌旧库 = 空间不一致,检索会 silently 变差

3.2 稀疏检索(关键词)

BM25 / Elastic 倒排:对 专有名词、报错码、API 名、货号 往往比纯向量稳。

向量强在语义(「怎么开票」≈「发票如何申请」),弱在精确字符。

重点 3.3 混合检索

常见做法:向量 top-n + BM25 top-n → RRF(倒数排名融合) 或加权分数 → 再交给 rerank。

RRF 直觉:score += 1 / (k + rank),不依赖分数量纲,适合融合两路。

生产默认可以记:中文知识库优先混合检索,纯向量当 demo。

3.4 过滤与多样性

  • 元数据过滤:时间、产品线、文档类型;权限必须在检索前过滤(见第 7 节)
  • MMR:在相关和多样之间折中,减少 top-k 全是同一段的改写
  • top-k:不是越大越好。k 太大噪声挤掉有效证据,也更贵、更 Lost in the Middle。先定 token 预算再反推 k

4. 查询侧(往往比换向量模型更有效)

用户原话经常不适合直接 embedding:指代、过短、口语、多意图。

技术做什么注意
对话改写「那个参数呢」→ 补全成独立问题改写错误会整段检索跑偏
多路 query生成 2–4 个改写分别检索再融合延迟和费用上升
HyDE先让模型写一篇假想答案再 embedding领域外会一本正经地检索到错文档
路由先判断走 FAQ / 手册 / API / 工具可用小分类器或规则
查询扩展加同义词、产品全称可能引入噪声

多轮 RAG:检索用的应该是 改写后的独立问题,但生成仍可带近几轮对话,避免答非所问。


重点 5. 精排(Rerank)

双塔 embedding 快但不精确(query 和 doc 没做过 token 级交互)。精排用 交叉编码器 或小 LLM,对 (query, chunk) 打分后重排,再截断到最终 m 段(m 常小于检索 k)。

何时上:

  • 召回尚可但 top-5 常被相近噪声挤掉
  • 延迟预算允许(通常多几十到一两百 ms)
  • 最终进模型的段数必须很少(例如 4–8)

何时不必上:语料极小、纯 FAQ 精确匹配已经够。

精排不能拯救「答案根本不在召回集合里」——那是切片/混合检索/改写的问题。


6. 组装与生成

01-Prompt与上下文工程 衔接,这里只记 RAG 特有约束:

  1. 少而准:rerank 后 4–8 段往往好过 20 段原文
  2. 每段带来源[doc_id, section, url],要求模型输出 citations[]
  3. 无证据则拒答:禁止「根据常识补充」
  4. 顺序:相关段不要埋在中间;当前问题放最后
  5. 冲突:多文档口径不一致时,规定优先级(时间新 > 官方手册 > 论坛),并让模型指出冲突
  6. 压缩:超长证据可抽句或摘要,但数字、条款号、否定句必须保留

生成侧幻觉的两种来源要分开说:

  • 检索幻觉:上下文里没有,模型编的
  • 归因幻觉:上下文有,但引用标错段 / 张冠李戴

重点 7. 权限过滤与多租户安全

  • ACL:先按用户身份过滤可见 doc_id,再检索。检索后再让模型「不要提机密」无效
  • 间接注入:网页/PDF 里写「忽略以上指令」。对策:文档当数据、工具权限服务端把关、高风险操作二次确认
  • 租户隔离:向量库按 tenant 分 collection 或强制 metadata filter,防跨租户近邻
  • 过期知识:changelog 与正文一起索引;生成时带 updated_at;政策类只检索指定空间

8. 进阶形态(能讲清场景即可)

形态要点适用
父子/层级索引小块召回,大块生成技术文档
多跳 RAG第一跳结果改写第二跳 query「A 的依赖版本和 B 是否兼容」
Agentic RAG检索变成工具,模型决定要不要再搜问题是否需要检索不确定、或要多步
GraphRAG实体关系图 + 社区摘要全局问题(「这批文档的主题是什么」),索引贵
LLM Wiki按页面/目录/双向链接组织,不先切碎手册型知识;和 GraphRAG 不同,偏文档结构
CRAG / 带校验的 RAG检索质量低则重搜或走网搜开放域
问答对索引文档预生成 FAQ 再检索高频、口径固定的客服

Agentic RAG 与「每次必检索」的差别:前者把检索当工具,可能 0 次或 N 次;要设最大步数和空结果退出。细节见 03-Agent与工具调用


重点 9. 评测与迭代(没有评测集就无法迭代)

把指标拆成检索和生成,不要只用「感觉答得好」

检索

  • Recall@k / Hit Rate:标准答案所在 chunk 是否出现在 top-k
  • MRR / nDCG:排得是否靠前
  • 没有标注时:至少做「黄金 50 问」人工看是否命中

生成

  • 忠实度(Faithfulness):论断能否在证据中找到
  • 答案相关性:有没有回答问题本身
  • 引用正确率:citation 是否指向真正用到的段
  • 拒答是否得当:该说不知道的时候有没有硬编

工程上:

  • 离线:固定语料快照 + 黄金问答,改切片/模型/k 都能回归
  • 在线:用户点踩、无引用率、空检索率、延迟、token
  • 改任何一环(切片、embedding、prompt)都要跑同一套集,否则无法归因

常见工具思路(不必绑死品牌):RAGAS 一类自动指标 + 人工抽检。自动指标有偏差,最终仍要黄金集。


10. 延迟与成本

链路耗时大致:改写(LLM)+ embedding + 向量检索 + 可选 BM25 + rerank + 生成。

优化方向:

  • 能规则路由就不要每次多路 query
  • 向量检索 k 可以稍大,精排后截小再生成(生成才是大头)
  • 高频问缓存:query 规范化后缓存答案(注意权限和文档版本作 cache key)
  • Prompt cache:稳定的系统提示和工具定义放前缀
  • 小文档集合可先关键词命中 FAQ,命中则跳过向量

11. 故障对照表

现象更可能的原因先试
完全答不上,上下文里也没有切片切破、没解析出、召回失败看该答案落在哪个 chunk;混合检索;改写
上下文有,仍然答错段太多/顺序差、prompt 未强制引用减 k、rerank、问题放最后、强制 citation
专有名词/报错码总 miss纯向量弱上 BM25 混合
总引用过期政策旧 chunk 没删、没按时间过滤按 doc 重建;metadata 时间
偶尔泄露他人文档ACL 在生成侧做的检索前过滤 + 分库
表格/数字错表被切碎或只嵌了文字描述按表切;重要数走工具查询
改 embedding 后整体变差旧向量未重算全量重嵌

12. 可复述的默认设计(当作自己的基线)

  1. 按标题结构切,FAQ 单独一条一块,chunk 带标题路径和 doc_id/acl/updated_at
  2. 混合检索(向量 + BM25)→ RRF → cross-encoder 精排 → 送 4–8 段
  3. 多轮先 query 改写再检索
  4. 生成:低温度、必须引用、无证据拒答、文档冲突按时间优先
  5. 权限在 filter 里做掉;更新文档按 id 先删后写
  6. 黄金 50 问看 Recall@k 和忠实度,再改切片或模型

13. 建议复习顺序

  1. 总链路:切 → 嵌 → 召回 → 精排 → 生成 → 引用
  2. 切片与 overlap、父子切片
  3. 向量 vs BM25 vs 混合、RRF
  4. query 改写、多轮
  5. 权限过滤、增量更新
  6. 评测:Recall@k vs 忠实度(分清检索坏还是生成坏)
  7. GraphRAG / Agentic RAG 的适用场景(点到为止)

配合:01 的窗口组装与拒答;03 的检索即工具;07 的注入与评测体系。自己的文档 RAG 能力映射见简历站的 ThingJS RAG 项目口述。


相关代码示例