RAG 从理论到实战
检索增强生成的完整链路:切块、向量化、混合检索、RRF 融合、重排、引用溯源、Agentic RAG 与向量库选型。
RAG 从理论到实战
RAG(Retrieval-Augmented Generation,检索增强生成):把外部知识检索出来,喂给 LLM 生成,从而降低幻觉、接入私有数据。核心是「查得到 → 读得懂 → 敢信它」的证据链闭环。
核心链路
graph LR
A[文档] --> B[解析]
B --> C[结构感知切块]
C --> D[向量化 Embedding]
D --> E[向量库]
Q[用户 Query] --> QE[Query 向量化]
QE --> R[混合检索]
E --> R
R --> RR[RRF 融合]
RR --> RK[Rerank 精排]
RK --> G[LLM 生成]
G --> CITE[引用校验]
链路八步:解析 → 清洗 → 分块 → 向量化/存储 → 检索 → 重排 → 注入 prompt → 生成 + 引用溯源。
一、结构感知切块(Chunking)
切分依据:语义边界优先(段落/标题/代码块),固定字符数是兜底。
- 标题路径和段落边界进入 chunk 元数据,超长段落保持完整,不硬切段落。
- chunk 大小:300-500 token 起调;FAQ 一条一块,长文按语义段。
- overlap:防信息在切片边界断裂,比例 10%-20%,语义连贯性要求高的场景加大。
⚠️ 别背「15% 最好」「1024 token 最佳」这类具体数字——它们来自特定实验条件。稳妥说法:「业界经验是 chunk 512-1024 token、overlap 10%-20%,具体按文档类型和评估集实测」。
父子索引
子 chunk 用于检索(粒度准),命中后把父 chunk(更大上下文块)喂给 LLM 生成——解决「检索到碎片但答不完整」。
增量更新
文档局部改 → 用版本号/内容哈希判断只重向量化变更块,软删除旧向量后台清理,不全量重建。
二、混合检索 + RRF 融合
为什么混合
- 向量检索抓语义,但漏精确词/专名(订单号、型号、人名)
- BM25 关键词检索精确匹配,但不懂同义改写
- 两路召回互补。项目落地:BM25 标题加权,中文 2-gram + 英文词
融合方式三选一
- RRF(Reciprocal Rank Fusion,按排名倒数求和,最常用、无参、稳)
- 加权分数融合(需调权/归一化)
- 级联(先向量粗召回再 BM25/规则精排)
RRF 公式(面试可能手写)
$$RRF(d) = \sum_{i \in \text{检索器集合}} \frac{1}{k + rank_i(d)}$$
rank_i(d):文档 d 在第 i 路检索结果中的名次(从 1 开始)k:平滑常数,业界常用 k = 60(出自 Cormack 等 2009 年 RRF 原论文)
为什么用 RRF 而不是加权求和:BM25 分数(无界,0几十)与余弦相似度(-11)量纲完全不同,直接加权要先归一化且要调权重;RRF 只看名次不看分数,天然免归一化、无需调参。k=60 的作用是压平头部差异,避免对单路检索第 1 名过度信任。
在哪一步赢:混合检索的提升发生在召回阶段(Recall 提升),不在精排阶段。如果 query 以语义表达为主、无专名,混合收益小——讲得出这个边界才显真懂。
三、Rerank 精排
向量相似度 ≠ 语义相关性。Rerank 解决的局限:
- 词汇不匹配(向量可能漏掉语义对但用词不同的片段)
- 粒度不匹配(chunk 大小不完美)
- 多跳推理(需组合多片段才能回答)
- 时效性(向量检索不感知时间)
成本视角:rerank 是 top-50 粗召回 → 精排到 top-5,成本与效果的 trade-off——先便宜向量召回,再用贵一点的交叉编码器(如 bge-reranker)精排,避免对全库精排。
Top-K 取值:粗召回 K=10-50,rerank 后压到 K=3-5 进生成。K 过大会信息过载、上下文浪费、答案漂移(引入矛盾信息)。
四、生成阶段防幻觉(Prompt 边界)
- 明确检索范围:「仅基于以下参考内容回答,不要使用参考内容之外的知识」
- 要求引用来源:「每个结论标注对应参考片段编号」
- 允许说不知道:「参考内容没有相关信息时,明确说明未找到」
- 给反例(幻觉回答 vs 正确拒答的示例)
- 结构化输出:先列证据再给结论
- 系统级兜底:输出后用工具/规则做事实校验、低 temperature
引用溯源闭环:生成强制 [来源N] 标记 → 程序校验越界引用 → 前端展示引用卡片可展开原文。检索→引用→校验形成证据链,才是 RAG 防幻觉的工程闭环。
五、RAG vs 微调
- RAG 改知识:可随时更新、可溯源、零成本换文档
- 微调 改行为/风格/格式:不改知识、成本高、慢、易灾难性遗忘、更新要重训
一句话:先 RAG,RAG 解决不了的行为问题(输出格式、领域语言习惯)才考虑微调,二者也常组合(微调格式 + RAG 事实)。
六、Agentic RAG / GraphRAG
- 朴素 RAG:一次检索→一次生成,查不到就答错
- Agentic RAG:检索本身 Agent 化——查不到改写 query 重查、把大问题拆子问题分别检索、多路交叉验证、判断「该检索还是该调工具还是该拒答」
- GraphRAG:把实体关系建成图,适合全局性问题(「这些文档讲了哪些主题/实体间什么关系」),普通局部问答用不上——图是成本,不是装饰
七、向量库选型
普通 B-tree 索引不适合高维相似度检索(维度灾难、无 ANN),所以需要专门的向量索引(HNSW/IVF)。
| 选型 | 定位 |
|---|---|
| Milvus | 工业级分布式,全 SDK/监控 |
| Chroma / FAISS | 单机 embedded,小项目/入门 |
| pgvector | PG 插件——数据量小直接少一套基础设施 |
| Qdrant / Weaviate / Pinecone | 中间档,Qdrant 单机/local 也常用 |
高分答法(挑战自己的选型):「我项目这个数据量 pgvector 完全够,不用单独起向量库」——面试官要的是工程判断不是背参数。
实战踩坑(项目真实)
- Qdrant point id 不能用 Python
hash():哈希随机化导致幂等失效,要改用hashlib - 解析降级链:MinerU 云 → markitdown → 纯文本,带 sha256 缓存
- rerank 失败静默回退:不影响主链路
- PDF 扫描件要 OCR、表格要结构化提取(转 markdown/HTML 保留结构)
一句话收尾:「RAG 落地效果由三段决定:检索质量(查得到)、注入格式(读得懂)、引用校验(敢信它)。」