跳到主要内容

一句话进去,一句话出来 — RAG 到底是哪两个动作

这一章讲三件事: 机器为什么答不了你的问题;把资料贴给它、它凭什么会理睬; 以及这套做法拆开之后是哪六站。 它在全书链条里的位置: 这是第一环,后面十一章全是这六站各自的展开 —— 第 02 章展开第一站,第 03 章展开第二站,以此类推。 不需要任何基础,遇到的生词都在当场解释。

1. 顶层全景

你问一句话


┌─── 提问时才跑的 ────────────────────────────────┐
│ ⑤ 去资料堆里搜一遍,挑出最像的几段 │
│ ⑥ 把搜到的原文 + 你的问题拼成一段话,交给机器 │
└─────────────────────────────────────────────────┘

│ 资料堆是事先备好的:

① 读进来 → ② 切成块 → ③ 每块变成一串数 → ④ 存起来

图说:①–④ 是离线做一次的备料,⑤⑥ 是每问一次就跑一次的现场动作。
这本书的十一章,就是这六个格子各自的展开。

一句话链条: 机器只认眼前的文字 → 那就把该看的资料塞进它眼前的文字里 → 可资料格式各异,先统一成同一种形状 → 太长塞不下,切块 → 切完的块要能按意思被找到, 所以变成一串数 → 存起来,查的时候取最近的几条 → 拼进提示 → 作答。

2. 先看现象:它答不了你的问题

你问它「我们公司上个季度的退货政策改了什么」,它会给你一段听起来很像那么回事的话 —— 而那段话是编的。

这不是它坏了。原因有两条,而且都是结构性的,不是「换个更大的就好」:

问题为什么换个大的也没用
事实会过期它肚子里的东西是「读书」那阵子固定下来的,读完就不再更新
你们家的文档它没见过那些东西根本不在公开的网上,再大的机器也读不到没有的东西

书对这件事的表述很干脆:这套做法存在的理由,就是给模型接上外部知识源1

那重新读一遍新材料行不行? 那等于把这台机器重新造一遍 —— 一次要烧掉的钱和时间,和你今天下午想让它知道一份新文档,完全不是一个量级。 而且明天又有新的。

这条路走不通,所以只剩另一条。

3. 它凭什么会理睬你贴给它的东西

这一节是整件事的地基,也是最容易被跳过的一步。 跳过它,后面所有东西看起来都像魔法。

先看一段真实输出

书里有个配方,把两句资料贴在问题前面交给机器,并且在提示里明写「不要只是重复词句, 要给出清晰的解释」2

结果它给出的答案是这样的:

贴给它的资料: It reduces hallucinations by grounding answers in retrieved documents
instead of relying only on the model's memory
Retrieval-Augmented Generation (RAG) is a technique that improves
AI responses by combining document retrieval with language generation

它的答案: Retrieval-Augmented Generation (RAG) is a technique that improves
AI responses by combining document retrieval with language generation.
It reduces hallucinations by grounding answers in retrieved documents
instead of relying only on the model's memory.

图说:两段话一字不差,只是换了个顺序。这是书里印出来的真实输出,不是我们编的。

它老实到暴露了机制。

机制:它一次只接一个词,而「眼前的文字」就是它的全部依据

这台机器做的事只有一件:看着眼前已有的这段文字,算出下一个词该是什么,写上去, 再从头看一遍,再算下一个。 循环几百次,就是你看到的那段回答。

它眼前的这一整段文字有个名字,叫上下文(英文 context): 指的就是这一次它能看到的全部文字 —— 你打的问题、贴进去的资料、之前说过的话,全在里面。

关键在于:它眼前的这段文字里,哪些是你打的、哪些是别人贴的,它分不出来,也不需要分。 所有内容都是同一份输入。

所以你写进去的资料,和它肚子里的知识是同等待遇 —— 都只是「眼前的文字」的一部分, 而且贴在眼皮底下的那份,离得更近、更具体、更容易被接下去。

结论:别动这台机器,动它眼前看到的东西。

