递归分割(recursively),这个文本分割器是用于通用文本的推荐工具。它接受一个字符列表作为参数。它会按顺序尝试在这些字符上进行分割,直到块足够小。默认的字符列表是 ["\n\n", "\n", " ", ""]
。这样做的效果是尽可能保持所有段落(然后是句子,再然后是单词)在一起,因为这些通常看起来是语义上相关的文本块。
下面我们展示一个使用示例。
要直接获取字符串内容,请使用 .split_text
。
要创建 LangChain Document 对象(例如,用于下游任务),请使用 .create_documents
。
%pip install -qU langchain-text-splitters
#示例:recursively_split.py
from langchain_text_splitters import RecursiveCharacterTextSplitter
# 加载示例文档
with open("../../resource/knowledge.txt", encoding="utf-8") as f:
state_of_the_union = f.read()
text_splitter = RecursiveCharacterTextSplitter(
# 设置一个非常小的块大小,只是为了展示。
chunk_size=100,
chunk_overlap=20,
length_function=len,
is_separator_regex=False,
)
texts = text_splitter.create_documents([state_of_the_union])
print(texts[0])
print(texts[1])
让我们来看看上述 RecursiveCharacterTextSplitter
的参数设置:
chunk_size
:块的最大大小,大小由 length_function
决定。chunk_overlap
:块之间的目标重叠。重叠的块有助于在上下文分割时减少信息丢失。length_function
:确定块大小的函数。is_separator_regex
:分隔符列表(默认为 ["\n\n", "\n", " ", ""]
)是否应被解释为正则表达式。一些书写系统没有词边界,例如中文、日文和泰文。使用默认分隔符列表 ["\n\n", "\n", " ", ""]
分割文本可能会导致单词被分割在不同块之间。为了保持单词在一起,您可以覆盖分隔符列表,包括额外的标点符号:
.
",Unicode 全角 句号 ".
"(用于中文文本),以及表意句号 "。
"(用于日文和中文),
",Unicode 全角逗号 ",
",以及 Unicode 表意逗号 "、
"#示例:recursively_separator.py
text_splitter = RecursiveCharacterTextSplitter(
separators=[
"\n\n",
"\n",
" ",
".",
",",
"\u200b", # 零宽空格
"\uff0c", # 全角逗号
"\u3001", # 表意逗号
"\uff0e", # 全角句号
"\u3002", # 表意句号
"",
],
# 已有的参数
)
下面介绍如何根据语义相似性拆分文本块(semantic chunks)。如果嵌入足够远,文本块将被拆分。
在高层次上,这将文本拆分成句子,然后分组为每组3个句子,最后合并在嵌入空间中相似的句子。
#pip install --quiet langchain_experimental langchain_openai
#示例:semantic_split.py
# 这是一个长文档,我们可以将其拆分。
with open("../../resource/knowledge.txt", encoding="utf-8") as f:
knowledge = f.read()
from langchain_experimental.text_splitter import SemanticChunker
from langchain_openai.embeddings import OpenAIEmbeddings
text_splitter = SemanticChunker(OpenAIEmbeddings())
docs = text_splitter.create_documents([knowledge])
print(docs[0].page_content)
这个拆分器的工作原理是确定何时“断开”句子。这是通过查找任意两个句子之间的嵌入差异来完成的。当该差异超过某个阈值时,它们就会被拆分。
有几种方法可以确定该阈值,这由breakpoint_threshold_type
关键字参数控制。
拆分的默认方式是基于百分位数。在此方法中,计算所有句子之间的差异,然后任何大于X百分位数的差异都会被拆分。
#示例:semantic_split_percentile.py
text_splitter = SemanticChunker(
OpenAIEmbeddings(), breakpoint_threshold_type="percentile", breakpoint_threshold_amount=50
)
docs = text_splitter.create_documents([knowledge])
print(docs[0].page_content)