Appearance
14.1.2 Chunk 不是越小越好,也不是越大越好,为什么?
先给结论:Chunk 的目标不是“尽量小”或“尽量大”,而是让检索结果同时具备“可命中”和“可解释”两种能力。
很多人做 RAG,最先调整的参数就是 chunk_size。这很正常,因为它最直观,也最容易改。
但真正的问题是:chunk 大小不是一个孤立参数,而是语义完整性、检索粒度、上下文预算之间的平衡。
所以 chunk 不存在一个放之四海而皆准的“最佳值”。
你真正要追求的是:检索回来的片段能不能单独承担解释责任。
chunk 太小,会发生什么
chunk 太小最直接的问题是碎片化。常见表现包括:
- 一句话看起来相关,但缺上下文
- 步骤和注意事项被拆开
- 主条款和例外条款被拆开
- 检索结果像答案,但永远少半句
这类问题在下面几种文档里尤其明显:
- API 文档中的参数说明和限制条件
- 操作手册中的步骤与异常处理
- 规则制度中的正文与补充条款
表面上看,你提高了检索粒度;实际上你切断了语义闭环。
chunk 太大,会发生什么
chunk 太大也会带来另一种失效:
- 关键信号被大量背景文字稀释
- 一个 chunk 混入多个主题
- 相似度匹配被噪声干扰
- 模型读到了很多信息,但抓不住真正关键的部分
这时你常看到的现象不是“完全找不到”,而是“总能找到一些像答案的内容,但不够准”。
所以大 chunk 的问题,不是检索不到,而是召回结果不够聚焦。
为什么这个问题不能靠一个固定数字解决
因为不同数据的自然边界不一样。
例如:
- FAQ 类内容本来就短,通常可以切得更细
- 操作文档需要保留步骤连续性,不能切太碎
- 法规、合同、制度类内容需要保留完整条款和例外条件
- 代码和配置类内容更适合按函数、类、配置块等结构边界切
如果你拿一个固定长度去切所有文档,通常只会有一部分类型表现正常。
怎么判断当前 chunk 是偏小还是偏大
你可以用下面几个信号判断:
偏小的信号
- 检索结果经常只有半句有效信息
- 同一个问题需要拼接前后两块才能看明白
- 模型回答总漏掉限制条件或前置条件
偏大的信号
- 检索结果总是很长,但真正相关的内容只占一小段
- 相似度还可以,但答案经常被背景信息带偏
- 不同问题命中同一大段内容,区分度很差
更关键的信号
不要只看“能不能搜到相关内容”,还要看:
这个 chunk 被单独拿出来时,是否足以支撑一个清晰回答。
如果不能,它就不是理想的回答单元。
一个更靠谱的调法
与其凭感觉改,不如按下面的顺序做:
- 先选 20 到 50 个典型问题做最小评测集
- 为每个问题记录理想证据大致应该出现在哪类片段里
- 用当前切块策略跑一遍,判断“缺上下文”还是“噪声过多”更常见
- 如果更常缺上下文,适当增大 chunk 或提高 overlap
- 如果更常噪声过多,适当减小 chunk,或改成结构感知切块
结构感知切块通常比纯长度切块更稳,例如:
python
from langchain_text_splitters import RecursiveCharacterTextSplitter
splitter = RecursiveCharacterTextSplitter(
chunk_size=800,
chunk_overlap=120,
separators=["\n## ", "\n### ", "\n\n", "\n", " ", ""],
)
chunks = splitter.split_text(text)这里最重要的不是具体数字,而是切分优先级:先按标题和段落边界切,保住结构,再退化到更细粒度。
常见误区
误区一:用固定大小解决所有文档
切块策略应该跟数据结构走,而不是跟一个统一数字走。
误区二:只看召回率
召回到了并不代表能解释。
真正要关注的是:召回结果能不能构成一个完整、稳定、可引用的答案证据。
一句话总结
Chunk 的最佳大小,不是“越小越好”,也不是“越大越好”,而是“让检索结果既能命中问题,又能独立承担解释责任”。