当前位置: 首页 > 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.jsqmd.com/news/947874/

相关文章:

  • 船舶航向响应仿真C++代码:基于四阶RK法的Nomoto模型实现
  • 别再手动配角色了!用PFCG批量分配Fiori磁贴权限(以Manage Banks为例)
  • 绩效考核的致命漏洞:量化考核悖论如何催生无效内卷
  • MATLAB图像缺陷检测入门实战包:含12张实拍样图、带注释代码与坐标标注表
  • 告别重复劳动:用快马平台的ai能力生成高效开发工具函数
  • 告别代码混乱!大型前端项目架构设计方案:分层解耦+规范目录,可直接落地
  • PHP本地音乐网站源码包:带完整MySQL数据库、登录后台与百万级歌曲数据
  • Carnice-V2-27B未来展望:AI智能体模型的发展趋势与技术路线图
  • YOLO26#YOLO11重塑计算机视觉新格局 YOLO11与yolo26 差异 基于“YOLO11”与“YOLO26”构想的未来目标检测模型解析与实现
  • 九、LangChain之核心组件--(7)文本向量(上)
  • 佛山六大黄金回收门店:闲置金饰上门变现指南 - 余生黄金回收
  • Python vs MATLAB:手把手教你实现信号波形特征提取(附完整代码与避坑指南)
  • 微软拼音中 通过注册表快速添加小鹤双拼
  • 别再只盯着M.2了!工控机里那个‘小插槽’MiniPCIe,到底能接多少种宝贝?
  • 互联网大厂 Java 求职者面试:技术栈与幽默的碰撞
  • 告别PCL的臃肿!用Cilantro和Easy3D写更清爽的C++点云处理代码
  • 别再只会录屏了!用FFmpeg的gdigrab和x11grab,5分钟搞定Windows/Linux桌面精准捕获
  • 从 Volatile 到 ThreadLocal:Java 线程安全机制备忘
  • 到访杭州伴手礼怎么选?老牌非遗杨先生糕点,把江南风土装进礼盒 - 玖叁鹿
  • Qwen3.5-27B推理蒸馏模型架构深度解析:技术实现细节
  • GPT-4.1系列实战指南:从编程协作者到边缘AI部署
  • 2026Q3 海南注册公司选址推荐|自贸港分行业园区落地指南|正规注册代办机构权威榜单 - 品牌智鉴榜
  • KUKA KRC4/VKRC4/KR C5机器人ProfiNet通信用GSDML文件合集(2012–2022全版本)
  • PC端浏览器的monkey测试工具
  • MySQL-主从/集群架构
  • 新疆旅拍摄影专属向导!懂拍照、会取景,定格新疆绝美风光 - 纯玩旅游分享
  • 2026 广州黄金出手避坑|收的顶稳居优选,五家实体门店全测评 - 奢侈品回收评测
  • 别再手动找电影了!教你用Node.js + 豆瓣API + Telegram Bot打造个人电影推送机器人
  • 破解苏州平江路观前街核心商圈亲子住宿痛点:4D家庭住宿优化方法论如何打造高性价比四口之家住宿解决方案? - 速递信息
  • AI_Python基础-9.NumPy