LangChain 中的文档加载器(Loader)与文本切分器(Splitter)详解《二》

news2025/6/10 17:04:57

🧠 LangChain 中 TextSplitter 的使用详解:从基础到进阶(附代码)

一、前言

在处理大规模文本数据时,特别是在构建知识库或进行大模型训练与推理时,文本切分(Text Splitting) 是一个非常关键的预处理步骤。LangChain 提供了多种灵活的文本切分器(TextSplitter),可以帮助开发者根据实际需求对文本进行合理划分。

本文将围绕你在实际项目中使用的 TextSplitter 类型展开讲解,并结合具体代码示例,帮助你更好地理解如何选择和配置不同的文本切分策略。


二、什么是 TextSplitter?

TextSplitter 是 LangChain 中用于将长文本分割成小块(chunks)的一个工具类。它的核心作用是:

  • 将一段较长的文本按照指定规则切分为多个较小的段落;
  • 支持设置每个段落的最大长度(chunk_size);
  • 支持相邻段落之间的重叠部分(chunk_overlap),以保留上下文信息;
  • 支持基于字符、语言模型 tokenizer 等方式切分。

三、常见的 TextSplitter 类型

LangChain 提供了多种类型的 TextSplitter,每种适用于不同的场景:

类名说明
RecursiveCharacterTextSplitter按照指定字符递归切分,默认按 [“\n\n”, “\n”, " ", “”] 切分
SpacyTextSplitter基于 SpaCy 的语言模型进行句子级切分
MarkdownHeaderTextSplitter专门用于 Markdown 格式文档,根据标题层级切分
TokenTextSplitter基于 Token 数量进行切分,常用于 GPT 系列模型

四、实战代码解析

1. 定义 SPLITTER_CLASS_MAP 映射

为了方便切换不同的切分器,我们可以先定义一个映射字典:

SPLITTER_CLASS_MAP = {
    "RecursiveCharacterTextSplitter": RecursiveCharacterTextSplitter,
    "SpacyTextSplitter": SpacyTextSplitter,
    "MarkdownHeaderTextSplitter": MarkdownHeaderTextSplitter,
    "TokenTextSplitter": TokenTextSplitter,
}

这样可以根据字符串名称动态获取对应的切分器类。


2. 使用 from_tiktoken_encoder 构建切分器

TextSplitter = SPLITTER_CLASS_MAP["RecursiveCharacterTextSplitter"]
text_splitter = TextSplitter.from_tiktoken_encoder(
    encoding_name=text_splitter_dict["RecursiveCharacterTextSplitter"]["tokenizer_name_or_path"],
    chunk_size=CHUNK_SIZE,
    chunk_overlap=OVERLAP_SIZE
)

这段代码使用的是 tiktoken 编码器来计算 token 数量,适用于 GPT-3/4 等 OpenAI 模型。其中:

  • encoding_name: 指定使用的编码器(如 "cl100k_base");
  • chunk_size: 每个 chunk 的最大 token 数;
  • chunk_overlap: 相邻 chunk 的重叠 token 数。

3. 使用默认参数初始化 RecursiveCharacterTextSplitter

splitter = RecursiveCharacterTextSplitter(
    chunk_size=CHUNK_SIZE,
    chunk_overlap=OVERLAP_SIZE
)

这是最常用的方式,适用于大多数中文文本的切分任务,不依赖特定的 tokenizer,而是通过字符方式进行切分。


4. 使用 HuggingFace 的 Tokenizer 初始化切分器

from transformers import GPT2TokenizerFast
from langchain.text_splitter import CharacterTextSplitter

tokenizer = GPT2TokenizerFast.from_pretrained("gpt2")
text_splitter_1 = TextSplitter.from_huggingface_tokenizer(
    tokenizer=tokenizer,
    chunk_size=CHUNK_SIZE,
    chunk_overlap=OVERLAP_SIZE
)

这种方式适用于需要与 HuggingFace 模型配合使用的场景,比如 LLaMA、Bloom 等开源模型。它会根据 tokenizer 来精确控制每个 chunk 的 token 数量。


五、总结与建议

切分方式特点推荐场景
RecursiveCharacterTextSplitter快速简单,支持自定义切分符通用文本处理
SpacyTextSplitter支持多语言语义切分英文为主、语义敏感任务
MarkdownHeaderTextSplitter按标题层级切分文档类 Markdown 处理
TokenTextSplitter基于 token 数量切分适配 GPT、LLM 输入限制

