Skip to content

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:最基础

单一分隔符,按字符数分割。

js
import { CharacterTextSplitter } from '@langchain/textsplitters';

const splitter = new CharacterTextSplitter({
  separator: '\n',
  chunkSize: 200,
  chunkOverlap: 20,
});

缺点:只能指定一个 separator,不够灵活。

RecursiveCharacterTextSplitter:最常用(推荐)

多个分隔符,从前往后递归尝试。先用 \n 分割,太大就用 ,再大用 ……

js
import { RecursiveCharacterTextSplitter } from '@langchain/textsplitters';

const splitter = new RecursiveCharacterTextSplitter({
  chunkSize: 150,
  chunkOverlap: 20,
  separators: ['\n', '。', ','],
});

优先保证语义完整,宁愿 chunk 小一点也不会强行截断。

支持自定义长度函数

默认按字符计数。如果需要严格控制 token 数量(如计费场景),可以用 lengthFunction

js
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 指定语言,按对应语法分割,不会破坏代码完整性:

js
const codeSplitter = RecursiveCharacterTextSplitter.fromLanguage('js', {
  chunkSize: 300,
  chunkOverlap: 60,
});

支持的语言:java、go、js、html、python、rust、swift、markdown 等。

Markdown / Latex 分割

都是 RecursiveCharacterTextSplitter 的子类:

  • MarkdownTextSplitter:按 ###### 等标题递归分割
  • LatexTextSplitter:按数学公式语法递归分割
js
import { MarkdownTextSplitter } from '@langchain/textsplitters';

const splitter = new MarkdownTextSplitter({
  chunkSize: 400,
  chunkOverlap: 80,
});

TokenTextSplitter:严格按 token 分割

js
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 没有固定换算关系,取决于模型的分词器:

js
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 关系图

text
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