LangChain 文档处理集成指南:面向知识管理开发者
引言
文档处理是知识管理系统的核心能力。LangChain 提供丰富的文档加载器和处理工具,帮助你处理各种格式的文档。
一、主流文档处理工具对比
| 工具/库 | 支持格式 | 是否免费 | 是否需要 API Key | 说明 |
|---|---|---|---|---|
| PyPDF2/pypdf | 免费 | 否 | Python 库,轻量快速 | |
| Unstructured | PDF, Word, HTML, TXT | 免费 | 否 | 开源库,支持多种格式 |
| Beautiful Soup | HTML, XML | 免费 | 否 | 网页解析 |
| Python-docx | Word (.docx) | 免费 | 否 | 微软 Word 文档 |
| DirectoryLoader | 批量文件 | 免费 | 否 | LangChain 内置 |
| pypdfium2 | 免费 | 否 | 高性能 PDF 解析 | |
| SURF | 免费 | 否 | 高级文档解析 | |
| Docugami | Word, PDF | 有免费层 | 是 | 企业级文档解析 |
二、文档加载器详解
2.1 PDF 文档
方案一:pypdf(简单快速)
python
from langchain_community.document_loaders import PyPDFLoader
loader = PyPDFLoader("document.pdf")
pages = loader.load_and_split()
print(f"加载了 {len(pages)} 页")
for i, page in enumerate(pages[:2]):
print(f"\n第 {i+1} 页内容(前 200 字):")
print(page.page_content[:200])
方案二:UnstructuredPDFLoader(更强大)
python
from langchain_community.document_loaders import UnstructuredPDFLoader
loader = UnstructuredPDFLoader("document.pdf")
documents = loader.load()
print(f"PDF 总字数:{len(documents[0].page_content)}")
2.2 Word 文档
python
from langchain_community.document_loaders import Docx2txtLoader
loader = Docx2txtLoader("report.docx")
documents = loader.load()
print(f"Word 文档内容:{documents[0].page_content[:300]}...")
2.3 HTML/网页
python
from langchain_community.document_loaders import BSHTMLLoader
# 本地 HTML 文件
loader = BSHTMLLoader("page.html")
documents = loader.load()
print(f"HTML 内容:{documents[0].page_content[:200]}")
# 远程网页
from langchain_community.document_loaders import WebBaseLoader
web_loader = WebBaseLoader("https://example.com/article")
web_docs = web_loader.load()
print(f"网页内容:{web_docs[0].page_content[:200]}")
2.4 纯文本文件
python
from langchain_community.document_loaders import TextLoader
loader = TextLoader("notes.txt", encoding="utf-8")
documents = loader.load()
print(f"文档内容:{documents[0].page_content[:300]}")
2.5 Markdown 文件
python
from langchain_community.document_loaders import UnstructuredMarkdownLoader
loader = UnstructuredMarkdownLoader("README.md")
documents = loader.load()
print(f"Markdown 内容:{documents[0].page_content[:300]}")
三、批量文档加载
3.1 加载目录下所有文件
python
from langchain_community.document_loaders import DirectoryLoader
# 加载所有 .txt 文件
loader = DirectoryLoader(
"./documents",
glob="**/*.txt",
use_multithreading=True
)
documents = loader.load()
print(f"加载了 {len(documents)} 个文档")
# 加载多种格式
from langchain_community.document_loaders import TextLoader, PyPDFLoader
loader = DirectoryLoader(
"./documents",
glob="**/*",
loader_cls=TextLoader, # 默认用 TextLoader
show_progress=True # 显示进度
)
documents = loader.load()
3.2 同时加载多种格式
python
from langchain_community.document_loaders import DirectoryLoader
from langchain_community.document_loaders.pdf import PyPDFLoader
from langchain_community.document_loaders.text import TextLoader
import glob
import os
all_documents = []
# 加载 PDF
pdf_loader = DirectoryLoader("./documents", glob="**/*.pdf", loader_cls=PyPDFLoader)
all_documents.extend(pdf_loader.load())
# 加载 TXT
txt_loader = DirectoryLoader("./documents", glob="**/*.txt", loader_cls=TextLoader)
all_documents.extend(txt_loader.load())
print(f"总共加载 {len(all_documents)} 个文档")
四、文档分割与处理
4.1 文本分割
python
from langchain_text_splitters import RecursiveCharacterTextSplitter
# 创建分割器
splitter = RecursiveCharacterTextSplitter(
chunk_size=500, # 每块大小
chunk_overlap=50, # 重叠部分
length_function=len, # 计算长度的函数
separators=["\n\n", "\n", "。", ";", " ", ""] # 分隔符(中文优化)
)
# 分割文档
from langchain_community.document_loaders import TextLoader
docs = TextLoader("article.txt").load()
chunks = splitter.split_documents(docs)
print(f"分割为 {len(chunks)} 个片段")
for i, chunk in enumerate(chunks[:3]):
print(f"\n片段 {i+1}: {chunk.page_content[:100]}...")
4.2 元数据提取与管理
python
from langchain_core.documents import Document
# 创建带元数据的文档
docs = [
Document(
page_content="RAG 技术原理...",
metadata={"source": "tech_blog", "author": "张三", "date": "2024-01-15"}
),
Document(
page_content="大模型应用...",
metadata={"source": "tech_blog", "author": "李四", "date": "2024-02-01"}
)
]
# 基于元数据筛选
ai_docs = [d for d in docs if "AI" in d.page_content or "RAG" in d.page_content]
print(f"找到 {len(ai_docs)} 个 AI 相关文档")
五、实战:构建知识库系统
python
from langchain_chroma import Chroma
from langchain_openai import OpenAIEmbeddings, ChatOpenAI
from langchain_community.document_loaders import DirectoryLoader, TextLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnablePassthrough
from langchain_core.output_parsers import StrOutputParser
class KnowledgeBase:
def __init__(self, docs_dir: str = "./knowledge_docs"):
self.docs_dir = docs_dir
self.db = None
self.llm = ChatOpenAI(
base_url="http://localhost:11434/v1/",
api_key="ollama",
model="qwen3.5:4b"
)
self.embeddings = OpenAIEmbeddings(
base_url="http://localhost:11434/v1/",
api_key="ollama",
model="nomic-embed-text"
)
self.rag_chain = None
def load_documents(self):
"""加载目录下所有文档"""
loader = DirectoryLoader(
self.docs_dir,
glob="**/*.txt",
loader_cls=TextLoader,
use_multithreading=True
)
documents = loader.load()
print(f"加载了 {len(documents)} 个文档")
return documents
def split_documents(self, documents):
"""分割文档"""
splitter = RecursiveCharacterTextSplitter(
chunk_size=500,
chunk_overlap=50,
separators=["\n\n", "\n", "。", ";", " ", ""]
)
chunks = splitter.split_documents(documents)
print(f"分割为 {len(chunks)} 个片段")
return chunks
def build_vector_store(self, chunks):
"""构建向量数据库(本地,免费)"""
self.db = Chroma.from_documents(
documents=chunks,
embedding=self.embeddings,
persist_directory="./kb_db"
)
print("向量数据库构建完成")
def setup_rag(self):
"""设置 RAG 查询链"""
retriever = self.db.as_retriever(search_kwargs={"k": 3})
prompt = ChatPromptTemplate.from_template("""
你是一个知识管理助手。根据提供的上下文回答问题。
上下文:{context}
问题:{question}
请基于上下文给出详细回答。如果上下文中没有答案,请说"抱歉,我没有找到相关信息"。
""")
self.rag_chain = (
{"context": retriever, "question": RunnablePassthrough()}
| prompt
| self.llm
| StrOutputParser()
)
def query(self, question: str) -> str:
"""查询知识库"""
if not self.rag_chain:
return "请先初始化知识库"
return self.rag_chain.invoke(question)
# 使用示例
if __name__ == "__main__":
kb = KnowledgeBase()
# 构建知识库(只需执行一次)
documents = kb.load_documents()
chunks = kb.split_documents(documents)
kb.build_vector_store(chunks)
kb.setup_rag()
# 查询
print("\n=== 知识库查询测试 ===")
response = kb.query("RAG 技术的核心是什么?")
print(f"回答:{response}")
六、快速选择指南
| 场景 | 推荐方案 | 是否免费 | 说明 |
|---|---|---|---|
| 简单 PDF 解析 | PyPDFLoader | 免费 | 简单快速 |
| 复杂 PDF 解析 | UnstructuredPDFLoader | 免费 | 更好的格式保留 |
| Word 文档 | Docx2txtLoader | 免费 | 支持 .docx |
| 网页内容 | WebBaseLoader | 免费 | 支持远程 URL |
| 批量处理 | DirectoryLoader | 免费 | 多线程加载 |
| 中文文档优化 | 自定义分割器 | 免费 | 调整分隔符 |
七、常见问题
Q: 如何处理大型 PDF 文件?
A: 使用 PyPDFLoader 的 load_and_split() 方法,或使用 RecursiveCharacterTextSplitter 进一步分割。
Q: 如何提高文档处理速度?
A: 使用 use_multithreading=True 启用多线程,或使用更轻量的加载器。
Q: 如何处理不同编码的文本文件?
A: 在 TextLoader 中指定 encoding 参数,如 encoding="utf-8" 或 encoding="gbk"。
Q: 如何优化中文文档的分割效果?
A: 在 RecursiveCharacterTextSplitter 中添加中文分隔符如 "。", ";", ","。
LangChain 的文档处理工具让知识管理变得简单:
- 格式丰富:支持 PDF、Word、HTML、TXT 等多种格式
- 免费开源:所有核心工具都免费,无需 API Key
- 灵活分割:可自定义分割策略和参数
- 元数据管理:轻松管理文档信息
- 向量集成:直接对接向量数据库
推荐入门路径:先用 PyPDFLoader + TextLoader 处理基础文档,再根据需求扩展到更多格式。