判断(我们的,不是书里的): 上面这个例子严格说不是对照实验 —— 书从头到尾没有做过一次「不给资料」的对照组(同一个问题问两遍:一遍给资料、一遍不给, 两边并排比;没有这一步,就说不清好转是不是资料带来的),所以「贴了才答对」这件事, 书里没有直接证据。我们拿它当证据用的,是另一件事: 输出与输入逐字重合,说明模型确实在照抄眼前的文字往下写。 如果错,会错在: 如果那两句话本来就在模型肚子里(它们是关于 RAG 的通用表述, 完全可能),那么这次逐字重合也可能是巧合。判据是:换一段模型绝对没读过的文字 (比如你们公司内部的编号规则)再试一次 —— 这个实验书里没做,我们也没跑。

4. RAG 是两个动作,不是一种模型

现在可以给它下定义了。它是两个动作,一个都不能少:

  1. 检索 —— 拿用户的问题去你自己的资料堆里搜一遍,挑出最相关的几段;
  2. 增强生成 —— 把挑出来的原文,连同问题一起写成一段话,交给机器。

这套做法叫检索增强生成,英文 retrieval-augmented generation,缩写 RAG。 这三个字母你在任何一家的文档、界面、报错里都会撞见,说的就是这里这件事。

书自己的定义句是:它把大模型的能力和一套检索系统合起来, 以此提高回答的事实准确性、跟上下文的贴合度,以及质量3

有三个字最容易被略过:「原文」。

不是摘要,不是改写,不是「让另一个机器先总结一下」—— 是把找到的那几段字,原封不动地贴进去。 后面第 09 章你会看到:一旦在这中间插一道改写,证据当场就被改坏了。

交给机器的那段话叫「提示」

那段拼好的文字有个名字:提示(prompt)。它一般长这样:

You are an expert assistant. Use the context below to answer the question.

Context:
<这里贴搜回来的原文>

Question:
<这里贴用户的问题>

Answer:

图说:这就是书里第 1 章那个模板的骨架。所谓「RAG 系统」,
最朴素的版本就是一段这样的字符串拼接。

5. 拆开来是六站流水线

书把这条流水线切成六站,并且说明白了:这本书的十一章,就是这六站的展开4

① 加载 ─→ ② 切块 ─→ ③ 嵌入 ─→ ④ 入库 │ ⑤ 检索 ─→ ⑥ 生成
└────────── 离线备料,做一次 ─────────┘ └── 每问一次跑一次 ──┘

图说:这条竖线是全书最重要的一条分界。左边慢一点没关系,右边慢一秒用户就能感觉到。
干什么展开在哪一章
① 加载把各种格式的文件读成同一种东西第 02 章
② 切块把长文档切成一段一段第 03 章
③ 嵌入把每块变成一串数第 04 章
④ 入库把这些数存起来、建好排序结构第 05 章
⑤ 检索拿问题去取最像的前几条第 06、07 章
⑥ 生成拼进提示,交给机器作答第 08、09 章

为什么这条分界重要: 你以后调试一套 RAG,第一件事永远是判断问题出在左边还是右边。 答案不对,九成出在左边 —— 是资料没找对,不是机器不会答。

6. 流水线里流的不是字符串,是「一段正文 + 一小袋标签」

第一站读进来的东西,不是一个字符串,而是一个有两个格子的小盒子。书给它下过定义, 说它是流水线里流动的基本数据单位5:

Document
├─ page_content : 一段正文(就是字)
└─ metadata : 一小袋键值对
{'source': 'local_file', 'category': 'tutorial', 'author': 'Deepak'}

图说:这两个格子从第一站一路带到最后一站。上面那袋标签就是书里说的「元数据」。

元数据就是挂在这段正文上的标签:哪来的、谁写的、什么时候的、属于哪一类。 书给它的定位是两件事:用来过滤,以及用来追溯来源6

而它必须在第一站就挂上。 理由很硬:

  • 文件被读进来之后,「它原来在哪个文件的第几页」这个信息就没了 —— 除非你当时记下来;
  • 后面所有「只在 2024 年的文档里搜」「这句话是从哪份合同里来的」,全靠这袋标签。

