Skip to main content

Recursive Splitter

Written: 2026.06

1. 为什么需要这讲

本项目的文档切分(第 3 讲和第 16 讲)使用 LangChain 的 RecursiveCharacterTextSplitter,这是整个入库链路中最关键的参数决策点。主讲义只展示了分隔符列表,没有解释递归降级切分的核心算法。理解这个算法才能理解为什么 chunk_size 和 overlap 的设置会影响检索质量。

2. 朴素切分的问题

最直观的切分方式是定长切分:每 N 个字符切一刀。
问题:
  • 句子被从中间切断,语义不完整
  • LLM 看到”签订劳动”和”合同和保密协议”两个碎片,不如看到一个完整的”签订劳动合同和保密协议”

3. 递归降级切分算法

RecursiveCharacterTextSplitter 的核心思想:用一组分隔符,从粗到细递归尝试

4. 具体例子

假设有如下文本(chunk_size=200):
第一轮:尝试 \n\n(段落)
全部在 200 以内 → 完成!三个按段落划分的 chunk,语义边界完美。 但如果 chunk_size=50

5. Overlap 的作用

chunk_overlap 让相邻 chunk 之间有重叠内容:
对于中文,本项目配置:

6. Markdown 文件的特殊处理

对于 .md 文件,LangChain 提供了一个增强切分器:
这使得后续 LLM 生成的答案可以引用”来源:入职管理 > 入职流程”这样的层级结构。

7. 表格文件的特殊保护

这是本项目的一个重要设计:表格行的内容(表头+行号+单元格键值对)是一个完整的语义单元。递归切分会破坏这个完整性。

8. chunk_size 调优的权衡

本项目的选择(父块 2000 + 子块 500)是一种折中:
  • 用子块(500)做检索 → 精确
  • 用父块(2000)给 LLM → 完整

9. 小结

  • 递归降级:从段落 → 换行 → 句号 → 逗号 → 字符,逐步降级
  • 优先级:优先在语义边界切分,只在必要时才强制截断
  • Overlap:防止切分边界切断关键信息
  • 父子块策略:子块检索 + 父块生成,兼顾精度和完整性
  • 表格保护:表格行不参与递归切分,保持语义单元完整