中文RAG知识库最常见的失败模式是:问题明明在知识库里,检索却召回不到;或者召回了正确片段,但上下文被切断,模型只能看到一段残缺文字。这类问题往往不是向量模型不够强,而是文本分块这一层就没有做好。

本文聚焦一个工程问题:在中文场景下,chunk_size、chunk_overlap、分词器选择如何影响检索效果,以及如何用可验证的方法找到适合自己知识库的参数组合。

1. 先理解中文分块的特殊约束

英文文本天然以空格和标点作为边界,按字符或Token切分通常能维持语义单元完整。中文没有这类显式边界,直接按固定字符数切分,很容易出现三种问题:

  • 语义截断:一个完整概念被从中间切开,导致向量表示偏离原意;
  • 召回碎片化:检索命中的chunk只覆盖问题的一部分,无法提供完整上下文;
  • 跨chunk实体断裂:人名、机构名、产品名被拆成两个不完整片段。

从工程角度,中文分块应该同时考虑字符串边界和语义边界,而不是只追求固定长度。

2. 参数调优的核心是验证方法

很多团队在调chunk_size时,凭感觉在500、800、1000之间来回试,最后用一两个示例问题判断效果。这种做法最大的问题是样本太小,无法区分参数影响和偶然波动。

一个可执行的验证流程是:

  1. 从真实使用场景整理50~100个测试问题,覆盖知识库的典型查询类型;
  2. 对每个问题标注期望命中的原文段落或期望答案来源;
  3. 对不同分块参数组合进行检索,记录召回命中率、答案完整性、是否需要多跳检索;
  4. 对失败案例进行归类,判断是分块粒度问题、overlap不足问题,还是分词边界问题。

这个流程不需要引入复杂的评测框架。只要把测试集和判定规则固定下来,就能比较不同参数的相对优劣。

3. chunk_size:从业务问题粒度反推

chunk_size不应该是一个从工具文档里抄来的数字,而应该由知识库中最常见的“问题答案单元”决定。

一个有效的判断方法:

  • 如果知识库是操作手册、合同条款、标准规范,答案通常是一整段条文,chunk_size需要覆盖这个长度;
  • 如果知识库是产品FAQ或短说明,答案往往在两三句话内,chunk_size过大会引入噪音;
  • 如果知识库是长文章或研究报告,单个chunk可能不够,还需要依赖检索后的重排或上下文拼接。

实际操作中,可以先用250、500、800、1200等几个梯度做粗筛,然后围绕效果最好的区间做细调。重点不是找到全局最优值,而是确定一个适合自己知识库的区间。

4. chunk_overlap:处理跨块语义断裂

chunk_overlap存在的意义,是为了避免一个完整的语义单元恰好被切到两个chunk边界上。它在两个场景下尤其重要:

  • 段落之间没有明确空行,直接连续切分;
  • 回答依赖前文定义的术语、缩写或前提条件。

但overlap不是越大越好。过大的overlap会导致同一内容被重复embedding,增加存储和检索成本,也可能让检索结果中出现大量近似重复文本。一个比较稳妥的做法是:overlap设置为chunk_size的10%~20%,然后通过测试集验证是否仍有边界断裂问题。

如果发现大量失败案例都指向“答案被切断”,优先考虑增大overlap;如果失败案例是“检索结果重复度高,有效信息密度低”,则应该调小overlap。

5. 分词器选择:按语言特性区分

英文RAG常用的splitter大多以空格、标点或换行为边界。中文场景下,直接用这类splitter会把连续中文切成固定长度的字符块,语义边界几乎完全丢失。

可考虑的方案大致有三类:

  • 基于标点与换行的分块:先按句号、分号、换行等边界切分子句,再合并为符合chunk_size要求的块。这种方式更接近语义段落,是中文RAG中常见的工程做法。
  • 基于词边界的分块:利用分词工具识别词边界后再组装chunk。词边界有助于减少实体截断,但依赖分词质量和额外计算资源。
  • 基于结构的递归分块:按章节、段落、句子、字符的优先级逐层递归切分,先保留结构完整性,再适配长度限制。

这三类方案不是互斥的。很多实际项目采用“按结构优先、按长度兜底”的混合策略。

选型时需要注意:分词器是否支持中文,是否保留标点,是否支持自定义词典,是否能在批量切分时有足够吞吐。对于垂直领域知识库(如法律、医疗、金融),自定义词典往往比通用分词模型更重要。

6. 中文场景下的参数优先级

基于检索失败案例的常见分布,调参优先级可以这样安排:

  1. chunk_size:决定答案单元是否完整,优先级最高;
  2. 分割边界规则:决定语义边界是否被尊重,优先级与chunk_size相当;
  3. chunk_overlap:解决边界断裂,但不解决chunk_size不合适带来的整体偏差;
  4. 分词器/分块器选择:影响边界质量,但如果chunk_size已经明显不合理,更换分词器收效有限。

从工程角度看,先固定一个合理的分块策略,再调整长度参数,比频繁更换分块器更有效。

7. 从错误案例迭代参数

参数调优不是一次性实验。分块效果最终要由检索结果来验证。

建议建立一个简单的错误案例库,每条记录包含:原始问题、期望命中的段落、实际命中的chunk、失败类型。常见的失败类型有:

  • 粒度过大:chunk覆盖多个主题,query向量被稀释;
  • 粒度过小:答案被截断,召回后无法生成完整回答;
  • overlap不足:答案跨越两个chunk,单个chunk都不完整;
  • 边界规则不当:列表、表格、代码块被拆碎。

每轮调整后,用同一组测试集对比命中率,并把新增失败案例归入类型。这样积累两三轮后,参数调整会从“猜”变成“基于证据的迭代”。

8. 与向量模型、检索后处理的配合

分块参数不是孤立变量。它和向量模型的输入长度限制、检索TopK、重排策略共同决定最终的召回质量。

一种常见的工程误区是:分块长度超过向量模型的输入上限,导致embedding前被静默截断。另一种误区是:把TopK设得过小,即使分块合理,也无法覆盖跨块知识。

此外,中文长文档中,如果单个chunk无法承载完整答案,可以考虑在检索后拼接相邻chunk,或者将父子块关联作为补充上下文。这部分依赖具体RAG框架的实现,不一定是所有方案都支持。

9. 总结

中文RAG的分块调优,本质上是在回答一个问题:知识库中的答案单元是什么形状,如何让检索单元尽可能贴合它。

没有一套参数能适配所有知识库。真正可复用的是验证方法:建立测试集、固定判定标准、做对比实验、按失败案例归类迭代。把chunk_size、overlap、分词器边界规则放在这条流程里验证,比直接照搬某个项目的“最优参数”可靠得多。