当前位置: 首页 > news >正文

九、LangChain之核心组件--(6)文本分割器

目录

6. 文本分割器(Text Splitters)

6.1 概念:为什么要拆分?

6.2 按文档长度与语义拆分

6.2.1 基于字符长度拆分 — CharacterTextSplitter

chunk_overlap 的作用

6.2.2 基于 Token 长度拆分

6.2.3 硬性约束长度拆分 — RecursiveCharacterTextSplitter

对比:

6.3 特殊文档结构拆分


6. 文本分割器(Text Splitters)

6.1 概念:为什么要拆分?


你已经用 PyPDFLoader 把 PDF 加载成了 Document 对象。一个 Document 可能包含一整页甚至整个文件的文本。

直接拿整个文档去检索有三大问题:

文本分割器的任务就是:把大文档切成小块,每块语义相对完整,大小可控。

一个 Document(整篇 MD 文件)

▼ 文本分割器

N 个 Document(每个小块都是一个 Document,保留原始 metadata)

我们已经知道可以通过文档加载器完成各种数据源的加载,将其转换为文档对象Document 。那么接下来要做的就是文档拆分。
文档拆分通常是将大文本分解为更小的、易于管理的块。这对于索引数据并将其传递到模型中都很有用。因为,大块更难搜索并且不适合模型的有限上下文窗口。拆分可以提高搜索结果的粒度,从而可以更精确地将查询与相关文档部分进行匹配。LangChain 的文本分割器便能将大型文档分解为更小的块。如下图所示:

6.2 按文档长度与语义拆分


拆分的核心矛盾:

块太小 → 语义断裂,搜到的片段缺少上下文
块太大 → 精度下降,浪费 token

分为两种: 基于字符长度拆分和基于Token长度拆分。

所以需要配置两个关键参数:chunk_sizechunk_overlap

6.2.1 基于字符长度拆分 — CharacterTextSplitter

from langchain_text_splitters import CharacterTextSplitter

所有参数:

代码:

from langchain_community.document_loaders import UnstructuredMarkdownLoader from langchain_text_splitters import CharacterTextSplitter # 先加载文档 loader=UnstructuredMarkdownLoader("./file/Day 1 详解:总览.md") data = loader.load() # 创建文本分割器 text_splitter = CharacterTextSplitter( separator="\n\n", # 先用双换行(段落间)切 chunk_size=100, # 目标:每块不超过 100 字符 chunk_overlap=20, # 相邻两块之间有 20 字符的重叠 length_function=len, # 用 Python 内置 len() 数字符 is_separator_regex=False, # separator 是普通字符串,不是正则 ) # 分割 texts = text_splitter.split_documents(data) # 查看前 10 块 for doc in texts[:10]: print("*" * 30) print(f"{doc}\n")

在这里要说明关于这里的爆红提示,这是一个在使用LangChain 的文本分割器时非常常见的问题。看到这个信息,不要担心,这不是错误,而是预期的行为。
原因是为了保持语义的完整性!当文本分割器用尽所有指定的分隔符都无法将一段文本分割到你的目标大小 chunk_size 以下时,它会选择保留整个文本块,而不是强行将其截断为无意义的片段,因此我们会看到这个提示信息。因此我们可以看到,被分割出来的段落,基本上都是语义完整的一段话。
那么分割逻辑到底是什么?

它宁愿保留一个超长但语义完整的块,也不强行在第 100 字符处截断——那样会把单词截断成乱码。

解决方案: 如果大部分块都超长,把 chunk_size 调大就行了。比如调到 2500:

#创建文本分割器 text_splitter=CharacterTextSplitter( separator="\n\n", chunk_size=2500, chunk_overlap=20, length_function=len, is_separator_regex=False, )

chunk_overlap 的作用


理解为相邻两块之间的"安全区"。块 1 的最后 20 个字符会出现在块 2 的开头:

块1: [....................ABCDEFGHIJ]
← 重叠区
块2: [ABCDEFGHIJ....................]

