第 1 章:为什么做 RAG?
能用一段零依赖代码演示 RAG 的核心机制,并讲清为什么解析、切分、检索与评估同样关键
📊 学习时长:30-40 分钟 🎯 完成后能力:能用一段零依赖代码演示 RAG 的核心机制,并讲清为什么解析、切分、检索与评估同样关键 🔗 关联面试题:5 道(覆盖 5 个不同角度,见 Part 3)
这一章你会学到什么
- ✓ 零基础也能跟着做:用 20 行不依赖任何库的代码,亲手演示一遍 RAG 的核心机制
- ✓ 看懂 3 个核心概念:什么是幻觉、什么是 RAG、什么是"上下文"
- ✓ 建立 RAG 的"两条链路"心智模型(这张图决定了本书后面 9 章的顺序)
- ✓ 学会判断:什么场景该上 RAG、什么场景上了也是白上
- ✓ 理解一个反直觉的事实:做 RAG,模型反而是最不用操心的部分
本章按三段式组织,不同基础的读者各取所需:
段落 给谁看 内容 占比 🚀 Part 1 · 主线实战 零基础,想先跑起来 概念白话 + 20 行迷你 RAG ~50% 🎯 Part 2 · 面试深度 想讲透、备战面试 三硬伤 + 两链路 + 选型 + 私货 ~40% 🏆 Part 3 · 验收串题 检验学到位没 关联面试题 + 自检清单 ~10%
🚀 Part 1 · 主线实战 | ~50% 这部分零基础也能跟着做。不用 API key、不用装库,20 行代码就能让你亲眼看到 RAG 到底改变了什么。
在开始之前
你需要:
- ✅ 装好 Python(3.9+)
- ✅ 能看懂基础 Python(字典、函数、for 循环)
- ✅ 就这些:本章的 demo 不需要联网、不需要 API key、不需要装任何库
先看一个教学场景(这是本章的"为什么")
下面是为了讲清问题而构造的教学场景,不是作者或学员的客户经历。假设要做一套保险资料问答系统,资料里既有产品条款 PDF,也有培训 PPT、内部制度 Word 和录播视频字幕。
如果第一版直接把"这款产品的现金价值怎么算"丢给通用大模型,模型可能给出一套读起来很专业、但在资料里找不到依据的公式。
这正是大模型最危险的地方之一:没有依据时,它仍可能生成流畅而笃定的答案。 在事实问答里,这样的输出必须被检索、引用和拒答机制约束。
这件事用一张图就能说清:直接问模型是"闭卷考试",上了 RAG 是"开卷考试"。
3 个核心概念(先白话,再术语)
概念 1:什么是"幻觉"?
幻觉(hallucination),就是模型不知道答案时,不说"我不知道",而是一本正经地编一个。
它不是故意撒谎,而是大模型的工作方式决定的,它本质是在"预测下一个最像样的词",所以哪怕没有依据,也能拼出一段读起来很专业的话。开篇那个编出来的现金价值公式,就是典型幻觉。
概念 2:什么是 RAG?
RAG(Retrieval-Augmented Generation,检索增强生成),拆开就三件事:
- 检索(Retrieval):拿用户的问题,去你的知识库里查出相关的几段资料;
- 增强(Augmented):把查到的资料,拼到问题前面一起交给模型,相当于给它"开了卷";
- 生成(Generation):模型照着这几段资料组织出答案,而不是凭脑子里的记忆硬答。
说白了:别让模型凭记忆答题,先去知识库里"查资料",把查到的真实内容塞进去,再让它照着资料回答。
一个比喻记一辈子:RAG 就是把模型从"闭卷考试"改成"开卷考试"。模型还是那个模型,但答题时手里多了一本随时能更新、且属于你自己的参考书。
概念 3:什么是"上下文(context)"?
上下文,就是你这一次塞给模型、让它参考的那段文字。
模型一次能读的上下文有长度上限(就像一口能吃的饭量),这个"量"用 **token(粗略 = 1 个汉字或 0.5 个英文单词)**来计。RAG 的关键动作,就是"检索出最相关的几段资料,拼进上下文",而不是把整个知识库一股脑塞进去。后面整本书很多功夫,都花在"怎么让塞进上下文的那几段,又准又全"。
🛠️ 跟着做:20 行代码,看懂 RAG 的核心机制
不用 API key,我们先用一个"迷你 RAG"把机制跑通。
Step 1:新建文件
新建 mini_rag_demo.py(完整文件见 code-snippets/mini_rag_demo.py):
# 一个极简"知识库":工程系统里会换成经过解析、切分和索引的文档块(第 3、4 章)
# 这里就用一个字典:键是"关键词",值是"对应的知识"
knowledge = {
"犹豫期": "本产品犹豫期为 15 天,自您签收合同的次日 0 时起算。",
"现金价值": "现金价值 = 累计已交保费 − 各项费用 − 风险保费,具体见合同附表。",
"等待期": "本产品等待期为 90 天,等待期内出险不予赔付。",
}
def retrieve(question):
"""检索:从知识库里找出和问题相关的那条资料。
最朴素的"检索":哪个关键词出现在问题里,就返回它对应的知识。
真实系统会换成"向量检索":把问题和知识都转成向量,按"意思相近"找(第 4 章)。
"""
for key, text in knowledge.items(): # 逐条看知识库里的每个关键词
if key in question: # 关键词出现在问题里 → 命中
return text
return None # 一圈下来都没命中 → 库里没这条知识
def answer(question):
"""回答:先检索,再决定"照着资料答"还是"没依据"。"""
context = retrieve(question) # ① 先去知识库检索
if context is None: # ② 没检索到 → 模型没依据,只能瞎猜
return "【没检索到资料】模型只能凭记忆瞎猜,这就是幻觉的温床"
# ③ 检索到了 → 把这条真实资料当"依据"交给模型(这里只演示,不真调 LLM)
return f"【检索到资料,照着答】依据:{context}"
# 三个问题:前两个库里有,第三个库里没有
for q in ["犹豫期是多少天?", "现金价值怎么算?", "高原反应保不保?"]:
print(q, "->", answer(q))
Step 2:运行
python mini_rag_demo.py
你的终端应该看到这三行:
犹豫期是多少天? -> 【检索到资料,照着答】依据:本产品犹豫期为 15 天……
现金价值怎么算? -> 【检索到资料,照着答】依据:现金价值 = 累计已交保费……
高原反应保不保? -> 【没检索到资料】模型只能凭记忆瞎猜,这就是幻觉的温床
如果看到的是别的:
- 报
SyntaxError/IndentationError→ Python 对缩进敏感,检查函数体是不是统一 4 空格缩进; - 中文显示成乱码 → 终端编码问题,不影响逻辑,换个支持 UTF-8 的终端即可。
🐛 跑不通?看这里
报错 IndentationError: unexpected indent
- 复制时缩进乱了:
knowledge、两个函数、for循环都要顶格,函数体内统一缩进 4 个空格。
报错 NameError: name 'answer' is not defined
- 三段(knowledge / 两个函数 / for 循环)要放在同一个文件里,顺序从上到下。
三行都打印"没检索到资料"
- 你的
knowledge字典的键(犹豫期/现金价值/等待期)没和问题里的词对上:检查有没有打错字。
Step 3:读懂这三行输出
- 前两个问题,知识库里有对应资料 → 被
retrieve找到 → 模型"照着答",这就是开卷; - 第三个问题"高原反应保不保",知识库里没有 → 检索为空 → 模型只能凭记忆编,这就是幻觉的来源(私域盲区)。
🎉 你刚跑通的,就是 RAG 最核心的一条流水线:检索 → 把资料塞进上下文 → 基于资料回答。真实系统只是把"关键词匹配"换成了更聪明的"向量检索"(把文字变成一串数字向量,靠"语义相近"而不是"字一样"来找),把"一条字典"换成了"几千份文档切成的块",但骨架就是这个。
🛠️ 动手实验:给知识库加一条,看结果怎么变
往 knowledge 字典里加一条"高原反应":
knowledge = {
"犹豫期": "本产品犹豫期为 15 天,自您签收合同的次日 0 时起算。",
"现金价值": "现金价值 = 累计已交保费 − 各项费用 − 风险保费,具体见合同附表。",
"等待期": "本产品等待期为 90 天,等待期内出险不予赔付。",
"高原反应": "本产品为意外险,高原反应属于高原疾病,不在意外伤害保障范围内。", # 新增这一条
}
再跑一次。观察:"高原反应保不保"这道题,从原来的"【没检索到资料】瞎猜",变成了"【检索到资料,照着答】"。
同一个程序、同一个问题,只因为知识库里多了一条,答案就从"瞎猜"变成"有据可答"。 这一步你亲手验证了 RAG 的铁律:答案质量的上限,由你知识库的质量决定。库里有且准,模型就能答对;库里没有,再强的模型也只能编。
这一节你掌握了什么?
- ✅ 幻觉是什么、为什么会发生
- ✅ RAG 是什么(检索→增强→生成,开卷考试)
- ✅ 跑通了一个零依赖的迷你 RAG,看懂了"检索→塞上下文→回答"
- ✅ 亲手验证了"知识库决定答案上限"
你刚才做的,等于真实系统的什么?
- 你那个
knowledge字典 = 工程系统里的知识库(通常会换成一批经过解析、切分并写入索引的文档块); - 你写的
retrieve= 真实系统的检索模块(把"关键词匹配"换成"向量检索 + BM25",第 4、5 章); - 你写的
answer里"把 context 当依据" = 真实系统的上下文拼接 + 生成(换成 Prompt 工程 + 真·大模型,第 9 章)。
换句话说:你这 20 行代码演示的是 RAG 的最小逻辑骨架;后面 9 章会逐步补上解析、切分、索引、评估和引用等工程环节。它不是生产系统,但能帮助你理解生产系统为什么需要这些模块。
下面 Part 2,我们把这条流水线展开成真实系统的样子,并回答一个关键问题:为什么这套系统里,大模型反而是最省心的部分?
🎯 Part 2 · 面试深度 | ~40% 这部分讲清三个硬伤、两条链路,以及一个反直觉但极其重要的认知。学完你能把"为什么做 RAG"讲到面试官点头。
2.1 大模型的三个硬伤
直接问大模型一个它没"复习"过的问题,会撞上三堵墙:
- 幻觉:不知道也照样流畅地编,语气还特别笃定(就是开篇那个现金价值公式);
- 知识时效:训练数据有截止日期,之后更新的条款、费率、产品它一律不知道;
- 私域盲区:你公司的保单、理赔指南、内部资料,它压根没见过(就是 Step 3 里"高原反应"那条)。
RAG 用"开卷"一次性补上这三个洞:检索回来的资料是实时的、私域的、有出处的。
2.2 RAG 的两条链路:离线建库 + 在线问答
把 Part 1 那条迷你流水线展开成真实系统,就是两条链路。理解这张图,你就理解了本书的章节为什么这么排:
- 离线建库:把各种格式的文档解析、切分,经 Embedding(把文字转成一串数字向量)转成向量,存进向量库。只跑一次或定期更新,用户感知不到。
- 在线问答:用户每次提问,把问题向量化、检索、重排,把最相关的几段拼成上下文交给模型生成。每次提问都要实时跑完。
- 两条链路靠向量库这一个交汇点连起来,这正是 Part 1 里
retrieve()那一步的"真实版"。
注意一个常被忽略的细节:连录播视频都要进知识库,先用语音识别(ASR)转成字幕文本再切段入库。RAG 的"知识"远不止 PDF。
2.3 一个反直觉的事实:模型是这套系统里最省心的部分
新人常以为做 RAG 的难点在"调模型"。把系统按完整链路拆开后会发现,大量工作都在"怎样把资料变成可检索的证据"上。继续沿用上面的保险教学场景,可以重点演练三类问题:
- 用户问"如何推销保险产品",检索却空了,因为文档里写的是"如何销售保险产品"。"推销"和"销售"是同义词,但关键词检索认死理,字不一样就是不匹配。
- 问"保单的现金价值怎么算",检索也找不准,因为通用向量模型没见过"现金价值""退保费"这类保险黑话,在向量空间里把它们放错了位置。
- 同一个问题问法五花八门:"报销制度是什么"是流程型问题(答案在规章制度里);"怎么提升业绩"是思考型问题(答案零散在培训材料里)。一套检索策略很难同时伺候好两类。
工程提示:Garbage in, garbage out。 RAG 的质量不只由模型决定,还取决于解析、切分、检索、重排和评估。不同项目的工时占比没有统一答案,正文不使用无法核验的固定百分比。你以为在学 RAG,其实也在学:怎么把一座杂乱的文档山,整理成模型能查到并引用的参考书。
2.4 什么场景该上 RAG?(以及什么时候别上)
金融保险几乎是 RAG 的天选场景,因为它同时满足四个条件:
- 错一个字都不行:答错条款可能引发理赔纠纷,模型必须基于真实条款回答;
- 必须可溯源:答案要能指回"依据是第 3 条第 2 款",用户和合规都要看出处,这正是 RAG 自带的能力;
- 知识频繁更新:产品、费率、条款一直变,微调跟不上,RAG 只需更新知识库;
- 私域文档为主:保单、理赔指南、内部资料,通用模型完全没见过。
反过来,如果你的需求是"写一首关于春天的诗":纯创作、无需事实依据、也不要求溯源,那 RAG 不仅帮不上忙,反而是多余负担。
顺带厘清 RAG 和它两个"邻居"的分工:
| 方案 | 解决什么 | 什么时候用 |
|---|---|---|
| RAG | 外部/私域/会变 + 要溯源的知识 | 知识会变、量大、要出处 |
| 微调 | 模型的风格/格式/领域语感 | 想改说话方式、固定输出格式 |
| 长上下文直接塞 | 一次性、少量文档 | 文档就三五篇,塞得下 |
业内行话:"我该不该上 RAG"其实常常是个伪问题,真问题是"我的知识库值不值得、能不能建好"。 三者也常叠着用:RAG 管"知识对不对",微调管"话说得顺不顺",比如一个保险客服:用 RAG 去查实时条款保证"答得对",再用微调统一话术口吻保证"答得像客服"。
2.5 一个必须戳破的误区:RAG ≠ 零幻觉
很多人以为"上了 RAG 模型就不会胡说了"。不对。 RAG 大幅降低幻觉,但不消灭它,它把幻觉的来源,从"模型瞎编"换成了"喂错了料"。
想想 Part 1 那个迷你 RAG:如果 retrieve 召回的是一条不相关甚至相反的资料(比如把"免责条款"当成"承保条款"召回了),模型照样会"照着错资料"答出一个错答案,而且因为"有依据"显得更可信。这正是第 3 章核辐射失败演练要说明的:检索给出残缺或错误证据,生成阶段会继续放大。
业内行话:面试聊到"RAG 怎么防幻觉",别只说"加了 RAG 就没幻觉了",那会暴露你没真做过。说到点子上的是两层:① 检索层:召回得准,这是根(本书 3–6 章都在干这个);② 生成层,在 Prompt 里硬约束"只依据给定资料作答、资料里没有就说不知道",再对输出做一遍校验(第 9 章)。两层都做,才是真正的"防幻觉"。
🏆 Part 3 · 验收串题 | ~10% 学到这一步,做几道题验证一下,知道自己学到位没。
关联面试题(5 道,覆盖 5 个角度)
- 【概念基础】 请解释 RAG 的基本概念与工作原理。
- 【业务价值/治幻觉】 RAG 如何提升大模型的事实准确性和知识覆盖?
- 【与替代方案对比】 系统比较 RAG 与传统"先检索后生成"流水线的差异。
- 【工程组件初探】 RAG 的技术原理、核心组件、工作流程及实际应用中的优势与挑战。
- 【数据漂移场景】 线上数据分布快速变化时,如何用外挂数据库结合大模型提升响应准确性?
学完这一章你应该能干嘛
- 能跑通那 20 行的迷你 RAG,并给知识库加一条让"瞎猜"变"有据可答"(Part 1)
- 能说清大模型的三个硬伤、RAG 分别怎么补,并用"开卷考试"讲给非技术的人听
- 能说清为什么不能只调模型,还要检查解析、切分、检索、重排和评估
- 能判断一个具体业务该不该上 RAG,以及为什么"RAG ≠ 零幻觉"
2 项以下 → 回去重做;3 项 → 再看一遍 Part 2;4 项全会 → 进入下一章。
完整代码 + 数据集
本书每章的完整可运行代码 + 测试样本,都在配套 GitHub 仓库:
🔗 github.com/MisterBooo/rag-from-zero
- 跟着教程 clone 下来就能跑
- 本章的零依赖迷你 RAG(
mini_rag_demo.py)也在里面- 欢迎 Star ⭐ / Issue 反馈
导航