RAG (检索增强生成)
Retrieval-Augmented Generation,让 AI 在生成回答前先从知识库检索相关信息,解决大模型知识过时和幻觉问题。
什么是 RAG
RAG(Retrieval-Augmented Generation,检索增强生成)是一种 AI 架构模式:在让大模型生成回答之前,先从外部知识库中检索相关信息,把检索到的内容作为上下文喂给模型。
简单说就是:先查资料,再回答。
解决什么问题
大模型有三个固有缺陷,RAG 可以缓解:
- 知识截止 — 模型训练数据有截止日期,不知道最新信息
- 幻觉 — 模型会一本正经地编造不存在的信息
- 领域知识不足 — 通用模型不了解企业内部文档、私有数据
RAG 通过引入外部知识库,让模型基于真实文档回答,大幅降低幻觉率。
工作流程
用户提问
↓
① 查询向量化 — 把问题转成向量
↓
② 向量检索 — 从知识库找最相关的文档片段
↓
③ 组装上下文 — 问题 + 检索到的文档片段 → 组合 prompt
↓
④ LLM 生成 — 大模型基于上下文生成回答
↓
⑤ 引用标注 — 标注回答来源(哪个文档的哪一段)
关键组件
向量数据库
存储文档的向量表示,支持相似度检索:
| 向量库 | 特点 | 适用场景 |
|---|---|---|
| Chroma | 轻量、Python 原生 | 原型开发 |
| Qdrant | Rust 高性能、支持过滤 | 生产环境 |
| Milvus | 分布式、大规模 | 企业级 |
| Pinecone | 托管 SaaS | 免运维 |
| pgvector | PostgreSQL 扩展 | 已有 PG 的项目 |
| SQLite-VSS / libsql | SQLite 扩展 | 轻量部署 |
Embedding 模型
把文本转成向量,详见 Embedding:
| 模型 | 维度 | 特点 |
|---|---|---|
| OpenAI text-embedding-3 | 1536/3072 | 通用、稳定 |
| BGE-large-zh | 1024 | 中文效果好 |
| Jina Embeddings v3 | 1024 | 多语言 |
| Cohere embed v4 | 1024 | 多语言+多模态 |
文档分块
把长文档切成小块(chunk)是 RAG 的关键步骤:
- 固定大小分块 — 每 500-1000 token 一块,简单粗暴
- 语义分块 — 按段落/章节自然边界切分
- 滑动窗口 — 相邻块有重叠(如 200 token),避免切断上下文
分块太短 → 检索准但上下文不足 分块太长 → 上下文全但检索精度低
RAG 进阶模式
朴素 RAG
基础流程:query → embed → search → stuff → generate。简单但不够精准。
高级 RAG
在基础流程上增加优化:
- 查询改写(Query Rewriting) — LLM 先把用户问题改写成更适合检索的形式
- 重排序(Reranking) — 向量检索后用 Cross-Encoder 重排序
- 多路召回(Hybrid Search) — 同时用向量检索 + BM25 关键词检索
- 上下文压缩 — 检索后先摘要再喂给 LLM
Late Chunking
传统做法:先切块再 embedding。问题是每个 chunk 失去全文上下文。
Late Chunking:先 embedding 整篇文档,在 token-level embedding 输出后再做 pooling 切块。每个 chunk 的向量保留了全文语境。Jina v3、BGE-M3 等模型支持。对长文档 / 需要跨段上下文的场景效果显著提升。
HyDE(Hypothetical Document Embeddings)
思路:用户的问题很短、检索时和长文档难匹配。先让 LLM 基于问题"假装回答"一段,用假回答去检索——假回答和真文档语义近,召回率显著提升。
用户问题 → LLM 生成假设答案 → embed 假答案 → 检索 → 真答案
代价:多一次 LLM 调用 + 多一次 embedding。适合检索难命中的专业场景。
Multi-Query Expansion
让 LLM 把一个问题展开成多个角度的子问题,并行检索后融合:
"我们的退货政策" →
├─ "退货流程"
├─ "退款时效"
└─ "哪些商品不支持退货"
→ 三路检索 → 合并去重 → 喂给 LLM
适合用户问题模糊、单次检索覆盖不全的情况。
模块化 RAG
把 RAG 拆成可替换的模块:检索、路由、融合、排序、生成。每一步都可以独立优化。
评估指标:怎么知道 RAG 做得好不好
不评估的 RAG 是黑盒。主流指标:
| 指标 | 衡量什么 | 怎么算 |
|---|---|---|
| Recall@K | 检索召回率 | top-K 检索结果中有多少真包含答案 |
| MRR(Mean Reciprocal Rank) | 第一个相关结果排第几 | 1/rank 的平均值 |
| Faithfulness | 答案是否忠于检索内容 | LLM-as-judge 逐句核对 |
| Answer Relevance | 答案是否回应了问题 | LLM-as-judge 打分 |
| Context Precision | 检索内容有多大比例真用上了 | 看 LLM 生成里引用了哪些 |
主流工具:
- RAGAS — 开源 RAG 评测框架,前 4 个指标都有内置
- TruLens — RAG 三角评估(context relevance / groundedness / answer relevance)
- DeepEval — pytest 风格的 LLM 评测
经验:先打 100 条 golden case + 期望答案,跑 RAGAS 出基线。每次改 chunking / embed model / reranker 都跑一遍对比,别凭感觉。
Naive RAG 的常见失败案例
知道怎么坏才能改对:
- 问题用代词,检索丢上下文——「它的价格是多少?」「它」指什么?解决:检索前用 LLM 改写带历史的查询。
- 关键词命中但语义跑偏——搜「苹果」匹配到水果商品而不是苹果公司财报。解决:混合检索 BM25 + 向量。
- 检索到了但被中间遗忘——top-10 太长,关键文档被夹中段被忽略。解决:reranker 重排把最相关放首尾,参考 Context Engineering。
- 空召回硬答——知识库里压根没有,模型不老实拒答反而幻觉。解决:检索分数低于阈值直接回退到"未找到相关资料"。
- 多文档冲突——A 文档说 X,B 文档说 not X,模型选一个自圆其说。解决:让 LLM 显式标注冲突 + 让用户决策。
- 更新延迟——文档更新了但索引没重建。解决:建立增量索引 pipeline + 版本号校验。
生产 RAG 的监控清单
上线后要持续盯的信号:
- 检索分数分布——突然下移说明 query 模式变了
- 空召回率——多少请求没拿到 top-K 任何文档
- 延迟分布——embedding / 向量检索 / rerank / LLM 各阶段 p50/p95/p99
- 答案长度异常——突然变短可能是模型在拒答,变长可能是幻觉扩写
- 用户反馈 👍/👎 ——把负反馈样本回流到评测集
- token 成本——RAG 把 prompt 撑长,成本容易失控,详见 Token
在哪些工具中用到 RAG
- Dify — 内置 RAG 流程,上传文档自动建索引
- FastGPT — 知识库为核心,RAG 优先设计
- Coze — 知识库功能,支持自动分块
- LangChain / LlamaIndex — RAG 开发框架
- 各种客服 Bot / 企业知识助手 — RAG 是标准架构
RAG vs Fine-tuning
| 维度 | RAG | Fine-tuning |
|---|---|---|
| 知识更新 | 实时(更新文档即可) | 需重新训练 |
| 计算成本 | 低(只需检索+推理) | 高(需要 GPU 训练) |
| 可解释性 | 高(能标注来源) | 低(黑盒) |
| 适用场景 | 事实性问答、知识检索 | 调整模型风格/格式 |
| 幻觉控制 | 好(有出处) | 一般 |
建议:大多数企业知识问答场景用 RAG,不要 fine-tune。详细对比见 Fine-tuning vs RAG。
延伸阅读
- 底层基础:Embedding
- 上下文组装:Context Engineering
- 幻觉缓解:Hallucination
- 与微调对比:Fine-tuning vs RAG