为什么需要重叠? 防止重要信息刚好卡在边界上被切开,后续检索时遗漏。

6.2.2 基于 Token 长度拆分

之前我们讲过,LLM 大模型实际上并不是直接接收字符串,而是需要先做 token 切分编码。这里我们可以借助 【tiktoken 分词器】来进行 token 的切分编码。

先看 tiktoken 怎么切分一段文本:

import tiktoken enc = tiktoken.get_encoding("cl100k_base") tokens = enc.encode("my name is LiHua!") print(tokens) # → [2465, 836, 374, 14851, 39, 4381, 0] for token in tokens: print(enc.decode_single_token_bytes(token)) # b'my' ← 1 个 token # b' name' ← 1 个 token(注意前面有空格) # b' is' # b' Li' # b'H' # b'ua' # b'!'

解释: cl100k_base 是tiktoken 分词器中的一种编码方式。gpt-4 、gpt-3.5-turbo 等
都采用这种切分编码方式。
可以看到采用切分编码cl100k_base ,拆解后的文本字符串为["my", "name", "is", "Li", "H", "ua", "!"] 。token 编码表示为[2465, 836, 374, 14851, 39, 4381,0] 。

在 LangChain 中,用 CharacterTextSplitter.from_tiktoken_encoder() 按 token 数拆分:

text_splitter = CharacterTextSplitter.from_tiktoken_encoder( encoding_name="cl100k_base", # 编码方式 chunk_size=200, # 每块最多 200 个 token chunk_overlap=50, # 重叠 50 个 token ) texts = text_splitter.split_documents(data)

和基于字符长度拆分的区别:

6.2.3 硬性约束长度拆分 — RecursiveCharacterTextSplitter


前面两种都允许超长块(为了语义完整)。如果你要求任何块都不能超过指定大小,用这个RecursiveCharacterTextSplitter.from_tiktoken_encoder方法,它会严格遵守对块大小的硬约束

from langchain_text_splitters import RecursiveCharacterTextSplitter text_splitter = RecursiveCharacterTextSplitter.from_tiktoken_encoder( encoding_name="cl100k_base", chunk_size=100, chunk_overlap=0, ) texts = text_splitter.split_documents(data)

输出(严格不超 100 token):

注意第二块和第三块的关系: "加深对 Java" → "编程语言和相关技术的理解..." ,句子被硬生生截成两半。没有 chunk_overlap 时,检索可能漏掉信息。

对比:

你的场景:
├─ 一般情况 → CharacterTextSplitter.from_tiktoken_encoder()(Token 版)
│ 理由:和 LLM 消耗对齐,语义完整

├─ 上下文窗口紧,必须严格限制 → RecursiveCharacterTextSplitter
│ 理由:绝不让任何块超限

└─ 不需要 tiktoken 依赖 → CharacterTextSplitter()(字符版)
理由:最简单,零额外依赖

chunk_size 决定块的大小,chunk_overlap 决定相邻块的重叠量。文本分割器优先保语义完整,RecursiveCharacterTextSplitter 才做硬性截断。

6.3 特殊文档结构拆分

前面的 CharacterTextSplitter 和 RecursiveCharacterTextSplitter 是通用分割器——它们把文本当"一大段字符"来切,不关心内容是什么。

但对代码、Markdown、HTML 这类有结构的文本,用理解语法的专用分割器效果更好。

对于这类代码等特殊文本,可以尝试使用 Language 提供的不同的分割器(如PythonCodeTextSplitter 、HTMLHeaderTextSplitter 等)效果会更好,它会理解代码的
语法结构。这里了解下常见的拆分原则即可:

这里我们以 Python 代码举例,其他的使用姿势可以参考官网接口,实际上用法与我们上面讲解的类似。

from langchain_text_splitters import PythonCodeTextSplitter PYTHON_CODE = """ def hello_world(): print("Hello, World!") def hello_python(): print("Hello, Python!") """ python_splitter = PythonCodeTextSplitter( chunk_size=50, chunk_overlap=0 ) python_docs = python_splitter.create_documents([PYTHON_CODE]) for doc in python_docs[:2]: print(doc)

PythonCodeTextSplitter理解了 def 的语法意义,以函数为边界切分,而不是在代码中间某个字符位置截断。每个函数单独成块,语义完整。

你的文档类型:
├─ 纯文本、文章、聊天记录 → CharacterTextSplitter / RecursiveCharacterTextSplitter
├─ Markdown → MarkdownHeaderTextSplitter(按标题层级分块)
├─ HTML → HTMLHeaderTextSplitter(按标签结构分块)
├─ Python / JS / Java 等代码 → PythonCodeTextSplitter 或对应语言的专用分割器
└─ JSON 数据 → RecursiveJsonSplitter

http://www.gsyq.cn/news/1459390.html

相关文章:

  • 含数据库脚本与运行指南的SpringBoot+Vue在线考试系统源码包
  • 九、LangChain之核心组件--(7)文本向量(上)
  • 告别PCL的臃肿!用Cilantro和Easy3D写更清爽的C++点云处理代码
  • Qwen3.5-27B推理蒸馏模型架构深度解析:技术实现细节
  • 2026Q3 海南注册公司选址推荐|自贸港分行业园区落地指南|正规注册代办机构权威榜单 - 品牌智鉴榜
  • PC端浏览器的monkey测试工具
  • AI_Python基础-9.NumPy
  • 上海留学托管课程有保障:全程监管专业指南参考 - 虚拟星辰
  • 如何快速构建Go语言网络自动化工具:终极完整指南
  • 2026 淮北全域工装甄选指南|商铺 / 门面 / 办公室 / 商城翻新 3 家正规工装排行榜 + 本地专属避坑全攻略 - 本地便民网
  • 别再凭感觉调锅了!手把手教你用手机App和量角器搞定卫星天线三大角(方位/仰角/极化角)
  • 【官方原创】白皮书|18nm FD-SOI+ePCM双剑合璧,STM32 MCU刷新性能上限
  • 去杭州旅游别乱囤特产,本地人过节送礼认准杨先生非遗手工糕点 - 玖叁鹿
  • 2026拼多多代运营公司推荐:拼便宜+百亿补贴玩法,利润不降反增 - 百推信源
  • 实战工业缺陷检测:基于快马平台生成端到端的yolov8训练与部署代码
  • Windows 64位C++项目可用的ONNX Runtime 1.18.0 GPU推理开发包(CUDA 11.8+/TensorRT双加速)
  • 2026深圳手表变现指南:收的顶精准鉴定,无损耗无隐形收费更靠谱 - 奢侈品回收测评
  • GPT-5.5 Pro实战指南:工作流原生AI如何重塑工程与知识生产
  • 2026天津黄金回收避坑必读 收的顶黄金回收教你识破套路 - 奢侈品回收评测
  • BetterJoy完整指南:5分钟让Switch手柄在电脑上完美工作
  • 从流水灯代码反推:新手如何理解C51中的变量类型与位运算(附避坑指南)
  • DeepSeek-V4 实测分析:模型行为机理与稳定输出优化指南
  • google文字识别库导入成功
  • 【智能制造】- APS系列|16 提前期:概念、价值与缩短方法
  • 儿童Python编程入门包:Pygame版‘飞鸟’游戏源码+全套图片素材,开箱即玩
  • 来杭州旅游怎么选伴手礼?一口非遗糕点,收纳整座江南的风土滋味 - 玖叁鹿
  • 从机床小白到数据采集能手:我是如何通过FANUC FOCAS API理解CNC内部世界的
  • AI驱动的智能编曲平台落地全链路(从MIDI解析到混音自动化)
  • 学Simulink——氢燃料电池堆(PEMFC)动态响应特性分析
  • 【江门各区黄金上门回收指南:六大靠谱门店实地测评】 - 余生黄金回收