Skip to content

14.1.2 Chunk 不是越小越好,也不是越大越好,为什么? ​

先给结论:Chunk 的目标不是“尽量小”或“尽量大”,而是让检索结果同时具备“可命中”和“可解释”两种能力。

很多人做 RAG,最先调整的参数就是 chunk_size。这很正常,因为它最直观,也最容易改。
但真正的问题是:chunk 大小不是一个孤立参数,而是语义完整性、检索粒度、上下文预算之间的平衡。

所以 chunk 不存在一个放之四海而皆准的“最佳值”。
你真正要追求的是:检索回来的片段能不能单独承担解释责任。

chunk 太小,会发生什么 ​

chunk 太小最直接的问题是碎片化。常见表现包括:

  • 一句话看起来相关,但缺上下文
  • 步骤和注意事项被拆开
  • 主条款和例外条款被拆开
  • 检索结果像答案,但永远少半句

这类问题在下面几种文档里尤其明显:

  • API 文档中的参数说明和限制条件
  • 操作手册中的步骤与异常处理
  • 规则制度中的正文与补充条款

表面上看,你提高了检索粒度;实际上你切断了语义闭环。

chunk 太大,会发生什么 ​

chunk 太大也会带来另一种失效:

  • 关键信号被大量背景文字稀释
  • 一个 chunk 混入多个主题
  • 相似度匹配被噪声干扰
  • 模型读到了很多信息,但抓不住真正关键的部分

这时你常看到的现象不是“完全找不到”,而是“总能找到一些像答案的内容,但不够准”。

所以大 chunk 的问题,不是检索不到,而是召回结果不够聚焦。

为什么这个问题不能靠一个固定数字解决 ​

因为不同数据的自然边界不一样。

例如:

  • FAQ 类内容本来就短,通常可以切得更细
  • 操作文档需要保留步骤连续性,不能切太碎
  • 法规、合同、制度类内容需要保留完整条款和例外条件
  • 代码和配置类内容更适合按函数、类、配置块等结构边界切

如果你拿一个固定长度去切所有文档,通常只会有一部分类型表现正常。

怎么判断当前 chunk 是偏小还是偏大 ​

你可以用下面几个信号判断:

偏小的信号 ​

  • 检索结果经常只有半句有效信息
  • 同一个问题需要拼接前后两块才能看明白
  • 模型回答总漏掉限制条件或前置条件

偏大的信号 ​

  • 检索结果总是很长,但真正相关的内容只占一小段
  • 相似度还可以,但答案经常被背景信息带偏
  • 不同问题命中同一大段内容,区分度很差

更关键的信号 ​

不要只看“能不能搜到相关内容”,还要看:
这个 chunk 被单独拿出来时,是否足以支撑一个清晰回答。

如果不能,它就不是理想的回答单元。

一个更靠谱的调法 ​

与其凭感觉改,不如按下面的顺序做:

  1. 先选 20 到 50 个典型问题做最小评测集
  2. 为每个问题记录理想证据大致应该出现在哪类片段里
  3. 用当前切块策略跑一遍,判断“缺上下文”还是“噪声过多”更常见
  4. 如果更常缺上下文,适当增大 chunk 或提高 overlap
  5. 如果更常噪声过多,适当减小 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 的最佳大小,不是“越小越好”,也不是“越大越好”,而是“让检索结果既能命中问题,又能独立承担解释责任”。