递归字符切分是什么
递归字符切分是目前最常用的默认方案:按分隔符的层级依次尝试断开,先按段落,切不动就按换行,再不行按句号与逗号,尽量让每个片段落在语义边界上,只有实在超长才退到更小的单位。这样切出来的片段读得通、检索命中率也更高。它不依赖模型的 tokenizer,按字符数控制长度,工程上简单稳定。
基本信息
| 原理 | 按分隔符优先级递归切分,优先在语义边界断开 |
|---|---|
| 分隔符顺序 | 通常从段落、换行、句号到更小的标点,逐级降级 |
| 长度口径 | 按字符数控制片段长度,不按 token |
| 重叠 | 相邻片段保留一小段重叠,避免答案被切断 |
| 适用文档 | 结构清晰的说明书、政策文件、技术文档 |
| 局限 | 对表格与代码块的切分效果一般,需要单独处理 |
三个核心参数
| 参数 | 作用 | 取值思路 |
|---|---|---|
| 片段长度 | 单个片段的最大字符数 | 几百到一千字符起步,按文档结构与检索粒度调整 |
| 重叠长度 | 相邻片段共享的字符数 | 取片段长度的百分之十到二十,兼顾上下文与冗余 |
| 分隔符序列 | 按优先级排列的断点 | 中英文文档要把中文标点一并列入 |
| 长度函数 | 计算片段长度的方法 | 复杂场景需按实际分词方式计算 |
| 起始分隔符 | 从哪一级开始尝试 | 结构化文档可从段落开始,纯文本可更细 |
典型使用场景
- 技术文档入库:按章节与段落切分,保持语义完整
- 制度与政策文件:条文边界清晰,按条款切分最合适
- 网页正文清洗后切分:去掉导航与广告后按段落断开
- 多语言资料:中英文混排时同时配置两种标点作为断点
- 作为基线方案:先用它跑通召回效果,再针对问题调优
递归切分示例
递归切分示例
from langchain_text_splitters import RecursiveCharacterTextSplitter
splitter = RecursiveCharacterTextSplitter(
chunk_size=800, # 单片段最大字符数
chunk_overlap=120, # 相邻片段重叠,避免答案被切断
separators=["\n\n", "\n", "。", ";", " "], # 从粗到细的断点
)
chunks = splitter.split_text(document)
print(len(chunks), chunks[0][:80]) # 检查片段开头是否读得通效果调优方向
| 现象 | 原因 | 调整 |
|---|---|---|
| 片段读起来缺头少尾 | 长度太小或重叠不足 | 适当加大片段长度与重叠 |
| 检索命中但不完整 | 答案被切在两个片段之间 | 提高重叠比例,或按标题聚合片段 |
| 片段里混入无关内容 | 文档噪声未清理 | 先过滤页眉页脚与导航再切分 |
| 表格被切碎 | 按字符切分破坏表格结构 | 表格单独解析并整体保留 |
| 小片段过多 | 分隔符过细,句子被拆成碎片 | 减少细粒度分隔符,优先在段落断开 |
切分没有通用最优值:同一套参数在不同文档上表现差别很大,用评测集对比召回效果才是判断依据。
把重叠设得过大是常见浪费:片段数量成倍增加,入库与检索成本上升,但召回不一定改善。