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

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

—— 从入门到实战,构建你的知识库预处理系统

作者:zgw
时间:2025/4
标签:LangChain、LLM、RAG、AI Agent、文档处理


一、前言

随着大语言模型(LLM)在 RAG(Retrieval-Augmented Generation)、智能问答、Agent 构建等方向的应用日益广泛,如何高效地导入和处理原始文档成为关键问题。

LangChain 提供了丰富的 DocumentLoaderTextSplitter 模块,帮助开发者快速实现文档解析、切分、向量化流程。本文将为你详细介绍 LangChain 中常用的 文档加载器(Loader)文本切分器(Splitter),并提供完整可运行的代码示例,助你快速上手构建本地知识库系统。


二、LangChain 常用文档加载器(Loader)

✅ 功能说明:

文档加载器用于从各种格式中读取数据,并将其转换为统一的 Document 对象,便于后续处理。

加载器名称 来源模块 支持格式 特点
UnstructuredFileLoader langchain.document_loaders PDF, DOCX, TXT, HTML 等 支持多种非结构化文件
PyPDFLoader langchain.document_loaders PDF 基于 PyPDF 解析
CSVLoader langchain.document_loaders CSV 可指定列名
JSONLoader / JSONLinesLoader langchain.document_loaders JSON / JSONL 支持 jq schema 解析
WebBaseLoader langchain.document_loaders URL 抓取网页内容
DirectoryLoader langchain.document_loaders 文件夹 批量加载目录下文件
WikipediaLoader langchain.document_loaders Wikipedia API 获取维基百科内容
NotionDirectoryLoader langchain.document_loaders Notion 导出文件 读取 Notion 内容
GitbookLoader langchain_community.document_loaders GitBook 在线文档 自动抓取 GitBook 页面

三、LangChain 文本切分器(Splitter)

✅ 功能说明:

文本切分器用于将长文档按一定规则切分为多个小段落(chunks),以便送入 LLM 处理。

切分器名称 来源模块 切分方式 特点
RecursiveCharacterTextSplitter langchain.text_splitter 按字符递归分割 默认推荐,适用于大多数文本
CharacterTextSplitter langchain.text_splitter 固定字符长度切分 更简单直接
TokenTextSplitter langchain.text_splitter 按 token 数切分 适合 GPT 类模型
MarkdownHeaderTextSplitter langchain.text_splitter 按 Markdown 标题层级分割 保留结构信息
SpacyTextSplitter langchain.text_splitter 按句子分割(依赖 spaCy) 更语义化的中文支持
Language langchain.text_splitter 支持多语言(如 Chinese) 结合 RecursiveCharacterTextSplitter 使用
NLTKTextSplitter langchain.text_splitter 使用 NLTK 进行切分 适合英文,中文需自定义
SentenceTransformersTokenTextSplitter langchain.text_splitter 按 token 分割 适用于 BERT 类模型

四、实战代码:使用 LangChain 加载文档并进行切分

步骤说明:

  1. 使用 PyPDFLoader 加载 PDF 文件
  2. 使用 RecursiveCharacterTextSplitter 将其切分为 chunks
  3. 输出每个 chunk 的内容与长度

✅ 安装依赖:

pip install langchain unstructured pypdf spacy nltk transformers sentence-transformers

✅ 示例代码:

from langchain_community.document_loaders import PyPDFLoader, CSVLoader, WebBaseLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter, TokenTextSplitter, SpacyTextSplitter, MarkdownHeaderTextSplitter
from pathlib import Path
import os

# 设置文件路径
pdf_path = "data/sample.pdf"
csv_path = "data/sample.csv"
url = "https://example.com"

# ====== 1. 加载 PDF 文件 ======
def load_pdf():
    print(" 加载 PDF 文件...")
    loader = PyPDFLoader(pdf_path)
    docs = loader.load()
    print(f"共加载 {len(docs)} 个 Document")
    return docs

# ====== 2. 加载 CSV 文件 ======
def load_csv():
    print(" 加载 CSV 文件...")
    loader = CSVLoader(csv_path)
    docs = loader.load()
    print(f"共加载 {len(docs)} 行数据")
    return docs

