跳到主要内容

切成小块 — 五种切法,以及每一种会在哪里翻车

这一章讲三件事: 为什么非切不可;五种切法各自在哪儿失手; 以及那条唯一的判据——一块 = 一个完整的意思。 位置:入库线的第二步。前面四章讲「读进来」,从这一章开始讲「怎么收拾」。 这是全书篇幅最大、也最有实操价值的一章。

1. 先看现象:同一份新闻页,切法不同,搜出来的东西差很多

书里用的例子特别好懂:一个新闻聚合页,上面依次是政治、体育、医疗三块内容。

用户问:「昨天那场比赛的比分是多少?」

  • 切法 A(数着字数硬切): 某一块的前半截是政治新闻的结尾,后半截是体育新闻的开头。 这块被搜出来了,里面一半内容跟比赛无关;
  • 切法 B(顺着段落切): 政治归政治、体育归体育,搜出来的那块干干净净。

书里对切法 A 的评价没留情面:它根本不考虑文档的结构, 从句子和段落的中间生生切开;

这么切,撕开的不只是句子和段落,还有文字的整个意思—— 作者为了把文档组织好所付出的一切努力,就此报废。1

这一章讲的就是:怎么下刀。

2. 顶层全景:五种切法排成一条阶梯

① 数着字数硬切 ── 只看长度 ── 最快最笨,会拦腰截断
② 顺着结构切 ── 优先在空行、换行、标点处断 ── 默认选它
③ 认得格式再切 ── 懂 Markdown / 代码 / 网页的写法 ── 源文件有格式时选它
④ 按意思切 ── 用嵌入判断上下句还是不是一回事 ── 文档没结构时选它
⑤ 让模型读一遍再切 ── 模型把内容改写成一条条独立陈述 ── 最贵,内容互相牵连时才值

图说:从上到下越来越聪明,也越来越慢越来越贵。书里的立场很明确——
②是默认答案,往下走要有具体理由。

书里在第 2 章开头就把这条阶梯的选择规则写清楚了: 最简单的是定长切;但更好的做法是考虑文档结构、在段落或标题处断开; 对付录音转写、聊天记录这类没有结构的文档,试按意思切或让模型来切, 只是这两种比顺着结构切更复杂也更贵2

先说清一个词:「块」(英文 chunk)就是切出来的那一小段文字, 它是入库和检索的最小单位——一块算一串数,搜也是按块搜回来的。

3. 为什么必须切:两个理由,分量不一样

理由一:嵌入模型一次吃不下太多

书里给的理由:把长文本拆成小块,是为了让文本嵌入模型消化得了3

这是硬约束。举个书里给的具体数字:OpenAI 的 text-embedding-3-small 这个模型一次最多吃 8191 个标记,超了就得先切4。 (标记见第 01 章:模型切分文字的最小单位,英文里大致 4 个字符算一个。)

8191 个标记是多少? 按 4 个字符算一个,大约 3 万 2 千个英文字符, 差不多一篇长报告的篇幅;而下一节要推荐的常用块大小是 1000–2000 个标记, 只占它的八分之一到四分之一——也就是说,这个上限平时并不紧,真正决定块大小的是别的理由。

理由二(更重要):块太大,搜出来的东西就不精准

这个理由书里没有直说,但整章都在暗示。书里那句直接相关的话是:

块越大,发给模型的提示就越大,会拖慢响应、抬高运行成本4

我们把这条推到底:

一块 = 整章(5000 字) → 这一块的「一串数」代表整章的平均意思 → 搜什么都有点像,搜什么都不够准
一块 = 一句话 → 每句话的意思很精确 → 但答案要用的上下文被切没了

图说:块大小是一个两头都疼的取舍。这就是为什么书里给的是一个区间,不是一个数。

4. 切多大:书里唯一给了数字的地方

这一节是全章最实用的几行,值得抄下来。

书里的建议4:

书里的说法
常用块大小1000–2000 个标记,约合 4000–8000 个字符(英文)
换算英文里 1 个标记 ≈ 4 个字符
上限别超过你那个嵌入模型的上限(书里的例子是 8191 个标记)
代价块越大 → 提示越大 → 越慢越贵

书里的示例代码故意用了 100 个字符,那是为了在书页上看得见效果,不是推荐值5

切分工具干活之前,要你交待给它几个数,这几个数行话叫「设定项」。 上面那个块大小就是其中一个——你把 1000 还是 2000 填进去,填的就是这一项。

还有另一个设定项叫「重叠」: 让相邻两块共享结尾和开头的一小段文字, 好处是跨在切口上的那句话不会两边都不完整

书里的示例给了两个不同的值,却没有一个字解释为什么: 数着字数硬切和顺着结构切那两个示例设的是 0,而认得格式再切的那三个示例设的是 506书里从头到尾没有解释这个差别,也没说该怎么定这个数——这是这一章一个明显的缺口。

还有一件事必须在这一步做,书里在第 02 章那边说过、到了切分这一节却没再提: 切下来的每一块都要把元数据带上。 一份 PDF 的第 87 页切出三块, 这三块各自都得贴着「员工手册.pdf / 第 87 页」这张标签走。 这是第 02 章那条规矩在这一步的落点——切块是元数据最容易掉的地方, 一旦在这里掉了,后面答案里就再也给不出「见第 87 页」。

