Skip to content

LangChain 文档加载与切分

之前的文章我们手动输入文本,但在实际项目中,文档可能来自 PDF、网页、Markdown 文件等。

本节介绍如何使用 Document Loader 加载各类文档,以及如何用 Text Splitter 将文档切分成适合检索的小块。


Document Loader——加载文档

LangChain 提供了数十种文档加载器,覆盖常见文件格式:

Loader来源安装包
TextLoader.txt 文件langchain(内置)
PyPDFLoaderPDF 文件langchain-community + pypdf
WebBaseLoader网页 URLlangchain-community + beautifulsoup4
CSVLoaderCSV 文件langchain-community
UnstructuredMarkdownLoaderMarkdown 文件langchain-community + unstructured

实例

bash

# 加载文本文件(内置,无需额外安装)

from langchain_community.document_loaders import TextLoader

loader = TextLoader("knowledge.txt", encoding="utf-8")

docs = loader.load()

print(f"加载了 {len(docs)} 个文档")

print(f"内容预览: {docs[0].page_content[:150]}...")

# 加载网页

# pip install langchain-community beautifulsoup4

from langchain_community.document_loaders import WebBaseLoader

loader = WebBaseLoader("https://www.runoob.com/python/python-tutorial.html")

docs = loader.load()

print(f"\n网页内容: {docs[0].page_content[:150]}...")

Text Splitter——文档切分

文档通常太长,需要切分成小块(chunk)才能有效检索。切分策略直接影响 RAG 效果:

实例

python

from langchain_text_splitters import RecursiveCharacterTextSplitter

# 创建切分器

text_splitter = RecursiveCharacterTextSplitter(

    chunk_size=500,         # 每块最多 500 个字符

    chunk_overlap=50,       # 块之间重叠 50 个字符

    separators=["\n\n", "\n", "。", "!", "?", ";", ",", " ", ""],

    # 优先按段落分割,然后是句子,最后是字符

)

# 示例文档

long_text = """菜鸟教程(RUNOOB)是一个免费的编程学习平台。

平台提供了丰富的编程语言教程,包括但不限于:

- Python 教程:从基础语法到数据分析

- Java 教程:面向对象编程到 Spring 框架

- 前端教程:HTML、CSS、JavaScript 及其框架

所有教程都配有详细的代码示例和在线运行环境。

学习者可以通过边学边练的方式快速掌握编程技能。"""

# 切分文档

chunks = text_splitter.split_text(long_text)

print(f"原文长度: {len(long_text)} 字")

print(f"切分后: {len(chunks)}\n")

for i, chunk in enumerate(chunks):

    print(f"--- 块 {i+1} ({len(chunk)} 字) ---")

    print(chunk)

    print()

运行结果:

python
原文长度: 153
切分后: 3

---1 (54 字) ---
菜鸟教程(RUNOOB)是一个免费的编程学习平台。
平台提供了丰富的编程语言教程,包括但不限于:

---2 (49 字) ---
- Python 教程:从基础语法到数据分析
- Java 教程:面向对象编程到 Spring 框架

---3 (50 字) ---
- 前端教程:HTMLCSS、JavaScript 及其框架
所有教程都配有详细的代码示例和在线运行环境。

chunk_overlap 很重要。如果块之间没有重叠,一个完整的句子可能被切成两半,导致检索时遗漏关键信息。50-100 字符的重叠是常见的设置。


切分参数设置指南

场景chunk_sizechunk_overlap原因
FAQ 问答200~50020~50问答对较短,小块即可
技术文档500~100050~100技术内容需要更多上下文
长文章/论文1000~2000100~200需要保留段落完整性
代码库500~15000~50函数/类作为自然边界

完整流程:加载 → 切分 → 向量化

实例

python

from langchain_text_splitters import RecursiveCharacterTextSplitter

from langchain_openai import OpenAIEmbeddings

from langchain_chroma import Chroma

# from langchain_community.document_loaders import TextLoader

# 流程 1:加载

# loader = TextLoader("runoob_knowledge.txt", encoding="utf-8")

# docs = loader.load()

# 为演示直接使用示例文本

docs = [

    "菜鸟教程(RUNOOB)是一个免费的编程学习网站。",

    "网站提供 Python、Java、HTML 等多种编程语言的教程。",

    "Python3 基础教程共 30 章,适合零基础入门学习。",

    "HTML 基础教程共 25 章,包含表单、多媒体等内容。",

    "菜鸟教程的所有基础教程都是免费的。",

]

# 流程 2:切分

text_splitter = RecursiveCharacterTextSplitter(

    chunk_size=100,

    chunk_overlap=20,

)

chunks = text_splitter.create_documents(docs)

# 流程 3:向量化存储

embeddings = OpenAIEmbeddings(model="text-embedding-3-small")

vector_store = Chroma.from_documents(

    documents=chunks,

    embedding=embeddings,

    persist_directory="./runoob_db",

)

print(f"已建立索引:{len(chunks)} 个文档块")

# 流程 4:检索

results = vector_store.similarity_search("Python 教程有多少章?", k=2)

for doc in results:

    print(f"检索结果: {doc.page_content}")

运行结果:

python
已建立索引:5 个文档块
检索结果: Python3 基础教程共 30 章,适合零基础入门学习。
检索结果: 菜鸟教程(RUNOOB)是一个免费的编程学习网站。

AI 思考中...

LangChain RAG

LangChain 构建 RAG Agent

基于 VitePress 构建,部署于 GitHub Pages