切成多大、在哪儿切 — 全书埋得最深的一颗雷
这一章讲三件事: 为什么整篇文档不能直接用;切块的两个旋钮(多大、在哪儿下刀)各自在动什么; 以及切坏了会在哪里、以什么形式爆发。 它在全书链条里的位置: 这是六站里的第二站,也是全书唯一一颗跨章的雷 —— 第 06、10 两章里那些「明明是对的答案却排在最后」的怪事,病根都在这一站。
1. 顶层全景
一篇长文档
│
├─ 旋钮 A:每块最多多大? (chunk_size)
├─ 旋钮 B:在哪儿下刀? (separators / 结构 / 意思)
├─ 旋钮 C:相邻两块重叠多少? (chunk_overlap)
▼
一串块 ──► 每块单独变成一串数 ──► 每块单独被检索
图说:最后那两个「单独」是全章的要害。
块和块之间从此互不相识——一块里说不清的事,别的块救不了它。
一句话链条: 整篇塞不下也搜不准 → 必须切 → 切的时候有三个旋钮 → 每个旋钮拧错都有具体后果 → 而其中一种后果要到七章之后才会显形。
2. 为什么必须切:三条硬约束
书列了四条理由,其中三条是硬约束、一条是结果1:
| 约束 | 具体是什么 |
|---|---|
| 模型一次能看的文字有上限 | 超了直接放不下 |
| 多用一分就多花一分钱 | 书的原话是「不必要地多用标记会直接增加使用成本」 |
| 整篇算成一个东西,搜什么都不像 | 一篇讲十件事的文档,压出来的那个点哪件事都不靠近 |
第三条书没有明说,但它是全书最实在的一条,所以我们把它讲透。
为什么整篇算一个点会「哪件事都不靠近」? 第 02 章那张 Excel 表已经演示过一次:三个人的记录压成一个点,谁都不像。 一篇二十页的文档同理 —— 你问其中第 17 页那件事,而整篇的「平均意思」离它很远。
书还列了三个坑,这三个坑正好对应下面三节2:
- 块太小 → 丢上下文(第 6 节讲重叠怎么救、什么时候救不了);
- 块太大 → 超模型上限(第 4 节讲块大小);
- 重叠和句子边界处理错 → 丢语义(第 5 到 9 节,一节一种切法)。
3. 「长度」的单位:字符不是标记
这一节只解释一个词,但这个词是这一章所有数字的单位。
先看现象:同一段文字,两个配方给的「长度」对不上
书里同一句 RAG 定义句,被两个配方各切了一遍。 一个把上限写成 300,注释说单位是「字符」;另一个把上限写成 30,注释说单位是另一样东西。
同一句话,一个说 300、一个说 30,差了十倍,而两个数说的都是「一块最多多大」。
那个单位叫「标记」
模型不是按字符数东西的,它数的是另一种单位,那个单位就叫标记**。**
标记是模型切分文字的最小单位 —— 它可能是一个完整的词,也可能只是词的一小截:
英文里像 pre、ing、ized 这样的词头词尾,各自算一个标记。
它的英文就叫 token。你在任何一家的计费页面、上限说明、报错信息里看到这个词,说的都是它。
于是上面那两个配方的差别就清楚了:
| 配方 | 上限怎么写 | 切出几块 |
|---|---|---|
| 配方 2 | chunk_size = 300,注释写「max characters」(字符) | 4 块,第一块 276 个字符 |
| 配方 3 | chunk_size=30,注释写「max tokens per chunk」(标记) | 3 块 |
一个标记大概多大?书里的两个输出就够算出来
这个比例不必去查,书自己给的两个数就能推出来:
那句定义句 276 个字符(配方 2 的输出印着 "Chunk 1 (276 chars)")
按标记切,每块 30 个标记、重叠 10 个 → 切出 3 块(配方 3 的输出印着 "Total Chunks: 3")
重叠 10 意味着每次往前挪 30 − 10 = 20 个标记。
挪两次(0、20、40)刚好切满 3 块 ⇒ 这句话一共 51 到 70 个标记之间。
276 ÷ 60 ≈ 4.6
图说:一个标记大约合四到五个英文字符。这个数是从书里两处输出算出来的,不是查来的。
这个比例一算出来,书里就露出一个矛盾
书在第 6 章给了一条经验值:块大小常在 300 到 800 个标记之间3。
换算成字符,是 1200 到 3600 个字符左右。
而书里所有配方用的 chunk_size 是: 300、500、200、1000、100、80、60、50 —— 单位是字符。
书自己推荐的下限 300 标记 ≈ 1200 字符
书自己配方里最大的 1000 字符 ≈ 220 标记
图说:书里最大的那个块,还不到它自己推荐下限的四分之三;
最小的那个(50 字符 ≈ 11 个标记)差了近三十倍。
判断(我们的,不是书里的): 这 不是书写错了数,是书在两个单位之间来回跳而从不声明。 那条 300–800 的经验值是对的(它和业界常见口径一致),而所有演示用的都是几百个字符的小块 —— 因为演示用的那三段话太短了,块开大了就只剩一块(下一节的走查里你会看到 1000 字符那次只剩 1 块)。 如果错,会错在: 如果作者那条经验值本来说的也是字符 (原文写的是 tokens,所以不太可能),那么书里的配方就没有矛盾,矛盾只存在于我们的换算。 判据是原文那个词:它写的是
300–800 tokens。
4. 主走查:同一段文字,块大小取三个值
这一节是本章的主走查。下面每一节的机制,都回到这条线上。
书里有一个配方专门做这件事:拿同一份 RAG.txt(就是第 01 章那段 RAG 正文,三个自然段),
把块大小依次取 200 / 500 / 1000 字符,重叠固定 50,每次都问同一个问题「What is RAG?」,
取前 3 条4。
这是全书数字前后对得上的一段走查:喂进去的那堆文本不换、问题不换、只动一个数。
(喂给程序的那一堆文本,行话就叫语料。这一章后面还会反复用到这个词。)