5. 切法一:数着字数硬切

怎么做: 用一个固定大小的窗口,切出一堆等长的块7

什么时候它反而是对的: 书里给了唯一一个正当理由——两类本来就没有 句子和段落边界的东西:

第一样是原始日志:就是程序自己一行一行记下来的运行流水账—— 「几点几分、谁做了什么、成没成」,一行一条,写完就不再改。

第二样是传感器每秒报一次的那种源源不断的读数:它像水管里的水一样一直涌进来, 根本没有「结尾」,也没有人替它分段。

对付这两样,定长切能保证块大小一致,处理起来简单,也容易卡在模型的上限之内8

它们都没有作者,也就没有段落——所以「顺着结构切」在它们身上无处下手。

其余情况一律别用。 理由见第 1 节那段引文。

书里这一节有个自相矛盾的地方要留神: 正文说「用空格作为分隔符(就是拿来断句的那个记号), 这样单词不会被从中间切断」,而示例代码里那一项填的是一对空引号——等于什么分隔符都没给9。 两者不是一回事——照着代码跑,单词真的会被拦腰截断。

书里还给了一个很实用的小工具:一个可视化各种切法效果的网页 chunkviz.up.railway.app, 把切出来的块画出来看,比读十页说明管用10

6. 切法二:顺着结构切(递归切分)——默认答案

「递归」的意思是: 先试着用最「大」的分隔符断开; 如果断出来的块还是太大,再退一步用次一级的分隔符接着断。一层层往下退,所以叫递归。

书里说这种切法认得那些标示文档结构的字符,默认的一串是: 两个换行(空行)、一个换行、空格、句号11

先试空行断 ──→ 块还太大? ──→ 再试单个换行断 ──→ 还太大? ──→ 试空格 ──→ 试句号

图说:空行通常意味着换段,换段通常意味着换了个意思。所以从最能代表「意思断开」的
分隔符开始试。

它为什么是默认答案? 书里的理由很朴素,而且我认为是全章最深的一句:

幸运的是,人在写东西时本来就会把结构写成意思的样子—— 相关的信息被归进同一个段落,同一个章节,配上清楚的标题12

换句话说:文档的排版,是作者免费送给你的一份「这里换了个意思」的记号。 顺着它切,等于白捡了人的判断。

两个必须知道的坑

坑一:块长度只是「大约」。 书里说得很老实: 生成出来的块实际长度会有出入——如果文章句子很长,切完可能超过你设的大小13

坑二:中文、日文、泰文要另设分隔符。 书里在一个「Note」框里点了这件事: 默认的那串分隔符对多数语言都还行,但对中文、日文、泰文这类词与词之间没有空格的语言, 可能会把词切错,需要自定义14

判断(我们的,不是书里的): 这一条对中文读者的分量比书里写的大得多。 默认分隔符里的「空格」和「句号」在中文里几乎是失效的—— 中文用的是全角标点(。、,、;),而英文的 . 匹配不上。 所以照抄默认配置处理中文文档,实际退化成了「只在换行处切」, 一段很长的中文没有换行时,就变成了定长硬切。 如果错,会错在: 如果你的中文文档段落本来就短、换行密集,那默认配置的结果可以接受。 判据是:切完之后抽查几块,看有没有从句子中间断开的。

7. 切法三:认得格式再切

适用场景: 源文件是用标记语言(一种用特殊符号表示排版的写法)写的—— Markdown、网页的 HTML、排版用的 LaTeX,或者干脆是代码。

举例: 比如 Markdown 里 # 开头是标题、* 开头是列表项、两个 * 夹住表示加粗15

为什么值得单独一种切法: 这些符号是明确的、没有歧义的结构信号, 比「空行大概表示换段」这种猜测强得多。切分工具认得这套写法,就能精确地按标题层级断开。

书里说 LangChain 为 Markdown、Python、HTML、LaTeX 各准备了专门的切分器, 你也可以自己写规则,但用现成的更省事16

书里这一节的示例代码有个错误: 它给 Markdown 的那个切分器交待了「块大小」和「重叠」两项, 而这个切分器根本不认这两项——它要的是「按哪几级标题切」17

8. 切法四:按意思切(语义切分)

先说名字:这里的「语义」就是「意思」的书面说法, 所以「语义切分」讲白了就是「按意思切」。本文两种说法混用,指的是同一件事。

这一节回答:文档压根没有结构的时候怎么办。

问题从哪儿来

书里问得很直接:写博客、写书的时候你自然会分段,这种结构最适合顺着切。 可要是你手上的东西根本没有结构呢?——比如一段录音转写、一段聊天记录18

做法:让机器自己找「话锋转了」的地方

核心思路:不管文档有没有结构,把意思相关的文字留在一起; 办法是用嵌入模型量一量相邻两句像不像,以此决定它们该不该待在同一块里19

四步20:

① 把文章拆成一小片一小片(比如按句子)
② 给每一片算出嵌入
③ 量相邻两片的距离 ── 距离小 = 说的是一回事
④ 一路往同一块里加,直到相邻两片的距离突然变大 ── 在那儿下刀

图说:这一招把「哪儿该断」从一个排版问题,变成了一个可以算的数值问题。

