RAG 文档切分怎么做?Chunk Size 实战对比

知识库

切分是 RAG 里最便宜也最容易被忽视的环节。本文对比固定长度、递归、结构化、语义切分四种策略和不同 Chunk Size 的实际表现,给出一套可以直接抄的默认配置和调优流程。

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 或按行展开成句子;代码按函数切并保留文件路径。这两类内容混进普通文本切分器,几乎必然出问题。
工程师在屏幕上调试数据处理脚本
工程师在屏幕上调试数据处理脚本

父子块检索:小块负责被找到,大块负责把话说完整。

一套可以照抄的调优流程

  1. 建评估集:从真实问题里挑 50 条,标注每条应命中的文档段落。没有这一步,后面全是玄学。
  2. 跑基线:递归切分 + 512 token + 15% 重叠,记录检索命中率(正确段落是否进 Top-5)。
  3. 单变量调整:只动 chunk size(256 / 512 / 768 各跑一轮),选命中率最高的一档。
  4. 换策略:如果文档有结构(标题、条款、代码),换结构化切分再跑一轮,通常还能再涨。
  5. 上父子块:命中率高但「答不全」的问题多时,加 Small-to-Big。
  6. 固化并监控:把配置写进代码和文档,之后每次换 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 的答准率。