# ====== 3. 加载网页内容 ======
def load_web():
    print(" 加载网页内容...")
    loader = WebBaseLoader(url)
    docs = loader.load()
    print(f"共加载 {len(docs)} 个网页段落")
    return docs

# ====== 4. 切分文本 ======

def split_documents(docs, splitter_name="recursive", chunk_size=500, chunk_overlap=50):
    print(f"✂️ 使用 {splitter_name} 切分文本")

    if splitter_name == "recursive":
        splitter = RecursiveCharacterTextSplitter(
            chunk_size=chunk_size,
            chunk_overlap=chunk_overlap,
            separators=["\n\n", "\n", ".", " ", ""]
        )
    elif splitter_name == "token":
        splitter = TokenTextSplitter(chunk_size=chunk_size, chunk_overlap=chunk_overlap)
    elif splitter_name == "spacy":
        splitter = SpacyTextSplitter(chunk_size=chunk_size, chunk_overlap=chunk_overlap)
    elif splitter_name == "markdown":
        splitter = MarkdownHeaderTextSplitter(headers_to_split_on=[("##", "Header 2"), ("#", "Header 1")])
    else:
        raise ValueError("未知的 splitter_name")

    all_splits = []
    for doc in docs:
        splits = splitter.split_text(doc.page_content)
        all_splits.extend(splits)

    print(f"切分后共 {len(all_splits)} 个 chunks")
    return all_splits

# ====== 5. 主函数测试 ======
if __name__ == "__main__":
    # 加载 PDF 并切分
    pdf_docs = load_pdf()
    pdf_chunks = split_documents(pdf_docs, splitter_name="recursive", chunk_size=500)
    
    print("\n PDF 切分样例:")
    for i, chunk in enumerate(pdf_chunks[:3]):
        print(f"Chunk {i+1} (长度: {len(chunk)}):\n{chunk}\n{'-'*40}")

    # 加载网页内容并切分
    web_docs = load_web()
    web_chunks = split_documents(web_docs, splitter_name="token", chunk_size=100)

    print("\n 网页切分样例:")
    for i, chunk in enumerate(web_chunks[:3]):
        print(f"Chunk {i+1} (长度: {len(chunk)}):\n{chunk}\n{'-'*40}")

五、扩展建议

✅ 自定义 Loader:

你可以继承 BaseLoader 实现自己的文档加载逻辑,例如 OCR PDF 加载器、数据库导出器等。

class CustomPDFLoader(BaseLoader):
    def __init__(self, file_path: str):
        self.file_path = file_path

    def load(self) -> List[Document]:
        # 实现自定义逻辑
        ...

✅ 自定义 Splitter:

你也可以根据需求继承 TextSplitter 实现中文优化切分器:

class ChineseTextSplitter(TextSplitter):
    def __init__(self, chunk_size=512, chunk_overlap=64):
        super().__init__()
        self.chunk_size = chunk_size
        self.chunk_overlap = chunk_overlap

    def split_text(self, text: str) -> List[str]:
        # 实现中文按句号、逗号、换行符等进行切分
        ...

六、典型应用场景

场景 描述
AI 助手后台 加载用户上传的 PDF/Word/Excel 文档
RAG 架构 构建文档检索系统的基础模块
聊天机器人 记忆管理、上下文注入
教育辅导系统 加载教材、试卷、习题
法律/医疗助手 高精度文档检索与理解

七、性能对比建议

方法 优点 缺点 推荐场景
RecursiveCharacterTextSplitter 简单、灵活、适配性强 不考虑语义 默认选择
TokenTextSplitter 与 GPT 类模型对齐 依赖 tokenizer 英文或 token-based 模型
SpacyTextSplitter 中文语义切分更准确 速度较慢 中文精细切分
MarkdownHeaderTextSplitter 保留结构 仅限 Markdown 文档展示类应用

八、总结一句话:

LangChain 提供了丰富的文档加载器与切分器模块,是构建 RAG、AI Agent、知识库系统的强大工具链。掌握这些模块,是迈向大模型落地的第一步。

你可能感兴趣的:(langchain系列,langchain,人工智能,机器学习,算法,深度学习,自然语言处理)