Skip to main content
在 GitHub 上打开

文本拆分器

先决条件
  • 文件
  • 分词 (/docs/concepts/tokens)

概述

对于许多应用程序来说,文档拆分通常是一个关键的预处理步骤。 它涉及将大文本分解成更小的、可管理的块。 此过程提供了多种好处,例如确保对不同文档长度的一致处理、克服模型的输入大小限制以及提高检索系统中使用的文本表示的质量。 拆分文档有几种策略,每种策略都有自己的优点。

关键概念

概念概述

文本拆分器将文档拆分为较小的块,以便在下游应用程序中使用。

为什么要拆分文档?

拆分文档的原因有以下几个:

  • 处理不统一的文档长度:实际文档集合通常包含不同大小的文本。拆分可确保所有文档之间的一致处理。
  • 克服模型限制:许多嵌入模型和语言模型具有最大输入大小限制。拆分允许我们处理超出这些限制的文档。
  • 提高表示质量:对于较长的文档,嵌入或其他表示的质量可能会降低,因为它们会尝试捕获太多信息。拆分可以使每个部分的表示更加集中和准确。
  • 提高检索精度:在信息检索系统中,拆分可以提高搜索结果的粒度,从而允许更精确地将查询与相关文档部分进行匹配。
  • 优化计算资源:使用较小的文本块可以提高内存效率,并允许更好地并行处理任务。

现在,下一个问题是如何将文档拆分为块!有几种策略,每种策略都有自己的优势。

延伸阅读
  • 请参阅 Greg Kamradt 的 chunkviz 来可视化下面讨论的不同拆分策略。

方法

基于长度

最直观的策略是根据文档的长度来拆分文档。这种简单而有效的方法可以确保每个数据块不超过指定的大小限制。 基于长度的分割的主要优点:

  • 直接实施
  • 一致的块大小
  • 轻松适应不同的模型要求

基于长度的分割类型:

  • 基于标记:根据标记数拆分文本,这在使用语言模型时非常有用。
  • 基于字符:根据字符数拆分文本,这在不同类型的文本中可以更加一致。

使用 LangChain 的CharacterTextSplitter使用基于 Token 的拆分:

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:按对象或数组元素拆分
  • 代码:按函数、类或逻辑块拆分
延伸阅读

基于语义意义

与之前的方法不同,基于语义的拆分实际上考虑了文本的内容。 虽然其他方法使用文档或文本结构作为语义含义的代理,但这种方法直接分析文本的语义。 有几种方法可以实现这一点,但从概念上讲,当文本含义发生重大变化时,该方法是拆分文本。 例如,我们可以使用滑动窗口方法来生成嵌入,并比较嵌入以发现显著差异:

  • 从前几个句子开始,然后生成一个嵌入。
  • 移动到下一组句子并生成另一个嵌入(例如,使用滑动窗口方法)。
  • 比较嵌入以发现显著差异,这表明语义部分之间可能存在 “断点”。

这种技术有助于创建语义上更加连贯的块,从而有可能提高下游任务(如检索或摘要)的质量。

延伸阅读