RAG 与向量数据库
RAG 详解:检索增强生成从零讲起
进阶 25 分钟 适合: 初学者 / 开发者 / 研究者
本课要点
- ▸RAG 在提问时从你自己的文档中检索相关段落放进提示,让模型依据证据回答,而不是凭记忆。
- ▸流程分离线建索引(加载 → 切分 → 向量化 → 存储)和在线问答(检索 → 重排 → 带引用生成)两半。
- ▸瓶颈在检索:切分方式、关键词加向量的混合检索、重排,往往比换哪个大模型更重要。
- ▸检索和生成要分开评估:取回的段落对不对?回答是否忠实于这些段落?
RAG 要解决什么问题
大模型的知识在训练时就被冻结在权重里了(见 大模型是什么)。它不知道你公司的内部文档、昨天的价格、你桌上的合同;硬问它,它可能编一个听起来合理的答案。
**检索增强生成(RAG)**这个名字来自 Lewis 等(2020),思路很简单:先把资料查出来,再让模型根据查到的内容回答。 闭卷考试变成了开卷考试。
流程总览
flowchart LR
subgraph Indexing["离线:建索引"]
D["文档"] --> C["切分"] --> E["向量化"] --> V[("向量 + 关键词索引")]
end
subgraph Query["在线:回答"]
Q["用户问题"] --> QE["问题向量化"] --> R["检索 top-k(向量 + BM25)"]
V --> R
R --> RR["重排"] --> P["提示:问题 + 段落 + 规则"]
P --> L["大模型"] --> A["带引用的回答"]
end1. 加载与切分
从 PDF、网页、文档、工单里提取干净的文本,再切成几百个 token 的文本块,块与块之间常留一些重叠。块太大,相关性被稀释;块太小,丢了上下文。按标题和段落切,比每隔 N 个字符硬切效果好。
2. 向量化与建索引
向量模型把每个文本块变成一个向量,让意思相近的段落彼此靠近(见 Token 与 Embedding)。这类稠密检索器(Karpukhin 等,2020)在很多问答任务上胜过关键词搜索。向量存进支持快速近似最近邻搜索的索引,常用 HNSW 图(Malkov & Yashunin,2016),可以放在向量数据库、带向量扩展的 Postgres,或者直接放内存。来源、日期、权限等元数据要一起存。
3. 检索
提问时,把问题向量化,取出最相似的 top-k 个块。实践中混合检索效果最好:把向量相似度和经典的关键词打分(BM25)结合起来,因为向量不擅长精确的名称、编号和数字,关键词又抓不住换了说法的同义表达。还要加元数据过滤,包括权限控制:用户无权看的内容绝不能检索出来。
4. 重排
重排模型(交叉编码器)把问题和每个候选段落放在一起读,相关性打分比向量距离准得多,但更贵,所以只对前 20 到 100 个候选运行。Anthropic 报告,在向量化之前给每个块补上上下文,再结合 BM25,在他们的测试集上把检索失败率降低了 49%,加上重排后降低了 67%(Contextual Retrieval)。
5. 带引用生成
把问题、选出的段落(带编号)和明确的规则一起写进提示:只根据资料回答;标注段落编号;资料不够就说“不知道”。 最相关的段落放在开头或结尾,因为模型对长上下文中间部分的利用不够可靠(Liu 等,2023)。
RAG、微调与长上下文对比
| RAG | 微调 | 只靠长上下文 | |
|---|---|---|---|
| 最新、会变化的事实 | ✅ 更新索引即可 | ❌ 要重新训练 | ✅ 但每次都要重新发送 |
| 带权限的私有数据 | ✅ 按用户过滤 | ❌ 写死在权重里 | ⚠️ |
| 标注出处 | ✅ | ❌ | ⚠️ 可以做到 |
| 改变风格、格式 | ⚠️ | ✅ | ⚠️ |
| 每次提问成本 | 低 | 低 | 资料多时很高 |
怎样评估 RAG
两半分开测(常用指标见 Gao 等,2023 的综述):
- 检索:准备一批已知相关段落的测试问题,看正确段落进入 top-k 的比例(recall@k)。
- 生成:回答是否忠实于检索到的段落,是否真正回答了问题?RAGAS(Es 等,2023)等框架用大模型当裁判自动做这些检查,但要先用人工标注校验裁判本身。
多数失败都能追溯到检索环节,所以调提示词之前,先看看到底检索出了什么。
进阶形态
- Agentic RAG:由 agent 决定什么时候搜、搜什么,可能搜好几轮(见 AI Agent 工作原理);搜索变成它的一个工具(见 工具调用与 MCP)。
- GraphRAG:先构建知识图谱和社区摘要,用来回答关于整个语料的“全局”问题(Edge 等,2024)。
不写代码也能试
AnythingLLM、Cherry Studio 等桌面应用可以直接拖入文档,用本地或云端模型和文档对话,很快就能看到切分和检索是怎么工作的,也能看到它们会在哪里出错。深入阅读:向量数据库与相似度搜索、切分、混合检索与重排(编写中)。
算法卡片
| 算法 | 一句话 | 原始论文 |
|---|---|---|
| 检索增强生成 RAG | 先检索相关段落放进提示,再让模型依据证据生成 | Lewis 等,2020 |
| HyDE 假设文档检索 | 先让模型写一段“假想答案”,用它的向量去检索真实文档 | Gao 等,2022 |
| GraphRAG | 从语料抽取实体关系图和社区摘要,回答需要全局汇总的问题 | Edge 等,2024 |
| 大模型当评委 | 用强模型按评分标准打分,自动评估回答质量和忠实度 | Zheng 等,2023 |
必读论文
- Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks(2020)——RAG 这个名字和“检索器 + 生成器”联合训练的出处。arXiv:2005.11401
- Precise Zero-Shot Dense Retrieval without Relevance Labels(2022)——HyDE:没有标注数据时,用生成的假想文档改写查询。arXiv:2212.10496
- From Local to Global: A Graph RAG Approach to Query-Focused Summarization(2024)——GraphRAG:用知识图谱和社区摘要回答“整个语料讲了什么”。arXiv:2404.16130
动手项目(约 8 学时)
为一套产品文档(例如某个开源项目的官方文档)搭一个 RAG 问答:准备 30 个带标准答案和出处段落的测试问题;比较三种切分策略(固定长度、按标题、按语义)和两种检索方式(纯向量、关键词 + 向量混合),用 RAGAS 记录检索召回率、忠实度和答案相关性,写一页结论。可参考 LlamaIndex 文档 和 Microsoft GraphRAG 文档。
自测
1. RAG 的“忠实度”衡量什么?
回答里的每个说法是否都能在检索到的段落里找到依据;它不衡量答案是否正确,只衡量有没有“脱离资料”。
2. GraphRAG 擅长哪类问题?
需要综合整个语料的主题类、全局汇总类问题(如“这些报告反复提到哪些风险”),普通的按片段检索很难答好。
3. 切块太大或太小各有什么问题?
太大:一块里混进很多无关内容,检索不准、占用上下文;太小:单块缺少上下文,答案被切散到多块里。
4. HyDE 为什么能提高检索效果?
用户问题往往很短,与文档的写法差别大;先生成一段假想答案,它在措辞和向量空间里更接近真实文档,所以更容易检索到相关段落。
常见问题
该用 RAG 还是微调?
需要会变化的、私有的或者必须标注出处的事实时,用 RAG;想改变行为、格式或风格时,用微调。两者可以结合:微调过的模型照样可以用 RAG。
做 RAG 一定要向量数据库吗?
不一定。小规模资料放在内存里,或用带向量扩展的 SQLite、Postgres 就够了;当文本块达到数百万、需要大规模过滤或高并发时,专用向量数据库才更有优势。单用关键词检索(BM25)也是合格的检索器。
上下文窗口这么长了,还需要 RAG 吗?
长上下文有帮助,但把所有内容都塞进去又慢又贵,而且模型对长输入中间部分的信息利用得不够可靠。检索能让提示短小、便宜、聚焦,还能给出出处。
为什么我的 RAG 还是会胡说?
通常是因为检索漏掉了正确段落、文本块缺少上下文,或者提示里没有要求模型只依据资料回答、资料不足时明确说不知道。