一、概述
在构建基于 LangChain 的智能问答系统时,处理 PDF 文档是常见的需求。本文将详细介绍如何使用 LangChain 加载和处理 PDF 文档,包括文本提取、图像处理(OCR)和多模态问答等方面,为构建智能文档问答系统打下坚实基础。
二、PDF 类型与处理方式概览
根据 PDF 的内容类型和结构复杂度,选择合适的处理方式至关重要。以下是常见 PDF 类型及推荐的处理方式:
PDF 类型 | 特征描述 | 推荐处理方式 |
---|---|---|
文本型 PDF | 包含可复制文本的标准 PDF,内容结构规整,适合直接提取 | PyPDFLoader |
图像型 PDF | 扫描件或图片格式,无法复制文本,需 OCR 识别 | UnstructuredLoader + OCR |
复杂布局 PDF | 包含图表、双栏、表格、公式,排版结构复杂 | 多模态模型处理 |
三、文本型 PDF 处理:PyPDFLoader
对于包含可复制文本的标准 PDF,PyPDFLoader
是首选工具。它依赖于 pypdf
库,支持分页提取、密码保护文件处理等功能。
- 安装依赖
%pip install -qU pypdf
- 示例代码
from langchain_community.document_loaders import PyPDFLoaderfile_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模式-安装依赖
%pip install -qU langchain-unstructured
- API模式-示例代码
import getpassimport osif "UNSTRUCTURED_API_KEY" not in os.environ: os.environ["UNSTRUCTURED_API_KEY"] = getpass.getpass("Unstructured API Key:") from langchain_unstructured import UnstructuredLoaderloader = 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) 依赖项。
%pip install -qU "unstructured[pdf]"
本地模式示例代码
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 页面转换为图像,结合多模态模型进行处理。
- 安装依赖
%pip install -qU PyMuPDF pillow langchain-openai
- PDF文件转图像-示例代码
import base64import ioimport fitzfrom 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")
- 多模态问答-示例代码
我们可以查询模型向它询问一个与页面上的图表相关的问题。
from langchain_openai import ChatOpenAIfrom langchain_core.messages import HumanMessagefrom IPython.display import Image as IPImagefrom 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、多模态处理等技术,将极大提升系统的性能和用户体验。