建议:如果你在处理中文文本,推荐优先使用 RecursiveCharacterTextSplitter,并搭配合适的 chunk_size(如 512 或 1024)和 overlap(如 64)。


六、区别

你提到的三个 TextSplitter 实例虽然都来自 LangChain 的 RecursiveCharacterTextSplitter 类,但它们使用了不同的初始化方式(构造方法),因此在底层处理文本的方式上也有所不同。下面我将详细分析这三者的区别:


🧩 一、整体结构回顾

你定义了一个映射字典:

SPLITTER_CLASS_MAP = {
    "RecursiveCharacterTextSplitter": RecursiveCharacterTextSplitter,
    ...
}

然后通过字符串名称获取类并创建实例:

TextSplitter = SPLITTER_CLASS_MAP["RecursiveCharacterTextSplitter"]
text_splitter = TextSplitter.from_tiktoken_encoder(...)

接着又分别使用了三种不同方式创建了三个 splitter 实例:

  1. text_splitter: 使用 .from_tiktoken_encoder(...)
  2. splitter: 直接使用默认构造函数 RecursiveCharacterTextSplitter(...)
  3. text_splitter_1: 使用 .from_huggingface_tokenizer(...)

这三个 splitter 都是 RecursiveCharacterTextSplitter 的实例,但它们的底层分词逻辑和 chunk 大小控制机制不同


📌 二、逐个分析三个 splitter 的区别

✅ Splitter 1: text_splitter = TextSplitter.from_tiktoken_encoder(...)
初始化方式:
text_splitter = TextSplitter.from_tiktoken_encoder(
    encoding_name="cl100k_base",
    chunk_size=CHUNK_SIZE,
    chunk_overlap=OVERLAP_SIZE
)
特点:
  • 基于 OpenAI 的 tiktoken 编码器
  • chunk_size 是以 token 数量 为单位;
  • 更适合用于与 GPT-3/4 等模型配合使用;
  • 不依赖具体的语言模型 tokenizer,而是使用 OpenAI 官方编码器;
  • 支持中文(取决于使用的 encoding_name);

⚠️ 注意:tiktoken 的 token 划分方式不同于传统的空格或句子划分,它会将中英文混合切分为 subwords 或 bytes。

示例:
"你好 world" -> ["你", "好", "Ġworld"]

✅ Splitter 2: splitter = RecursiveCharacterTextSplitter(...)
初始化方式:
splitter = RecursiveCharacterTextSplitter(
    chunk_size=CHUNK_SIZE,
    chunk_overlap=OVERLAP_SIZE
)
特点:
  • 默认使用 字符长度(char length) 来计算 chunk 大小;
  • 按照预设的一组字符递归切分(默认顺序是:\n\n, \n, " ", "");
  • 不依赖任何 tokenizer,只基于字符数量;
  • 适用于通用文本处理,尤其适合中文场景;
  • 最简单、最直接的切分方式;
示例:
text = "这是一个很长的段落..."
splitter.split_text(text)
# 输出:["这是...", "...下一段"]

✅ Splitter 3: text_splitter_1 = RecursiveCharacterTextSplitter.from_huggingface_tokenizer(...)
初始化方式:
tokenizer = GPT2TokenizerFast.from_pretrained("gpt2")
text_splitter_1 = RecursiveCharacterTextSplitter.from_huggingface_tokenizer(
    tokenizer=tokenizer,
    chunk_size=CHUNK_SIZE,
    chunk_overlap=OVERLAP_SIZE
)
特点:
  • 使用的是 HuggingFace 的 transformers tokenizer(如 GPT2、LLaMA、Bloom 等);
  • chunk_size 也是以 token 数量 为单位;
  • 更适合与开源 LLM 模型配合使用;
  • 支持自定义 tokenizer(如中文 BERT tokenizer);
  • 可以精确控制每个 chunk 的 token 数量,避免超出模型输入限制;

⚠️ 注意:这种方式需要安装 transformers 库,并且加载 tokenizer 可能较慢。


🔍 三、三者的核心区别总结

