前段时间处理一批合同 PDF,里面有报价表、审批记录、盖章页。
原本想着这事简单,直接丢给多模态模型,让它帮我提取字段。
结果第一批文件出来,我就发现不对劲。
文字基本没问题,但表格一塌糊涂。
明明 PDF 里面是这样的:
商品名称 数量 单价 金额
服务器 10 8000 80000
硬盘 20 500 10000
模型返回:
{
"商品名称": "服务器 硬盘",
"数量": "10 20",
"单价": "8000 500",
"金额": "80000 10000"
}
看起来字段都有,但行关系已经乱了。
这种问题在 PDF 解析里面非常常见。
文字识别不是难点,难的是理解 PDF 的布局。
后来我试了一下 LlamaParse,发现它在这类结构化文档上确实有点东西。
尤其是表格解析这一块,有时候比直接让 GPT-4V 看图片效果还稳定。
PDF 这个东西,本质上不是 Word
很多人第一次做 PDF 解析,会有一个误区。
觉得 PDF 就是一张图片或者一个文本文件。
实际上都不是。
PDF 更像一个"坐标集合"。
里面存的是:
- 这个字符是什么
- 出现在页面哪个位置
- 字体大小是多少
- 绘制顺序是什么
比如一行表格:
订单号 金额
A1001 5000
PDF 里面可能保存成:
A1001 -> x=80,y=300
5000 -> x=300,y=300
订单号 -> x=80,y=250
金额 -> x=300,y=250
它根本不知道这两个东西属于一行。
所以传统 PDF 提取工具经常出现这种情况:文字拿到了,结构丢了。
传统工具的边界在哪
以前项目里处理 PDF,我一般会先用 PyMuPDF 做基础解析。
比如:
import fitz
def extract_pdf_text(path):
doc = fitz.open(path)
pages = []
for index, page in enumerate(doc):
content = page.get_text("text")
pages.append({
"page": index + 1,
"text": content
})
return pages
result = extract_pdf_text("contract.pdf")
for item in result:
print(item["page"])
print(item["text"][:200])
这个方案速度很快。
普通报告、说明书,没有复杂排版,完全够用。
但是碰到:
马上暴露问题。
因为这些文档真正有价值的信息,往往不是文字,而是结构。
LlamaParse 解决的不是 OCR,而是理解文档
我第一次用 LlamaParse 的时候,最大的感觉是:它不像是在"读字",更像是在恢复原来的文档结构。
比如一个报价单:
产品 数量 金额
CPU 10 50000
内存 20 20000
普通 OCR 可能得到:
产品 数量 金额 CPU 10 50000 内存 20 20000
LlamaParse 会更倾向输出类似:
[
{
"产品": "CPU",
"数量": 10,
"金额": 50000
},
{
"产品": "内存",
"数量": 20,
"金额": 20000
}
]
这个差别在实际业务里非常明显。
因为后面你还要:
结构乱了,后面全是补锅。
Python 接入其实很简单
比如一个 PDF 文件:
invoice.pdf
直接解析:
from llama_parse import LlamaParse
parser = LlamaParse(
result_type="markdown",
verbose=True
)
documents = parser.load_data(
"./invoice.pdf"
)
for doc in documents:
print(doc.text)
这里我比较推荐先转 Markdown,不要一上来要求 JSON。
原因很简单。
PDF 本身结构复杂,Markdown 对标题、列表、表格这种结构保留更自然。后面再交给模型转 JSON,成功率反而更高。
比如:
from openai import OpenAI
client = OpenAI()
prompt = """
请从下面合同内容中提取:
1. 合同编号
2. 甲方
3. 乙方
4. 金额
返回 JSON。
内容:
%s
"""
response = client.chat.completions.create(
model="gpt-4.1-mini",
messages=[
{
"role": "user",
"content": prompt % documents[0].text
}
]
)
print(response.choices[0].message.content)
这里的流程其实是:
PDF → LlamaParse 恢复结构 → LLM理解业务字段 → JSON 输出
不要反过来。
为什么 GPT-4V 有时候反而不如专门解析工具
这个问题很多人问。
GPT-4V 能看图片,也能理解表格,但它面对 PDF 时,有几个天然问题。
第一,它看到的是视觉。
视觉理解擅长回答"这里有什么",但是企业 PDF 更需要回答"这个单元格属于哪个字段"。
第二,长文档处理成本高。
一个几十页合同,你让模型一次看完,然后问"帮我找付款节点",效果不一定稳定。
第三,表格结构容易丢。
尤其这种:
第一季度
月份 销售额 成本
1月 100 50
2月 200 80
视觉模型知道它是一张表,但是转文本以后,很容易不知道层级关系。
专业解析器在这方面会提前处理布局。
不过 LlamaParse 也不是万能的
实际使用下来,我觉得它比较适合:
- 合同解析
- 财务文件
- 技术文档
- 研究报告
- PDF 知识库建设
但是下面这些场景还是需要人工处理。
扫描件质量特别差,比如:
████ 合同编号
████ 金额
这种 OCR 都认不出来,后面模型再强也没用。
还有一些奇葩 PDF:设计师导出的宣传页,文字全部转成路径,肉眼能看,程序完全不知道是什么。这种只能走图片识别路线。
我的 PDF 处理流程
我现在处理 PDF 类需求,基本不会直接让大模型硬啃。
流程一般是:
PDF
|
|-- 普通文本
| |
| PyMuPDF
|
|-- 复杂排版
|
LlamaParse
|
Markdown
|
LLM抽取业务字段
|
数据库存储
不要小看中间这个解析步骤。
很多 AI 应用效果不好,不是模型能力不行,而是输入进去的东西已经坏了。垃圾结构进去,出来一定是垃圾。
PDF 解析这一步,之前一直是 AI 应用里的脏活累活。现在随着 LlamaParse 这种工具出现,至少不用每次都自己写一堆坐标计算、表格恢复逻辑。
对于做企业知识库、文档机器人、自动审核这些方向的人来说,这一步值得认真研究一下。