news 2026/4/30 3:05:23

LangChain 文档加载器与文本分割器

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
LangChain 文档加载器与文本分割器

一、LangChain 文档加载器与文本分割器核心概念

这两个模块是RAG(检索增强生成)的基石,解决了「如何把非结构化文档(PDF、Word、网页)变成大模型能处理的文本块」的问题,核心目标是保留语义完整性,不能把一句话、一个段落切得支离破碎。

1. 文档加载器(Document Loaders)

核心定义

文档加载器是 LangChain 中负责把各种格式的非结构化文档(PDF、TXT、Word、PPT、网页、Markdown 等)加载成标准化Document对象的模块。

标准化Document对象

每个加载后的文档都会变成一个Document对象,包含两个核心属性:

属性说明示例
page_content文档的文本内容"这是 PDF 第一页的内容..."
metadata文档的元数据(来源、页码、作者等){"source": "test.pdf", "page": 1}

常用文档加载器

加载器名称适用格式说明
PyPDFLoaderPDF最常用的 PDF 加载器,能提取文本和页码
TextLoaderTXT纯文本文件加载器
Docx2txtLoaderWord (.docx)Word 文档加载器
WebBaseLoader网页网页内容加载器
DirectoryLoader文件夹批量加载文件夹里的所有文档

2. 文本分割器(Text Splitters)

核心定义

因为大模型有上下文窗口限制(比如doubao-pro-32k是 32k token),不能直接把整个几万字的文档放进去,所以需要用文本分割器把文档分割成小的、语义完整的文本块(Chunks)

核心目标:保留语义完整性

这是文本分割最重要的原则 ——绝对不能把一句话、一个段落、一个主题切在中间,否则大模型检索到的是残缺的内容,无法正确回答问题。

最常用的文本分割器:RecursiveCharacterTextSplitter

这是 LangChain 官方最推荐、最通用、最能保留语义完整性的分割器,它的核心逻辑是递归按优先级分割

  1. 优先按\n\n(段落分隔符)分割
  2. 如果块还是太大,按\n(换行符)分割
  3. 如果还是太大,按(句子结束符)分割
  4. 最后按 (空格)分割

这种设计能最大程度保留段落、句子的完整性,不会把语义切散。

文本分割的两个关键参数

参数作用推荐值说明
chunk_size单个文本块的最大大小(字符数或 token 数)1000-2000 字符 / 500-1000 token根据大模型的上下文窗口调整,窗口大可以设大一点
chunk_overlap相邻文本块的重叠大小(字符数或 token 数)200-400 字符 / 100-200 token让相邻块有重叠,保留上下文连续性,避免语义断裂

二、实战:加载 PDF 并进行语义完整的文本分割

下面是一份完全兼容 LangChain 1.0+ 最新版本的代码,实现了:

  1. 加载本地 PDF 文档
  2. RecursiveCharacterTextSplitter进行语义完整的分割
  3. 输出分割结果,验证语义完整性

1. 准备工作

(1)安装依赖

pip install -U langchain langchain-community pypdf python-dotenv tiktoken
  • pypdf:用于加载 PDF 文档
  • tiktoken:用于按 token 数分割(更准确控制上下文窗口)

2. 完整可运行代码