「距离」的方向别记反了: 书里在一个提示框里专门说了—— 距离越小越相似,距离越大越不相似21

「突然变大」到底是多大:阈值怎么定

先说清「阈值」:就是你划的那道线,过线就动手,不过线就不动。 这是这一节唯一需要你做决定的地方。

书里列了三种划线的办法,示例用的是最好懂的那种——百分位 (把所有数从小到大排队,看某个数站在第百分之几的位置): 把所有算出来的距离收集起来, 当某个距离超过全部距离里的第 90 百分位时,就在那儿切一刀22

「第 90 百分位」的意思: 把所有距离从小到大排队,站在第 90% 位置上的那个值。 超过它,就说明这一处的「话锋转折」比 90% 的地方都剧烈。

书里的验证很朴素:拿讲递归切分时用过的那个新闻页,把标题和分段全删掉, 再交给这种切法——结果它准确地在政治和体育之间断开了23

但书里紧接着泼了一盆冷水: 这只是个简单例子, 你得自己试,才知道这个门槛定在哪儿适合你的文档24

它的代价

代价书里怎么说
光是决定在哪儿切,就得先给每一小片算一次嵌入25
库不成熟现成的库还是实验性的;你也可以自己实现,流程并不复杂26
可能是过度设计对简单的问答机器人来说可能太复杂了27

作者在这里说了一句挺可爱的话:机器学习(让程序自己从数据里找规律、 而不是靠人把规则一条条写死的那套做法)讲的是创造力,工具箱大一点总归有好处27

9. 切法五:让模型读一遍再切

这一节要格外小心,因为它涉及两个不是公认概念的词。

先立一个词:那段发给模型的稿子

发给模型的那段指令模板,行话叫「提示词」。 它是一张事先写好的稿子, 中间留着一个空——把要处理的那段文字填进去,整张稿子再发给模型。 这一节接下来讲的做法,全靠一段提示词指挥模型干活,所以先把它立在这儿。

再把两个词的来历说清楚

谁提出的是不是标准术语
代理式切分(让模型自己读一遍再决定怎么切)书里明说:作者第一次看到这个概念,是在 Greg Kamradt 的博客文章《文本切分的五个层次》里28不是。 它出自一篇博客,不是论文,也没有公认定义
命题(一句能独立看懂的陈述)出自一篇 2023 年 12 月的论文《Dense X Retrieval》——书里用的那段提示词正是从那篇论文抄来的29有论文出处,但拿它当检索单位仍是该论文的提案

这一节整套做法建立在这两个词上,所以先把它们的分量摆清楚: 一个是博客提出的做法,一个是论文提出的检索单位。都不是教科书概念。

命题是什么:书里的例子最清楚

命题就是一句能独立站住、不需要任何上下文就看得懂的陈述30

书里的例子:

原文一块:「莎拉买了一本新书。她喜欢读奇幻小说。」

拆成命题:① 莎拉买了一本新书。
② 莎拉喜欢读奇幻小说。 ← 「她」被换成了「莎拉」
③ 莎拉在空闲时间读奇幻小说。 ← 这一条是模型推出来的,原文没有

图说:第②条解决了「代词指谁」的问题;第③条是模型补的隐含信息——
它有用,也正是这一招最大的风险所在。

书里明确说了:那段提示词最主要的改动, 就是让模型把「他」「她」「他们」这类代词换成实体的全名31

完整做法

① 先用顺着结构切的办法,把文档切成比较大的段(比如按空行断)
② 把每一段交给模型,让它吐出一串命题
③ 逐条过一遍命题:这一条跟当前这块是一回事吗?
是 → 并进去 不是 → 另起一块
④ 得到的每一块,都是一组彼此相关、且各自能独立看懂的陈述

图说:第①步不是可有可无的。书里专门说,直接把整篇文档丢给模型「缺乏控制」——
你没法确认它有没有把该抽的都抽出来。

书里对第①步的说明是:你可以把整篇文档读进模型来生成命题, 但这样做无法控制模型是不是抽全了所有相关陈述;为了性能和可控性, 先把数据切成比较大的块32

它解决的是什么问题

书里给的动机是这一章最好的一段,用我们自己的话复述: 书、合同这类长文档里,不同章节和不同条款互相牵连,信息散落在各处,很难切成有意义的片段。 人碰到不懂的地方可以来回翻页、可以去查别的资料补上;模型不行—— 它只看得到一次检索捞回来的那几块。作者钉住这一点的那一句是:

光是把数据切开,就把「各章各段之间是怎么连着的」这层信息丢掉了。33

代理式切分就是拿模型把这层丢掉的联系重新补回去34

判断(我们的,不是书里的): 这一招最大的风险,书里一个字没提—— 模型会补上「隐含的」命题(比如上面那条「莎拉在空闲时间读奇幻小说」)。 那句话原文没有,它是模型推断出来的。推断可能对,也可能错; 一旦错了,这条错误陈述会以「原始资料」的身份进入你的知识库, 而且从此再也分不清哪些是原文、哪些是推断。 最低限度的防护是:给每条命题标上它来自原文的哪一段,并且标出它是抄的还是推的。 如果错,会错在: 如果你用的模型在这类改写上足够保守(只做代词替换、不做推断), 那这个风险很小。判据很实际:抽一百条命题,数数有几条在原文里找不到对应的话。

