13.3 分块策略 —— RAG 的地基
分块(Chunking)是 RAG 系统中最容易被低估的环节。检索质量的上限,很大程度上由分块策略决定。分得太大,检索不准;分得太小,语义不完整;分得不合理,后面全白搭。
13.3.1 为什么需要分块
三个原因。第一,Embedding 模型有输入长度限制。 很多开源 Embedding 模型的最大输入长度是 512 token(比如 BGE、m3e 这些常见的开源模型),更新的模型支持更长输入(text-embedding-ada-002 和 text-embedding-3-small 都支持约 8192 token),但输入的文本越长,Embedding 向量对细节的”分辨率”越低——整本书的 Embedding 只能表达”这本书大概是讲什么的”,而无法定位到”第 3 章第 2 节的那个具体论点”。第二,检索精度。 你需要的是”最相关的那几段话”,而不是”整篇文档”。分块让你能精确定位到相关段落。第三,上下文窗口。 即使 LLM 现在支持 128K 甚至 1M token 的上下文,你也不想把不相关的文本塞进去——浪费 token(=浪费钱),还会稀释相关信息,降低答案质量。
13.3.2 固定大小分块
最基础的分块策略:设置一个 chunk_size 和一个 chunk_overlap。比如 chunk_size=512, chunk_overlap=50,意思是每 512 token 切一块,相邻块之间重叠 50 token。
原文: [A B C D E F G H I J K L M N O P]
分块1: [A B C D E F G H] ← 512 token
分块2: [F G H I J K L M N] ← 512 token, 与块1重叠 F G H
分块3: [L M N O P] ← 剩余部分
chunk_size 的选择:太小(如 128 token),语义不完整,一个完整的概念被拆成好几块,检索到的片段可能”断章取义”。太大(如 2048 token),Embedding 分辨率下降,检索精度降低,而且占用更多上下文窗口。2026 年的经验值是 256-512 token,这是精度和完整性的平衡点。
但这条经验值有前提。 256-512 这个区间来自网页和论文语料,那些文本没有整齐的小标题。在本来就按 ## 组织好的文档上,实测结论不一样:固定分块一路往大走都比小块好(没有「过了 512 就变差」的拐点),而且全都追不上「按标题切」。数字和复现方式见 深挖-分块策略实测。
chunk_overlap 的作用:防止关键信息正好落在分块边界上。比如”苹果公司成立于 1976 年”这句话,如果”苹果公司成立于”在块 1 的末尾,“1976 年”在块 2 的开头,没有 overlap 的话,系统检索”苹果公司成立年份”就找不到完整信息。overlap 通常取 chunk_size 的 10%-20%。
优点:实现简单,计算量小,适合快速原型。缺点:不考虑语义边界,可能在句子中间切断,导致每块语义不完整。
13.3.3 语义分块
比固定大小更聪明的方式:按语义边界切分。比如按段落(\n\n)、按句号、按 Markdown 标题层级(##、###)切分。
语义分块的核心思想是:一个文本块应该是一个完整的语义单元。 一个段落、一个列表项、一个代码块,应该作为一个整体,不应该被切碎。
实现方式有两种:
- 基于分隔符:定义优先级
["\n\n", "\n", "。", ".", " ", ""],先尝试用段落分隔,如果块太大再降到句子级,还不够再降到词级。这是 LangChain 的RecursiveCharacterTextSplitter的做法。 - 基于模型:用一个小模型判断”这里是不是语义边界”。比如用 BERT 的下一句预测(NSP)来判断两句话是否属于同一段落。
优点:语义完整,检索质量更高。缺点:块大小不均匀,有些块可能很长(比如一个超长段落),有些块可能很短(比如一句话一段)。
13.3.4 递归分块
从大到小试:先用最大的分隔符(如 \n\n)尝试切分,如果切出来的块还是太大,就用更小的分隔符(如 \n)在这个块内部再切,直到所有块都满足大小要求。
尝试用 "\n\n" 切分 → 块 A 太大 → 用 "\n" 在块 A 内部再切 → 子块 A1 还是太大 → 用 "。" 在 A1 内部再切 → 完成
这是 2026 年生产环境中最常用的分块策略。它在语义完整性和块大小控制之间取得了最好的平衡。
13.3.5 Late Chunking(延迟分块)
2024 年出现的新思路:先对整篇文档做 Embedding,然后再分块。传统做法是”先分块,再 Embedding”——每个块的 Embedding 是独立计算的,块与块之间没有上下文联系。Late Chunking 的做法是”先 Embedding,再分块”——用长上下文 Embedding 模型(如 jina-embeddings-v3,支持 8192 token)先编码整篇文档,得到一个包含全文上下文的向量序列,然后再按位置切分。
这样做的好处是:每个块的向量”知道”自己在整篇文档中的位置和上下文。比如一个块里出现了”他”——传统分块模式下,Embedding 不知道”他”指的是谁;Late Chunking 模式下,Embedding 编码时看到了前文中的”张三”,所以”他”的向量里包含了”张三”的信息。
代价:计算成本更高,因为需要支持长上下文的 Embedding 模型。适用场景:文档内指代关系复杂的长文(如法律文书、学术论文)。
13.3.6 Agentic Chunking(智能体分块)
2025 年的前沿方向:让 Agent(智能体)来决定如何分块。Agent 读取文档,理解内容结构,然后自己决定在哪些边界切分。分块不再是机械的规则,而是一个智能决策过程。
Agent 可以根据文档类型动态调整策略:对学术论文,按章节和段落分;对对话记录,按说话人切换分;对代码,按函数和类分。Agent 还可以事后再调整——发现某个块检索效果不好,就重新切分那个区域。
代价:需要额外的 LLM 调用,成本高,速度慢,通常只在离线索引阶段使用。适用场景:文档类型多样、质量要求高的场景。
13.3.7 分块策略对比
| 策略 | 实现难度 | 语义完整性 | 检索精度 | 计算成本 | 适用场景 |
|---|---|---|---|---|---|
| 固定大小 | 极低 | 差 | 中 | 极低 | 快速原型 |
| 语义分块 | 低 | 好 | 高 | 低 | 通用场景 |
| 递归分块 | 低 | 好 | 高 | 低 | 2026 生产标配 |
| Late Chunking | 中 | 很好 | 很高 | 中 | 长文、法律文书 |
| Agentic Chunking | 高 | 最好 | 最高 | 高 | 高质量要求 |
2026 年建议:从递归分块开始(chunk_size=512, chunk_overlap=50),如果效果不理想,再考虑升级到 Late Chunking 或 Agentic Chunking。分块策略没有”银弹”——最好的策略是”针对你的文档类型做实验,用检索评估指标来验证”。
如果文档本来就有标题结构(比如这套笔记),可以先试最省事的一种:直接按 ## 小节切,每节一块,不加重叠。在结构化文档上它通常比递归分块更好,还更简单。实测见 深挖-分块策略实测。
深挖:深挖-分块策略实测 — 在自己 130 万字笔记上的分块实测
← 上一节:13.2 RAG 系统架构 | 下一节:13.4 第一代:关键词搜索(稀疏检索) →