ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

PDF转图片+多模态大模型:从扫描文档到结构化JSON的完整实践

PDF转图片+多模态大模型:从扫描文档到结构化JSON的完整实践

前阵子有个做运营的朋友半夜给我发消息,说她收到一批扫描版合同 PDF,需要把合同编号、金额、签署日期、甲方公司名分别录到表格里,几百份文件,手工敲到凌晨两点还没弄完。她问我有没有脚本能一键搞定。我说能,而且现在这个场景已经不太推荐老办法那种“先 OCR 出文字、再写规则抓字段”的路子了,更主流的做法是:先把 PDF 渲染成图片,再让多模态大模型直接“看”图,最后按约定结构输出 JSON。整个过程其实就是在做“图片识别 + 大模型结构化提取”。这篇帖子就沿着这个思路,把是什么、为什么、怎么办讲透,适合正在做单据识别、报告解析、数据抽取,或者单纯被一批 PDF 表格烦到想摔键盘的人。

1. 为什么要把 PDF 先转成图片,而不是直接扔给模型读

很多人第一次听到“把 PDF 转图片”会觉得多此一举:PDF 本身就是电子文档,有文字层,直接把内容取出来给大模型不就行了?真实业务里远没那么简单,关键卡在“布局”和“版式”上。

1.1 PDF 里的文字,其实是一盘散沙

PDF 标准在设计时并没有承诺“段落结构完整”,它保存的是文字位置、字体、颜色等排版指令。你在阅读器里看到的是一个完整的表格,但把 PDF 的文本层直接抽出来,得到的往往是一堆按行散落的字符串,单元格边界、合并关系、缩进层级都可能丢失。举个典型例子,合同里的“甲方:某某公司”在文本层可能是三四个独立的 text object 拼在一起,中间还夹着格式控制符,肉眼能看懂,程序很难稳定还原。

如果这份 PDF 还是扫描件,问题更大。扫描 PDF 的每一页本质上就是一张大图片,根本没有文字层,要么先走 OCR 把图转成文字,要么直接交给视觉模型看图理解。而“先转图片再识别”这条路,对文本型 PDF 和扫描型 PDF 都成立,因为图片把版面和文字的相对位置完整保留下来了,相当于在像素层面对整页做了一次快照。

1.2 直接读 PDF 文本层,到底差在哪里

我见过不少团队一开始图省事,直接把 PDF 文件内容塞给大模型,结果准确率忽高忽低。问题一般出在三处:

  • 版式信息丢失:文本抽取后,分栏、表格、跨行字段全被压成线性文本,模型只能靠猜来重组结构。
  • 页眉页脚和正文混在一起:页码、公司 logo 文字、页脚注释全掺进来,干扰字段抽取。
  • 字体编码异常:部分 PDF 用的非标准编码,抽出来是乱码,模型再强也没办法。

反过来,渲染成图片后,视觉大模型能看到一行文字在哪一列、一个金额数字紧挨着哪个标签、盖章是不是盖住了字段。这些“位置信息”恰恰是结构化提取最需要的上下文。所以我现在的默认方案是:除极少数纯文本、无复杂版式的 PDF 外,一律先转图再接模型。

有人担心转图会损失信息,其实不会。只要渲染分辨率足够,图片里的字不会比文本层更少,反而空间关系更明确。真正需要控制的变量是清晰度、页面方向和噪声,这几个点在第三部分会说怎么处理。

2. 从图片到结构化 JSON,中间到底发生了什么

“图片识别”听上去是一个动作,实际上是一条链路:图像渲染、视觉理解、语义抽取、结构校验。缺一个环节,结果就容易飘。

2.1 老牌 OCR 是“看见字”,大模型是“看懂版面”

很多人误解大模型结构化提取就是高级 OCR。严格来说,两者不是同一层的东西。OCR 引擎擅长把图片里的字符变成文本行,输出的是坐标框和文字,它对“这是一个字段名”“这是它对应的值”这类语义关系并不敏感。传统做法是在 OCR 结果之上堆大量坐标规则、关键字匹配逻辑,这套东西在版式固定的票据上很香,一旦版面变化,规则就要跟着改。

多模态大模型不一样,它可以同时感知图像里的文字、布局、语义,直接回答“这张单据的含税总金额是多少”。它不把文字和图片分成两件事,而是把整页当成一张信息图来理解。等于把原来“OCR 文字 + 规则判断 + 手工兜底”三步压缩成一步,更重要的是它适应非固定版式的能力强得多。

2.2 结构化输出是怎么被约束出来的

让大模型“看”图不难,难的是让它把答案吐成固定格式。实际做法是在请求里同时附上图片和一段明确的字段定义,也就是 schema,比如字段名叫什么、含义是什么、是字符串还是数字、找不到时怎么办。模型读完图以后,会对照这个 schema 生成一段 JSON。

