Appearance
3.2.1 Chunk 应该切多大?为什么没有统一答案?
先给结论:chunk 大小没有统一答案,因为它不是一个单独参数问题,而是在同时平衡检索粒度、语义完整性和上下文成本。
这也是为什么别人项目里好用的数值,搬到你的系统里经常不一定成立。
为什么大家总想先问“应该切多大”
因为这是最容易量化的问题。
比如很多人会直接问:
- 256 token 行不行?
- 512 token 是不是更稳?
- 1000 字会不会太长?
这些问题当然合理,但它们有个共同前提:默认 chunk 大小是一个可以脱离上下文单独决定的参数。
真实情况通常不是这样。
Chunk 大小真正影响的是什么
1. 影响检索到底在匹配什么粒度
chunk 越大,系统越像是在匹配“主题块”; chunk 越小,系统越像是在匹配“局部证据”。
所以 chunk 大小首先决定的,不是存储方式,而是:
系统以后准备按多大的知识单位做相关性判断。
2. 影响单个 chunk 的语义完整性
chunk 太小,常见问题是:
- 一句规则被切断
- 前提和结论分开
- 定义和例外条件分开
- 模型拿到的是残片,不是完整意思
chunk 太大,常见问题又会变成:
- 多个主题混在一起
- 无关内容把真正答案稀释掉
- 检索到了也不代表命中了最关键部分
3. 影响上下文成本和最终可塞入量
同样的 top-k 下:
- chunk 越大,单次召回成本越高
- chunk 越小,召回条目数可能更多
所以 chunk 大小还会直接影响:
- token 消耗
- 延迟
- 最终 Prompt 能装下多少证据
为什么没有统一答案
因为下面这些变量都在一起影响结果:
- 文档类型
- 文档结构稳定性
- 用户问题粒度
- 检索方式
- 是否有 rerank
- 模型上下文预算
这也是为什么同样是 RAG,有的系统更适合偏大的 chunk,有的系统反而更适合偏小的 chunk。
一个直观理解:太大和太小分别会怎样
可以先粗略记成这样:
chunk 太大时
更容易出现:
- 命中文档,但没命中答案核心
- 一个 chunk 里混着多个主题
- 无关内容占比高
- 后续上下文成本高
chunk 太小时
更容易出现:
- 语义断裂
- 定义、限制条件、例外分开
- 召回结果碎片化
- 模型需要自己补太多上下文
所以真正的问题通常不是“多大最好”,而是“当前系统更怕哪一边”。
一个最小示意
python
text = """
退款规则:
普通商品签收后 7 天内支持无理由退货。
定制类商品不支持无理由退货。
如存在质量问题,可在 15 天内申请售后。
"""
large_chunk = [
"退款规则:普通商品签收后 7 天内支持无理由退货。定制类商品不支持无理由退货。如存在质量问题,可在 15 天内申请售后。"
]
small_chunks = [
"普通商品签收后 7 天内支持无理由退货。",
"定制类商品不支持无理由退货。",
"如存在质量问题,可在 15 天内申请售后。",
]如果用户问的是“定制类商品能不能无理由退货”,较小的 chunk 更容易直接命中答案核心。
但如果用户问的是“退款规则整体怎么区分普通退货和质量问题售后”,过碎的切法又可能让回答失去整体性。
这就是 chunk 大小没有统一答案的原因。
更实用的判断方式
与其问“应该切多大”,不如先问下面几个问题:
- 用户问题通常更像问局部规则,还是问整段说明?
- 当前文档的语义边界清不清楚?
- 你的系统更常见的问题是“答得太散”,还是“答得太泛”?
- 后面是否还有 rerank、文档聚合或生成重组能力?
这些问题会直接影响 chunk 大小选择。
一个更贴近实际的经验
很多团队早期更适合的做法不是死抠某个固定数值,而是先建立一个可调范围。
比如:
- 先选一个中等大小作为起点
- 再根据召回结果看是偏大还是偏小
- 再结合文档类型逐步分流
因为真正有效的 chunk size,往往不是一次拍脑袋定出来的,而是在检索表现里迭代出来的。
怎么判断当前 chunk 更可能是太大还是太小
如果你经常看到这些现象,通常更像 chunk 太大:
- 高分结果看起来相关,但读进去全是大段无关背景
- 模型回答总是泛泛而谈,抓不到具体限制条件
- 上下文成本很快膨胀
如果你经常看到这些现象,通常更像 chunk 太小:
- 召回结果很多,但都像碎片
- 模型回答缺前提、缺例外条件
- 需要拿很多块拼起来才能勉强回答一个简单问题
一句话总结
Chunk 应该切多大,没有统一答案。因为这不是一个孤立的参数,而是在平衡“命中局部内容的能力”和“保留完整语义的能力”。真正合适的 chunk 大小,取决于文档类型、问题粒度和后续检索链路到底要怎么用它。