Appearance
3.1.2 为什么文档必须切块?
先给结论:因为大多数文档对人来说可以整篇阅读,但对 RAG 系统来说,整篇文档通常不是一个合适的检索和组织答案单位。
这就是为什么大多数 RAG 系统都要切块。
切块真正解决的,不只是“文档太长”
很多人第一次接触 chunk,会把切块理解成一个很简单的问题:
文档太长,所以切短一点。
这当然没错,但还不够。
切块真正解决的,通常至少有四类问题:
1. 让系统更容易定位相关局部
用户提的问题,很多时候只对应文档中的一小段,而不是整篇文档。
如果系统只能按整篇文档去做匹配,就很容易出现:
- 相关段落埋在整篇正文里
- 少量相关信息被大量无关内容包住
- 文档整体看起来相关,但真正答案部分并不突出
切块的第一层价值,就是让系统更容易命中“相关局部”,而不是只命中“相关文档”。
2. 让检索粒度更接近真实问答粒度
大多数用户问题都不是在问:
- “这份 30 页文档整体讲了什么?”
而更像在问:
- 某条规则怎么规定
- 某个流程具体怎么走
- 某个异常情况怎么处理
这些问题天然更接近段落、小节、表格说明、FAQ 条目,而不是整篇文档。
所以切块,本质上是在让知识粒度更贴近真实提问粒度。
3. 降低无关上下文对模型的干扰
如果每次都把整篇文档送给模型,哪怕里面确实包含答案,也会同时把大量无关内容一起送进去。
这样很容易导致:
- 上下文被稀释
- 模型抓不住重点
- 回答看起来泛泛而谈
- 成本和延迟都变高
切块的第二层价值,是尽量只把真正相关的部分送进后面的回答链路。
4. 让后面的治理和过滤更细粒度生效
很多系统后面要做:
- 版本优先
- 权限控制
- 来源追踪
- 文档聚合
如果文档始终只是一整篇大对象,这些能力虽然也能做,但粒度通常会比较粗,灵活性也更差。
切块以后,系统通常更容易:
- 在更细粒度上做排序
- 在 chunk 层展示引用来源
- 把同一文档中的不同部分按问题需要组合起来
一个最小示意:整篇文档和切块后的差别
python
document = """
退款规则
一、普通商品签收后 7 天内支持无理由退货。
二、定制类商品不支持无理由退货。
三、如商品存在质量问题,可在 15 天内申请售后。
四、企业采购订单需走专门审批流程。
"""
chunks = [
"普通商品签收后 7 天内支持无理由退货。",
"定制类商品不支持无理由退货。",
"商品存在质量问题,可在 15 天内申请售后。",
"企业采购订单需走专门审批流程。",
]如果用户问的是“定制类商品可以提现吗”,系统真正需要命中的,其实只是其中一小段。
这时切块的意义就很直观了:
- 整篇文档匹配的是“这份文档可能相关”
- chunk 匹配的是“这一段就是答案附近的内容”
为什么“先命中文档,再让模型自己找”通常不够稳
有人会觉得,只要整篇文档检索回来,再让模型自己从里面找答案不就行了?
这个思路在很小的 Demo 里有时能跑通,但在真实系统里往往不够稳。原因包括:
- 文档多了以后,整篇文档很难全部塞进上下文
- 一篇文档内部可能有多个主题,模型不一定每次都抓对局部
- 整篇文档之间常常还存在重复、旧版本和相似规则
- 检索阶段如果粒度太粗,后面的排序和上下文构造也会一起变粗
所以切块不是“可有可无的优化”,而是让后续链路真正站稳的前提。
切块其实是在做一件更底层的事
如果再往下说一层,切块其实是在定义:
系统以后准备按什么粒度理解知识。
这个粒度会直接影响:
- embedding 到底在表示什么
- top-k 召回到底拿回什么
- rerank 到底在比较什么
- 模型最后到底看到什么
所以“文档必须切块”不是一个格式问题,而是一个系统设计问题。
什么情况下切块尤为重要
下面这些场景里,切块几乎一定是刚需:
- 单篇文档很长
- 一份文档包含多个子主题
- 用户问题通常只命中文档中的局部段落
- 文档里有版本、章节、表格、FAQ 等不同结构
- 需要做引用、过滤和后续治理
这也是大多数真实业务文档的常见情况。
一个常见误解
很多人会把“文档必须切块”理解成一种技术限制:
- 因为模型窗口不够大
- 因为向量库只能存小片段
这些都不是最核心的原因。
更核心的原因其实是:
整篇文档往往不是一个好的知识匹配单位。
哪怕未来窗口更大、基础设施更强,这个判断在绝大多数场景里仍然成立。
一句话总结
文档必须切块,不是因为系统“看不了整篇文档”,而是因为整篇文档通常不是一个适合检索、排序和组织答案的知识粒度。切块的本质,是让系统更容易找到真正相关的局部内容,并把这些局部内容稳定组织成回答依据。