CharacterTextSplitter - 按固定字符数分块

- 实现方式:通过CharacterTextSplitter指定chunk_size(如1000字符)和chunk_overlap(重叠字符数)
- 特点:
- 简单粗暴,直接按字符数切割
- 默认以段落(\n\n)为分隔符,也可指定逗号、句号等
- 若段落超过设定值(如2000字符),会保持原段落不分块
- 局限性:不够智能,可能破坏语义完整性
示例代码
1 | from langchain_community.document_loaders import TextLoader |
执行结果,输出内容
1 | === 文档分块结果 === |
RecursiveCharacterTextSplitter – 递归分块

- 实现原理:
- 定义优先级分隔符列表(如[“\n\n”, “.”, “,”, “ “])
- 先尝试第一个分隔符,若块过大则尝试下一个
- 优势:
- 切割更精细(可细化到句子、短语级别)
- 通过多级分隔符保证块大小接近设定值
- 注意事项:
- 分隔符不宜过细(如空格),否则会破坏语义
- 英文中”.”需注意区分小数点和句号
- 对比固定分块:
- 相同设定下,递归分块数更多(如100字符设定产生22块 vs 固定分块11块)
- 但过度分割可能导致关键信息断裂(如价格”1.5元”被拆分为”1”和”.5元”)
示例代码
1 | from langchain_community.document_loaders import TextLoader |
执行结果,输出内容
1 |
|
分块的重要性
示例代码
1 | import os |
调整块的大小
- 关键发现:
- 100字符分块:返回错误答案$1.938B(无意义数值)
- 150字符分块:返回$1.524B(2021年正确值,但非问题要求的2022年)
- 250字符分块:正确返回$482M(2022年实际值)
- 原理分析:
- 过小分块割裂表格数据关联性
- 适当分块保留完整表格结构,使模型能正确对应年份与数值
- 过大分块(如2500字符)可能引入干扰信息
基于特定格式(如代码)分块
- 普通分块问题:
- 函数定义被强行拆分
- 类成员变量与方法分离
- 语言专用分块:
- 按class和def自然分割
- 保留完整类结构(如CombatSystem类完整包含所有方法)
- 支持多种语言(Python/Java/SQL等)的语法感知分割
示例代码
1 | from langchain_text_splitters import RecursiveCharacterTextSplitter |
执行结果,输出内容:
1 | ['\nfunction ', '\nconst ', '\nlet ', '\nvar ', '\nclass ', '\nif ', '\nfor ', '\nwhile ', '\nswitch ', '\ncase ', '\ndefault ', '\n\n', '\n', ' ', ''] |
语义分块
示例代码
1 | from llama_index.core import SimpleDirectoryReader |
- buffer_size参数:
- 默认值为1,控制评估语义相似度时组合的句子数量
- 设置为1时每个句子单独考虑
- 设置为3时每3个句子作为一组评估相似度
- breakpoint_percentile_threshold参数:
- 默认值为95,控制创建分割点的阈值
- 表示余弦不相似度的百分位数值
- 数值越小生成的节点越多(更容易达到分割值)
- 数值越大生成的节点越少(需要更大不相似度才会分割)
参数组合影响:
buffer_size:默认值为1
- 这个参数控制评估语义相似度时,将多少个句子组合在一起当设置为1时,每个句子会被单独考虑
当设置大于1时,会将多个句子组合在一起进行评估例如,如果设置为3,就会将每3个句子作为一个组来评估语义相似度
- 这个参数控制评估语义相似度时,将多少个句子组合在一起当设置为1时,每个句子会被单独考虑
breakpoint_percentile_threshold:默认值为95
- 这个参数控制何时在句子组之间创建分割点,它表示余弦不相似度的百分位数阈值,当句子组之间的不相似度超过这个阈值时,就会创建一个新的节点
- 数值越小,生成的节点就越多(因为更容易达到分割阈值)
- 数值越大,生成的节点就越少(因为需要更大的不相似度才会分割)
- 这个参数控制何时在句子组之间创建分割点,它表示余弦不相似度的百分位数阈值,当句子组之间的不相似度超过这个阈值时,就会创建一个新的节点
这两个参数共同影响文本的分割效果:
buffer_size 决定了评估语义相似度的粒度
breakpoint_percentile_threshold 决定了分割的严格程度
例如:
- 如果 buffer_size=2 且 breakpoint_percentile_threshold=90:每2个句子会被组合在一起,当组合之间的不相似度超过90%时就会分割,这会产生相对较多的节点
- 如果 buffer_size=3 且 breakpoint_percentile_threshold=98:每3个句子会被组合在一起,需要更大的不相似度才会分割,这会产生相对较少的节点
基础句子分块与语义分块特点
- 基础句子分块特点:
- 按固定字符数机械划分
- 不考虑内容语义连贯性
- 实现简单但可能切断语义关联
- 语义分块特点:
- 基于内容语义自动划分
- 识别主题边界形成自然段落
- 适合内容结构复杂的文档
使用Unstructured基于文档结构分块
基于对文档语义结构的识别,而非简单地根据空行或换行符来拆分文本。
- Basic策略 将文本元素顺序合并到同一个分块内,直到达到最大字符数(max_characters)或软限制(new_after_n_chars)。如果单个元素(如一段特别长的正文或一张很大的表格)本身超过了最大字符数,则会对该元素进行二次拆分。表格元素会被视为独立的分块;如果表格过大,也会被拆分为多个TableChunk。可以通过overlap与overlap_all等参数设置分块重叠。
- By Title策略 在保留Basic策略的基础行为的同时,会在检测到新的标题(Title元素)后立刻关闭当前分块,并开启一个新的分块。可以通过multipage_sections和combine_text_under_n_chars等参数进一步控制如何合并或拆分跨页片段、短小片段等。
通过API调用Unstructured时,还有以下两种额外的智能分块策略。
- lBy Page:确保每页的内容独立分块。
- lBy Similarity:利用嵌入模型将主题相似的元素组合成块。
参考学习地址:https://docs.unstructured.io/api-reference/partition/chunking