书里的坦白

作者对这一招的态度并不狂热,原话大意是:没有对错,做法有很多种; 你可以直接用工具包里的标准实现,也可以自己搞一套35。 他在别处也提醒过:用大模型扫描、分析、处理每一份文档,代价可能相当高; 你得自己判断块的质量提升值不值这个钱36

10. 唯一的判据:一块 = 一个完整的意思

五种切法都在追同一个东西,书里说了两遍,措辞几乎一样:

理想情况下,每一块应该覆盖一个想法。 作者写完一个念头、开始下一个念头时,我们就该结束这一块、另起一块37

切分过程的目标,就是造出每一块都覆盖一个单一想法的文本块。38

为什么这条判据管用: 回想第 01 章——每一块被压成一串数, 这串数代表这一块的「整体意思」。 一块里塞了两个意思,压出来的那串数就是两个意思的混合,它谁也不像。

书里给的反例正是第 1 节那个新闻页:随便切会把政治和体育混进同一块, 给提示里掺进噪音39

11. 作者的判断与证据

说法属于哪一类
定长切会撕掉文字的意思机制上必然,不需要证据
块大小取 1000–2000 个标记作者的经验值,没给来源和实验
「顺着结构切对多数文档都好用」作者的经验判断,理由(人写东西自带结构)成立
语义切分在示例上正确断开了政治与体育书里给的唯一一次实测,而且是单例、自选样本
语义切分「可能太复杂」作者的克制,值得记
命题式切分有论文出处,书里用的提示词就来自那篇论文
代理式切分这个概念出自一篇博客,书里自己标了来源

这一章有一次实测,是全书唯一一次——但它是作者自己挑的一个例子,不是评测。

12. 边界与局限

已经被时间冲掉的三处

这一章的三个示例各踩了一处,这里只点名:

  • 语义切分要用的 SemanticChunker 取自 langchain_experimental40—— 这个包已在 2026 年 6 月 24 日被官方封存、停止维护,而且它自己的说明里写着: 包里有些代码如果不跑在沙箱(一个被隔离起来的运行环境, 里面的程序碰不到你机器上的其他东西)里可能是危险的41;
  • 书里写的「OpenAI 的文本嵌入模型(Ada-003)」根本不存在42—— 第三代叫 text-embedding-3-smalltext-embedding-3-large,上一代叫 text-embedding-ada-002, 作者把两代的名字拼在了一起43;
  • 定长切那一节,正文说分隔符是空格,代码里却是一对空引号9—— 以正文为准;照代码跑会把单词从中间切开。

「今天该换成什么」的完整清单在第 07 章第 6 节,代码错误的完整清单在第 07 章第 5 节 ——那两张表是正本。

书里根本没讲的两件事

第一,重叠该设多少。 数着字数硬切和顺着结构切的示例设的是 0, 认得格式再切那三个示例设的是 50——书里从头到尾没有解释这个差别,也没说该怎么定6。 这是一个每个人都要做的决定,而书里把它留白了。

第二,切完之后怎么知道切得好不好。 全章没有任何评估手段—— 只有「你得自己试」。试完看什么?书里没说。

这本书之后出现的一条新思路:先算嵌入,再切

值得补一条,因为它直接冲击这一章的前提。

这一章从头到尾假设的顺序是:先切块 → 再给每块算嵌入。 2024 年 9 月有人提出反过来做,叫后期分块(late chunking): 先把整篇长文一次性喂给嵌入模型算完,再在模型输出的那一层上切44

它想解决什么?拿第 1 节那个新闻页举例。 老顺序下,体育那一块被切下来的时候, 前面政治那一段、后面医疗那一段都已经不在视野里了—— 这一块算出来的那串数,只反映这几百个字它自己。

先算后切是另一个顺序:整页从头到尾一次性喂给嵌入模型,模型内部本来就让每个字看过全页; 再在它输出的那一层上切。 这样体育那一块的那串数里, 还残留着「这是一个新闻聚合页、前面在讲政治」这一层信息。

判断(我们的,不是书里的): 这条思路不取代这一章,它取代的是「块的嵌入怎么算」, 不是「块的边界怎么定」——你仍然需要决定在哪儿下刀。 所以第 2 节那条阶梯依然有效,只是第 ⑤ 层之外多了一条正交的改进方向。 如果错,会错在: 如果你用的嵌入模型一次读不下整篇长文(比如上限只有几百个标记), 那这条路根本走不了——它的前提是一个能吃下长文的嵌入模型。

