文章目录
Prompt实战之构建语义搜索引擎 3)文本切分(Text Splitting)
在上一章中,我们成功将文档加载为 LangChain 中的 Document
对象。然而,对于大型文档(如 PDF 手册、网页文章),每个 Document
往往内容过长,无法直接传入语言模型中进行处理。
因此,我们需要将文档切分为更小的片段,这一步就是文本切分(Text Splitting)。
3.1 为什么需要文本切分?
- 语言模型的上下文长度有限(如 OpenAI 的 GPT-4 最大为 128k tokens);
- 长文档难以检索出关键内容,分段后便于建立语义索引;
- 多轮问答或摘要等应用中,切分片段可提升可控性与准确性。
💡小贴士:
有效切分的关键是:内容尽量完整、语义尽量连贯、片段大小合理。
3.2 LangChain 的文本切分器
LangChain 提供多种切分器(Splitter),最常用的是:
CharacterTextSplitter
:按字符数切分(适用于简单场景)RecursiveCharacterTextSplitter
:推荐,智能切分,优先按句、段、行等边界分割TokenTextSplitter
:按 token 数量切分(依赖 tokenizer)
3.3 使用 RecursiveCharacterTextSplitter
安装依赖
pip install tiktoken # 用于 token 统计
示例代码
from langchain.text_splitter import RecursiveCharacterTextSplitter
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=500,
chunk_overlap=100,
separators=["\n\n", "\n", ".", "。", "!", "?", " ", ""]
)
docs = text_splitter.split_documents(documents)
print(f"切分后得到 {len(docs)} 个文档片段")
print(docs[0].page_content[:300])
chunk_size
:每段的最大长度(字符或 token 数)chunk_overlap
:片段之间的重叠区,用于保持上下文连续separators
:优先分隔符,按顺序匹配(如中文句号、换行等)
📌 术语解释:
- Chunk(片段):切分后每一小段文档;
- Overlap(重叠区):相邻片段间共享的部分,有助于保持上下文。
3.4 可视化示例
设有一段文本:
“LangChain 是一个用于构建 LLM 应用的框架。它将文档加载、切分、嵌入与检索模块有机整合。本文介绍其基本使用方式……”
设置 chunk_size=50
,chunk_overlap=10
,可得到:
Chunk 1: LangChain 是一个用于构建 LLM 应用的框架。它将
Chunk 2: 应用的框架。它将文档加载、切分、嵌入与检索
Chunk 3: 嵌入与检索模块有机整合。本文介绍其基本使用方式…
📈 重叠设置(
chunk_overlap
)有助于语义连续性,尤其适用于问答任务。
3.5 进阶:按 Token 切分
使用 TokenTextSplitter
可更贴近模型的 token 计算方式,适用于生成任务或成本敏感场景。
from langchain.text_splitter import TokenTextSplitter
token_splitter = TokenTextSplitter(
chunk_size=300,
chunk_overlap=50
)
token_chunks = token_splitter.split_documents(documents)
需要安装 tokenizer 库(如 tiktoken
),否则可能报错。
3.6 自定义切分逻辑(选读)
可以继承 TextSplitter
自定义规则,例如按段落或特定格式(如 Markdown)分段。
3.7 本章小结
本章我们掌握了:
- 文本切分的动机与必要性;
- 使用
RecursiveCharacterTextSplitter
进行语义切分; - 了解 token 切分适用于更精细控制;
- 实践了多种切分策略与可视化片段生成。
练习区 🛠️
- 使用
RecursiveCharacterTextSplitter
将一个 5 页的 PDF 文档切分为 300 字符片段,并统计总片段数。 - 修改
chunk_overlap
的值为 0、50、150,对比生成片段数与连续性。 - 尝试用
TokenTextSplitter
切分一段中文文本,观察其与字符切分的区别。 - 实现一个简易函数,统计每个片段的字符数与词数。