文本分割器
- 文档
- Tokenization(/docs/concepts/tokens)
概览
文档分割通常是许多应用中的关键预处理步骤。 它涉及将大段文本拆分为更小、更易管理的片段。 这一过程具有多种优势,例如确保对不同长度文档的一致处理、克服模型输入大小限制,以及提升检索系统中使用的文本表示质量。 有多种文档分割策略,每种策略都有其独特的优势。
核心概念

文本分割器将文档拆分为更小的片段,以便在下游应用中使用。
为什么要拆分文档?
拆分文档有几个原因:
- 处理非统一的文档长度: 现实世界中的文档集合通常包含不同大小的文本。分割可以确保所有文档的一致性处理。
- 克服模型限制: 许多嵌入模型和语言模型都有最大输入大小的限制。分割允许我们处理那些原本会超出这些限制的文档。
- 提高表示质量: 对于较长的文档,嵌入或其他表示的质量可能会下降,因为它们试图捕捉过多的信息。分割可以导致每个部分的表示更加专注和准确。
- 提升检索精度: 在信息检索系统中,分割可以提高搜索结果的粒度,从而更精确地将查询与相关文档部分匹配。
- 优化计算资源: 使用较小的文本块可以更节省内存,并有助于更好地并行化处理任务。
现在,下一个问题是 如何 将文档拆分为块!有几种策略,每种都有其优势。
- 查看 Greg Kamradt 的 chunkviz,以可视化下面讨论的不同分割策略。
方法
Length-based
最直观的策略是根据文档的长度来分割文档。这种简单而有效的方法可以确保每个片段的大小不超过指定的限制。 基于长度分割的主要优势:
- 直接实现
- 一致的块大小
- 易于适应不同的模型需求
基于长度的分割类型:
- 基于令牌: 根据令牌数量分割文本,这在使用语言模型时非常有用。
- 基于字符: 根据字符数量分割文本,这在不同类型的文本中可能更加一致。
使用 LangChain 的 CharacterTextSplitter 结合基于标记的分割的示例实现:
from langchain_text_splitters import CharacterTextSplitter
text_splitter = CharacterTextSplitter.from_tiktoken_encoder(
encoding_name="cl100k_base", chunk_size=100, chunk_overlap=0
)
texts = text_splitter.split_text(document)
- 查看有关基于标记的分割的指南。
- 查看关于按字符分割的指南。
基于文本结构的
文本自然地组织成段落、句子和单词等层次结构。
我们可以利用这种固有结构来指导我们的分割策略,创建出保持自然语言流畅性、在分割内保持语义连贯性,并能适应不同文本粒度级别的分割。
LangChain的 RecursiveCharacterTextSplitter 实现了这一概念:
RecursiveCharacterTextSplitter试图保持较大的单元(例如段落)完整。- 如果一个单元超过块大小,它将移动到下一个级别(例如,句子)。
- 如果需要,此过程将继续到单词级别。
以下是使用示例:
from langchain_text_splitters import RecursiveCharacterTextSplitter
text_splitter = RecursiveCharacterTextSplitter(chunk_size=100, chunk_overlap=0)
texts = text_splitter.split_text(document)
- 查看有关递归文本分割的操操作指南。
基于文档结构的
某些文档具有固有的结构,例如 HTML、Markdown 或 JSON 文件。 在这些情况下,根据文档的结构进行分割是有益的,因为这通常能自然地将语义相关的文本分组。 基于结构分割的主要优势:
- 保持文档的逻辑结构
- 保持每个块内的上下文
- 对于检索或摘要等下游任务可能更有效。
基于结构的分割示例:
- Markdown: 基于标题分割(例如,#,##,###)
- HTML: 使用标签进行拆分
- JSON: 按对象或数组元素分割
- 代码: 按函数、类或逻辑块分割
- 查看关于 Markdown拆分 的操操作指南。
- 查看有关 递归JSON拆分 的指南。
- 查看有关 代码分割 的指南。
- 查看有关HTML拆分的操操作指南。
基于语义意义的
与之前的方法不同,基于语义的分割实际上考虑了文本的内容。 与其他方法使用文档或文本结构作为语义含义的代理不同,此方法直接分析文本的语义。 实现这一方法有几种方式,但其概念上是当文本的含义发生显著变化时进行分割。 例如,我们可以使用滑动窗口方法生成嵌入向量,并通过比较嵌入向量来发现显著差异:
- 从前几句开始并生成嵌入。
- 移动到下一组句子并生成另一个嵌入(例如,使用滑动窗口方法)。
- 比较嵌入向量以发现显著差异,这些差异表明语义段落之间可能存在“断点”。
这种技术有助于创建语义上更连贯的文本块,从而可能提升下游任务(如信息检索或摘要生成)的质量。
- 查看如何根据语义意义拆分文本的指南splitting text based on semantic meaning。
- 查看Greg Kamradt的笔记本,了解语义分割的展示。