(LangChain实战18):LangChain文本分割器的介绍与使用
·
LangChain文本分割器详解
一、基础准备
from langchain_community.document_loaders import TextLoader
from langchain_text_splitters import CharacterTextSplitter, RecursiveCharacterTextSplitter
# 加载文档
file_path = "./file/常见问题.txt"
text_load = TextLoader(file_path=file_path, encoding="utf-8")
docs = text_load.load()
# 假设常见问题.txt内容如下:
"""
欢迎使用我们的产品!
常见问题汇总:
问:如何注册账号?
答:点击首页右上角的注册按钮,填写手机号和验证码即可完成注册。
问:忘记密码怎么办?
答:在登录页面点击"忘记密码",通过手机验证码重置密码。
问:如何联系客服?
答:可以通过在线客服、客服电话400-123-4567或发送邮件到support@example.com联系我们。
技术支持电话:400-123-4567
服务时间:周一至周日 9:00-21:00
"""
二、CharacterTextSplitter的两种分割方式
方式1:禁用分隔符的字符级分割
for doc in docs:
splitter = CharacterTextSplitter(
chunk_size=50,
chunk_overlap=5,
separator="" # 空字符串,禁用分隔符
)
contents = splitter.split_text(doc.page_content)
for e, content in enumerate(contents):
print(f"{e+1}、{content}")
# 输出示例:
# 1、欢迎使用我们的产品!
#
# 常见问题汇总:
#
# 问:如何注册
# 2、册账号?
# 答:点击首页右上角的注册按钮,填写
# 3、写手机号和验证码即可完成注册。
#
# 问:忘记密码
# 4、码怎么办?
# 答:在登录页面点击"忘记密码",通过
# 5、过手机验证码重置密码。
#
# 问:如何联系
# 6、系客服?
# 答:可以通过在线客服、客服电话400-
# 7、-123-4567或发送邮件到support@exa
# 8、ample.com联系我们。
#
# 技术支持电
# 9、电话:400-123-4567
# 服务时间:周一至周日 9:00-21:00
特点:简单粗暴,按字符数硬切,可能切断完整句子(如"注册"被切成"册"和"账号")
方式2:指定分隔符的段落级分割
for doc in docs:
splitter = CharacterTextSplitter(
chunk_size=150, # 调小以便看到分割效果
chunk_overlap=20,
separator="\n\n" # 按段落分割
)
contents = splitter.split_text(doc.page_content)
for e, content in enumerate(contents):
print(f"块 {e+1} (长度: {len(content)} 字符):")
print(content)
print("-" * 40)
# 输出示例:
# 块 1 (长度: 47 字符):
# 欢迎使用我们的产品!
#
# 常见问题汇总:
# ----------------------------------------
# 块 2 (长度: 122 字符):
# 问:如何注册账号?
# 答:点击首页右上角的注册按钮,填写手机号和验证码即可完成注册。
# ----------------------------------------
# 块 3 (长度: 96 字符):
# 问:忘记密码怎么办?
# 答:在登录页面点击"忘记密码",通过手机验证码重置密码。
# ----------------------------------------
# 块 4 (长度: 148 字符):
# 问:如何联系客服?
# 答:可以通过在线客服、客服电话400-123-4567或发送邮件到support@example.com联系我们。
#
# 技术支持电话:400-123-4567
# 服务时间:周一至周日 9:00-21:00
# ----------------------------------------
特点:先按段落切,保持语义完整,超过阈值才进一步切分
三、RecursiveCharacterTextSplitter递归分割
for doc in docs:
splitter = RecursiveCharacterTextSplitter(
chunk_size=100, # 调小以便看到递归效果
chunk_overlap=20,
separators=["\n\n", "\n", "。", "?", ",", " ", ""],
keep_separator=True,
length_function=len,
)
contents = splitter.split_text(doc.page_content)
for e, content in enumerate(contents):
print(f"块 {e + 1} (长度: {len(content)} 字符):")
print(content)
print("-" * 40)
# 输出示例:
# 块 1 (长度: 47 字符):
# 欢迎使用我们的产品!
#
# 常见问题汇总:
# ----------------------------------------
# 块 2 (长度: 98 字符):
# 问:如何注册账号?
# 答:点击首页右上角的注册按钮,填写手机号和验证码即可完成注册。
# ----------------------------------------
# 块 3 (长度: 96 字符):
# 问:忘记密码怎么办?
# 答:在登录页面点击"忘记密码",通过手机验证码重置密码。
# ----------------------------------------
# 块 4 (长度: 97 字符):
# 问:如何联系客服?
# 答:可以通过在线客服、客服电话400-123-4567或发送邮件到support@example.com联系我们。
# ----------------------------------------
# 块 5 (长度: 49 字符):
# 技术支持电话:400-123-4567
# 服务时间:周一至周日 9:00-21:00
# ----------------------------------------