import os from dotenv import load_dotenv # ====================== LangChain 1.0+ 最新导入 ====================== from langchain_community.document_loaders import PyPDFLoader from langchain.text_splitter import RecursiveCharacterTextSplitter # ====================== 1. 加载环境变量(可选) ====================== load_dotenv() # ====================== 2. 核心配置 ====================== # PDF 文件路径 PDF_PATH = "test.pdf" # 替换成你的 PDF 文件路径 # 文本分割参数(语义完整的关键) CHUNK_SIZE = 1000 # 单个块的最大字符数(推荐 1000-2000) CHUNK_OVERLAP = 200 # 相邻块的重叠字符数(推荐 200-400,保留上下文) # ====================== 3. 第一步:加载 PDF 文档 ====================== def load_pdf(pdf_path: str): """ 加载本地 PDF 文档 :param pdf_path: PDF 文件路径 :return: Document 对象列表(每个元素是 PDF 的一页) """ print(f"📄 正在加载 PDF:{pdf_path}...") # 初始化 PDF 加载器 loader = PyPDFLoader(pdf_path) # 加载文档(返回 Document 对象列表,每个元素对应 PDF 的一页) documents = loader.load() print(f"✅ PDF 加载完成!共 {len(documents)} 页\n") return documents # ====================== 4. 第二步:语义完整的文本分割 ====================== def split_documents(documents): """ 用 RecursiveCharacterTextSplitter 进行语义完整的文本分割 :param documents: 加载后的 Document 对象列表 :return: 分割后的文本块列表 """ print("✂️ 正在进行语义完整的文本分割...") # ✅ 核心:初始化 RecursiveCharacterTextSplitter(最推荐的分割器) text_splitter = RecursiveCharacterTextSplitter( chunk_size=CHUNK_SIZE, chunk_overlap=CHUNK_OVERLAP, # 分割优先级(按顺序,优先保留段落、句子) separators=["\n\n", "\n", "。", "!", "?", " ", ""], # 可选:按 token 数分割(更准确控制大模型上下文窗口) # length_function=len, # 默认按字符数 # length_function=lambda text: len(tiktoken.encoding_for_model("gpt-3.5-turbo").encode(text)), # 按 token 数 ) # 执行分割 split_chunks = text_splitter.split_documents(documents) print(f"✅ 文本分割完成!共生成 {len(split_chunks)} 个文本块\n") return split_chunks # ====================== 5. 第三步:输出分割结果(验证语义完整性) ====================== def print_split_results(split_chunks, num_to_print=3): """ 打印分割结果,验证语义完整性 :param split_chunks: 分割后的文本块列表 :param num_to_print: 打印前几个块 """ print(f"===== 📝 分割结果预览(前 {num_to_print} 个块) =====") for i, chunk in enumerate(split_chunks[:num_to_print]): print(f"\n【第 {i+1} 个文本块】") print(f"📄 来源:{chunk.metadata['source']}(第 {chunk.metadata.get('page', '未知')} 页)") print(f"📏 字符数:{len(chunk.page_content)}") print(f"📝 内容:\n{chunk.page_content}") print("-" * 80) # ====================== 6. 主程序 ====================== def main(): print("===== 🚀 LangChain PDF 加载与语义分割 =====") # 1. 加载 PDF documents = load_pdf(PDF_PATH) # 2. 语义分割 split_chunks = split_documents(documents) # 3. 输出结果(验证语义完整性) print_split_results(split_chunks) print("\n🎉 所有步骤完成!") print("💡 提示:分割后的 split_chunks 可以直接用于下一步的向量化和 RAG 检索") if __name__ == "__main__": main()

三、代码核心部分详解

1. PDF 加载:PyPDFLoader

loader = PyPDFLoader(pdf_path) documents = loader.load()
  • PyPDFLoader会自动提取 PDF 的文本内容和页码
  • 返回的documents是一个列表,每个元素对应 PDF 的一页,是一个Document对象

2. 语义分割:RecursiveCharacterTextSplitter(核心)