13. 可带走的

  1. 必须切,有两个理由:嵌入模型一次吃不下;以及块太大会让这串数「谁都有点像」;
  2. 块大小的经验值:1000–2000 个标记(英文约 4000–8000 字符);别超嵌入模型的上限;
  3. 块越大 → 提示越大 → 越慢越贵,这是块大小的另一头;
  4. 五种切法从笨到聪明:数字数 → 顺结构 → 认格式 → 按意思 → 让模型来切; 默认选「顺结构」,往下走要有具体理由;
  5. 定长硬切只在一种场合是对的:日志、传感器读数这类本来就没有句子边界的东西;
  6. 顺结构切之所以好,是因为人写东西时排版本来就是意思的样子——白捡人的判断;
  7. 中文要自己设分隔符:默认的空格和英文句号在中文里几乎失效, 照抄配置等于退化成定长硬切;
  8. 按意思切 = 用嵌入量相邻两句像不像,在「话锋突然转了」的地方下刀; 阈值常用第 90 百分位;距离越小越相似,别记反;
  9. 让模型来切,是把内容改写成一条条能独立看懂的「命题」再重新归堆; 它解决的是「信息散落在各章各处」的问题;
  10. 这一招有个书里没提的风险:模型会补上原文没有的推断, 而它一旦进库就再也分不出真伪——给每条命题标上出处和「抄的还是推的」;
  11. 「代理式切分」出自一篇博客,不是公认术语;「命题」出自一篇论文——引用时说清楚;
  12. 唯一的判据是「一块 = 一个完整的意思」,书里说了两遍;
  13. 重叠该设多少,书里没讲——示例里定长和递归设的是 0、认格式那三个设的是 50, 差别没有任何解释;切完怎么评估,书里同样没讲。这两件事得你自己补;
  14. Ada-003 这个模型不存在;langchain_experimental 这个包已被封存。

14. 原文地图

主题原书章原文位置
为什么要切、切在对的地方Chapter 2. Data Preparationtext/05-ch02-chapter-2-data-preparation.txt:13(搜「we break down longer texts into smaller chunks to make them manageable for text embedding models」) · text/05-ch02-chapter-2-data-preparation.txt:15(搜「splitting it at the right points to create meaningful chunks」)
五种切法的选择规则Chapter 2. Data Preparationtext/05-ch02-chapter-2-data-preparation.txt:23(搜「they are more complex and costly than recursive chunking」)
定长切:做法与唯一的正当场景Chapter 2. Data Preparationtext/05-ch02-chapter-2-data-preparation.txt:372(搜「uses a fixed-size window to create chunks of equal length」) · text/05-ch02-chapter-2-data-preparation.txt:374(搜「raw log files or real-time data streams that lack clear sentence or paragraph breaks」)
块大小的数字与代价Chapter 2. Data Preparationtext/05-ch02-chapter-2-data-preparation.txt:385(搜「chunk sizes between 1000-2000 tokens or around 4000-8000 characters」) · text/05-ch02-chapter-2-data-preparation.txt:385(搜「has a context length of 8191 tokens」) · text/05-ch02-chapter-2-data-preparation.txt:385(搜「larger text chunks lead to larger prompts sent to the LLM」)
定长切会撕掉意思、可视化工具Chapter 2. Data Preparationtext/05-ch02-chapter-2-data-preparation.txt:408(搜「ripping not only the sentences and paragraphs apart」) · text/05-ch02-chapter-2-data-preparation.txt:412(搜「chunkviz.up.railway.app」)
递归切分的默认分隔符Chapter 2. Data Preparationtext/05-ch02-chapter-2-data-preparation.txt:432(搜「it uses two new lines」) · text/05-ch02-chapter-2-data-preparation.txt:466(搜「the actual length can vary」)
中日泰语要另设分隔符Chapter 2. Data Preparationtext/05-ch02-chapter-2-data-preparation.txt:470(搜「which lack word boundaries」)
一块一个意思、人写东西自带结构Chapter 2. Data Preparationtext/05-ch02-chapter-2-data-preparation.txt:474(搜「Ideally, each text chunk should cover a single idea」) · text/05-ch02-chapter-2-data-preparation.txt:476(搜「could mix information from politics and sports, adding noise to our prompt」) · text/05-ch02-chapter-2-data-preparation.txt:555(搜「The goal of the splitting process is to create text chunks that each cover a single idea」)
认格式再切Chapter 2. Data Preparationtext/05-ch02-chapter-2-data-preparation.txt:498(搜「In markdown files, headings start with a hashtag」) · text/05-ch02-chapter-2-data-preparation.txt:500(搜「LangChain provides specific splitters for different file types」)
按意思切:目标、四步、阈值Chapter 2. Data Preparationtext/05-ch02-chapter-2-data-preparation.txt:557(搜「Semantic chunking aims to keep related text together」) · text/05-ch02-chapter-2-data-preparation.txt:563(搜「Break text: Break the text into small pieces」) · text/05-ch02-chapter-2-data-preparation.txt:573(搜「we split the text and create a new chunk when the distance exceeds the 90th percentile」)
距离越小越相似Chapter 2. Data Preparationtext/05-ch02-chapter-2-data-preparation.txt:577(搜「A smaller distance means higher similarity」)
库还是实验性的、可能过度设计Chapter 2. Data Preparationtext/05-ch02-chapter-2-data-preparation.txt:559(搜「Existing libraries, like the Semantical Chunker, are still experimental」) · text/05-ch02-chapter-2-data-preparation.txt:622(搜「it may be too complex for simple RAG chatbots」) · text/05-ch02-chapter-2-data-preparation.txt:620(搜「Although this approach can be costly」)
删掉结构之后的实测Chapter 2. Data Preparationtext/05-ch02-chapter-2-data-preparation.txt:589(搜「all headings and paragraphs have been removed」) · text/05-ch02-chapter-2-data-preparation.txt:610(搜「You will need to experiment to find what works best for your documents」)
代理式切分的来历、命题的定义Chapter 2. Data Preparationtext/05-ch02-chapter-2-data-preparation.txt:640(搜「I saw the concept for the first time in Greg Kamradt」) · text/05-ch02-chapter-2-data-preparation.txt:642(搜「The idea is to create standalone statements called propositions」) · text/05-ch02-chapter-2-data-preparation.txt:656(搜「Sarah reads fantasy novels in her free time」)
提示词模板出自 Dense X 论文、替换代词Chapter 2. Data Preparationtext/05-ch02-chapter-2-data-preparation.txt:674(搜「The prompt template we use is from the paper Dense X Retrieval」) · text/05-ch02-chapter-2-data-preparation.txt:675(搜「replaces pronouns」)
先切大块再抽命题Chapter 2. Data Preparationtext/05-ch02-chapter-2-data-preparation.txt:707(搜「this approach lacks control over whether the LLM extracts all relevant statements」) · text/05-ch02-chapter-2-data-preparation.txt:707(搜「first chunk the data into relatively large sections」)
信息散落各处、模型只看得到搜回来的块Chapter 2. Data Preparationtext/05-ch02-chapter-2-data-preparation.txt:715(搜「information is often scattered throughout」) · text/05-ch02-chapter-2-data-preparation.txt:717(搜「our model only sees content from a single vector search」) · text/05-ch02-chapter-2-data-preparation.txt:719(搜「Agentic chunkers tackle this issue」)
Ada-003、实验性包Chapter 2. Data Preparationtext/05-ch02-chapter-2-data-preparation.txt:581(搜「Text Embedding model (Ada-003)」) · text/05-ch02-chapter-2-data-preparation.txt:583(搜「langchain_experimental package」)