属性from_tiktoken_encoder(...)__init__(...)from_huggingface_tokenizer(...)
切分依据token 数量(tiktoken 编码器)字符长度token 数量(HuggingFace tokenizer)
是否依赖 tokenizer是(tiktoken)是(transformers)
chunk_size 单位tokenchartoken
中文支持视 encoding 而定(一般较好)✔️ 很好视 tokenizer 而定
典型用途GPT-3/4 类模型适配通用文本处理开源 LLM(如 LLaMA、GPT-Neo)适配
性能快速极快较慢(需加载 tokenizer)

🎯 四、如何选择?

场景推荐方式
使用 OpenAI GPT-3/4 APIfrom_tiktoken_encoder
中文文档处理、快速构建本地知识库__init__()
使用开源 LLM(如 LLaMA、Bloom、GPT-Neo)from_huggingface_tokenizer
需要严格控制 token 数量后两者均可(根据 tokenizer)

📌 五、补充建议

如果你使用的是中文场景,推荐如下组合:

splitter = RecursiveCharacterTextSplitter(
    separators=["\n\n", "\n", "。", "!", "?", ",", " ", ""],
    chunk_size=512,
    chunk_overlap=64
)

你可以自定义 separators,让它更适合中文语义断句。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2406856.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

32单片机——基本定时器

STM32F103有众多的定时器,其中包括2个基本定时器(TIM6和TIM7)、4个通用定时器(TIM2~TIM5)、2个高级控制定时器(TIM1和TIM8),这些定时器彼此完全独立,不共享任何资源 1、定…

热门Chrome扩展程序存在明文传输风险,用户隐私安全受威胁

赛门铁克威胁猎手团队最新报告披露,数款拥有数百万活跃用户的Chrome扩展程序正在通过未加密的HTTP连接静默泄露用户敏感数据,严重威胁用户隐私安全。 知名扩展程序存在明文传输风险 尽管宣称提供安全浏览、数据分析或便捷界面等功能,但SEMR…

Matlab实现任意伪彩色图像可视化显示

