本文是《LangChain实战课》系列的第五篇,将带你深入了解LangChain中的Document概念,并学习如何使用各种Document Loaders从不同数据源加载数据。
前言
在前几篇文章中,我们学习了LangChain的Model I/O模块,包括Prompts模板和LLMs/ChatModels的使用。今天,我们将进入数据连接(Data Connection)模块,首先学习如何从多种数据源加载文档,这是构建基于私有数据的AI应用的第一步。
Document概念
在LangChain中,是一个基本的数据结构,用于表示一段文本内容及其元数据。一个Document对象通常包含两个主要部分:
Document
:字符串,表示文档的文本内容。
page_content:字典,包含文档的元数据,如来源、创建时间、作者等。
metadata
为什么需要Document?
标准化处理:无论数据来自何处,都转换为统一的Document格式,便于后续处理。保留元数据:在加载文档时保留原始元数据,有助于后续的检索和溯源。模块化设计:将数据加载、处理、存储等步骤分离,提高代码的可维护性和复用性。
安装必要的依赖
在使用Document Loaders之前,我们需要安装一些额外的依赖包:
# 安装LangChain核心库(如果尚未安装)
pip install langchain
# 安装常用Document Loaders依赖
pip install pypdf2 # 用于处理PDF文档
pip install docx2txt # 用于处理Word文档
pip install youtube-transcript-api # 用于获取YouTube字幕
pip install beautifulsoup4 # 用于网页抓取
pip install requests # 用于HTTP请求
pip install python-dotenv # 用于管理环境变量
# 可选:安装其他特定数据源的依赖
pip install wikipedia # 用于加载Wikipedia内容
pip install gitpython # 用于加载Git仓库内容
使用各种Document Loaders
LangChain提供了大量的Document Loaders,用于从不同数据源加载文档。我们将介绍几种常用的Loader。
1. 文本文件加载器
文本文件是最简单的数据源,我们可以使用来加载。
TextLoader
from langchain.document_loaders import TextLoader
# 加载文本文件
loader = TextLoader("./example.txt", encoding="utf-8")
documents = loader.load()
# 查看加载的文档内容
print(f"加载了 {len(documents)} 个文档")
print(f"第一个文档的内容: {documents[0].page_content[:200]}...")
print(f"元数据: {documents[0].metadata}")
2. PDF文件加载器
PDF文档是常见的文档格式,我们可以使用来加载。
PyPDFLoader
from langchain.document_loaders import PyPDFLoader
# 加载PDF文件
loader = PyPDFLoader("./example.pdf")
documents = loader.load()
# PDFLoader会将每一页转换为一个Document
print(f"加载了 {len(documents)} 页文档")
for i, doc in enumerate(documents):
print(f"第 {i+1} 页内容片段: {doc.page_content[:100]}...")
print(f"元数据: {doc.metadata}")
3. Word文档加载器
Word文档也是常见的办公文档格式,可以使用来加载。
Docx2txtLoader
from langchain.document_loaders import Docx2txtLoader
# 加载Word文档
loader = Docx2txtLoader("./example.docx")
documents = loader.load()
print(f"加载了 {len(documents)} 个文档")
print(f"内容: {documents[0].page_content[:200]}...")
print(f"元数据: {documents[0].metadata}")
4. 网页内容加载器
从网页加载内容可以使用,它使用BeautifulSoup来解析网页。
WebBaseLoader
from langchain.document_loaders import WebBaseLoader
# 加载单个网页
loader = WebBaseLoader("https://example.com")
documents = loader.load()
print(f"加载了 {len(documents)} 个网页文档")
print(f"网页标题: {documents[0].metadata['title']}")
print(f"内容片段: {documents[0].page_content[:200]}...")
5. 加载多个网页
也支持同时加载多个网页。
WebBaseLoader
from langchain.document_loaders import WebBaseLoader
# 加载多个网页
urls = [
"https://example.com/page1",
"https://example.com/page2",
"https://example.com/page3"
]
loader = WebBaseLoader(urls)
documents = loader.load()
print(f"加载了 {len(documents)} 个网页文档")
for doc in documents:
print(f"网页: {doc.metadata['source']}")
print(f"内容片段: {doc.page_content[:100]}...
")
6. CSV文件加载器
CSV文件是常见的数据存储格式,可以使用来加载。
CSVLoader
from langchain.document_loaders import CSVLoader
# 加载CSV文件
loader = CSVLoader("./example.csv")
documents = loader.load()
print(f"加载了 {len(documents)} 行数据")
for i, doc in enumerate(documents[:3]): # 显示前3行
print(f"第 {i+1} 行: {doc.page_content}")
print(f"元数据: {doc.metadata}
")
7. Notion加载器
Notion是一个流行的笔记和知识管理工具,我们可以使用来加载Notion导出的数据。
NotionDirectoryLoader
首先,你需要从Notion导出你的页面(选择Markdown & CSV格式),然后使用以下代码加载:
from langchain.document_loaders import NotionDirectoryLoader
# 加载Notion导出的目录
loader = NotionDirectoryLoader("./notion_export")
documents = loader.load()
print(f"加载了 {len(documents)} 个Notion文档")
for doc in documents[:2]: # 显示前2个文档
print(f"文档: {doc.metadata['source']}")
print(f"内容片段: {doc.page_content[:200]}...
")
8. YouTube视频字幕加载器
如果你需要处理YouTube视频内容,可以使用来加载视频的字幕。
YoutubeLoader
from langchain.document_loaders import YoutubeLoader
# 加载YouTube视频字幕
loader = YoutubeLoader.from_youtube_url(
"https://www.youtube.com/watch?v=example",
add_video_info=True # 添加视频信息作为元数据
)
documents = loader.load()
print(f"加载了 {len(documents)} 个文档")
print(f"视频标题: {documents[0].metadata['title']}")
print(f"内容: {documents[0].page_content[:500]}...")
9. 维基百科加载器
LangChain还提供了加载维基百科内容的Loader。
from langchain.document_loaders import WikipediaLoader
# 加载维基百科文章
loader = WikipediaLoader(query="人工智能", lang="zh", load_max_docs=2)
documents = loader.load()
print(f"加载了 {len(documents)} 篇维基百科文章")
for doc in documents:
print(f"标题: {doc.metadata['title']}")
print(f"内容片段: {doc.page_content[:300]}...
")
高级用法
1. 自定义Document Loader
如果LangChain没有提供你需要的Loader,你可以很容易地创建自定义Loader。
from langchain.docstore.document import Document
from langchain.document_loaders.base import BaseLoader
import json
class CustomJSONLoader(BaseLoader):
"""自定义JSON加载器"""
def __init__(self, file_path):
self.file_path = file_path
def load(self):
with open(self.file_path, 'r', encoding='utf-8') as f:
data = json.load(f)
documents = []
for item in data:
content = item.get('content', '')
metadata = item.get('metadata', {})
metadata['source'] = self.file_path
documents.append(Document(page_content=content, metadata=metadata))
return documents
# 使用自定义Loader
loader = CustomJSONLoader("./example.json")
documents = loader.load()
print(f"加载了 {len(documents)} 个文档")
2. 批量加载和处理
当需要从多个文件加载数据时,可以使用来批量加载。
DirectoryLoader
from langchain.document_loaders import DirectoryLoader
from langchain.document_loaders import TextLoader
# 批量加载目录中的所有文本文件
loader = DirectoryLoader(
"./data", # 目录路径
glob="**/*.txt", # 文件匹配模式
loader_cls=TextLoader, # 用于加载每个文件的Loader类
loader_kwargs={"encoding": "utf-8"}, # 传递给Loader的参数
silent_errors=True # 是否静默处理错误
)
documents = loader.load()
print(f"从目录中加载了 {len(documents)} 个文档")
3. 使用Unstructured文件加载器
是一个强大的Loader,可以处理多种文件格式,包括PDF、Word、HTML等。
UnstructuredFileLoader
from langchain.document_loaders import UnstructuredFileLoader
# 加载任意格式的文件
loader = UnstructuredFileLoader("./example.docx")
documents = loader.load()
print(f"加载了 {len(documents)} 个文档")
print(f"内容: {documents[0].page_content[:500]}...")
最佳实践
1. 错误处理
在实际应用中,良好的错误处理机制非常重要。
from langchain.document_loaders import TextLoader
import os
def safe_load_documents(loader, file_path):
"""安全加载文档,处理可能出现的错误"""
if not os.path.exists(file_path):
print(f"文件不存在: {file_path}")
return []
try:
documents = loader.load()
return documents
except Exception as e:
print(f"加载文件时出错 {file_path}: {e}")
return []
# 安全加载文档
loader = TextLoader("./example.txt", encoding="utf-8")
documents = safe_load_documents(loader, "./example.txt")
2. 内存管理
当处理大量或大文件时,需要注意内存使用。
from langchain.document_loaders import PyPDFLoader
# 分批处理PDF文档
loader = PyPDFLoader("./large_file.pdf")
documents = []
for page in loader.lazy_load(): # 使用惰性加载
# 在这里处理每一页,避免一次性加载所有内容
processed_content = process_page(page.page_content)
documents.append(Document(
page_content=processed_content,
metadata=page.metadata
))
# 可以定期清理或保存到磁盘,避免内存不足
if len(documents) % 100 == 0:
save_to_disk(documents)
documents = []
# 处理剩余文档
if documents:
save_to_disk(documents)
3. 元数据管理
合理使用元数据可以提高后续检索的效果。
from langchain.document_loaders import TextLoader
from datetime import datetime
# 加载文档并添加自定义元数据
loader = TextLoader("./example.txt", encoding="utf-8")
documents = loader.load()
# 为所有文档添加加载时间和处理版本
for doc in documents:
doc.metadata["load_time"] = datetime.now().isoformat()
doc.metadata["processor_version"] = "v1.0"
print(f"文档元数据: {documents[0].metadata}")
总结
通过本文,我们深入学习了LangChain中的Document Loaders:
✅ 理解了Document的概念和重要性✅ 掌握了从多种数据源加载文档的方法:
文本文件、PDF、Word文档网页内容、CSV文件Notion导出数据、YouTube字幕、维基百科
✅ 学习了高级用法,如自定义Loader和批量处理✅ 了解了错误处理、内存管理和元数据管理的最佳实践
这些知识将为你后续的文档处理、向量化和检索奠定坚实的基础。
下一步学习建议
尝试从你自己的数据源加载文档,如公司内部的文档、个人笔记等探索LangChain支持的其他Document Loaders,如GitHub、Google Drive等学习如何使用文档转换器(Document Transformers)对加载的文档进行处理了解如何将加载的文档存储到向量数据库中,为后续的检索做准备
欢迎在评论区分享你的数据加载经验! 你从哪些有趣的数据源加载过文档?遇到了什么挑战?如果有任何疑问,欢迎在评论区留言,我们会尽力解答。
下一篇预告:《LangChain实战:Document Transformers – 文本分割与处理》 – 我们将学习如何对加载的文档进行分割和处理,为后续的存储和检索做准备。




















暂无评论内容