从零理解 RAG:检索增强生成完整指南

从零理解 RAG:检索增强生成完整指南
Pei为什么需要 RAG?
大语言模型(LLM)虽然强大,但有三个致命问题:
- 知识有截止日期 — 训练数据是历史快照,不知道最新信息
- 无法访问私有数据 — 你公司的文档、个人笔记,它从没见过
- 会”幻觉” — 没见过的东西也能一本正经地编出来
RAG(Retrieval-Augmented Generation,检索增强生成)的解决方案很简单:先查资料,再回答问题。
1 | 没有 RAG: 你问"我们公司的报销流程是什么?" |
RAG 完整流程
RAG 不是单一步骤,而是一条完整的流水线,包含五个核心环节:
1 | 离线阶段(建索引): |
接下来逐一拆解。
1. 分块(Chunking)
大模型的上下文窗口有限(比如 GPT-3.5 只有 4K token),不能把整个文档塞进去。所以需要把长文档切成小块。
为什么要分块?
- 精确检索:块越小,检索越精准
- 不超限:每块控制在 200-500 字符
- 保持语义:每块要有完整的意思
常见分块策略
| 策略 | 原理 | 适用场景 |
|---|---|---|
| 固定长度 | 按字符数硬切 | 简单快速,学习用 |
| 递归分块 | 先段落→再句子→再字符 | 生产环境常用 |
| 语义分块 | 用 Embedding 检测语义断点 | 最智能但最慢 |
| 结构化分块 | 按 Markdown 标题、HTML 标签切 | 结构化文档 |
overlap(重叠)是什么?
相邻块之间重叠一部分文字,防止一句话被切断导致两头都不完整:
1 | 无 overlap: |
2. 向量化(Embedding)
把文本变成一串数字(向量),让计算机能算”两个文本有多像”。
原理
Embedding 模型把文本映射到高维空间。在这个空间中,语义相近的文本,向量距离也近。
1 | "猫是一种可爱的动物" → [0.12, 0.34, -0.56, ...](1536维) |
两种主流方案
TF-IDF(传统方案)
- 原理:词频 × 逆文档频率
- 优点:简单、快速、不需要 GPU
- 缺点:不理解语义(”猫”和”小猫”不认为是相似的)
Neural Embedding(神经网络方案)
- 原理:用深度学习模型编码语义
- 代表:OpenAI text-embedding-3-small、BGE、M3E
- 优点:理解语义,效果好
- 缺点:需要 API 或 GPU
TF-IDF 原理详解
TF-IDF = Term Frequency × Inverse Document Frequency
- TF(词频):一个词在当前文档中出现越多,越重要
- IDF(逆文档频率):一个词在所有文档中都出现(如”的”、”是”),就不那么重要;只在少数文档中出现,说明有区分度
1 | 文档1: "Spring Boot 快速开发" |
余弦相似度
计算两个向量有多”像”的常用方法:
$$\cos(A, B) = \frac{A \cdot B}{|A| \times |B|}$$
- 值为 1 → 完全相同方向(最相似)
- 值为 0 → 正交(无关)
- 值为 -1 → 完全相反
归一化后,余弦相似度 = 向量点积,计算更快。
3. 召回(Retrieval / Recall)
从所有文档块中快速筛选出可能相关的候选集。
类比
你是警察,要从 100 万人里找嫌疑人:
1 | 第一步「召回」: |
在 RAG 中
1 | 用户问:"怎么配数据库?" |
关键指标
召回率 = 找到的相关文档 / 所有相关文档
- 知识库里有 10 篇相关文档,你召回了 8 篇 → 召回率 80%
精确率 = 找到的相关文档 / 召回的所有文档
- 你召回了 20 篇,其中 8 篇是相关的 → 精确率 40%
两者通常矛盾:召回率高 → 可能混进不相关的;精确率高 → 可能漏掉相关的。所以需要两阶段策略。
4. 精排(Reranking)
对召回的候选用更精确的模型重新打分排序。
1 | 召回返回 50 个候选 |
为什么需要精排?
召回追求速度(毫秒级),用的是近似算法,结果不一定最准。精排追求准确性,用更重的模型(如 Cross-Encoder)对候选重新排序。
Cross-Encoder vs Bi-Encoder
| 维度 | Bi-Encoder(召回用) | Cross-Encoder(精排用) |
|---|---|---|
| 速度 | 快(毫秒级) | 慢(秒级) |
| 准确度 | 中等 | 高 |
| 用法 | 文本单独编码,算向量距离 | 两段文本一起输入,直接输出相关性分数 |
| 适用 | 召回(大规模筛选) | 精排(小规模精选) |
5. 生成(Generation)
把精排后的文档块 + 用户问题拼成 Prompt,发给大模型。
1 | === 参考资料 === |
Prompt Engineering 要点
- 明确告诉大模型”只根据参考资料回答”
- 如果资料中没有相关信息,要求诚实说”不知道”
- 控制上下文长度,太多会超 token 限制,太少信息不够
优化技巧
Hybrid Search(混合搜索)
关键词搜索 + 向量搜索融合,既不漏掉语义相关的,也不丢掉精确匹配的:
1 | 用户搜:"数据库连接超时怎么办" |
Query Rewriting(查询改写)
用 LLM 优化用户的问题,提高召回质量:
1 | 原始问题:"那个啥 就是数据库那个超时" |
Multi-query(多角度查询)
一个问题拆成多个角度去搜,提高覆盖率:
1 | "怎么配数据库?" |
HyDE(假设性文档嵌入)
先让 LLM 生成一个假设性答案,用答案去搜(因为答案的语义更接近目标文档):
1 | 问题:"Spring Boot 怎么配数据库?" |
评估指标
| 指标 | 含义 | 目标 |
|---|---|---|
| 召回率 | 相关文档里找到了多少 | 越高越好 |
| 精确率 | 找到的文档里有多少相关 | 越高越好 |
| F1 Score | 召回率和精确率的调和平均 | 综合评估 |
| Faithfulness | 回答是否忠实于检索资料 | 不胡编 |
| Answer Relevancy | 回答是否切题 | 越相关越好 |
生产环境选型
向量数据库
| 数据库 | 特点 |
|---|---|
| Milvus | 开源、性能强、国内用得多 |
| Chroma | 轻量、Python 友好、适合原型 |
| Pinecone | 全托管云服务、开箱即用 |
| Weaviate | 支持混合搜索 |
| pgvector | PostgreSQL 扩展、已有 PG 的直接用 |
Embedding 模型
| 模型 | 维度 | 特点 |
|---|---|---|
| text-embedding-3-small | 1536 | OpenAI,便宜够用 |
| text-embedding-3-large | 3072 | OpenAI,更精准 |
| BGE-large-zh | 1024 | 智源,中文优化 |
| M3E | 768 | 面壁智能,中文效果好 |
总结
1 | RAG = 分块 + 向量化 + 召回 + 精排 + 生成 |
RAG 不是什么高不可攀的技术,它就是给大模型装了个搜索引擎。理解了分块、向量化、召回、精排、生成这五个环节,你就掌握了 RAG 的全部核心。
本文配套 Spring Boot 实战项目见 GitHub,代码中有详细中文注释。