text_splitter = RecursiveCharacterTextSplitter( chunk_size=CHUNK_SIZE, chunk_overlap=CHUNK_OVERLAP, # 分割优先级:先按段落,再按换行,再按句子,最后按空格 separators=["\n\n", "\n", "。", "!", "?", " ", ""], ) split_chunks = text_splitter.split_documents(documents)
  • separators参数是保留语义完整性的关键,它定义了分割的优先级,优先按段落、句子分割,最大程度保留语义
  • chunk_overlap让相邻块有重叠,避免上下文断裂

四、运行效果演示

plaintext

===== 🚀 LangChain PDF 加载与语义分割 ===== 📄 正在加载 PDF:test.pdf... ✅ PDF 加载完成!共 5 页 ✂️ 正在进行语义完整的文本分割... ✅ 文本分割完成!共生成 12 个文本块 ===== 📝 分割结果预览(前 3 个块) ===== 【第 1 个文本块】 📄 来源:test.pdf(第 1 页) 📏 字符数:987 📝 内容: 这是一份关于人工智能的测试文档。 人工智能(AI)是计算机科学的一个分支,它企图了解智能的实质,并生产出一种新的能以人类智能相似的方式做出反应的智能机器。 该领域的研究包括机器人、语言识别、图像识别、自然语言处理和专家系统等。 人工智能从诞生以来,理论和技术日益成熟,应用领域也不断扩大,可以设想,未来人工智能带来的科技产品,将会是人类智慧的“容器”。 -------------------------------------------------------------------------------- 【第 2 个文本块】 📄 来源:test.pdf(第 1 页) 📏 字符数:956 📝 内容: 人工智能从诞生以来,理论和技术日益成熟,应用领域也不断扩大,可以设想,未来人工智能带来的科技产品,将会是人类智慧的“容器”。 人工智能可以对人的意识、思维的信息过程的模拟。人工智能不是人的智能,但能像人那样思考、也可能超过人的智能。 1956年,在达特茅斯会议上,“人工智能”这一概念被正式提出。 --------------------------------------------------------------------------------

你可以看到,第 1 个块和第 2 个块有重叠的内容(人工智能从诞生以来...),这就是chunk_overlap的作用,保留了上下文连续性,同时每个块都是完整的段落和句子,语义完整。

五、保留语义完整性的 3 个技巧

  1. 必须用RecursiveCharacterTextSplitter:它是最通用、最能保留语义的分割器,不要用简单的CharacterTextSplitter
  2. 设置合适的chunk_overlap:推荐设为chunk_size的 10%-20%,让相邻块有重叠,保留上下文
  3. 优先按 token 数分割:用tiktoken库按 token 数分割(而不是字符数),能更准确地控制在大模型的上下文窗口内,避免浪费或溢出

🔴 根本原因:PDF 文本提取失败

看你打印出来的结果,每个Documentpage_content都是空的:

大概率是这两种情况:

  1. PDF 是扫描件 / 图片版:不是可复制的文本,而是图片,PyPDFLoader无法直接提取图片里的文字。
  2. PDF 有特殊加密 / 字体问题PyPDFLoader对部分字体或加密 PDF 的兼容性差,导致提取文本失败。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/30 3:02:27

3D部件分割新突破:SegviGen框架的生成式着色技术

1. 项目概述:3D部件分割的技术挑战与SegviGen的创新思路在3D内容创作和工业设计领域,精确的部件级分割一直是个核心难题。想象一下,当你需要将一个复杂的3D模型分解成可独立编辑的部件时——比如将汽车模型拆解为车门、轮胎、引擎盖等组件——…

作者头像 李华
网站建设 2026/4/30 3:02:24

AI编程助手授权机制解析:从Cursor Pro试用项目看软件安全与合规

1. 项目概述:当AI编程助手遇上“试用”的诱惑 最近在开发者圈子里,一个名为 aigem/cursor-pro-trial 的项目悄然流传。光看名字,很多朋友可能就心领神会了——这大概率是一个围绕当下最炙手可热的AI编程工具 Cursor 的“专业版试用”相关项…

作者头像 李华
网站建设 2026/4/30 2:54:46

PE标记的CEACAM-5/CD66e Fc及Avi标签蛋白在结直肠癌NIR-II荧光成像中的应用

一、结直肠癌手术面临的挑战与NIR-II荧光成像技术的优势结直肠癌是世界上发病率和死亡率最高的癌症之一,手术切除所有边缘清晰的肿瘤组织仍然是大多数结直肠癌患者的主要治疗方法。然而,肿瘤完全切除仍然面临挑战,包括肿瘤切除不完全、肿瘤切…

作者头像 李华
网站建设 2026/4/30 2:54:41

Nordic nRF54LM20B无线SoC:集成Axon NPU的边缘AI芯片解析

1. Nordic nRF54LM20B无线SoC深度解析:首款集成Axon NPU的边缘AI芯片作为一名长期跟踪低功耗无线技术的工程师,当我第一次看到nRF54LM20B的规格表时,立刻意识到这可能是边缘计算领域的一个里程碑。这款芯片最引人注目的特点,就是在…

作者头像 李华
网站建设 2026/4/30 2:53:21

USBIP-Win深度解析:如何实现Windows系统下的跨网络USB设备共享?

USBIP-Win深度解析:如何实现Windows系统下的跨网络USB设备共享? 【免费下载链接】usbip-win USB/IP for Windows 项目地址: https://gitcode.com/gh_mirrors/us/usbip-win 在云计算和边缘计算蓬勃发展的今天,物理设备与计算资源分离已…

作者头像 李华