在 LangChain 中,langchain.text_splitter
模块提供了一系列工具类,用于将长文本分割成较小的块(chunks),以便于处理、嵌入生成或存储到向量数据库。该模块是构建检索增强生成(RAG)系统、文档索引或其他需要文本预处理的场景中的关键组件。
本文基于 LangChain 0.3.x,全面介绍 langchain.text_splitter
模块中的所有文本分割器,列出其功能、参数、适用场景,并提供代码示例,展示如何在 RAG 系统中使用不同分割器(以 RecursiveCharacterTextSplitter
为例,扩展 CharacterTextSplitter
)。
langchain.text_splitter
模块概述
langchain.text_splitter
模块包含多种文本分割器(TextSplitter
的子类),用于将长文本或文档分割为适合嵌入模型(如 OpenAIEmbeddings
)或语言模型(LLM)处理的块。分割器的核心目标是:
- 适配输入限制:确保每个块的长度适合嵌入模型或 LLM 的输入限制(通常 500-2000 字符或 token)。
- 保留上下文:通过重叠(
chunk_overlap
)或其他语义分割策略,防止信息丢失。 - 支持多样性:处理不同类型的文本,如纯文本、代码、Markdown、HTML 等。
核心类:
TextSplitter
:所有分割器的基类,提供split_text
和split_documents
方法。- 具体分割器:如
CharacterTextSplitter
、RecursiveCharacterTextSplitter
等,针对不同场景优化。
主要方法:
split_text(text: str) -> List[str]
:将字符串分割为块列表。split_documents(documents: List[Document]) -> List[Document]
:将Document
对象分割为更小的Document
对象。create_documents(texts: List[str], metadatas: Optional[List[dict]] = None) -> List[Document]
:从文本列表创建并分割Document
对象。
典型应用:
- 文档预处理:将长文档分割为小块,生成嵌入向量,存储到向量数据库(如 Chroma、FAISS)。
- RAG 管道:为检索提供合适的文本块,确保相关性。
- 文本分析:将大文本分解为可管理的部分。
langchain.text_splitter
模块中的所有分割器
以下是 langchain.text_splitter
模块中的所有文本分割器(截至 LangChain 0.3.x),共 12 种,基于源码(langchain/text_splitter.py
)和官方文档(Text Splitters)。按类型分类,详细说明功能、参数、适用场景,并指出推荐使用的分割器。
1. 通用文本分割器
这些分割器适用于通用文本,基于字符或 token 计数。
-
CharacterTextSplitter
- 功能:按字符数或指定分隔符(如
\n
)分割文本。 - 参数:
chunk_size
(默认 1000):最大块大小(字符)。chunk_overlap
(默认 200):块间重叠字符数。separator
(默认\n
):分隔符。strip_whitespace
(默认True
):去除首尾空白。length_function
(默认len
):长度计算函数。
- 适用场景:简单文本分割,不需要复杂语义。
- 局限性:可能截断句子或段落,语义不连续。
- 示例:
from langchain.text_splitter import CharacterTextSplitter splitter = CharacterTextSplitter(chunk_size=100, chunk_overlap=20, separator="\n")
- 功能:按字符数或指定分隔符(如
-
RecursiveCharacterTextSplitter
- 功能:递归尝试多种分隔符(如段落、句子、单词),优先保留语义边界。
- 参数:
chunk_size
(默认 1000):最大块大小。chunk_overlap
(默认 200):重叠大小。separators
(默认["\n\n", "\n", " ", ""]
):分隔符列表,按顺序尝试。length_function
(默认len
):长度计算函数。is_separator_regex
(默认False
):分隔符是否为正则表达式。
- 适用场景:通用文本(如文章、书籍),需要保留语义边界。
- 推荐:最常用的分割器,适合大多数 RAG 场景。
- 示例:
from langchain.text_splitter import RecursiveCharacterTextSplitter splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=100)
-
TokenTextSplitter
- 功能:按 token 计数分割,基于指定的分词器(如
tiktoken
)。 - 参数:
chunk_size
(默认 1000):最大 token 数。chunk_overlap
(默认 0):重叠 token 数。encoding_name
(默认cl100k_improved
):分词器编码(如 OpenAI 的tiktoken
)。
- 适用场景:严格遵循 LLM 的 token 限制(如 GPT 模型)。
- 局限性:需要安装
tiktoken
,对非 token 化文本不直观。 - 示例:
from langchain.text_splitter import TokenTextSplitter splitter = TokenTextSplitter(chunk_size=200, chunk_overlap=50, encoding_name="cl100k_improved")
- 功能:按 token 计数分割,基于指定的分词器(如
2. 代码分割器
这些分割器针对编程语言或代码文件优化。
-
LanguageTextSplitter
- 功能:根据编程语言的语法(如 Python、JavaScript)分割代码。
- 参数:
language
(必填):语言类型(如python
,javascript
)。chunk_size
(默认 1000):最大块大小。chunk_overlap
(默认 200):重叠大小。
- 适用场景:处理代码文件,保留函数、类等结构。
- 支持语言:Python, JavaScript, Java, C++, Go 等(见
langchain.text_splitter
文档)。 - 示例:
from langchain.text_splitter import LanguageTextSplitter splitter = LanguageTextSplitter(language="python", chunk_size=500, chunk_overlap=100)
-
PythonCodeTextSplitter
- 功能:专为 Python 代码优化,基于语法树分割(如函数、类)。
- 参数:
chunk_size
(默认 1000):最大块大小。chunk_overlap
(默认 200):重叠大小。
- 适用场景:Python 代码分析、文档生成。
- 示例:
from langchain.text_splitter import PythonCodeTextSplitter splitter = PythonCodeTextSplitter(chunk_size=500, chunk_overlap=100)
3. 格式化文档分割器
这些分割器针对特定格式(如 Markdown、HTML、LaTeX)。
-
MarkdownHeaderTextSplitter
- 功能:基于 Markdown 标题(如
#
,##
)分割,保留标题作为元数据。 - 参数:
headers_to_split_on
(必填):标题和分隔符列表(如[("#", "Header 1"), ("##", "Header 2")]
)。strip_headers
(默认True
):是否移除标题内容。
- 适用场景:Markdown 文档(如 GitHub README、文档站点)。
- 示例:
from langchain.text_splitter import MarkdownHeaderTextSplitter splitter = MarkdownHeaderTextSplitter(headers_to_split_on=[("#", "Header 1"), ("##", "Header 2")])
- 功能:基于 Markdown 标题(如
-
MarkdownTextSplitter
- 功能:继承
RecursiveCharacterTextSplitter
,使用 Markdown 特定的分隔符(如\n#
,\n-
)。 - 参数:
- 同
RecursiveCharacterTextSplitter
,分隔符默认为 Markdown 结构。
- 同
- 适用场景:Markdown 文件,保留结构化信息。
- 示例:
from langchain.text_splitter import MarkdownTextSplitter splitter = MarkdownTextSplitter(chunk_size=500, chunk_overlap=100)
- 功能:继承
-
HTMLTextSplitter
- 功能:基于 HTML 标签(如
<p>
,<div>
)分割,保留标签作为元数据。 - 参数:
chunk_size
(默认 1000):最大块大小。chunk_overlap
(默认 0):重叠大小。tags_to_split_on
(默认["p", "div", "h1", ...]
):分割标签。
- 适用场景:网页内容、HTML 文档。
- 示例:
from langchain.text_splitter import HTMLTextSplitter splitter = HTMLTextSplitter(chunk_size=500, chunk_overlap=100)
- 功能:基于 HTML 标签(如
-
LatexTextSplitter
- 功能:基于 LaTeX 命令(如
\section
,\subsection
)分割。 - 参数:
- 同
RecursiveCharacterTextSplitter
,分隔符为 LaTeX 特定(如\n\\section
,\n\\subsection
)。
- 同
- 适用场景:学术论文、LaTeX 文档。
- 示例:
from langchain.text_splitter import LatexTextSplitter splitter = LatexTextSplitter(chunk_size=500, chunk_overlap=100)
- 功能:基于 LaTeX 命令(如
4. 语义分割器
这些分割器基于语义或嵌入进行分割。
- SemanticChunker
- 功能:使用嵌入模型(如
OpenAIEmbeddings
)计算语义相似性,分割为语义相近的块。 - 参数:
embeddings
(必填):嵌入模型实例。breakpoint_threshold_type
(默认"percentile"
):分割阈值类型(如百分位、标准差)。breakpoint_threshold_amount
(默认 95):阈值大小。
- 适用场景:需要语义连续的场景,如长篇文章。
- 局限性:计算开销高,依赖嵌入模型。
- 示例:
from langchain.text_splitter import SemanticChunker from langchain_openai import OpenAIEmbeddings splitter = SemanticChunker(OpenAIEmbeddings(), breakpoint_threshold_type="percentile")
- 功能:使用嵌入模型(如
5. 其他专用分割器
这些分割器针对特定用例。
-
SpacyTextSplitter
- 功能:使用 SpaCy 分词器按句子分割。
- 参数:
chunk_size
(默认 1000):最大块大小(字符)。chunk_overlap
(默认 0):重叠大小。pipeline
(默认"en_core_web_sm"
):SpaCy 模型。
- 适用场景:需要按句子分割的自然语言处理任务。
- 局限性:需要安装 SpaCy 和模型(如
pip install spacy
和python -m spacy download en_core_web_sm
)。 - 示例:
from langchain.text_splitter import SpacyTextSplitter splitter = SpacyTextSplitter(chunk_size=500, pipeline="en_core_web_sm")
-
NLTKTextSplitter
- 功能:使用 NLTK 的句子分词器分割。
- 参数:
chunk_size
(默认 1000):最大块大小。chunk_overlap
(默认 200):重叠大小。separator
(默认\n
):分隔符。
- 适用场景:基于句子的文本分割,适合学术或通用文本。
- 局限性:需要安装 NLTK(
pip install nltk
)并下载分词器(如nltk.download('punkt')
)。 - 示例:
from langchain.text_splitter import NLTKTextSplitter splitter = NLTKTextSplitter(chunk_size=500, chunk_overlap=100)
推荐与选择指南
- 通用推荐:
RecursiveCharacterTextSplitter
是最通用的分割器,适合大多数文本类型(如文章、文档),优先保留段落、句子等语义边界。 - 代码:
PythonCodeTextSplitter
或LanguageTextSplitter
适合代码文件。 - 格式化文档:
MarkdownHeaderTextSplitter
(Markdown)、HTMLTextSplitter
(网页)、LatexTextSplitter
(学术)。 - 语义分割:
SemanticChunker
适合需要语义连续的场景,但计算成本高。 - 按 token:
TokenTextSplitter
适合严格遵循 LLM token 限制。 - 按句子:
SpacyTextSplitter
或NLTKTextSplitter
适合 NLP 任务。
参数建议:
chunk_size
:500-2000 字符或 token,适配嵌入模型(如text-embedding-3-small
的 8192 token 限制)。chunk_overlap
:10-20% 的chunk_size
(如 50-200),确保上下文连续性。- 分隔符:根据文本类型选择(如 Markdown 用
#
,代码用函数边界)。
结合 RAG 系统的使用
在RAG 系统中构建多轮对话的知识库问答系统。langchain.text_splitter
的分割器用于预处理文档,生成适合向量存储的块。以下示例使用 RecursiveCharacterTextSplitter
(推荐的通用分割器),并迁移到 LCEL 链,延续 CharacterTextSplitter
示例。
LCEL RAG 示例
以下代码展示如何使用 RecursiveCharacterTextSplitter
分割文档,结合 LCEL 链实现 RAG,包含问题浓缩(模拟 condense_question_llm
)和对话历史管理。
import os
os.environ["OPENAI_API_KEY"] = "Your OpenAI API Key"
from operator import itemgetter
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
from langchain_community.vectorstores import Chroma
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough, RunnableWithMessageHistory
from langchain_community.chat_message_histories import ChatMessageHistory
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_core.documents import Document
# 原始文档
texts = [
"""人工智能(AI)是计算机科学的一个分支,专注于创建智能系统。
机器学习是 AI 的子领域,涉及从数据中学习模型。
深度学习是机器学习的一种,使用神经网络进行复杂模式识别。
生成式 AI 是 AI 的新兴领域,专注于生成文本、图像等内容。"""
]
# 使用 RecursiveCharacterTextSplitter 分割文档
splitter = RecursiveCharacterTextSplitter(
chunk_size=100,
chunk_overlap=20,
separators=["\n\n", "\n", " ", ""]
)
documents = [Document(page_content=text) for text in splitter.split_text(texts[0])]
# 初始化嵌入模型和向量存储
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
vectorstore = Chroma.from_documents(documents, embeddings)
# 初始化 LLM
main_llm = ChatOpenAI(temperature=0, model="gpt-4")
condense_llm = ChatOpenAI(temperature=0, model="gpt-3.5-turbo")
# 问题浓缩提示模板
condense_prompt = ChatPromptTemplate.from_messages([
("system", "给定以下对话历史和当前问题,重写当前问题为一个独立的、上下文无关的问题。"),
MessagesPlaceholder(variable_name="history"),
("human", "当前问题:{question}\n独立问题:")
])
# 回答提示模板
answer_prompt = ChatPromptTemplate.from_messages([
("system", "你是一个助手,根据以下上下文和对话历史回答问题:\n上下文:{context}"),
MessagesPlaceholder(variable_name="history"),
("human", "{question}")
])
# 创建浓缩链
condense_chain = (
{
"question": itemgetter("question"),
"history": itemgetter("history") | RunnablePassthrough()
}
| condense_prompt
| condense_llm
| StrOutputParser()
)
# 创建 LCEL 链
runnable = (
{
"context": condense_chain | vectorstore.as_retriever(search_kwargs={"k": 2}),
"question": itemgetter("question"),
"history": itemgetter("history") | RunnablePassthrough()
}
| answer_prompt
| main_llm
| StrOutputParser()
)
# 初始化消息历史存储
store = {}
def get_session_history(session_id: str) -> ChatMessageHistory:
if session_id not in store:
store[session_id] = ChatMessageHistory()
return store[session_id]
# 创建带历史的链
qa = RunnableWithMessageHistory(
runnable,
get_session_history,
input_messages_key="question",
history_messages_key="history"
)
# 调用链
session_id = "user1"
response = qa.invoke(
{"question": "什么是人工智能?", "history": []},
config={"configurable": {"session_id": session_id}}
)
print(response)
response = qa.invoke(
{"question": "它包含哪些子领域?", "history": []},
config={"configurable": {"session_id": session_id}}
)
print(response)
输出示例:
人工智能(AI)是计算机科学的一个分支,专注于创建能够执行需要人类智能的任务的系统,例如学习、推理和决策。
人工智能包含子领域,如机器学习、深度学习和生成式 AI。
代码说明
- 文本分割:
RecursiveCharacterTextSplitter
使用分隔符(\n\n
,\n
,chunk_size=100
和chunk_overlap=20
适合小规模测试。- 每个块转换为
Document
对象。
- 向量存储:
Chroma.from_documents
为每个块生成嵌入向量。- 检索器返回 2 个相关块(
k=2
)。
- 浓缩链:
condense_chain
使用gpt-3.5-turbo
生成独立问题。- 输入:
{"question": "...", "history": [...]}
。
- 回答链:
answer_prompt
结合上下文、历史和原始问题。main_llm
(gpt-4
)生成答案。
- 输入处理:
itemgetter("question")
和itemgetter("history")
确保正确提取字段。
- 历史管理:
ChatMessageHistory
存储对话历史,session_id
区分会话。
改进:
- 使用
RecursiveCharacterTextSplitter
替代CharacterTextSplitter
,提高语义连续性。 - LCEL 链替代
ConversationalRetrievalChain
,避免废弃警告。
注意事项
- API 密钥:
- 使用
.env
文件:from dotenv import load_dotenv load_dotenv()
- 确保密钥支持
text-embedding-3-small
、gpt-3.5-turbo
和gpt-4
。
- 使用
- 依赖:
- 安装:
pip install --upgrade langchain langchain-community langchain-openai langchain-core chromadb
- 安装:
- 分割优化:
- 生产环境建议
chunk_size=500-1000
,chunk_overlap=100-200
。 - 对于复杂文档,测试
SemanticChunker
或特定分割器(如MarkdownHeaderTextSplitter
)。
- 生产环境建议
- Ollama 替代:
- 使用
langchain_ollama
:from langchain_ollama import ChatOllama, OllamaEmbeddings main_llm = ChatOllama(model="qwen3:7b") condense_llm = ChatOllama(model="qwen3:1.7b") embeddings = OllamaEmbeddings(model="nomic-embed-text")
- 使用
- 迁移:
- 使用
langchain migrate
CLI:pip install langchain-cli langchain migrate
- 使用
常见问题
Q1:如何选择合适的分割器?
A:根据文本类型选择:
- 通用文本:
RecursiveCharacterTextSplitter
。 - 代码:
PythonCodeTextSplitter
或LanguageTextSplitter
。 - Markdown/HTML/LaTeX:
MarkdownHeaderTextSplitter
,HTMLTextSplitter
,LatexTextSplitter
。 - 语义:
SemanticChunker
。 - 按 token:
TokenTextSplitter
。
Q2:chunk_size
和 chunk_overlap
如何设置?
A:chunk_size
设为 500-2000(适配嵌入模型),chunk_overlap
为 10-20%(如 100-200),测试效果后调整。
Q3:CharacterTextSplitter
和 RecursiveCharacterTextSplitter
的区别?
A:CharacterTextSplitter
按固定字符数或单一分隔符分割,可能截断语义;RecursiveCharacterTextSplitter
递归尝试多级分隔符,保留段落/句子边界。
Q4:如何调试分割结果?
A:打印 splitter.split_text(text)
检查块内容和长度;用 langchain.debug = True
查看 RAG 管道日志。
总结
langchain.text_splitter
模块包含 12 种分割器:
- 通用:
CharacterTextSplitter
,RecursiveCharacterTextSplitter
,TokenTextSplitter
。 - 代码:
LanguageTextSplitter
,PythonCodeTextSplitter
。 - 格式化文档:
MarkdownHeaderTextSplitter
,MarkdownTextSplitter
,HTMLTextSplitter
,LatexTextSplitter
。 - 语义:
SemanticChunker
。 - 其他:
SpacyTextSplitter
,NLTKTextSplitter
。