漏挂了补不回来。 这是这本书里少数几条真正的工程忠告之一,可惜它只说了一句就过去了。

7. 主走查:一段 RAG 正文,六站走一遍

这一节是本章的主走查。上面每个机制,在下面都占一步。

书里有一段讲 RAG 是什么的英文正文,三个自然段。作者把它存成了三个文件 —— RAG.pdfRAG.txtRAG.docx —— 在第 1 章里反复用。

但有一件事必须先说清楚:书从没在同一份输入上把六站跑完一遍。 下面这条线是我们接起来的,每一步都标出它出自哪个配方,接缝处照实说书换了什么。

出自具体的数 / 字串
① 加载配方 1三种格式各出一个 Document → Total documents loaded: 3,三个的前 275 字符一模一样
② 切块配方 2(RAG.docx,按 300 字符切、重叠 50)印出 Total chunks created: 4,可只印了 3 块:276 / 282 / 166 字符
接缝配方 4 / 9 / 11 换成 RAG.txt,换了切分器同样是 300/50,这回切出 3 块 —— 书换了文件名和刀法,重跑了一次
③ 嵌入配方 6(又换了输入:三句手写的话)3 条 → 每条 384 个数;第一条的前 5 个是 [-0.0874, -0.0331, -0.0124, 0.0260, -0.0541]
④⑤ 入库 + 检索配方 11(RAG.txt 切出的那 3 块)问「What is RAG?」→ 三个分数 0.9408 / 1.3505 / 2.0506
⑥ 生成配方 14(又换了输入:RAG.pdf,问题换成「这份文档在讲什么」)答案是:「The document appears to be about LangChain…」

下面逐步展开。

第 ① 步:三种格式,读出来一模一样

配方 1 一口气读了 PDF、TXT、DOCX 三个文件,汇成一个列表,打印出 Total documents loaded: 3,然后各印前 275 个字符7

三段印出来几乎一字不差 —— 因为它们本来就是同一段文字存成的三种格式。 这恰好演示了第一站的全部意义:格式各异,进来之后长一个样。

第 ② 步:切成 4 块,但书只印了 3 块

配方 2 拿 RAG.docx 切,给的设置是「每块最多 300 个字符、相邻两块重叠 50 个字符」。

书印出来的结果是8:

Total chunks created: 4

--- Chunk 1 (276 chars) --- Retrieval Augmented Generation (RAG) is an architecture that…
--- Chunk 2 (282 chars) --- Traditional generative models rely solely on internal parameters…
--- Chunk 3 (166 chars) --- Traditional generative models laid the foundation for today's LLMs…

图说:程序说切出 4 块,书只印了 3 块。第 4 块是接在第 3 块后面的那句
「However, they are now mostly replaced or augmented by…」——
这一点可以从另外两个配方对同一份正文的输出里看出来(配方 4、配方 5)。

这不是我们数错了,是书漏排了一块。 之所以要挑明,是因为你照着数只能数出三个数, 会以为自己看漏了。

第一块是 276 个字符,正好是那句完整的定义句。 记住这件事 —— 第 03 章会让你看到,同一段文字换个块大小,这句话会被拦腰切断。

接缝:书在这里换了文件和刀法

后面的配方 4、9、11 都改用 RAG.txt,并且换了另一种切分器。 同样是 300/50,这回切出来是 3 块,而且第 3 块把「However, they are now mostly replaced…」 整句都收了进去9

为什么会不一样? 因为两种切分器的退让顺序不同 —— 这是第 03 章的内容。 这里只需要记住一件事:换个刀,块就不一样;而块不一样,后面全都不一样。

第 ③ 步:每块变成 384 个数

配方 6 把三句话交给嵌入模型,输出是10:

Generated 3 embeddings.
Each vector has 384 dimensions.

--- Embedding 1 (first 5 dims) ---
[-0.08739510923624039, -0.03305370360612869, -0.012390639632940292,
0.02596159651875496, -0.05413474142551422]