Matlab实现任意伪彩色图像可视化显示 1、灰度原始图像2、RGB彩色原始图像 在科研研究中,如何展示好看的实验结果图像非常重要!!! 1、灰度原始图像 灰度图像每个像素点只有一个数值,代表该点的​​亮度(或…

图解JavaScript原型:原型链及其分析 | JavaScript图解

​​ 忽略该图的细节(如内存地址值没有用二进制) 以下是对该图进一步的理解和总结 1. JS 对象概念的辨析 对象是什么:保存在堆中一块区域,同时在栈中有一块区域保存其在堆中的地址(也就是我们通常说的该变量指向谁&…

《信号与系统》第 6 章 信号与系统的时域和频域特性

目录 6.0 引言 6.1 傅里叶变换的模和相位表示 6.2 线性时不变系统频率响应的模和相位表示 6.2.1 线性与非线性相位 6.2.2 群时延 6.2.3 对数模和相位图 6.3 理想频率选择性滤波器的时域特性 6.4 非理想滤波器的时域和频域特性讨论 6.5 一阶与二阶连续时间系统 6.5.1 …

一些实用的chrome扩展0x01

简介 浏览器扩展程序有助于自动化任务、查找隐藏的漏洞、隐藏自身痕迹。以下列出了一些必备扩展程序,无论是测试应用程序、搜寻漏洞还是收集情报,它们都能提升工作流程。 FoxyProxy 代理管理工具,此扩展简化了使用代理(如 Burp…

AxureRP-Pro-Beta-Setup_114413.exe (6.0.0.2887)

Name:3ddown Serial:FiCGEezgdGoYILo8U/2MFyCWj0jZoJc/sziRRj2/ENvtEq7w1RH97k5MWctqVHA 注册用户名:Axure 序列号:8t3Yk/zu4cX601/seX6wBZgYRVj/lkC2PICCdO4sFKCCLx8mcCnccoylVb40lP

02.运算符

目录 什么是运算符 算术运算符 1.基本四则运算符 2.增量运算符 3.自增/自减运算符 关系运算符 逻辑运算符 &&:逻辑与 ||:逻辑或 !:逻辑非 短路求值 位运算符 按位与&: 按位或 | 按位取反~ …

uni-app学习笔记三十五--扩展组件的安装和使用

由于内置组件不能满足日常开发需要,uniapp官方也提供了众多的扩展组件供我们使用。由于不是内置组件,需要安装才能使用。 一、安装扩展插件 安装方法: 1.访问uniapp官方文档组件部分:组件使用的入门教程 | uni-app官网 点击左侧…

6.9-QT模拟计算器

源码: 头文件: widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QMouseEvent>QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass Widget : public QWidget {Q_OBJECTpublic:Widget(QWidget *parent nullptr);…

java高级——高阶函数、如何定义一个函数式接口类似stream流的filter

java高级——高阶函数、stream流 前情提要文章介绍一、函数伊始1.1 合格的函数1.2 有形的函数2. 函数对象2.1 函数对象——行为参数化2.2 函数对象——延迟执行 二、 函数编程语法1. 函数对象表现形式1.1 Lambda表达式1.2 方法引用&#xff08;Math::max&#xff09; 2 函数接口…

数据结构第5章:树和二叉树完全指南(自整理详细图文笔记)

名人说&#xff1a;莫道桑榆晚&#xff0c;为霞尚满天。——刘禹锡&#xff08;刘梦得&#xff0c;诗豪&#xff09; 原创笔记&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 上一篇&#xff1a;《数据结构第4章 数组和广义表》…

Windows电脑能装鸿蒙吗_Windows电脑体验鸿蒙电脑操作系统教程

鸿蒙电脑版操作系统来了&#xff0c;很多小伙伴想体验鸿蒙电脑版操作系统&#xff0c;可惜&#xff0c;鸿蒙系统并不支持你正在使用的传统的电脑来安装。不过可以通过可以使用华为官方提供的虚拟机&#xff0c;来体验大家心心念念的鸿蒙系统啦&#xff01;注意&#xff1a;虚拟…

基于江科大stm32屏幕驱动,实现OLED多级菜单(动画效果),结构体链表实现(独创源码)

引言 在嵌入式系统中&#xff0c;用户界面的设计往往直接影响到用户体验。本文将以STM32微控制器和OLED显示屏为例&#xff0c;介绍如何实现一个多级菜单系统。该系统支持用户通过按键导航菜单&#xff0c;执行相应操作&#xff0c;并提供平滑的滚动动画效果。 本文设计了一个…

yaml读取写入常见错误 (‘cannot represent an object‘, 117)

错误一&#xff1a;yaml.representer.RepresenterError: (‘cannot represent an object’, 117) 出现这个问题一直没找到原因&#xff0c;后面把yaml.safe_dump直接替换成yaml.dump&#xff0c;确实能保存&#xff0c;但出现乱码&#xff1a; 放弃yaml.dump&#xff0c;又切…

WebRTC调研

WebRTC是什么&#xff0c;为什么&#xff0c;如何使用 WebRTC有什么优势 WebRTC Architecture Amazon KVS WebRTC 其它厂商WebRTC 海康门禁WebRTC 海康门禁其他界面整理 威视通WebRTC 局域网 Google浏览器 Microsoft Edge 公网 RTSP RTMP NVR ONVIF SIP SRT WebRTC协…

针对药品仓库的效期管理问题,如何利用WMS系统“破局”

案例&#xff1a; 某医药分销企业&#xff0c;主要经营各类药品的批发与零售。由于药品的特殊性&#xff0c;效期管理至关重要&#xff0c;但该企业一直面临效期问题的困扰。在未使用WMS系统之前&#xff0c;其药品入库、存储、出库等环节的效期管理主要依赖人工记录与检查。库…

从零开始了解数据采集(二十八)——制造业数字孪生

近年来&#xff0c;我国的工业领域正经历一场前所未有的数字化变革&#xff0c;从“双碳目标”到工业互联网平台的推广&#xff0c;国家政策和市场需求共同推动了制造业的升级。在这场变革中&#xff0c;数字孪生技术成为备受关注的关键工具&#xff0c;它不仅让企业“看见”设…

AD学习(3)

1 PCB封装元素组成及简单的PCB封装创建 封装的组成部分&#xff1a; &#xff08;1&#xff09;PCB焊盘&#xff1a;表层的铜 &#xff0c;top层的铜 &#xff08;2&#xff09;管脚序号&#xff1a;用来关联原理图中的管脚的序号&#xff0c;原理图的序号需要和PCB封装一一…

JDK 17 序列化是怎么回事

如何序列化&#xff1f;其实很简单&#xff0c;就是根据每个类型&#xff0c;用工厂类调用。逐个完成。 没什么漂亮的代码&#xff0c;只有有效、稳定的代码。 代码中调用toJson toJson 代码 mapper.writeValueAsString ObjectMapper DefaultSerializerProvider 一堆实…