一、概述
在构建基于 LangChain 的智能问答系统时,处理 PDF 文档是常见的需求。本文将详细介绍如何使用 LangChain 加载和处理 PDF 文档,包括文本提取、图像处理(OCR)和多模态问答等方面,为构建智能文档问答系统打下坚实基础。
二、PDF 类型与处理方式概览
根据 PDF 的内容类型和结构复杂度,选择合适的处理方式至关重要。以下是常见 PDF 类型及推荐的处理方式:
PDF 类型 | 特征描述 | 推荐处理方式 |
---|---|---|
文本型 PDF | 包含可复制文本的标准 PDF,内容结构规整,适合直接提取 | PyPDFLoader |
图像型 PDF | 扫描件或图片格式,无法复制文本,需 OCR 识别 | UnstructuredLoader + OCR |
复杂布局 PDF | 包含图表、双栏、表格、公式,排版结构复杂 | 多模态模型处理 |
三、文本型 PDF 处理:PyPDFLoader
对于包含可复制文本的标准 PDF,PyPDFLoader
是首选工具。它依赖于 pypdf
库,支持分页提取、密码保护文件处理等功能。
- 安装依赖
bash
%pip install -qU pypdf
- 示例代码
python
from langchain_community.document_loaders import PyPDFLoader
file_path = (
"../../docs/integrations/document_loaders/example_data/layout-parser-paper.pdf"
)
loader = PyPDFLoader(file_path)
pages = []
# 异步懒加载,异步读取,每次处理一页
async for page in loader.alazy_load():
pages.append(page)
# 每一页是一个 Document 对象
print(pages[0].page_content) # 输出第一页的文本
四、图像型 PDF 处理:UnstructuredLoader + OCR
对于扫描件或图片格式的 PDF,UnstructuredLoader
结合 OCR 技术可以有效提取文本内容,支持通过API 或本地解析处理两种模式。
- API模式 vs 本地模式对比
特性 | API模式 | 本地模式 |
---|---|---|
处理速度 | 快(服务器资源) | 中等(依赖本地硬件) |
准确性 | 高(最新模型) | 可配置(依赖本地模型) |
数据隐私 | 数据需上传 | 完全本地处理 |
网络要求 | 需要稳定连接 | 离线可用 |
成本 | 按使用量计费 | 一次性安装成本 |
- API模式-安装依赖
shell
%pip install -qU langchain-unstructured
- API模式-示例代码
python
import getpass
import os
if "UNSTRUCTURED_API_KEY" not in os.environ:
os.environ["UNSTRUCTURED_API_KEY"] = getpass.getpass("Unstructured API Key:")
from langchain_unstructured import UnstructuredLoader
loader = UnstructuredLoader(
file_path=file_path,# 要加载的文件路径
strategy="hi_res",#提取策略,如 "hi_res", "fast" 等,用于控制处理精度与速度(Unstructured支持)
partition_via_api=True,
coordinates=True,
)
docs = []
# 同步懒加载,一页一页读
for doc in loader.lazy_load():
docs.append(doc)
first_page_docs = [doc for doc in docs if doc.metadata.get("page_number") == 1]
for doc in first_page_docs:
print(doc.page_content)
-
本地模式安装依赖
-
在本地解析需要安装Poppler 和Tesseract (OCR) 依赖项。
bash%pip install -qU "unstructured[pdf]"
-
-
本地模式示例代码
python
loader_local = UnstructuredLoader(
file_path=file_path,
strategy="hi_res",
)
docs_local = []
# 同步懒加载,一页一页读
for doc in loader_local.lazy_load():
docs_local.append(doc)
- OCR精度优化建议
- 指定语言 :明确设置 OCR 的语言参数,如
eng
、chi_sim
等,以提高识别准确率。 - 区域聚焦:如果只需识别特定区域的文本,可设置区域坐标,减少干扰。
- 分辨率调整:提高扫描图像的 DPI(建议 300 以上)有助于提升识别质量。
- 后处理校正:结合正则表达式等方法,修正常见的 OCR 错误。
五、复杂布局 PDF 处理:多模态模型
对于包含图表、双栏、表格等复杂结构的 PDF,传统的文本提取方法可能无法准确获取信息。此时,可将 PDF 页面转换为图像,结合多模态模型进行处理。
- 安装依赖
shell
%pip install -qU PyMuPDF pillow langchain-openai
- PDF文件转图像-示例代码
python
import base64
import io
import fitz
from PIL import Image
# 将pdf转换为 base64 编码
def pdf_page_to_base64(pdf_path: str, page_number: int):
pdf_document = fitz.open(pdf_path)
page = pdf_document.load_page(page_number - 1) # input is one-indexed
pix = page.get_pixmap()
img = Image.frombytes("RGB", [pix.width, pix.height], pix.samples)
buffer = io.BytesIO()
img.save(buffer, format="PNG")
return base64.b64encode(buffer.getvalue()).decode("utf-8")
- 多模态问答-示例代码
我们可以查询模型向它询问一个与页面上的图表相关的问题。
python
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage
from IPython.display import Image as IPImage
from IPython.display import display
# 将pdf转换为 base64 编码
base64_image = pdf_page_to_base64(file_path, 11)
llm = ChatOpenAI(model="gpt-4o-mini")
query = "What is the name of the first step in the pipeline?"
message = HumanMessage(
content=[
{"type": "text", "text": query},
{
"type": "image_url",
"image_url": {"url": f"data:image/jpeg;base64,{base64_image}"},
},
],
)
response = llm.invoke([message])
print(response.content)
六、性能优化建议
-
大文件处理 :使用
lazy_load
方法分批处理,避免内存溢出。 -
多文档处理:利用线程池并行处理多个文档,提高效率。
-
成本控制:对文档进行预过滤,选择性处理,提高性价比。
-
响应速度:预先构建向量索引,结合缓存机制,提升响应速度。
七、常见问题与解决方案
-
无法提取文本:可能是图像型 PDF,需结合 OCR 技术处理。
-
OCR 识别错误多:检查语言设置,调整图像分辨率,或使用更先进的 OCR 模型。
-
多模态模型响应慢:考虑使用更高效的模型或优化图像大小。
-
向量检索结果不准确:调整文本切分策略,优化嵌入模型参数。
八、总结
通过合理选择处理方式,结合 LangChain 提供的工具和模型,可以高效地处理各种类型的 PDF 文档,实现智能问答系统的构建。根据实际需求,灵活应用文本提取、OCR、多模态处理等技术,将极大提升系统的性能和用户体验。