图说:一句话进去,384 个小数出来。上面只印了前 5 个。
384 这个数是模型定死的,不是可以调的参数(第 04 章讲)。

接缝提醒: 配方 6 喂进去的是三句手写的话,不是上一步切出来的块。 书在这里换了输入,只是没说。

384 有多少? 拿它和这段文字本身比:那句定义句有 276 个字符、42 个单词, 压完之后是 384 个小数 —— 比原文的词数还多。 所以这一步不是「压缩」,是「换一种表示」。

第 ④⑤ 步:入库,然后问一句

配方 11 把 RAG.txt 切出的 3 块存进索引,问「What is RAG?」, 要前 3 条并带上分数11:

Score: 0.9408 ← 那句完整的 RAG 定义句
Score: 1.3505 ← 讲传统生成模型局限的那段
Score: 2.0506 ← 讲传统生成模型历史的那段

图说:排第一的是数字最小的那个。这三个数越小越近 —— 它量的是「距离」,不是「像的程度」。
它具体是哪种距离、还有哪两种量法、方向为什么朝那边,第 04 章讲。

书从头到尾没有解释过这三个数是什么。 它只是印出来。 一个第一次看到的人,本能会以为 2.05 最好 —— 这是必须补的第一处。

第 ⑥ 步:六站走完了,答案却是错的

配方 14 是全书第一条「从文件一路走到答案」的完整程序: 读 RAG.pdf → 切块 → 嵌入 → 存进库 → 问「What is the document about?」→ 交给本地模型作答。

它印出来的答案是12:

The document appears to be about LangChain, a framework for building applications using Large Language Models.

(原文末尾还跟着缩写 LLMs,就是导读里说的那个大语言模型。)

可是 RAG.pdf 讲的是 RAG,不是 LangChain。 这一点配方 1 的输出可以作证 —— 它印过 RAG.pdf 的正文,开头就是那句 RAG 定义句。

为什么会这样? 因为配方 14 存库用的目录名,和前面配方 8、10、12 用的是同一个 (chroma_vector_store)。那个目录里还躺着配方 8 灌进去的四条样例句, 其中一条正是「LangChain is a framework for builing applications using LLM.」13 (拼写错误是书里原有的)。

于是这次检索取回来的是上一次跑剩下的数据。六站全走通了,答案还是错的。

判断(我们的,不是书里的): 我们认为这是重复灌库造成的,不是模型答错。 依据有三条:① 三个配方共用同一个落盘目录,而这个库不会自动清空; ② 配方 10 从这个库里查「What is RAG?」,返回的正是配方 8 那条带拼写错误的句子; ③ 答案里那句话和配方 8 的样例句在措辞上高度重合。 如果错,会错在: 如果作者每次跑之前都手工删过那个目录、而 RAG.pdf 的内容 恰好也在讲 LangChain,那这个解释就不成立。判据是 RAG.pdf 的正文 —— 配方 1 印出来的那 275 个字符里,一个 LangChain 都没有。 (这件事该怎么防,第 05 章讲。)

8. 这本书全程本地零 API,而模型逐章缩水

环境口径:一次交代,后面不再重复

书在第 1 章给了一份环境清单:16 GB 内存、Windows、Python 3.13.3、 LangChain 1.0.5,以及在本机跑的 Ollama llama3.2:3b14

它一次都没有调过任何一家公司的在线服务。 这在同类书里很少见,好处是你照着跑不花钱、 资料不出本机;代价是所有输出的质量都被这个选择压着

一件书从不交代、却解释了后面几乎所有怪输出的事

生成用的模型逐章缩水,而书的环境清单一直没改。

实际用的模型大概多大环境清单上写的
第 1–6 章Ollama llama3.2:3b约 30 亿个数一致
第 7–10 章google/flan-t5-base约 2.5 亿个数,只有上一档的十二分之一第 7 章把这一行整个删了15
第 11 章t5-small约 6000 万个数,只有第一档的五十分之一仍然写着 llama3.2:3b

