从PDF到适用于AI的文本:如何选择合适的数据提取工具
PDF数据提取的质量直接影响着人工智能的准确性。成都长风云Drupal开发团队在构建BetterRegulation的文档处理系统时发现,简单的提取方式会让40 - 60%的上下文窗口浪费在PDF的干扰项上。在评估了ChatGPT API、传统Python库和Unstructured.io之后,我们实现了30%的令牌减少,还显著提高了文档分类的效果。以下就是我们的经验总结。
本文内容概览:
- 为什么PDF数据提取具有挑战性?
- 为什么PDF对人工智能来说如此难处理?
- 不同的PDF数据提取方法有何优劣?
- Unstructured.io是如何工作的?
- 性能和成本之间如何权衡?
- 我们在实际生产中取得了哪些成果?
- 其他可选的PDF数据提取工具
- 何时该使用哪种PDF提取工具
- 想改进你的PDF处理流程吗?
一、为什么PDF数据提取具有挑战性?
当我们开始构建BetterRegulation的文档处理系统时,很快就遇到了一个现实问题:PDF文件无处不在。合同、报告、规格说明、法规、研究论文——我们需要处理的每一份监管文档都是PDF格式。
但我们很快意识到一个问题:PDF文件极不适合人工智能处理。
PDF最初是为打印和视觉展示设计的,并非用于文本提取和机器可读性。它编码的是位置、字体、颜色和布局信息,而非语义内容。
当简单地从PDF中提取文本时,结果会杂乱无章且无法使用。页眉和页脚会在每一页重复出现,页码会嵌入到句子中间,水印会与实际内容混在一起。多列文本会按从左到右的顺序读取,而不是按列正确读取,脚注会随意打断段落,表格数据会变成无结构的乱码。此外,格式标记和PDF元数据会使输出内容混乱,换行符会出现在完全随机的位置,导致句子在单词中间断开。
简单PDF提取示例:
2024年第三季度企业风险评估 第1页,共45页
执行摘 - 以下报告 机密
要 提供了全面的
风险因素 企业风险敞 - 风险类别
财务风险 口识别 高
于2024年第三季度
运营风险 审计程序期间。 中
合规风险 高
2024年第三季度企业风险评估 第2页,共45页
[更多破碎文本继续...]
这就是我们最初提供给人工智能的数据,难怪它会感到困惑并出现分类错误。
我们了解到人工智能真正需要的内容:
执行摘要
以下报告提供了2024年第三季度审计程序期间确定的企业风险敞口的全面概述。
风险因素:
- 财务风险:高
- 运营风险:中
- 合规风险:高
干净、结构化、易读的文本,能够准确代表文档的语义内容。
本文将分享我们是如何解决这一挑战的,以及在此过程中吸取的经验教训。
另请阅读: Drupal中的人工智能文档处理:准确率达95%的技术案例研究
二、为什么PDF对人工智能来说如此难处理?
了解PDF为何会给人工智能带来问题,有助于解释为什么选择合适的提取工具至关重要。以下是我们遇到的四个主要挑战。
一、格式标记和元数据
PDF包含的位置信息、字体规格和布局指令并非实际内容的一部分:
/F1 12 Tf % 字体大小12
(执行摘要) Tj
72 650 Td % 坐标位置
/F2 10 Tf % 字体大小10
(以下报告...) Tj
这些标记可能会使30 - 50%的人工智能上下文窗口被非内容信息占用。
二、复杂的布局
多列布局、文本框、侧边栏——PDF将这些编码为带有坐标的独立文本对象,而不是按照逻辑阅读顺序:
[第一列文本] [第二列文本]
[第一列更多内容] [第二列更多内容]
简单提取会按从左到右的顺序读取: “第一列文本 第二列文本 第一列更多内容 第二列更多内容”
正确的阅读顺序: “第一列文本 第一列更多内容” 然后 “第二列文本 第二列更多内容”
三、嵌入式内容
图像、图表、表格、页眉、页脚、页码——所有这些都作为独立对象嵌入。简单提取要么会包含所有内容(产生干扰),要么会跳过重要内容(导致数据丢失)。
四、结构的多样性
没有两份PDF的内容结构是相同的。适用于简单报告的方法,对于带有复杂脚注和引用的法律文档、带有嵌入式表格和图表的技术规格说明、需要进行光学字符识别(OCR)的扫描文档,或具有特定字段布局的结构化表单,可能完全不适用。每种文档类型都需要不同的提取策略。
提取效果不佳会对人工智能产生什么影响?
PDF数据提取效果不佳的后果非常严重。仅令牌浪费一项,就会使40 - 60%的上下文窗口被PDF的干扰项占用,而非实际内容。人工智能会试图将页码、页眉和格式标记解释为有意义的信息,从而产生混淆。这会导致诸如多列文本混淆、句子断裂、上下文缺失和文档分类错误等问题。最终,你是在为处理PDF的干扰信息付费,而不是真正重要的内容。
三、不同的PDF数据提取方法有何优劣?
在选择解决方案之前,我们评估了三种主要方法。
一、直接将PDF发送到ChatGPT API
工作原理: 直接将PDF发送到ChatGPT Vision API,让OpenAI处理提取。
这是我们采用的第一种方法——只需一次API调用,就能简单快速地实现初步方案。它实现速度快,无需额外的基础设施,对于快速原型开发很有吸引力。然而,这种简单性也带来了显著的权衡。你无法控制OpenAI如何提取文本,PDF的干扰项往往会留在上下文中,调试提取问题几乎变得不可能。而且,它比自托管的替代方案更昂贵,并且会使你局限于OpenAI的模型。这种方法最适用于简单的PDF、低批量处理,或者在速度比成本或控制更重要的初始原型阶段。
二、传统PDF库(PyPDF2、pdfplumber等)
工作原理: 使用Python库解析PDF结构并提取文本。
接下来,我们测试了这些库,评估开源路线是否能提供更好的控制。
示例:
import PyPDF2
with open("document.pdf", "rb") as file:
reader = PyPDF2.PdfReader(file)
text = ""
for page in reader.pages:
text += page.extract_text()
这些库是免费的、开源的,并且可以完全离线工作,对于简单的用例很有吸引力。对于基本需求,实现起来很直接——只需几行Python代码就能提取文本。然而,提取质量充其量只能算基本水平。这些库在处理复杂布局时存在显著局限性,无法自动清理PDF的干扰项,需要手动处理多列文本、表格和其他结构元素。为了得到可用的结果,需要进行大量的后期处理。它们适用于简单的、单栏的、格式最少的PDF,但对于更复杂的情况,需要更好的解决方案。
三、Unstructured.io(我们的最终选择)
工作原理: 这是一个高级的PDF处理库,具有布局分析、OCR和智能文本提取功能。
在评估了之前选项的局限性后,我们转向了Unstructured.io,它满足了我们的需求。
示例:
from unstructured.partition.pdf import partition_pdf
elements = partition_pdf("document.pdf")
clean_text = "\n\n".join([el.text for el in elements])
Unstructured.io提供了出色的提取质量,能够处理其他工具无法处理的复杂布局。它会自动清理PDF的干扰项,保留文档结构,对于扫描文档还包含OCR功能,并且仍然是开源的,同时提供商业支持。作为一个Python库,它可以通过pip安装并直接在代码中使用。对于需要大规模基于API处理的生产系统,你可以选择使用Docker/Kubernetes将其部署为自托管服务。主要需要考虑的是高级功能(如OCR)的系统依赖,以及学习该库的配置选项。对于复杂的PDF、高批量处理和生产系统来说,这些考虑是非常值得的。BetterRegulation正是出于这些原因选择了Unstructured.io。
另请阅读: Drupal中的人工智能自动化器:如何编排多步骤人工智能工作流程
四、Unstructured.io是如何工作的?
由于我们选择了Unstructured.io,并将其作为提取流程的基础,下面我将分享我们对其工作原理的了解。
一、工作原理
Unstructured.io结合了多种复杂的技术,从PDF中提取干净、结构化的文本。它首先进行布局分析,识别列、页眉、页脚和侧边栏,然后确定逻辑阅读顺序,将主要内容与辅助元素分开。在文本提取过程中,它会保留文档结构,同时保持段落和章节的边界,并正确处理会让简单工具产生混淆的多列布局。
该库将每个文本元素分类为标题、叙述文本、列表项、表格或其他类型,从而实现选择性提取,你可以选择只处理主要内容,同时过滤掉干扰信息。其清理流程会去除页眉和页脚,过滤页码,清理多余的空格,并规范换行符,以生成易读的文本。在处理扫描文档时,Unstructured.io会自动检测是否需要OCR,并无缝应用该功能,甚至可以处理同时包含数字文本和扫描图像的混合文档。
二、自托管设置(可选的API服务器)
对于基本使用,只需使用 pip install unstructured 安装Python库即可。以下的Docker/Kubernetes设置仅在你想将Unstructured.io作为API服务器运行,以便应用程序远程调用时才需要。
Docker Compose(本地开发):
version: '3'
services:
unstructured - api:
image: downloads.unstructured.io/unstructured - io/unstructured - api:latest
ports:
- "8000:8000"
使用 docker - compose up 启动。
Kubernetes(生产环境):
BetterRegulation将Unstructured.io作为Kubernetes pod运行:
apiVersion: apps/v1
kind: Deployment
metadata:
name: unstructured - api
spec:
replicas: 2
selector:
matchLabels:
app: unstructured - api
template:
metadata:
labels:
app: unstructured - api
spec:
containers:
- name: unstructured - api
image: downloads.unstructured.io/unstructured - io/unstructured - api:latest
ports:
- containerPort: 8000
resources:
requests:
memory: "2Gi"
cpu: "1000m"
limits:
memory: "4Gi"
cpu: "2000m"
基础设施要求:
- 每个实例需要2 - 4GB内存
- 每个实例需要1 - 2个CPU核心
- 可水平扩展以处理高流量
三、法律文档的配置
经过大量实验,我们为复杂的法律PDF文件确定了以下配置:
from unstructured.partition.pdf import partition_pdf
elements = partition_pdf(
filename="document.pdf",
strategy="hi_res", # 高分辨率分析
include_page_breaks=False, # 不包含分页标记
infer_table_structure=True, # 检测并保留表格
ocr_languages=["eng"], # 需要时进行OCR
extract_images_in_pdf=False, # 跳过图像(不需要)
model_name="yolox", # 布局检测模型
)
# 仅过滤出主要内容
main_content = [el for el in elements if el.category in [
"标题",
"叙述文本",
"列表项",
"表格"
]]
# 以适当的间距连接
clean_text = "\n\n".join([el.text for el in main_content])
关键参数解释:
strategy="hi_res" 设置使用最高质量的分析,虽然速度较慢,但对于复杂文档的准确性显著提高。设置 include_page_breaks=False 可以去除会使输出混乱的分页标记。使用 infer_table_structure=True 时,库会检测并保留表格格式,而不是输出无结构的表格数据。最后,extract_images_in_pdf=False 在只需要文本处理时跳过图像提取,提高性能。
四、过滤和清理
移除特定元素:
# 过滤掉页眉、页脚、页码
filtered = [el for el in elements if el.category not in [
"页眉",
"页脚",
"页码",
"分页"
]]
# 移除短元素(可能是干扰信息)
filtered = [el for el in filtered if len(el.text) > 10]
# 移除仅为页码或日期的元素
import re
filtered = [el for el in filtered if not re.match(r'^第 \d+ 页$', el.text)]
filtered = [el for el in filtered if not re.match(r'^\d{1,2}/\d{1,2}/\d{4}$', el.text)]
这种程度的控制对我们来说是一个重大突破——我们可以精确调整哪些内容进入我们的人工智能模型。
五、与人工智能流程集成
以下是我们将Unstructured.io集成到处理工作流程中的方式:
# 步骤1:提取干净的文本
def extract_pdf_text(pdf_file):
elements = partition_pdf(
filename=pdf_file,
strategy="hi_res",
include_page_breaks=False,
infer_table_structure=True,
)
# 过滤出主要内容
main_content = [el for el in elements if el.category in [
"标题",
"叙述文本",
"列表项"
]]
return "\n\n".join([el.text for el in main_content])
# 步骤2:发送到人工智能
def categorize_document(pdf_file):
clean_text = extract_pdf_text(pdf_file)
prompt = build_categorization_prompt(clean_text)
response = openai.ChatCompletion.create(
model="gpt - 4o - mini",
messages=[
{"role": "用户", "content": prompt}
]
)
return parse_ai_response(response)
这种提取和人工智能处理的清晰分离,使我们在遇到问题时更容易进行调试。
另请阅读: 数据提取的提示工程:如何在法律文档中实现95%的准确率
六、文本输出优化
我们在令牌效率方面取得了显著提升:
清理前(包含PDF干扰项):
- 75页的文档:约65,000个令牌
- 包含:页眉、页脚、页码、格式标记
清理后(使用Unstructured.io):
- 同一文档:约45,000个令牌
- 令牌减少30% = 成本节省30%
上下文窗口管理:
GPT - 4o - mini的128K令牌窗口最初看起来足够。然而,使用简单提取方法处理350页的法规文件时,超出了这个限制。在实施Unstructured.io的清理后,即使是我们最大的文档也能轻松适应上下文窗口。
五、性能和成本之间如何权衡?
除了提取质量,选择PDF处理工具还涉及到速度、成本和基础设施方面的实际权衡。以下是我们在生产部署中的发现。
一、PDF提取速度有多快?
以下是我们在生产环境中测量的数据:
| 文档大小 | 提取时间 | 总处理时间 |
|---|---|---|
| 极小(2 - 3页) | 约2秒 | 约10秒 |
| 小(10 - 20页) | 约5秒 | 约15 - 20秒 |
| 中等(50 - 75页) | 约15秒 | 约30 - 45秒 |
| 大(100 - 150页) | 约30秒 | 约1分钟 |
| 非常大(200 - 350页) | 约45 - 60秒 | 约1.5 - 2分钟 |
我们发现,提取时间约占总处理时间的30 - 40%,其余时间用于人工智能分析。
另请阅读: 聊天机器人问题的智能路由:我们如何将人工智能API成本降低95%
二、PDF提取成本是多少?
Unstructured.io的软件即服务(SaaS)模式:
- 每份文档0.10 - 0.20美元
- 无基础设施成本
- 按需付费
Unstructured.io的自托管模式:
- 基础设施:约每月50 - 100美元(Kubernetes pod)
- 处理:无每份文档费用
- 收支平衡:约每月250 - 500份文档
对于我们的处理量(每月200多份文档): 自托管模式很快实现了收支平衡,现在为我们节省了成本。
对于较小的处理量(每月少于100份文档): SaaS模式更具成本效益。
三、基础设施成本
以下是我们的自托管基础设施情况:
- 2个Kubernetes pod(冗余)
- 每个2GB内存
- 每个1个CPU核心
- 总成本:约每月50 - 70英镑
替代方案(AWS Lambda):
- 无服务器的Unstructured.io处理
- 按调用次数付费
- 无闲置成本
- 适用于可变或间歇性的处理量
六、我们在实际生产中取得了哪些成果?
为了验证我们的选择,我们将三种方法在实际生产工作负载的真实文档上进行了基准测试。结果差异显著。
一、提取质量对比如何?
我们在生产语料库中选取了具有代表性的文档,对三种方法进行了测试:
PyPDF2(简单提取):
- 多列布局经常读取错误
- 文本在句子中间断开
- 页眉、页脚和页码与内容混在一起
- 需要大量的手动后期处理
直接使用ChatGPT:
- 比PyPDF2好,但效果不稳定
- 提取的文本中仍存在PDF干扰项
- 无法控制包含或过滤的内容
Unstructured.io:
- 干净、逻辑有序的文本
- 正确处理复杂布局
- 自动过滤页眉和页脚
- 几乎不需要后期处理
二、提取效果如何影响人工智能分类?
提取质量直接影响了我们人工智能的分类性能:
提取效果不佳(PyPDF2)时:
- 由于上下文断裂或缺失,经常出现分类错误
- 多列文本混淆导致文档类型分配错误
- 大多数文档需要手动审核和纠正
提取效果良好(Unstructured.io)时:
- 分类准确率显著提高
- 大多数错误是由于文档本身的歧义造成的,而非提取问题
- 仅在边缘情况下需要手动审核
教训很明确:更好的提取直接带来更高的人工智能准确率。
另请阅读: 我们如何通过文档分级将RAG聊天机器人的准确率提高40%
七、其他可选的PDF数据提取工具
虽然我们选择了Unstructured.io,但根据你的具体需求和限制,还有其他几种工具值得考虑。
一、Adobe PDF Services API
Adobe的商业服务提供高质量的提取,并提供全面的企业支持,能够很好地处理复杂的PDF。然而,它每页的费用为0.05 - 0.30美元,价格昂贵,无法自托管,并且会使你局限于Adobe的生态系统。如果你有预算购买高级服务,并且需要企业级的支持合同,可以考虑这个选项。
二、AWS Textract
亚马逊的文档分析服务提供OCR和布局分析,在处理表单和表格方面表现出色,并且能够与AWS无缝集成。然而,在大规模使用时成本较高,它专门针对表单进行了优化,而不是通用文档,并且需要云基础设施。如果你已经在使用AWS,并且主要处理表单或发票,那么它是一个不错的选择。
三、Google Document AI
谷歌云的文档处理利用了先进的机器学习模型,能够很好地处理各种类型的文档,并与GCP原生集成。缺点是成本高,定价结构复杂,难以进行预算规划,并且只能在云端部署。如果你已经投资了GCP基础设施,并且需要谷歌的高级处理功能,可以选择这个工具。
四、Apache Tika
这个开源框架是免费的,能够处理多种文档格式,而不仅仅是PDF,在Java生态系统中很有用。然而,提取质量基本,需要Java基础设施,并且布局分析能力有限。如果你需要多格式文档支持,并且已经在Java环境中工作,可以考虑Tika。
另请阅读: LangChain vs LangGraph vs Raw OpenAI:如何选择你的RAG堆栈
八、何时该使用哪种PDF提取工具
没有一种工具适用于所有场景。以下是一个基于文档类型和处理需求的实用决策框架。
一、简单的PDF → PyPDF2或pdfplumber
对于具有标准布局、最少格式和纯文本内容的简单单栏PDF,如基本报告、备忘录或信件,PyPDF2或pdfplumber就足够了。这些免费、简单的库可以处理简单的文档,而无需复杂的基础设施。
二、复杂的PDF → Unstructured.io
当你处理多列布局、表格和图表、需要过滤的页眉和页脚、混合格式,或者对准确性要求很高的情况时,Unstructured.io是明确的选择。法律文档、技术规格说明和研究论文都属于这一类别,Unstructured.io在处理这些复杂情况时能提供最佳的提取质量。
三、扫描文档 → 带有OCR功能的Unstructured.io
需要OCR处理且质量参差不齐的基于图像的PDF,如扫描合同或历史文档,需要Unstructured.io内置的OCR功能。该库会自动检测扫描内容,并在无需人工干预的情况下应用OCR。
四、表单和发票 → AWS Textract
具有键值对和表格数据的结构化表单,如发票、申请表或标准化表单,是AWS Textract的强项。该服务专门针对表单处理进行了优化,对于这类文档能提供出色的结果。
五、原型开发 → 直接使用ChatGPT
对于处理低批量、相对简单的文档以快速取得成果的情况,直接将PDF发送到ChatGPT API是最快的方法。这是最简单的实现方式,非常适合在投资更复杂的提取基础设施之前进行原型开发。
九、想改进你的PDF处理流程吗?
这个案例研究基于我们为BetterRegulation进行的实际生产实施,我们使用Unstructured.io构建了一个完整的PDF提取流程,实现了30%的令牌减少,并显著提高了人工智能分类的准确率。该系统在生产环境中每月处理200多份文档,结果稳定。
你是否有兴趣为你的平台构建类似的解决方案?成都长风云Drupal开发团队擅长创建生产级的人工智能文档处理流程,能够在提取质量、成本效率和可扩展性之间取得平衡。我们可以处理从Unstructured.io设置和Kubernetes部署到自定义提取流程和人工智能集成的所有方面。访问我们的生成式人工智能开发服务页面,了解我们如何帮助你。