这个 JSON 不是模型凭空想出来的,它本质上是模型对图片内容的“语义压缩”:把像素信息降维成文本字段。这里有三个要点:

  • 字段要少而明确:字段越少,模型注意力越集中,不容易编造。
  • 输出格式要严格约束:在提示词里写明“只输出 JSON,不要解释,不要 Markdown 代码块”。
  • 风险字段给容错出口:看不清的值输出 null,不要逼模型猜。

链路跑通之后,你就可以拿一段标准 JSON 去做入库、做对账、做报表,这也是“结构化提取”最值钱的地方:它把非结构化文档变成了可计算的数据。

3. 实操:从导入 PDF 到拿到 JSON 的完整步骤

这一部分我按真实项目里跑通的流程来写,分四步:渲染图片、图像预处理、调用视觉大模型、解析与校验。每一步都有关键参数,做错了后面准确率直接打折。

3.1 第一步:把 PDF 渲染成高清图片,分辨率怎么定

用 PDF 渲染库把每一页导出成 PNG 或 JPEG。核心参数是 DPI,也就是每英寸点数。我的经验是:

  • 普通文字版 PDF:150 DPI 够用,图片体积小,识别速度快。
  • 有表格、小字号、扫描件的 PDF:建议 200-300 DPI。
  • 图片宽度最好不低于 1500 像素,太窄了模型看不清细节。

渲染时候尤其注意两点:一是按原始页面大小渲染,不要强制缩放,防止文字变形;二是扫描型 PDF 本身分辨率就低,盲目拉高 DPI 并不能增加信息量,只是把模糊像素放大而已。判断标准很简单:你导出图片后,肉眼能看清的最小字符是几个像素宽,如果小到一个字糊成一团,模型也好不到哪里去。

3.2 第二步:图片预处理,能不做就不做

新手上路容易把时间耗在“图像增强”上:去噪、锐化、二值化、倾斜校正……我在实际项目里吃过亏,预处理做过头反而会引入错误。比如把一页有浅色底纹的表单强行二值化,印章和字段名的边界就糊了。

我的建议是分层次处理:

  • 第一轮:直接用原始渲染图像调用大模型,看失败率。
  • 第二轮:只对“失败案例”做定向增强,比如方向自动纠正、去除明显黑边、裁剪无关区域。
  • 除非图像质量实在太差,否则不要全局套用增强滤镜。

有一种情况需要预处理,就是页面方向不稳定。有些 PDF 扫描件个别页面是横的,模型虽然能识别旋转后的文字,但结构判断容易乱。建议先用一个简单的分类逻辑判断页面方向,必要时旋转成统一方向再送入识别。

3.3 第三步:定义 Schema 与提示词模板,决定结果上限

这是全流程里对准确率影响最大的一步。先定义清楚你最终要哪些字段,比如合同场景要“合同编号、签署日期、甲方、乙方、含税总金额”。接着把这些字段翻译成机器可理解的描述,写进提示词。下面是一个可参考的 schema 示例:

{ "type": "object", "properties": { "contract_no": { "type": ["string", "null"], "description": "合同编号,如 HT-2025-001" }, "contract_date": { "type": ["string", "null"], "description": "签署日期,输出格式 YYYY-MM-DD" }, "party_a": { "type": ["string", "null"], "description": "甲方公司全称" }, "total_amount": { "type": ["string", "null"], "description": "含税总金额,保留货币单位" } }, "required": ["contract_no", "total_amount"] }

提示词我用的大致模板是:

  • 你是一个文档信息抽取助手。
  • 请阅读图片中的文字和版面。
  • 严格按照给定字段定义输出 JSON。
  • 不要输出任何解释、示例或 Markdown 代码块。
  • 如果字段内容无法辨认,填写 null,不要猜测。
  • 如果金额字段出现“大写”和“小写”不一致,以小写为准并备注。

为什么这样写?因为多模态模型对“角色设定 + 输出约束 + 容错策略”非常敏感,把边界条件写清楚,能显著减少答非所问和幻觉。这里的核心心态是:你是在“约束模型”,不是在“期待模型”。

3.4 第四步:解析、清洗与人工复核闭环

模型返回的不一定永远是干净 JSON,尤其是流式接口或长文本场景下,偶尔会多出几个字、少一个括号。所以解析层要写容错逻辑:

  • 提取字符串中第一个{到最后一个}之间的内容。
  • 尝试用 JSON 解析器解析,失败时记录原始返回,进入重试队列。
  • 对关键字段做规则校验:金额是不是数字,日期格式对不对。
  • 把置信度低的样本,比如某字段为 null 或多次重试仍失败的页面,推入人工审核队列。

这部分看着不起眼,却是生产环境能不能长期跑的关键。没有校验环节,哪怕模型准确率是 98%,处理一万页也会产生两百个错误单据,返工成本远高于校验逻辑的开发成本。

4. 提示词与解析策略:把准确率抠上去的细节

很多团队用大模型做提取,第一版效果还行,一上复杂数据就崩。问题通常不在模型,而在“怎么提问”和“怎么收尾”。

4.1 坚持“最少字段”原则,不要一次问太多