(上面那列「大概多大」数的是机器内部那些在训练时被反复调整的数 —— 每一个这样的数都叫参数, 它们的总数就叫参数量。这三个数字不在书里,是通用知识16。)

为什么这件事是钥匙: 从第 7 章起,你会不断看到「提示里明写了要求,输出完全没照做」 「让它一步步想清楚再答,它把原文抄了回来」这类现象。书把它们当成功案例印了出来。 读到那里的时候记得回来看这张表 —— 至少有一半是模型太小,不是方法不行。

9. 作者的判断与证据

书里给了证据的:

说法证据
三种格式读进来是同一种东西配方 1 的输出:三段正文几乎一字不差
切块参数会改变结果配方 2 与配方 4 对同一段正文给出 4 块与 3 块
一句话可以变成一串固定长度的数配方 6 的输出:3 条 → 各 384 个数
检索能按意思排出名次配方 11 的三个分数,排第一的确实是定义句
元数据可以用来过滤配方 13:三条文档里两条带同一个标签,过滤后只返回那两条

作者只是断言、没有给证据的:

说法缺什么
「切分技术保证每一块内容都待在上下文之内」17没有任何一处测过块的长度是否真的没超限,也没说「上下文」的上限是多少
「RAG 提高事实准确性」全书没有一次「不用 RAG」的对照,这个说法始终没有被量出来
配方 8 那行注释说 add_texts 是「把向量库落盘」这是书里的错:那一行做的是把同一批数据又灌了一遍

10. 边界与局限

  • 书没做过任何对照组。 「用了 RAG 比不用好」这句话,全书没有一次并排的对比输出。
  • 第 1 章的六站里,只有五站在同一份输入上跑过;第六站换了输入,而且答案是错的。
  • similarity_search_with_score 那三个数,书一个字没解释。 方向、量纲、可比性全缺。
  • 代码可用性差。 这一章里就有两处全角引号(print(f”\n Query: {query}\n”)), 照抄下来会直接报错。这类问题全书都是,我们只在这里说一次,后面各章不再重复。
  • 两处已经废弃两年的写法(from langchain.vectorstores import Chroma) 和同书其他配方的新写法打架,而书自称基于 LangChain 1.0.5。

11. 可带走的

全章那条走查,一行写完: 一段 RAG 正文 → 三种格式读成 3 个 Document → 切成 4 块(276/282/166 字符,第 4 块书没印)→ 每块 384 个数 → 存进索引 → 问「What is RAG?」→ 0.9408 / 1.3505 / 2.0506 → 拼进提示 → 交给本地模型 → 答案却在讲 LangChain,因为库是脏的。

  1. 机器只会照自己肚子里的东西答,事实过期和领域空白是结构性的,换个大的没用;
  2. 它做的事是「照着眼前这段文字往下接」 —— 所以提示里的内容和它肚子里的知识同等待遇;
  3. RAG 是两个动作:先搜,再把原文塞进提示。 不是一种模型,不是一个产品;
  4. 「原文」两个字是承重的 —— 中间插一道改写,证据就被改坏了;
  5. 拆开是六站,前四站离线备料、后两站每次提问都跑;答案不对,九成出在前四站;
  6. 流水线里流的是「一段正文 + 一小袋标签」,标签必须在第一站挂上,漏了补不回来;
  7. 检索分数越小越近(这一版用的是距离,不是相似度)—— 别看到 2.05 就以为它最好;
  8. 同一个落盘目录反复灌数据,库会越来越脏,而这本书踩了这个坑还没发现;
  9. 这本书全程本地、零云端,而负责作答的那个模型从 30 亿个数一路缩到 6000 万 —— 后面所有「输出很怪」,先怀疑这件事。

12. 原文地图