Footnotes

  1. 出处:「Chapter 2. Data Preparation」第 408 段(text/05-ch02-chapter-2-data-preparation.txt:408,搜「ripping not only the sentences and paragraphs apart」)。同一段前面还说它「完全不把文档的结构考虑在内」(text/05-ch02-chapter-2-data-preparation.txt:408,搜「It doesn」)。

  2. 出处:「Chapter 2. Data Preparation」第 23 段(text/05-ch02-chapter-2-data-preparation.txt:23,搜「they are more complex and costly than recursive chunking」)。这一段是第 2 章的总纲,把五种切法的适用场景一次列全。

  3. 出处:「Chapter 2. Data Preparation」第 13 段(text/05-ch02-chapter-2-data-preparation.txt:13,搜「we break down longer texts into smaller chunks to make them manageable for text embedding models」)。

  4. 出处:「Chapter 2. Data Preparation」第 385 段(text/05-ch02-chapter-2-data-preparation.txt:385,搜「chunk sizes between 1000-2000 tokens or around 4000-8000 characters」)、同段(text/05-ch02-chapter-2-data-preparation.txt:385,搜「has a context length of 8191 tokens」)与同段(text/05-ch02-chapter-2-data-preparation.txt:385,搜「larger text chunks lead to larger prompts sent to the LLM」)。补充(不在书里):OpenAI 官方文档今天给出的这两个第三代嵌入模型的输入上限写作 8192 个标记,和书里写的 8191 差 1,不影响判断。来源:OpenAI「Embeddings」https://developers.openai.com/api/docs/guides/embeddings(查阅于 2026-08-25)。 2 3

  5. 出处:「Chapter 2. Data Preparation」第 383 段(text/05-ch02-chapter-2-data-preparation.txt:383,搜「sets a chunk size of 100 with zero overlap」)。原文写明这是「用来演示概念」。

  6. 出处:设 0 的两处示例见「Chapter 2. Data Preparation」第 397 段(text/05-ch02-chapter-2-data-preparation.txt:397,搜「text_splitter = CharacterTextSplitter(」)与第 457 段(text/05-ch02-chapter-2-data-preparation.txt:457,搜「RecursiveCharacterTextSplitter(」)——两处的 chunk_overlap 都写在紧随其后的第 399、459 行,值都是 0。设 50 的三处示例见第 527 段(text/05-ch02-chapter-2-data-preparation.txt:527,搜「PythonCodeTextSplitter(chunk_size=500」)、第 529 段(text/05-ch02-chapter-2-data-preparation.txt:529,搜「LatexTextSplitter(chunk_size=500」)与第 531 段(text/05-ch02-chapter-2-data-preparation.txt:531,搜「MarkdownHeaderTextSplitter(chunk_size=500」),三处都写着 chunk_overlap=50。前两处属于定长切分与递归切分,后三处属于认格式再切;原文对这个差别没有任何说明。 2

  7. 出处:「Chapter 2. Data Preparation」第 372 段(text/05-ch02-chapter-2-data-preparation.txt:372,搜「uses a fixed-size window to create chunks of equal length」)。

  8. 出处:「Chapter 2. Data Preparation」第 374 段(text/05-ch02-chapter-2-data-preparation.txt:374,搜「raw log files or real-time data streams that lack clear sentence or paragraph breaks」)。

  9. 出处:「Chapter 2. Data Preparation」第 383 段(text/05-ch02-chapter-2-data-preparation.txt:383,搜「uses a space (' ') as the separator」);示例代码见第 400 段(text/05-ch02-chapter-2-data-preparation.txt:400,搜「separator=」),那里写的是一对空引号。 2

  10. 出处:「Chapter 2. Data Preparation」第 412 段(text/05-ch02-chapter-2-data-preparation.txt:412,搜「chunkviz.up.railway.app」)。我们没有打开过这个网址核对它今天还在不在,所以只转述书里的说法。

  11. 出处:「Chapter 2. Data Preparation」第 432 段(text/05-ch02-chapter-2-data-preparation.txt:432,搜「it uses two new lines」)。原文列的默认分隔符依次是两个换行、一个换行、空格、句号。

  12. 出处:「Chapter 2. Data Preparation」第 474 段(text/05-ch02-chapter-2-data-preparation.txt:474,搜「humans often structure texts to reflect their meaning」)。

  13. 出处:「Chapter 2. Data Preparation」第 466 段(text/05-ch02-chapter-2-data-preparation.txt:466,搜「the actual length can vary」)。

  14. 出处:「Chapter 2. Data Preparation」第 470 段(text/05-ch02-chapter-2-data-preparation.txt:470,搜「which lack word boundaries」)。原文点名的是中文、日文和泰文,并让读者去查工具的官方文档找最佳实践。「中文里默认分隔符实际失效」这一步推论是我们补的,不是原文。

  15. 出处:「Chapter 2. Data Preparation」第 498 段(text/05-ch02-chapter-2-data-preparation.txt:498,搜「In markdown files, headings start with a hashtag」)。

  16. 出处:「Chapter 2. Data Preparation」第 500 段(text/05-ch02-chapter-2-data-preparation.txt:500,搜「LangChain provides specific splitters for different file types」)。

  17. 出处:「Chapter 2. Data Preparation」第 531 段(text/05-ch02-chapter-2-data-preparation.txt:531,搜「MarkdownHeaderTextSplitter(chunk_size=500」)。补充(不在书里,来自通用知识):这个切分器要你交待的是「按哪几级标题切」,而不是块大小与重叠;交错了会直接报错。

  18. 出处:「Chapter 2. Data Preparation」第 555 段(text/05-ch02-chapter-2-data-preparation.txt:555,搜「But what if you」)。

  19. 出处:「Chapter 2. Data Preparation」第 557 段(text/05-ch02-chapter-2-data-preparation.txt:557,搜「Semantic chunking aims to keep related text together」)。

  20. 出处:「Chapter 2. Data Preparation」第 563 段(text/05-ch02-chapter-2-data-preparation.txt:563,搜「Break text: Break the text into small pieces」)与第 569 段(text/05-ch02-chapter-2-data-preparation.txt:569,搜「Merge text chunks」)。

  21. 出处:「Chapter 2. Data Preparation」第 577 段(text/05-ch02-chapter-2-data-preparation.txt:577,搜「A smaller distance means higher similarity」)。

  22. 出处:「Chapter 2. Data Preparation」第 573 段(text/05-ch02-chapter-2-data-preparation.txt:573,搜「we split the text and create a new chunk when the distance exceeds the 90th percentile」)。书里第 569 段列出的三种阈值定法是百分位、标准差和梯度,但只演示了百分位一种。

  23. 出处:「Chapter 2. Data Preparation」第 589 段(text/05-ch02-chapter-2-data-preparation.txt:589,搜「all headings and paragraphs have been removed」)与第 608 段(text/05-ch02-chapter-2-data-preparation.txt:608,搜「it correctly chose the breakpoints」)。

  24. 出处:「Chapter 2. Data Preparation」第 610 段(text/05-ch02-chapter-2-data-preparation.txt:610,搜「You will need to experiment to find what works best for your documents」)。

  25. 出处:「Chapter 2. Data Preparation」第 620 段(text/05-ch02-chapter-2-data-preparation.txt:620,搜「Although this approach can be costly」)。原文紧接着说,块的质量高了,检索会更快、更省、更可靠。

  26. 出处:「Chapter 2. Data Preparation」第 559 段(text/05-ch02-chapter-2-data-preparation.txt:559,搜「Existing libraries, like the Semantical Chunker, are still experimental」)。

  27. 出处:「Chapter 2. Data Preparation」第 622 段(text/05-ch02-chapter-2-data-preparation.txt:622,搜「it may be too complex for simple RAG chatbots」)与同段(text/05-ch02-chapter-2-data-preparation.txt:622,搜「Machine learning is about creativity」)。 2

  28. 出处:「Chapter 2. Data Preparation」第 640 段(text/05-ch02-chapter-2-data-preparation.txt:640,搜「I saw the concept for the first time in Greg Kamradt」)。同一节末尾又指向了同一位作者的代码仓库(text/05-ch02-chapter-2-data-preparation.txt:727,搜「GitHub repository on chunking strategies」)。补充(不在书里):该仓库确实存在一个名为 tutorials/LevelsOfTextSplitting 的目录,页面署名为 Greg Kamradt 与 FullStackRetrieval.com;我们打开时页面只展示了目录结构,没有展开五个层次的具体名称。来源:GitHub「FullStackRetrieval-com/RetrievalTutorials」https://github.com/FullStackRetrieval-com/RetrievalTutorials(查阅于 2026-08-25)。

  29. 出处:「Chapter 2. Data Preparation」第 674 段(text/05-ch02-chapter-2-data-preparation.txt:674,搜「The prompt template we use is from the paper Dense X Retrieval」)。补充(不在书里):该论文首次提交于 2023 年 12 月 11 日,作者为 Tong Chen、Hongwei Wang、Sihao Chen 等;它把命题定义为「文本中的原子表达,每一条封装一个独立的事实,以简洁、自足的自然语言形式呈现」,并给出结论:按命题这种细粒度单位建索引,在检索任务上明显优于按段落建索引。来源:《Dense X Retrieval: What Retrieval Granularity Should We Use?》https://arxiv.org/abs/2312.06648(查阅于 2026-08-25)。

  30. 出处:「Chapter 2. Data Preparation」第 642 段(text/05-ch02-chapter-2-data-preparation.txt:642,搜「The idea is to create standalone statements called propositions」)与同段(text/05-ch02-chapter-2-data-preparation.txt:642,搜「clear and understandable without needing additional context」)。

  31. 出处:「Chapter 2. Data Preparation」第 675 段(text/05-ch02-chapter-2-data-preparation.txt:675,搜「replaces pronouns」)。书里的例子见第 656 段(text/05-ch02-chapter-2-data-preparation.txt:656,搜「Sarah reads fantasy novels in her free time」),原文在这一条后面明确标了「(implied)」,即这是推断出来的。

  32. 出处:「Chapter 2. Data Preparation」第 707 段(text/05-ch02-chapter-2-data-preparation.txt:707,搜「this approach lacks control over whether the LLM extracts all relevant statements」)与同段(text/05-ch02-chapter-2-data-preparation.txt:707,搜「first chunk the data into relatively large sections」)。

  33. 出处:「Chapter 2. Data Preparation」第 715 段(text/05-ch02-chapter-2-data-preparation.txt:715,搜「information is often scattered throughout」)与第 717 段(text/05-ch02-chapter-2-data-preparation.txt:717,搜「our model only sees content from a single vector search」)。

  34. 出处:「Chapter 2. Data Preparation」第 719 段(text/05-ch02-chapter-2-data-preparation.txt:719,搜「Agentic chunkers tackle this issue」)。

  35. 出处:「Chapter 2. Data Preparation」第 723 段(text/05-ch02-chapter-2-data-preparation.txt:723,搜「There is no right or wrong」)。

  36. 出处:「Chapter 2. Data Preparation」第 267 段(text/05-ch02-chapter-2-data-preparation.txt:267,搜「identifying similar information across documents and building propositions」)。这段话出现在第 06 章要讲的那个配方的「另见」里,原文的结论是:你得自己判断块的质量提升值不值这笔额外开销。

  37. 出处:「Chapter 2. Data Preparation」第 474 段(text/05-ch02-chapter-2-data-preparation.txt:474,搜「Ideally, each text chunk should cover a single idea」)。

  38. 出处:「Chapter 2. Data Preparation」第 555 段(text/05-ch02-chapter-2-data-preparation.txt:555,搜「The goal of the splitting process is to create text chunks that each cover a single idea」)。

  39. 出处:「Chapter 2. Data Preparation」第 476 段(text/05-ch02-chapter-2-data-preparation.txt:476,搜「could mix information from politics and sports, adding noise to our prompt」)。原文还提到:即便检索这一步工作正常,混进来的无关内容也会推高成本、拖慢响应,并让模型更难写出好答案。

  40. 出处:「Chapter 2. Data Preparation」第 583 段(text/05-ch02-chapter-2-data-preparation.txt:583,搜「langchain_experimental package」)。

  41. 补充(不在书里):langchain-experimental 的包页面写明「本包中的部分代码如果没有部署在沙箱环境里可能是危险的」,并标注该项目正在停止支持;最新版本 0.4.2 发布于 2026 年 5 月 22 日,项目已于 2026 年 6 月 24 日封存(仓库转为只读,不再接受任何改动)。来源:PyPI「langchain-experimental」https://pypi.org/project/langchain-experimental/(查阅于 2026-08-25)。

  42. 出处:「Chapter 2. Data Preparation」第 581 段(text/05-ch02-chapter-2-data-preparation.txt:581,搜「Text Embedding model (Ada-003)」)。

  43. 补充(不在书里):OpenAI 官方文档列出的嵌入模型是 text-embedding-3-smalltext-embedding-3-large 与上一代的 text-embedding-ada-002,没有任何叫 ada-003 的模型;文档明确说第三代模型以模型名里的 -3 标识。来源:OpenAI「Embeddings」https://developers.openai.com/api/docs/guides/embeddings(查阅于 2026-08-25)。

  44. 补充(不在书里):这条思路出自 2024 年 9 月 7 日提交的论文,作者为 Michael Günther、Isabelle Mohr 等;做法是「先把长文本的所有标记都过一遍模型,分块动作放在模型之后、汇总成一个向量之前」,针对的问题是「先切后嵌」得到的块嵌入会丢失周围块的上下文信息。来源:《Late Chunking: Contextual Chunk Embeddings Using Long-Context Embedding Models》https://arxiv.org/abs/2409.04701(查阅于 2026-08-25)。