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 对象,便于后续处理。

加载器名称来源模块支持格式特点
UnstructuredFileLoaderlangchain.document_loadersPDF, DOCX, TXT, HTML 等支持多种非结构化文件
PyPDFLoaderlangchain.document_loadersPDF基于 PyPDF 解析
CSVLoaderlangchain.document_loadersCSV可指定列名
JSONLoader / JSONLinesLoaderlangchain.document_loadersJSON / JSONL支持 jq schema 解析
WebBaseLoaderlangchain.document_loadersURL抓取网页内容
DirectoryLoaderlangchain.document_loaders文件夹批量加载目录下文件
WikipediaLoaderlangchain.document_loadersWikipedia API获取维基百科内容
NotionDirectoryLoaderlangchain.document_loadersNotion 导出文件读取 Notion 内容
GitbookLoaderlangchain_community.document_loadersGitBook 在线文档自动抓取 GitBook 页面

🔍 三、LangChain 文本切分器(Splitter)

✅ 功能说明:

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

切分器名称来源模块切分方式特点
RecursiveCharacterTextSplitterlangchain.text_splitter按字符递归分割默认推荐,适用于大多数文本
CharacterTextSplitterlangchain.text_splitter固定字符长度切分更简单直接
TokenTextSplitterlangchain.text_splitter按 token 数切分适合 GPT 类模型
MarkdownHeaderTextSplitterlangchain.text_splitter按 Markdown 标题层级分割保留结构信息
SpacyTextSplitterlangchain.text_splitter按句子分割(依赖 spaCy)更语义化的中文支持
Languagelangchain.text_splitter支持多语言(如 Chinese)结合 RecursiveCharacterTextSplitter 使用
NLTKTextSplitterlangchain.text_splitter使用 NLTK 进行切分适合英文,中文需自定义
SentenceTransformersTokenTextSplitterlangchain.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、知识库系统的强大工具链。掌握这些模块,是迈向大模型落地的第一步。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

要努力啊啊啊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值