主题原书章原文位置
RAG 是干什么的、六个部件CHAPTER 1 Foundation of Retrieval-augmented Generationtext/08-fm-introduction.txt:7(搜「external knowledge sources」) · text/08-fm-introduction.txt:9(搜「document loading, splitting, embedding, retrieval, and generation」)
环境清单(全书唯一一次完整给出)同上text/08-fm-introduction.txt:51(搜「LangChain: 1.0.5」) · text/08-fm-introduction.txt:53(搜「Ollama」)
三种格式读成同一种东西同上text/08-fm-introduction.txt:217(搜「Total documents loaded: 3」)
为什么必须切块同上text/08-fm-introduction.txt:239(搜「Splitting technique ensures that each piece of content stays within the context」)
切成 4 块(书只印 3 块)同上text/08-fm-introduction.txt:319(搜「Total chunks created: 4」) · text/08-fm-introduction.txt:321(搜「Chunk 1 (276 chars)」)
换文件换刀法之后的 3 块同上text/08-fm-introduction.txt:503(搜「However, they are now mostly replaced」)
384 个数同上text/08-fm-introduction.txt:689(搜「Each vector has 384 dimensions」)
带分数的检索同上text/08-fm-introduction.txt:1201(搜「Score: 0.9408」) · text/08-fm-introduction.txt:1209(搜「Score: 1.3505」)
落盘目录被反复灌同上text/08-fm-introduction.txt:841(搜「RAG is a polpular framework」) · text/08-fm-introduction.txt:1095(搜「RAG is a popular framework to make Agentic AI applications」)
六站走完、答案却是 LangChain同上text/08-fm-introduction.txt:1672(搜「What is the document about?」) · text/08-fm-introduction.txt:1729(搜「The document appears to be about LangChain」)
Document / 元数据 / 加载器的定义CHAPTER 2 Document Loaders for RAG Pipelinestext/09-fm-introduction.txt:37(搜「fundamental data unit passed through a RAG pipeline」) · text/09-fm-introduction.txt:39(搜「contextual key-value data associated with a document」)
提示明写「别复述」而输出正是复述CHAPTER 8 Prompt Engineering for RAG Systemstext/15-fm-introduction.txt:185(搜「Do not just repeat words」) · text/15-fm-introduction.txt:242(搜「Answer: Retrieval-Augmented Generation (RAG) is a technique」)

