基于 LangChain 实现 PDF 文档检索:从加载到向量检索全流程

在大模型应用开发中,文档检索是核心能力之一,尤其是针对 PDF 这类非结构化文档的精准检索,能极大提升问答、知识库等场景的体验。本文将基于 LangChain 框架,完整拆解从 PDF 文档加载、文本分割、向量嵌入到相似性检索的全流程,手把手教你实现针对 PDF 文档的智能检索。

一、核心技术栈说明

在开始编码前,先明确本次用到的核心工具和库:

  • LangChain:一站式 LLM 应用开发框架,提供文档加载、文本分割、向量存储等全套工具链;
  • PyPDFLoader:LangChain 内置的 PDF 文档加载器,可高效解析 PDF 内容;
  • RecursiveCharacterTextSplitter:递归字符文本分割器,支持按自定义规则拆分长文本;
  • DashScopeEmbeddings:阿里云灵积平台的文本嵌入模型,将文本转化为向量表示;
  • FAISS:Facebook 开源的向量数据库,支持高效的相似性检索。

二、实现步骤:从 PDF 到智能检索

1. 文档加载:读取 PDF 内容

首先需要将 PDF 文档的内容加载到程序中,LangChain 的PyPDFLoader提供了极简的加载方式,无需关注底层 PDF 解析细节:

python 复制代码
from langchain_community.document_loaders import PyPDFLoader

# 初始化PDF加载器,指定PDF文件路径
loader = PyPDFLoader("./PDFQA/卢浮宫.pdf")
# 加载PDF文档,返回Document对象列表
docs = loader.load()
# 打印第一页内容,验证加载结果
print(docs[0].page_content)

除了 PDF,LangChain 还支持维基百科、文本文件等多种数据源加载,比如通过WikipediaLoader加载维基百科内容:

python 复制代码
from langchain_community.document_loaders import WikipediaLoader
loader = WikipediaLoader(query="周杰伦", load_max_docs=3, lang="zh")
docs = loader.load()
print(docs[1].page_content)

2. 文本分割:解决长文本嵌入限制

PDF 加载后的文本通常较长,而嵌入模型对输入文本长度有约束,且过长的文本会降低检索精度。因此需要将长文本拆分为大小适中的文本块(Chunk)。

这里使用RecursiveCharacterTextSplitter,它会按指定的分隔符递归拆分文本,同时保留文本语义完整性:

python 复制代码
from langchain_text_splitters import RecursiveCharacterTextSplitter

# 初始化文本分割器
text_splitter = RecursiveCharacterTextSplitter(
    chunk_size=500,          # 每个文本块的最大字符数
    chunk_overlap=100,       # 相邻文本块的重叠字符数(提升上下文连续性)
    separators=["\n\n", "\n", "。", "!", "?", ",", "、", ""]  # 中文文本分隔符
)
# 拆分加载的PDF文档
texts = text_splitter.split_documents(docs)
# 打印第三个文本块,验证分割效果
print(texts[2].page_content)

关键参数说明

  • chunk_size:控制单个文本块的长度,需结合嵌入模型的输入限制调整;
  • chunk_overlap:重叠部分能避免文本被拆分后丢失上下文关联;
  • separators:优先按列表前序分隔符拆分,适配中文文本的语义停顿规则。

3. 文本嵌入:将文本转化为向量

文本无法直接被计算机用于相似性检索,需要通过嵌入模型转化为数值向量(Embedding)。本文使用阿里云灵积平台的DashScopeEmbeddings,也可替换为 OpenAI Embeddings 等其他模型。

python 复制代码
import os
from langchain_community.embeddings import DashScopeEmbeddings

# 初始化嵌入模型(需配置阿里云灵积API密钥)
embeddings_model = DashScopeEmbeddings(
    model="text-embedding-v2",
    dashscope_api_key=os.getenv("DASHSCOPE_API_KEY")  # 从环境变量读取API密钥,避免硬编码
)

# 测试文本嵌入效果
# 单文本查询嵌入
query_result = embeddings_model.embed_query("卢浮宫这个名字怎么来的?")
print("单个文本向量长度:", len(query_result))

# 多文本文档嵌入
doc_results = embeddings_model.embed_documents(["My friends call me TOM", "Hello World!"])
print("文档向量数量:", len(doc_results), ",单个文档向量长度:", len(doc_results[0]))

进阶配置 :如果希望降低向量维度(减少存储和计算成本),可使用text-embedding-v3模型并指定dimensions参数:

python 复制代码
embeddings_model = DashScopeEmbeddings(
    model="text-embedding-v3",
    dashscope_api_key=os.getenv("DASHSCOPE_API_KEY"),
    dimensions=1024  # 指定向量维度为1024
)

4. 向量存储与检索:基于 FAISS 实现相似性查询

将分割后的文本块嵌入为向量后,存入 FAISS 向量数据库,即可实现基于语义的相似性检索。

python 复制代码
from langchain_community.vectorstores import FAISS

# 将文本块向量存入FAISS
db = FAISS.from_documents(texts, embeddings_model)

# 将数据库转为检索器,用于相似性查询
retriever = db.as_retriever()

# 示例1:检索"卢浮宫这个名字怎么来的?"相关文本
retrieved_docs = retriever.invoke("卢浮宫这个名字怎么来的?")
print("检索结果1:\n", retrieved_docs[0].page_content)

# 示例2:检索"是否可以使用闪光灯"相关文本
retrieved_docs = retriever.invoke("是否可以使用闪光灯")
print("检索结果2:\n", retrieved_docs[0].page_content)

批量处理优化:如果 PDF 文档量较大,可分批将文本块加入 FAISS,避免单次加载过多数据:

python 复制代码
batch_size = 10
persist_directory = "./faiss_db"  # 向量库持久化路径
for i in range(0, len(texts), batch_size):
    batch_docs = texts[i:i+batch_size]
    if i == 0:
        # 第一批文档创建向量库
        vectordb = FAISS.from_documents(
            documents=batch_docs,
            embedding=embeddings_model,
            persist_directory=persist_directory
        )
    else:
        # 后续批次添加到现有向量库
        vectordb.add_documents(batch_docs)

三、核心流程总结

  1. 文档加载:通过 PyPDFLoader 读取 PDF 内容,转化为 LangChain Document 对象;
  2. 文本分割:用 RecursiveCharacterTextSplitter 拆分文本块,平衡长度与语义;
  3. 文本嵌入:通过 DashScopeEmbeddings 将文本转为向量,实现语义数字化;
  4. 向量检索:基于 FAISS 构建向量库,通过检索器快速匹配相似文本块。

四、扩展与优化建议

  1. 模型替换:可将 DashScopeEmbeddings 替换为 OpenAI Embeddings、智谱 AI 嵌入等,适配不同平台;
  2. 向量库持久化 :使用 FAISS 的save_local方法保存向量库,避免重复嵌入;
  3. 检索参数调优 :调整retrieversearch_kwargs(如k值),控制返回的相似文本数量;
  4. 多数据源支持:结合 LangChain 的其他 Loader(如 CSVLoader、MarkdownLoader),支持多格式文档检索。

五、应用场景

该方案可直接用于构建 PDF 问答机器人、企业知识库检索系统、智能文档分析工具等场景,核心优势是基于语义的精准检索,相比传统关键词检索更贴合自然语言查询的需求。

通过以上步骤,我们完成了从 PDF 文档加载到语义检索的全流程实现。LangChain 的模块化设计让整个流程高度可定制,开发者可根据实际需求替换组件,快速搭建符合业务场景的文档检索系统。

相关推荐
小袁说公考1 小时前
公考培训机构2025年度测评:财务健康度与用户体验重构排名格局
大数据·人工智能·经验分享·笔记·其他·重构·ux
xinlianyq1 小时前
2026 AI 生成电商短视频工具推荐与性价比分析,电商垂类与综合工具
人工智能·ai
跨境猫小妹1 小时前
爆款复制难度提高之后跨境卖家如何转向稳定型商品布局
大数据·人工智能·产品运营·跨境电商·营销策略
跟尚西学PowerBI1 小时前
【供应链AI实践案例】OpenClaw+PowerBI 打造 AI 智能库存预警实战
大数据·人工智能·数据分析·openclaw
动物园猫1 小时前
交通标识与信号灯数据集分享(适用于YOLO系列深度学习检测任务)
人工智能·深度学习·yolo
YangYang9YangYan1 小时前
2026运营岗位学习数据分析对于提升个人能力的价值
学习·数据挖掘·数据分析
weixin_377634841 小时前
【SkillRL】强化学习详解
人工智能
吃好睡好便好2 小时前
在Matlab中绘制抛物三维曲面图
开发语言·人工智能·学习·算法·matlab·信息可视化
Li_yizYa2 小时前
【大模型篇】谈谈对于Function Calling、MCP、Skill的理解
ai·大模型