🧩 一句话先说清楚
TextSplitter是抽象基类(定义规范),RecursiveCharacterTextSplitter是具体实现(一种切分策略)。
RecursiveCharacterTextSplitter继承自 TextSplitter,所以会自动拥有它的所有方法(除非被重写)。
1. TextSplitter 是什么(抽象层)
TextSplitter 可以理解为:
"所有文本切分器必须遵守的接口规范 + 通用能力封装"
它的职责不是"怎么切",而是:
- 定义统一接口(比如
split_text、create_documents) - 管理通用参数(
chunk_size、chunk_overlap) - 提供基础工具方法(比如 chunk 合并逻辑)
👉 换句话说:
它解决的是 "切分器应该长什么样"
2. RecursiveCharacterTextSplitter 是什么(实现层)
它是 TextSplitter 的一个具体子类,实现了一种策略:
按"语义优先"的递归分隔符切分文本
核心特点:
- 有一套默认分隔符:
["\n\n", "\n", " ", ""] - 按优先级递归切
- 尽量保持语义完整
👉 它解决的是:
"具体怎么切文本"
3. 用代码结构理解关系(非常关键)
你可以把它想象成这样:
python
class TextSplitter:
def split_text(self, text):
raise NotImplementedError
def create_documents(self, texts):
# 通用逻辑
pass
class RecursiveCharacterTextSplitter(TextSplitter):
def split_text(self, text):
# 具体实现:递归按分隔符切
pass
👉 关键点:
- 父类定义"接口 + 通用流程"
- 子类实现"切分算法"
4. 更本质的区别(从设计角度)
| 维度 | TextSplitter | RecursiveCharacterTextSplitter |
|---|---|---|
| 类型 | 抽象基类 | 具体实现类 |
| 关注点 | 规范 & 通用能力 | 切分策略 |
| 是否直接使用 | ❌ 很少直接用 | ✅ 常用 |
| 是否需要理解 | ✔(框架理解) | ✔✔(实战必须) |
5. 为什么要这样设计(重点)
LangChain 不是只提供一个切分器,而是支持很多种:
- 按字符(Recursive)
- 按 token
- 按 Markdown 结构
- 按 HTML
- 按代码语法
👉 如果没有 TextSplitter 这个抽象层:
- 每个 splitter API 都不一致
- 下游(embedding / retriever)不好统一处理
所以:
TextSplitter的存在,是为了让所有 splitter 可替换、可扩展、接口一致
6. 从"用"的角度看区别
你什么时候关心 TextSplitter?
- 写自定义 splitter
- 理解 LangChain 设计
- 读源码
你什么时候用 RecursiveCharacterTextSplitter?
- 做 RAG
- 切普通文本
- 默认方案
7. 一个更高级的理解
TextSplitter= 策略接口(Strategy Interface)RecursiveCharacterTextSplitter= 一个具体策略(Concrete Strategy)
这其实就是经典的:
👉 策略模式(Strategy Pattern)
🎯 最终总结
TextSplitter:定义"切分器应该怎么用"(接口 + 通用逻辑)RecursiveCharacterTextSplitter:实现"具体怎么切"(递归分隔策略)
LangChain 默认推荐 RecursiveCharacterTextSplitter,不是因为它"更高级",而是因为它在"语义完整性 + 通用性 + 成本"之间是最稳的默认解。