特点:智能递归,优先按段落切,段落超长再按句子切,保持语义完整性
四、其他分割方式(补充)
1. TokenTextSplitter(按token数分割)
from langchain_text_splitters import TokenTextSplitter
text = "LangChain is a framework for developing applications powered by language models."
splitter = TokenTextSplitter(chunk_size=5, chunk_overlap=1)
chunks = splitter.split_text(text)
for i, chunk in enumerate(chunks):
print(f"Chunk {i+1}: {chunk}")
# 输出示例:
# Chunk 1: LangChain is a framework for
# Chunk 2: for developing applications powered by
# Chunk 3: by language models.
2. MarkdownHeaderTextSplitter(保留层级)
from langchain_text_splitters import MarkdownHeaderTextSplitter
markdown_text = """
# 第一章:引言
这是引言内容...
## 1.1 背景
背景介绍...
## 1.2 目标
目标说明...
# 第二章:方法
方法介绍...
"""
headers_to_split_on = [
("#", "Header 1"),
("##", "Header 2"),
]
splitter = MarkdownHeaderTextSplitter(headers_to_split_on)
chunks = splitter.split_text(markdown_text)
for chunk in chunks:
print(f"元数据: {chunk.metadata}")
print(f"内容: {chunk.page_content[:30]}...")
print("-" * 30)
# 输出示例:
# 元数据: {'Header 1': '第一章:引言'}
# 内容: 这是引言内容......
# ------------------------------
# 元数据: {'Header 1': '第一章:引言', 'Header 2': '1.1 背景'}
# 内容: 背景介绍......
# ------------------------------
# 元数据: {'Header 1': '第一章:引言', 'Header 2': '1.2 目标'}
# 内容: 目标说明......
# ------------------------------
# 元数据: {'Header 1': '第二章:方法'}
# 内容: 方法介绍......
# ------------------------------
3. PythonCodeTextSplitter(代码分割)
from langchain_text_splitters import PythonCodeTextSplitter
python_code = """
def hello_world():
print("Hello, World!")
class Calculator:
def add(self, a, b):
return a + b
def subtract(self, a, b):
return a - b
# 主程序
if __name__ == "__main__":
calc = Calculator()
result = calc.add(5, 3)
print(f"5 + 3 = {result}")
"""
splitter = PythonCodeTextSplitter(chunk_size=50, chunk_overlap=10)
chunks = splitter.split_text(python_code)
for i, chunk in enumerate(chunks):
print(f"代码块 {i+1}:")
print(chunk)
print("-" * 30)
# 输出示例:
# 代码块 1:
# def hello_world():
# print("Hello, World!")
# ------------------------------
# 代码块 2:
# class Calculator:
# def add(self, a, b):
# return a + b
# ------------------------------
# 代码块 3:
# def subtract(self, a, b):
# return a - b
# ------------------------------
# 代码块 4:
# # 主程序
# if __name__ == "__main__":
# calc = Calculator()
# result = calc.add(5, 3)
# ------------------------------
# 代码块 5:
# print(f"5 + 3 = {result}")
# ------------------------------
五、优缺点对比
| 分割方式 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| CharacterTextSplitter | 简单易用,控制精确 | 语义完整性差 | 测试、简单文本 |
| RecursiveCharacterTextSplitter | 语义保留好,智能灵活 | 性能略低 | 通用场景(最常用) |
| TokenTextSplitter | 匹配LLM token限制 | 可能切词 | LLM精确控制 |
| MarkdownHeaderTextSplitter | 保留文档结构 | 仅限markdown | 技术文档 |
| CodeTextSplitter | 符合代码结构 | 仅限代码 | 代码处理 |
六、推荐使用
RecursiveCharacterTextSplitter 是最常用、最通用的选择,智能平衡语义和长度限制,适合大多数文本处理场景。从输出示例可以看出,它能较好地保持句子和段落的完整性。
更多推荐


所有评论(0)