在 RAG 的整条流水线里,切分(Chunking)是投入产出比最高的环节:不用换模型、不用加组件,改几个参数就可能让检索命中率上一个台阶。但它也是最容易被拍脑袋决定的环节——很多系统的 chunk size 是「框架默认多少就多少」,从上线到废弃都没人动过。
这篇文章讲清楚三件事:为什么切分方式直接决定答案质量、四种主流切分策略各自适合什么文档、以及一套可以直接照抄的默认配置和调优流程。
切分的本质:把文档拆成「既能被检索命中,又能独立回答问题」的单元。
为什么切分这么重要
检索是以 chunk 为单位进行的,所以每个 chunk 必须同时满足两个互相矛盾的要求:
- 足够小:内容聚焦,Embedding 向量才能准确表达它的语义,检索才打得准;
- 足够大:命中之后自身要携带完整信息,模型才有料可答。
切太碎,命中的片段只有半句话,模型开始脑补,幻觉就来了;切太大,一个 chunk 混了三四个主题,向量变成「平均语义」,什么都沾边、什么都不准。所谓 chunk size 调优,就是在这两端之间找平衡点,而平衡点因文档类型而异——这也是为什么不存在放之四海皆准的「最佳 chunk size」。
四种主流切分策略
1. 固定长度切分(Fixed-size)
按固定 token/字符数硬切,配一定重叠。实现最简单,速度最快,但会在句子中间、表格中间落刀。只适合快速原型或结构非常均匀的纯文本。
2. 递归切分(Recursive)
主流框架的默认策略:按分隔符优先级(段落 → 换行 → 句号 → 空格)递归下切,尽量在自然边界断开,超长再降级。LangChain 的 RecursiveCharacterTextSplitter、LlamaIndex 的 SentenceSplitter 都是这个思路。通用性最好,是大多数场景的合理起点。
3. 结构化切分(Structure-aware)
按文档自身结构切:Markdown 按标题层级、HTML 按 DOM、代码按函数/类、合同按条款。每个 chunk 天然对应一个完整语义单元,还能把「文档名 > 章节 > 小节」的路径写进元数据或拼进 chunk 开头。对于本身有结构的文档,这是效果上限最高的策略,代价是要为每类文档写解析逻辑。
4. 语义切分(Semantic)
逐句算 embedding,在相邻句子语义突变处断开。适合没有格式结构的长文(访谈稿、字幕、纯文本小说),能切出主题连贯的块。缺点是入库成本高(每句都要算向量)、切分结果不稳定,一般只在前三种都不理想时才用。
| 策略 | 实现成本 | 效果上限 | 适合文档 |
|---|---|---|---|
| 固定长度 | 极低 | 低 | 原型验证 |
| 递归切分 | 低 | 中 | 通用默认 |
| 结构化切分 | 中 | 高 | Markdown/HTML/代码/合同 |
| 语义切分 | 高 | 中高 | 无结构长文 |
Chunk Size 实战对比:大小到底怎么选
我们用同一批中文文档(制度文档、技术手册、FAQ 混合,约 800 页)在相同的检索配置下(bge 系向量 + Top-5 召回)对比过几档常见尺寸,结论和社区主流经验一致:
| Chunk Size(token) | 检索命中表现 | 典型问题 |
|---|---|---|
| 128–256 | 精确问题命中好 | 答案跨块被切断,需要靠重叠和多召回弥补 |
| 384–512 | 综合最稳 | 少数长流程类问题仍需扩展上下文 |
| 1024 | 命中率开始下降 | 向量语义变「平均」,混主题块增多 |
| 2048+ | 明显下降 | 一块多题,检索准度和答案聚焦都变差 |
几条可以直接用的经验:
- 默认从 512 token、10%–20% 重叠起步,FAQ 和短条款类偏小(256 左右),流程和教程类偏大(512–768)。
- 重叠不是越多越好:超过 30% 会让相邻块高度相似,检索结果里同一内容重复出现,挤占候选位。
- 中文按字符估算时,1 token 约等于 1–1.5 个汉字,512 token 大致对应 400–700 字,别直接套英文经验值。
进阶技巧:检索单元和生成单元分离
切分调优到后期,最有效的一招是不再让「检索的块」和「给模型看的块」是同一个东西:
- Small-to-Big / 父子块:用小块(如 256)做检索保证命中精度,命中后返回它所属的父块(如 1024 或整节)给模型,兼顾两端。LlamaIndex 的
SentenceWindowNodeParser、LangChain 的ParentDocumentRetriever是现成实现。 - 上下文增强(Contextual Chunking):入库前用模型给每个 chunk 生成一句「这段出自哪份文档、讲什么」的前缀再做向量化。Anthropic 提出的 Contextual Retrieval 就是这个思路,对代词多、上下文依赖强的文档改善明显,代价是入库时多一次模型调用(配合 Prompt Caching 可以把成本压低)。
- 表格与代码单独处理:表格转 Markdown 或按行展开成句子;代码按函数切并保留文件路径。这两类内容混进普通文本切分器,几乎必然出问题。
父子块检索:小块负责被找到,大块负责把话说完整。
一套可以照抄的调优流程
- 建评估集:从真实问题里挑 50 条,标注每条应命中的文档段落。没有这一步,后面全是玄学。
- 跑基线:递归切分 + 512 token + 15% 重叠,记录检索命中率(正确段落是否进 Top-5)。
- 单变量调整:只动 chunk size(256 / 512 / 768 各跑一轮),选命中率最高的一档。
- 换策略:如果文档有结构(标题、条款、代码),换结构化切分再跑一轮,通常还能再涨。
- 上父子块:命中率高但「答不全」的问题多时,加 Small-to-Big。
- 固化并监控:把配置写进代码和文档,之后每次换 embedding 模型或大改语料,重跑评估集。
注意事项:改切分参数意味着全量重建索引,大语料库要评估重建时间和向量化费用;线上系统建议新旧索引并行、灰度切换,避免重建期间检索质量抖动。
每次只改一个变量,用同一份评估集对比,一天之内就能把 chunk size 调到位。
适用人群与替代方案
适合正在搭建或优化 RAG 知识库的工程师和技术产品经理。如果你的场景是「文档总量不到几万字」,可以跳过切分,直接把全文塞进上下文窗口;如果用 Dify、FastGPT、Coze 等平台,本文的尺寸经验同样适用——平台的「分段设置」「父子分段」就是上文策略的封装。真正无法绕过切分的,只有语料大、更新频繁、要控成本的自建场景。
常见问题
Q:切分和检索方式哪个优先调? A:先切分后检索。切分是数据质量问题,数据切坏了,Hybrid Search 和 Rerank 都是在坏数据上打补丁。三者的关系见《RAG 为什么答不准?10 个工程原因和解决方案》。
Q:换了 embedding 模型需要重新调 chunk size 吗? A:建议至少重跑一遍评估集。不同模型的最优输入长度不同(多数 embedding 模型对 256–512 token 的输入表现最好),512 的默认值通常仍然安全。
Q:一个库里既有 FAQ 又有长手册,怎么办? A:按文档类型分别切分(FAQ 一问一答一块,手册按章节结构化切),入库时打上类型元数据。不要为了省事用同一套参数处理所有文档。
小结
切分没有银弹,但有明确的方法论:默认递归切分 + 512 token 起步,有结构的文档上结构化切分,答不全就上父子块,一切改动用 50 条评估集说话。把这个环节做扎实,往往比升级模型更能提升 RAG 的答准率。