RAG 入门系列 · 5集全
理解 RAG
从 LLM 的根本缺陷出发,5集走完 RAG 核心路径:原理 → 架构 → 检索优化 → 评估 → 生产化。每集 5–10 分钟,跟着真实代码输出学。
5 集 · 约 34 min
含真实输出
Why→What→How→What if
01
LLM 的两个缺陷,RAG 是什么解法
学完这集你能回答
RAG 解决了 LLM 的哪两个根本问题?用一句话解释什么是 RAG?什么情况下不需要用 RAG?
WHY · 为什么需要 RAG
[00:00]LLM 有两个根本缺陷
缺陷 1:知识截止日期
GPT-4o 训练截止 2024 年初。你问它"昨天 A 股发生了什么",它不知道——不是不聪明,是物理上没有这段记忆。
GPT-4o 训练截止 2024 年初。你问它"昨天 A 股发生了什么",它不知道——不是不聪明,是物理上没有这段记忆。
缺陷 2:私有数据盲区
你公司的内部报销规定、产品文档、合同模板,LLM 从没见过。问它"我们公司报销需要几天审批",它只能猜。
你公司的内部报销规定、产品文档、合同模板,LLM 从没见过。问它"我们公司报销需要几天审批",它只能猜。
具体场景:问"RAG 分块推荐用多大?"——LLM 会给一个模糊的通用答案("通常 256-512 tokens……"),因为它不知道你的知识库用的什么框架、存的什么内容。
WHAT · RAG 是什么
[01:30]一句话定义 + 一个类比
RAG = 每次回答前,先去检索相关资料,再基于资料回答。
全称 Retrieval-Augmented Generation(检索增强生成)。
全称 Retrieval-Augmented Generation(检索增强生成)。
类比:闭卷考试
纯 LLM = 闭卷考试。考生只能靠脑子里记住的知识作答。知识截止日期之后的事,以及你公司的私有信息,永远答不上来。
纯 LLM = 闭卷考试。考生只能靠脑子里记住的知识作答。知识截止日期之后的事,以及你公司的私有信息,永远答不上来。
类比:开卷考试
RAG = 开卷考试。考试时可以翻书。LLM 仍然负责"理解题意、组织语言、给出答案",但知识来自实时检索的文档。
RAG = 开卷考试。考试时可以翻书。LLM 仍然负责"理解题意、组织语言、给出答案",但知识来自实时检索的文档。
HOW · 真实输出对比
[02:45]跑一下 v1,看看差别
输出── 无 RAG ──────────────────────────────
Q: RAG 分块推荐用多大?
A: 通常建议 256-512 tokens,具体取决于您的使用场景。
对于长文档建议 512 tokens,短文档可以用 256 tokens。
(模糊通用答案,无来源)
── 有 RAG(v1 运行结果)───────────────────
Q: RAG 分块推荐用多大?
[检索] 命中文档片段:
"推荐200-500字符,overlap设置10%-20%以保持上下文连贯"
A: 根据知识库文档,推荐分块大小 200-500 字符,
overlap 设置 10%-20%。这样既保证检索精度,
又能保留句子间的上下文连贯性。
关键差别:有 RAG 的回答有来源、有具体数字、可以追溯。这是因为检索到了你自己写进知识库的文档片段。
WHAT IF · 什么时候不用 RAG
[04:00]三种不需要 RAG 的情况
| 情况 | 原因 | 更好的方案 |
|---|---|---|
| 知识量 < 50 页 | 直接塞进 context window 就够了 | Long-context LLM(Gemini 1M token) |
| 需要改变 LLM 行为 | RAG 只补充知识,不改变模型"性格" | Fine-tuning |
| 秒级实时数据 | 建索引本身有延迟,无法做到实时 | Tool Calling + 数据库直查 |
自测 RAG 解决了 LLM 的什么问题? 点击查看答案 ↓
RAG 解决了 LLM 的两个根本缺陷:知识截止日期(训练后的新信息 LLM 不知道)和私有数据盲区(企业内部文档、产品手册等 LLM 从未见过)。通过在每次推理时检索相关文档并注入 prompt,RAG 让 LLM 能基于最新的、特定的知识回答问题,而不是仅凭训练时的记忆猜测。
02
RAG 怎么运作,四层拆解
学完这集你能回答
RAG 的四层架构分别是什么?离线阶段做什么、在线阶段做什么?每层的核心决策点是什么?
WHY · 10 行够用,但不够好
[00:00]v1 能跑,为什么生产 RAG 需要更多设计?
v1 的 RAG 只有约 10 行核心代码就能工作。但生产环境中你会遇到:文档太长塞不进 context、相似问题找到不相关的内容、模型"脑补"了知识库里没有的答案。这就是为什么每一层都有必要被认真设计。
WHAT · 四层架构
[01:30]离线 + 在线,两阶段四层
离线阶段(一次性)
数据层
文档加载、清洗、分块(Chunking)
索引层
Embedding → 存入向量数据库
在线阶段(每次请求)
检索层
Query Embedding → ANN 搜索 → Top-K 文档
生成层
构造 Prompt + 调用 LLM → 最终回答
HOW · 逐层拆解,每层一个决策点
[03:00]四层各自解决什么问题
🗂 数据层:Chunking — 为什么不把整本书扔进去?
LLM 有 context 上限(即使 1M token 也贵);更重要的是检索精度问题——一大段文字的向量是"平均值",无法精确匹配用户的具体问题。分块让每个片段语义聚焦,检索命中率更高。
推荐:200-500 字符,overlap 10-20%
📐 索引层:Embedding — 文字怎么变成可搜索的数字?
Embedding 模型把文本映射到高维向量空间。语义相似 = 向量方向相似(余弦相似度高)。"分块大小"和"chunk size"的向量在空间里彼此靠近,即使一个中文一个英文。
🔍 检索层:Vector DB — 为什么不用 MySQL?
MySQL 全表扫描计算余弦相似度复杂度 O(n),百万文档时慢到不可用。向量数据库(ChromaDB、Pinecone、Weaviate)用 ANN(近似最近邻)索引,复杂度接近 O(log n),毫秒级返回 Top-K。
✍️ 生成层:为什么要约束"仅基于以下内容回答"?
不加约束,LLM 会混合知识库内容和训练时的记忆,悄悄"脑补"。加上
仅基于以下检索内容回答,如无相关信息请说"我不知道" 这行约束,可以大幅降低幻觉概率,让回答可以追溯到具体文档片段。
WHAT IF · 每层出问题的诊断信号
[06:30]回答不对,是哪一层的问题?
| 症状 | 根因层 | 诊断方向 |
|---|---|---|
| 回答内容是编造的(有文档但答错) | 生成层 | 检查 Prompt 约束是否够强;检索到的内容是否被完整传入 |
| 找到的内容不相关 | 检索层 | 检查 Embedding 模型;考虑混合检索;查看 Top-K 文档 |
| 分析表格、图片、代码失败 | 数据层 | PDF 解析器是否支持结构化提取;图片需要多模态处理 |
| 相关内容存在但没被检索到 | 索引层 | 检查 Chunking 策略;文档是否成功入库;Embedding 维度是否匹配 |
自测 用户问了一个问题,RAG 执行了哪几步? 点击查看答案 ↓
在线阶段执行两步:
1. 检索层:将用户问题 Embedding 成向量 → 在向量数据库中 ANN 搜索 → 返回 Top-K 最相关文档片段。
2. 生成层:将检索到的文档片段 + 用户问题拼接成 Prompt → 调用 LLM → 得到基于文档的回答。
离线阶段(数据层 + 索引层)在用户提问之前就已完成,是一次性的预处理工作。
1. 检索层:将用户问题 Embedding 成向量 → 在向量数据库中 ANN 搜索 → 返回 Top-K 最相关文档片段。
2. 生成层:将检索到的文档片段 + 用户问题拼接成 Prompt → 调用 LLM → 得到基于文档的回答。
离线阶段(数据层 + 索引层)在用户提问之前就已完成,是一次性的预处理工作。
03
检索为什么会失败,三个递进解法
学完这集你能回答
BM25 和向量检索各自的盲区是什么?混合检索如何互补?MRR 从 0.71 提升到 1.00 经历了哪些步骤?
WHY · 先看一个真实的失败案例
[00:00]纯向量检索的盲区
输出── v3.5 基线评估(纯向量检索)────────────────
Query: "RAG 中推荐的分块大小和 overlap 是多少?"
Top-1: "embedding 模型选型建议..." ← 排第1(错)
Top-2: "推荐200-500字符,overlap 10%-20%" ← 正确答案排第2
MRR@3: 0.50 (正确答案排第2,得分0.5,不是1.0)
原因分析: 问题包含"RAG"这个主题词,污染了向量方向
向量模型把"RAG"当成主要语义,而非背景信息
这个案例由 Andrej Karpathy 在演讲中展示过类似模式:越精确的词越容易被稀释。用户真正想问的是"分块大小",但"RAG"这个词的向量权重把检索方向拉偏了。
WHAT · 三种检索方式的盲区对比
[02:30]没有银弹,只有互补
| 检索方式 | 优势 | 盲区 |
|---|---|---|
| 稀疏检索(BM25) | 精确词匹配强;不受语义方向污染;无需 GPU | 不理解语义;"汽车"找不到"automobile" |
| 稠密检索(向量) | 理解语义和同义词;支持跨语言 | 精确词弱;长 query 语义被平均;主题词污染 |
| 混合检索(RRF) | 两路互补;精确 + 语义双保险 | 需要调权重;偶尔有平局问题 |
RRF(Reciprocal Rank Fusion):把两路检索的排名倒数相加。比如某文档在 BM25 排第2、向量检索排第1,则 RRF 得分 = 1/(60+2) + 1/(60+1) ≈ 0.0323。取所有文档 RRF 得分最高的 K 个。
HOW · MRR 数字演进,步步为营
[05:00]从 0.71 到 1.00 的四个版本
| 版本 | MRR@3 | 关键改动 | 解决的问题 |
|---|---|---|---|
v3.5 基线 |
0.71 | 人工标注 8 条 Query,纯向量检索 | — |
v5 混合检索 |
0.85 | 加入 BM25,RRF 融合两路结果 | 精确词被稀释的问题 |
v6 加权 RRF |
0.92 | w_bm25=1.5,解决排名平局 |
两路得分相同时的模糊排序 |
v6 + Reranking |
1.00 | Cross-encoder 精排 Top-K 结果 | 双路召回后的排序精度问题 |
Reranking 的原理:Cross-encoder 模型同时"看"Query 和文档,计算两者的相关性得分。比 Bi-encoder(向量)的近似相似度更精准,但更慢,所以只在 Top-K 上做精排,不做全量搜索。
WHAT IF · 检索好了但回答还是差?
[08:30]问题可能出在 Query 本身
MRR 提升到 1.00 之后,如果回答质量还是不够好,原因可能是:用户的 Query 本身不清晰、包含多个子问题、或者使用了知识库里没有的术语。这就需要 Query 变换——在检索之前先对问题进行改写、拆解或扩展。这是 v7 的核心内容,下一集介绍。
自测 BM25 和向量检索各自的盲区是什么? 点击查看答案 ↓
BM25(稀疏检索)的盲区:只做词频匹配,不理解语义。"汽车"和"automobile"、"分块"和"切割"对它来说是完全不同的词,无法召回语义相关但用词不同的文档。
向量检索(稠密检索)的盲区:精确词匹配弱。当 Query 中有强主题词(如"RAG")时,向量方向会被平均拉偏,导致包含精确答案但不那么"主题相关"的文档排名靠后。
混合检索的价值:两路互补——BM25 保住精确词命中,向量检索保住语义理解,RRF 融合后综合排序。
向量检索(稠密检索)的盲区:精确词匹配弱。当 Query 中有强主题词(如"RAG")时,向量方向会被平均拉偏,导致包含精确答案但不那么"主题相关"的文档排名靠后。
混合检索的价值:两路互补——BM25 保住精确词命中,向量检索保住语义理解,RRF 融合后综合排序。
04
怎么知道系统好不好,从 MRR 到 RAGAS
学完这集你能回答
MRR 和 RAGAS 各自衡量什么?RAGAS 四个指标分别代表什么?什么时候从 MRR 切换到 RAGAS?
WHY · "感觉变好了"不够
[00:00]7 个版本迭代完,系统到底在什么水平?
从 v1 到 v7,我们做了分块优化、混合检索、Reranking、Query 变换……每次修改后都感觉"好了一点"。但感觉不是指标。没有量化评估,你不知道:各项改进叠加后总效果如何?检索好了但生成还在出错吗?新功能是否引入了退步?
WHAT · 两种评估工具的分工
[01:30]MRR vs RAGAS,用哪个?
MRR(平均倒数排名)
评估:检索排名质量
成本:无 LLM 调用
速度:毫秒级
适用:早期迭代,频繁调整检索参数
只看"正确文档排第几",不管生成质量
评估:检索排名质量
成本:无 LLM 调用
速度:毫秒级
适用:早期迭代,频繁调整检索参数
只看"正确文档排第几",不管生成质量
RAGAS(4 维度评估框架)
评估:检索 + 生成全链路
成本:每条需调用 LLM 评判
速度:分钟级(取决于 Query 数量)
适用:阶段性全面评估,上线前验收
覆盖完整 RAG 链路,有 ground truth 更准
评估:检索 + 生成全链路
成本:每条需调用 LLM 评判
速度:分钟级(取决于 Query 数量)
适用:阶段性全面评估,上线前验收
覆盖完整 RAG 链路,有 ground truth 更准
HOW · RAGAS 四个指标,直观解释
[03:00]每个指标回答一个具体问题
Context Recall · 该找到的信息找到了多少?
把 ground truth 答案分解成若干信息点,检查每个信息点是否出现在检索到的文档里。衡量检索的覆盖率——重要信息有没有遗漏。
Context Precision · 找到的里有多少是有用的?
检索到的文档中,有多少比例真正被用于回答问题。衡量检索的精准率——有没有引入噪音文档把 LLM 搞糊涂。
Faithfulness · 回答有没有编造内容?
把生成的回答拆解成若干陈述,检查每个陈述是否可以从检索到的文档中推断出来。衡量生成层的幻觉率——是否基于文档作答。
Answer Relevancy · 回答有没有切题?
检查生成的回答是否真正回答了用户的问题(而不是答非所问或过于宽泛)。衡量回答的相关性——有没有废话、有没有跑题。
输出── v8 RAGAS 评估结果(8条标注Query)─────────
Context Recall: 0.87 ← 87% 的关键信息被检索到
Context Precision: 0.79 ← 79% 的检索内容有用
Faithfulness: 0.91 ← 91% 的回答陈述可追溯到文档
Answer Relevancy: 0.88 ← 88% 的回答切题
瓶颈:Context Precision 0.79,说明检索引入了
约 21% 的噪音文档,可进一步优化 Reranking
WHAT IF · 没有 ground truth 怎么办?
[05:00]合成 Query 的陷阱
没有人工标注的 ground truth 时,常见做法是用 LLM 从文档自动生成 Query-Answer 对。但要注意:合成 Query 评估出来的 RAGAS 指标会系统性虚高 10-30%。原因是合成的问题天然契合文档内容,和真实用户提问的分布完全不同。合成评估适合回归测试(防止退步),但不能替代真实用户标注。
自测 为什么不一直用 MRR,什么时候切换到 RAGAS? 点击查看答案 ↓
一直用 MRR 的问题:MRR 只评估检索排名,完全不看生成质量。即使检索 MRR = 1.0,LLM 还是可能基于检索到的文档产生幻觉、答非所问或遗漏关键信息。MRR 无法发现这些生成层的问题。
切换时机:早期迭代(频繁调整 Chunking、Embedding、检索参数)用 MRR——快、无成本。阶段性全面评估时(每隔几个版本、或上线前)切换到 RAGAS,用 4 个维度全面检查整个链路,找出瓶颈所在。
切换时机:早期迭代(频繁调整 Chunking、Embedding、检索参数)用 MRR——快、无成本。阶段性全面评估时(每隔几个版本、或上线前)切换到 RAGAS,用 4 个维度全面检查整个链路,找出瓶颈所在。
05
Demo 到生产,差了什么
学完这集你能回答
生产 RAG 系统有哪四个核心关注点?语义缓存和精确缓存有什么区别?数据秒级更新时 RAG 怎么办?
WHY · v1 能跑 ≠ 生产能用
[00:00]生产环境的四个真实挑战
v1 跑通了,但部署到生产环境会遇到:相同问题反复调 API 浪费钱、出问题不知道哪一步错了、A 部门看到 B 部门的文档、一篇文档更新要重建整个索引。这四个问题是从 Demo 到生产必须解决的工程关键。
WHAT · 四个生产关注点
[01:00]v10 企业级 RAG 的核心设计
语义缓存
相似问题命中缓存,不重复调 LLM API。"RAG 分块多大"和"RAG chunk size 推荐"语义相似,第二个问题直接返回缓存结果。
相似问题命中缓存,不重复调 LLM API。"RAG 分块多大"和"RAG chunk size 推荐"语义相似,第二个问题直接返回缓存结果。
请求追踪
每次请求打一个 trace ID,记录检索了哪些文档、生成了什么 Prompt、LLM 返回了什么。出问题时能定位到具体步骤。
每次请求打一个 trace ID,记录检索了哪些文档、生成了什么 Prompt、LLM 返回了什么。出问题时能定位到具体步骤。
多租户隔离
不同部门的文档打上 tenant_id 标签。检索时自动过滤,保证 A 部门只能看到 A 部门的内容。
不同部门的文档打上 tenant_id 标签。检索时自动过滤,保证 A 部门只能看到 A 部门的内容。
增量索引
文档更新时只重新 Embedding 修改的部分,不重建全量索引。大知识库尤其关键(全量重建可能需要数小时)。
文档更新时只重新 Embedding 修改的部分,不重建全量索引。大知识库尤其关键(全量重建可能需要数小时)。
HOW · 语义缓存效果对比
[03:00]v10 真实输出
输出── v10 语义缓存效果(生产压测)────────────────
请求 1: "RAG 的分块推荐用多大?"
状态: MISS (未命中缓存,完整执行检索+生成)
耗时: 624ms
→ 结果写入语义缓存
请求 2: "RAG 分块大小推荐是多少?"
状态: HIT (命中缓存,跳过检索和 LLM 调用)
耗时: 117ms 节省 81% 延迟
相似度阈值: 0.85(低于此值不命中,防止误匹配)
81% 的延迟节省在实际业务中意味着什么:高峰时段 80% 的问题是同类问题的变体(不同措辞问同一件事),语义缓存可以让这些请求不花一分 API 费用、不占用 LLM 资源。
WHAT IF · 数据秒级更新怎么办?
[04:15]RAG 的边界在哪里
RAG 的索引有延迟——即使是增量索引,也需要几秒到几分钟。对于股票价格、实时库存、当前系统状态这类秒级更新的数据,RAG 不适合。
正确方案:Tool Calling + 数据库直查。让 LLM 生成 SQL 或调用 API,实时查询数据库。这是 RAG 和 Agent 的边界——静态知识用 RAG,动态数据用 Tool。详见概念手册的"实时性"部分。
正确方案:Tool Calling + 数据库直查。让 LLM 生成 SQL 或调用 API,实时查询数据库。这是 RAG 和 Agent 的边界——静态知识用 RAG,动态数据用 Tool。详见概念手册的"实时性"部分。
自测 语义缓存和精确缓存(Redis key-value)的区别? 点击查看答案 ↓
精确缓存(Redis key-value):以完整的问题字符串为 key。"RAG 分块多大"和"RAG分块多大"(少个空格)是不同的 key,不会命中。只有一字不差才能命中。
语义缓存:先把问题 Embedding 成向量,在缓存向量库中搜索语义相似的历史问题。"RAG 分块推荐用多大"和"RAG chunk size 推荐是多少"虽然措辞完全不同,但向量相似度 > 阈值(如 0.85),可以命中同一条缓存。
适用场景:用户提问措辞多变时,语义缓存命中率远高于精确缓存,但需要多一次向量查询的开销。
语义缓存:先把问题 Embedding 成向量,在缓存向量库中搜索语义相似的历史问题。"RAG 分块推荐用多大"和"RAG chunk size 推荐是多少"虽然措辞完全不同,但向量相似度 > 阈值(如 0.85),可以命中同一条缓存。
适用场景:用户提问措辞多变时,语义缓存命中率远高于精确缓存,但需要多一次向量查询的开销。
系列完结
你已走完 RAG 核心路径
从两个缺陷出发 → 四层架构 → 检索优化 → 量化评估 → 生产化