LangChain全部Splitter
LangChain 的 Splitter 有三大类:CharacterTextSplitter(单分隔符基础分割)、RecursiveCharacterTextSplitter(多分隔符递归分割,最常用)、TokenTextSplitter(按 token 数严格分割)。绝大多数场景直接用 RecursiveCharacterTextSplitter 就够了,它支持多分隔符递归尝试、代码分割(fromLanguage)、自定义长度函数(可按 token 计数),功能最全面且能保证语义完整。overlap 只在文本被打断时才加,不是每个 chunk 都有。
# LangChain 全部 Splitter:其实只需要其中的一个
上节学了 Loader 和 Splitter 的概念,这节把所有 Splitter 过一遍。
# 核心概念:separator vs chunkSize
先区分两个概念:
- separator(分隔符):在哪些位置断开文本(如
。、\n、#) - chunkSize(块大小):每个 chunk 最多多大
分割逻辑:先按 separator 分割,再按 chunkSize 放入 chunk。如果分割后还大于 chunkSize,就用下一个 separator 继续拆。overlap 只在文本被打断时才加,不是每个 chunk 都有。
# CharacterTextSplitter:最基础
单一分隔符,按字符数分割。
import { CharacterTextSplitter } from '@langchain/textsplitters';
const splitter = new CharacterTextSplitter({
separator: '\n',
chunkSize: 200,
chunkOverlap: 20,
});
缺点:只能指定一个 separator,不够灵活。
# RecursiveCharacterTextSplitter:最常用(推荐)
多个分隔符,从前往后递归尝试。先用 \n 分割,太大就用 。,再大用 ,……
import { RecursiveCharacterTextSplitter } from '@langchain/textsplitters';
const splitter = new RecursiveCharacterTextSplitter({
chunkSize: 150,
chunkOverlap: 20,
separators: ['\n', '。', ','],
});
优先保证语义完整,宁愿 chunk 小一点也不会强行截断。
# 支持自定义长度函数
默认按字符计数。如果需要严格控制 token 数量(如计费场景),可以用 lengthFunction:
import { getEncoding } from 'js-tiktoken';
const enc = getEncoding('cl100k_base');
const splitter = new RecursiveCharacterTextSplitter({
chunkSize: 150,
chunkOverlap: 20,
separators: ['\n', '。', ','],
lengthFunction: (text) => enc.encode(text).length, // 按 token 计数
});
这样就完全不需要用 TokenTextSplitter。
# 支持代码分割(fromLanguage)
用静态方法 fromLanguage 指定语言,按对应语法分割,不会破坏代码完整性:
const codeSplitter = RecursiveCharacterTextSplitter.fromLanguage('js', {
chunkSize: 300,
chunkOverlap: 60,
});
支持的语言:java、go、js、html、python、rust、swift、markdown 等。
# Markdown / Latex 分割
都是 RecursiveCharacterTextSplitter 的子类:
- MarkdownTextSplitter:按
#、##、###等标题递归分割 - LatexTextSplitter:按数学公式语法递归分割
import { MarkdownTextSplitter } from '@langchain/textsplitters';
const splitter = new MarkdownTextSplitter({
chunkSize: 400,
chunkOverlap: 80,
});
# TokenTextSplitter:严格按 token 分割
import { TokenTextSplitter } from '@langchain/textsplitters';
const splitter = new TokenTextSplitter({
chunkSize: 50, // 每个块最多 50 个 token
chunkOverlap: 10, // 块之间重叠 10 个 token
encodingName: 'cl100k_base', // OpenAI 的编码方式
});
缺点:严格按 token 数,会强行打断文本,破坏语义完整性。
# 字符 vs Token
字符和 token 没有固定换算关系,取决于模型的分词器:
import { getEncoding } from 'js-tiktoken';
const enc = getEncoding('cl100k_base');
console.log(enc.encode('apple').length); // 1
console.log(enc.encode('pineapple').length); // 2
console.log(enc.encode('苹果').length); // 1-2
# 所有 Splitter 关系图
CharacterTextSplitter ← 单分隔符,基础
RecursiveCharacterTextSplitter ← 多分隔符递归,最常用
├── MarkdownTextSplitter ← 按标题分割
├── LatexTextSplitter ← 按数学语法分割
└── fromLanguage('js') ← 按代码语法分割
TokenTextSplitter ← 按 token 严格分割
# 结论
虽然讲了很多 Splitter,但结论很简单:用 RecursiveCharacterTextSplitter 就好了。
- CharacterTextSplitter:功能是 RecursiveCharacterTextSplitter 的子集,没必要用
- TokenTextSplitter:严格按 token 会破坏语义,不如用 RecursiveCharacterTextSplitter + 自定义
lengthFunction - RecursiveCharacterTextSplitter:功能最全,支持多分隔符递归、代码分割、自定义长度函数
# 要点
- separator 和 chunkSize 是两个维度 — separator 决定在哪断开,chunkSize 决定每块多大
- overlap 只在文本被打断时才加 — 不是每个 chunk 都有 overlap
- RecursiveCharacterTextSplitter 是万能选手 — 递归分割 + 代码分割 + 自定义长度函数
- fromLanguage 支持代码分割 — 按语法分割,不会破坏代码完整性
- lengthFunction 可自定义计数方式 — 实现按 token 计数,替代 TokenTextSplitter