Footnotes

  1. 出处:「CHAPTER 1 Foundation of Retrieval-augmented Generation」第 7 段(text/08-fm-introduction.txt:7,搜「external knowledge sources」)。原文的说法是这套架构「通过给大模型接上外部知识源来增强它的能力」。

  2. 出处:「CHAPTER 8 Prompt Engineering for RAG Systems」第 185 段(text/15-fm-introduction.txt:185,搜「Do not just repeat words」)与第 240 段(text/15-fm-introduction.txt:240,搜「Retrieved Context: It reduces hallucinations」)。提示原文写的是「用下面的上下文,用一到两个完整句子回答问题。不要只是重复词句 —— 给出清晰的解释」。

  3. 出处:「CHAPTER 1 Foundation of Retrieval-augmented Generation」第 221 段(text/08-fm-introduction.txt:221,搜「Retrieval Augmented Generation (RAG) is an architecture that combines the ability of large」),下接第 223 段(text/08-fm-introduction.txt:223,搜「language models (LLMs) with a retrieval system to enhance the factual accuracy」)。这几段是书里那份示例文档的正文,也是全书被反复切分、反复检索的那段文字。

  4. 出处:「CHAPTER 1 Foundation of Retrieval-augmented Generation」第 9 段(text/08-fm-introduction.txt:9,搜「document loading, splitting, embedding, retrieval, and generation」)。书列的是五个名字(加载、切分、嵌入、检索、生成),「存」这一站在小节标题里单列(text/08-fm-introduction.txt:25,搜「Store」),合起来是六站。

  5. 出处:「CHAPTER 2 Document Loaders for RAG Pipelines」第 37 段(text/09-fm-introduction.txt:37,搜「fundamental data unit passed through a RAG pipeline」)。这是全书唯一一次给数据结构下定义的地方。

  6. 出处:「CHAPTER 2 Document Loaders for RAG Pipelines」第 39 段(text/09-fm-introduction.txt:39,搜「contextual key-value data associated with a document」)。原文说元数据「增强过滤与检索,并使可追溯成为可能」。加载器接口的定义在同章第 41 段(text/09-fm-introduction.txt:41,搜「implements a standard interface for ingesting external data」)。

  7. 出处:「CHAPTER 1 Foundation of Retrieval-augmented Generation」第 217 段(text/08-fm-introduction.txt:217,搜「Total documents loaded: 3」)。三段正文分别印在第 221、231、235 段。

  8. 出处:同章第 319 段(text/08-fm-introduction.txt:319,搜「Total chunks created: 4」)与第 321 段(text/08-fm-introduction.txt:321,搜「Chunk 1 (276 chars)」)。程序里的循环是 for i, chunk in enumerate(chunks),会把所有块都打印出来,所以少的那一块是排版漏掉的,不是程序没输出。

  9. 出处:同章第 503 段(text/08-fm-introduction.txt:503,搜「However, they are now mostly replaced」)。这是配方 4 的输出,用的是 RAG.txtCharacterTextSplitter;配方 5 用按句子切,同一句被单独切成了第 4 块(text/08-fm-introduction.txt:603,搜「However, they are now mostly replaced or augmented by deep learning-based transformer models」)。

  10. 出处:同章第 689 段(text/08-fm-introduction.txt:689,搜「Each vector has 384 dimensions」)与第 693 段(text/08-fm-introduction.txt:693,搜「-0.08739510923624039」)。用的嵌入模型是 sentence-transformers/all-MiniLM-L6-v2

  11. 出处:同章第 1201 段(text/08-fm-introduction.txt:1201,搜「Score: 0.9408」)、第 1209 段(text/08-fm-introduction.txt:1209,搜「Score: 1.3505」)、第 1217 段(text/08-fm-introduction.txt:1217,搜「Score: 2.0506」)。查询是 What is RAG?(text/08-fm-introduction.txt:1173,搜「query = "What is RAG?"」)。

  12. 出处:同章第 1729 段(text/08-fm-introduction.txt:1729,搜「The document appears to be about LangChain」)。查询写在第 1672 段(text/08-fm-introduction.txt:1672,搜「What is the document about?」),读的文件是 RAG.pdf(text/08-fm-introduction.txt:1630,搜「loader = PyPDFLoader("RAG.pdf")」)。

  13. 出处:同章第 841 段(text/08-fm-introduction.txt:841,搜「RAG is a polpular framework」)—— 这是配方 8 灌进 chroma_vector_store 的四条样例句之一,polpular 是书里原有的拼写错误。配方 10 从同一个目录里查「What is RAG?」,返回的正是这句(text/08-fm-introduction.txt:1095,搜「RAG is a popular framework to make Agentic AI applications」;这一处书把拼写改回来了,前后不一致)。

  14. 出处:同章第 51 段(text/08-fm-introduction.txt:51,搜「LangChain: 1.0.5」)与第 53 段(text/08-fm-introduction.txt:53,搜「Ollama」)。

  15. 出处:「CHAPTER 7 Response Generation with LLM in RAG Systems」第 47 段起的那份环境清单(text/14-fm-introduction.txt:47,搜「System with a minimum of 16.0 GB RAM」)—— 这一份只剩内存、Python、LangChain 三行,「LLM model」和「Operation system」两行都不见了。这一章实际用的模型写在代码里(text/14-fm-introduction.txt:135,搜「runs fully local」)。第 11 章的清单则仍写着 llama3.2:3b(text/18-fm-introduction.txt:53,搜「LLM model」),而代码里用的是 t5-small(text/18-fm-introduction.txt:111,搜「model=t5-small」)。

  16. 补充(不在书里,来自通用知识):llama3.2:3b 约 30 亿参数,google/flan-t5-base 约 2.5 亿参数,t5-small 约 6000 万参数。「参数」指的是机器内部那些在训练时被反复调整的数,数量越多,一般能装下的本事越多。

  17. 出处:「CHAPTER 1 Foundation of Retrieval-augmented Generation」第 239 段(text/08-fm-introduction.txt:239,搜「Splitting technique ensures that each piece of content stays within the context」)。这句话在书里是断言,没有任何一处给出上限数值或验证。