有些需求方恨不得一次提取五十个字段,我把这种做法叫“贪心请求”。字段一多,模型会在相近语义之间来回摇摆,比如“甲方地址”和“乙方地址”就可能互相串。更稳的拆法是分三轮:

  • 第一轮提取核心字段:编号、日期、金额、双方名称。
  • 第二轮根据业务需要提取扩展字段:地址、联系人、开户行。
  • 第三轮做交叉校验:让模型根据已有字段判断是否存在矛盾。

分轮不是增加成本,反而是降低整体成本。因为第一轮质量高了,后面几轮不需要反复重试,总体调用次数会更少。

4.2 表格、多栏、盖章遮挡:三类常见硬骨头

表格是最容易翻车的版式。我现在的写法是:在提示词里声明“如果图片中有表格,请将每一行视为一个独立对象,输出为数组,每个对象包含该行所有单元格的文本,并保留表头”。这比让模型自由发挥稳定得多。复杂表格还会额外要求输出“单元格横跨几列”,不过这对模型要求较高,一般场景不必强求。

多栏排版需要控制阅读顺序。论文、报纸、公众号长图都属于这类。处理方式有两种:一是提示模型“按照从左上到右下、先左栏后右栏的顺序阅读”;二是干脆按栏裁剪成多张图片分别识别,再用程序合并。后一种对模型压力小,但需准确切栏,版式不固定时会增加代码复杂度。

盖章遮挡频繁出现在合同和发票场景。这里有个重要原则:不要试图让模型“脑补”被遮挡的文字。比如公章盖住了金额数字,应该允许字段值为 null,或者用上下文推导并标记“推测值”。把“不确定”如实暴露出来,比给一个看似正确但不可信的答案更有价值。落地时在 JSON 里增加一个confidence字段记录模型自评置信度,方便后续人工筛选。

5. 常见问题与排查实录

做这类项目,八成的调试时间都花在“结果不对”的排查上。我把踩过的坑整理成一张速查表,你可以按图索骥。

5.1 图片渲染出来很模糊

优先检查渲染分辨率,而不是换模型。举个实际指标:对于信纸大小的页面,如果渲染后的图片宽度只有 800 像素,说明 DPI 太低。工业界经验值是 200-300 DPI,确保最小可识别文字宽度不低于 15 像素。还有一种情况是原 PDF 本身就是低分辨率扫描件,这时候调整渲染参数没用,只能降低预期,或者基于多帧扫描件做超分,但这属于额外的投入,不是第一优先方案。

5.2 模型返回的不是合法 JSON

排查顺序是:提示词是否明确提到“只输出 JSON”,解析逻辑是否容错,模型采样参数 temperature 是否调到了接近 0。生产环境不要依赖“模型永不犯错”,解析层至少做两层兜底:正则提取 JSON 片段 + 调用解析失败时自动重新生成一次。

5.3 字段串位,比如把乙方名称当成甲方

这类问题多出现在两个字段语义相近时。解决办法是加强 schema 里的描述,比如“甲方是合同中委托方,通常出现在‘甲方’字样右侧或下方”。另一个思路是减少字段数量,把争议字段拆分到第二轮专门识别。还有一个容易被忽略的细节:如果图片中包含多个相似对象,比如一份合同有多个附件,模型会产生混淆,这时候优先裁剪局部区域,而不是整个页面一起识别。

5.4 推理速度慢、调用成本高

处理长文档时尤其明显。优化策略很简单:先用传统 OCR 或轻量筛选逻辑判断页面上是否存在目标字段,只把“有内容的页面”交给大模型。比如一份 300 页的年度报告,真正的合同签名页可能只有 20 页,没必要全量识别。再就是统一图片压缩,在保持清晰度的前提下把单张图控制在 1MB 以内,减少网络传输和视觉 token 消耗。

页面类型推荐做法原因
纯文本型 PDF、版式简单可直接抽文本层,也可以转图后识别成本低,结构风险小
表格密集、小字号多转图 + 多模态模型 + 结构化 schema保留表格边界,减少文本层断行干扰
扫描件 + 盖章 + 手写转图 + 多模态,字段允许 null避免模型编造被遮挡的内容
超长文档,非全页有效先做轻量筛选,再局部裁剪识别节省时间和调用成本

6. 一点实际操作的体会

我在几个实际项目里反复验证过这套流程,最大的体会是:不要一上来就追求“全自动无人值守”。第一版先做“半自动”,把模型识别结果全部推到人工复核区,跑两周积累足够的失败样本,再针对高频问题优化提示词和预处理策略,慢慢再把复核比例降下来。

另一个心得是,先把“什么不做”想清楚。遇到模糊不清的字段,宁可直接标 null,也不要用正则硬凑或用模型硬猜。一个错误的字段值进入数据库之后,排查成本可能是当时识别成本的十倍。数据质量这件事,越早暴露风险越省钱。

最后分享一个实用习惯:每次跑完一批数据,把识别结果的 JSON 和原图放在同一个文件目录里。后面不管是排查问题还是跟业务方对齐需求,都能拿得出证据。这样调试的时候你手里有料,说话也有底气,整个流程越跑越顺。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进