检索增强生成 RAG
Retrieval-Augmented Generation 是当下最实用的"让 LLM 用上私有知识"的工程范式。它不是一个模型,而是一条流水线:先检索,再让模型基于检索结果回答。
为什么需要 RAG
LLM 的知识来自预训练,这意味着两个硬限制:知识有截止日期、私有数据它根本没见过。微调可以注入新知识,但成本高、迭代慢、容易引入新的幻觉。
RAG 把"知识"从模型权重里搬出来,放在外部知识库里,每次回答前临时取出最相关的几段,作为上下文一起喂给模型。知识可以热更新,模型不用动。
一条最小可用流水线
原始文档 ──► 清洗 / 切块 ──► 计算向量 ──► 写入向量库
(离线)
用户提问 ──► 计算向量 ──► 向量检索 + 关键词检索 ──► 重排 ──► 拼提示 ──► LLM ──► 答案
(在线)
关键环节与常见坑
1. 切块(Chunking)
- 过长:一段里夹杂多个主题,向量被"平均",相关度下降。
- 过短:上下文不完整,模型回答时缺背景。
- 建议:以语义边界(段落、标题、列表项)为主,配合 200–800 token 的目标长度,并保留少量 overlap。
2. Embedding 模型
选 Embedding 模型时关注三件事:语种覆盖、向量维度、是否对称(query/passage 是否用同一个模型)。中文场景务必测试中文实际效果,不要只看英文榜单。
3. 向量库与检索
- 千万级以下:PostgreSQL + pgvector、SQLite + sqlite-vec 已经够用。
- 更大规模:Milvus、Qdrant、Weaviate、Vespa 各有取舍。
- 不要只用向量检索:与 BM25 等关键词检索做混合检索,对专有名词和长尾 query 帮助显著。
4. 重排(Re-ranking)
第一阶段召回往往返回 50–100 段候选,让一个交叉编码器(cross-encoder)重排,取 top-K 喂给生成模型。这一步常常比换更大的生成模型更划算。
5. 提示拼装
- 明确告诉模型"只能依据下方资料回答,资料中没有的请直说不知道"。
- 给每段引用编号,让模型在回答中标注来源(可选但强烈推荐)。
- 注意上下文窗口预算:检索内容 + 系统提示 + 历史对话 + 输出预留,必须留出冗余。
RAG 不是银弹
如果检索召回的资料是错的,LLM 会非常自信地把错误答案"包装"成正确答案的样子。
- 评测优先:先准备一份带标准答案的问答集,每次改动都跑一次。
- 失败可见:把召回的段落、得分、最终拼装的 prompt 都记下来,出了问题才有的查。
- 边界处理:明确"不在知识库范围"的 query 该如何拒答或转人工。
下一步
如果让模型不只是"看资料回答",还能主动去调用工具、规划步骤、调用其他模型,就进入了 AI 智能体 的世界。