先看现象。把财务报表截图交给 gpt-4o 转 markdown,合并单元格那一列在结果里变成上下两行,第二行少了科目名,直接入库后金额挂到了错误科目下,人工抽检 50 条错了 7 条。

排查方向其实有限,先把可能性排一排。视觉模型按网格线切格子,合并区域只识别一次内容。另一种情况是表格没有完整边框,模型把两列并成一列。

不容易想到的是,截图缩放后线宽变细,网格识别漏掉中间分隔线。

还有一种情况,输出格式只要求 markdown,没有约束空值怎么表示。

上来先把截图放大一倍并增强对比度再送入模型

python -c "from PIL import Image,ImageEnhance;im=Image.open('t.png').convert('L');im=im.resize((im.width*2,im.height*2));ImageEnhance.Contrast(im).enhance(1.6).save('t2.png')"

提示词里要求合并单元格向下补全,空值写 null

python run_extract.py --prompt prompts/table_v3.txt --image t2.png

接着用 JSON 输出并给每行带上行号便于回查

curl https://api.openai.com/v1/chat/completions -H "Authorization: Bearer $KEY" -d '{"model":"gpt-4o","response_format":{"type":"json_object"},"messages":[{"role":"user","content":"把表格转成 JSON,每行加 row_no,合并单元格的值向下补全"}]}'

剩下的就是抽 20 行与原表逐项比对,把差异记成回归样本

python diff_rows.py --llm out.json --gold gold.csv

恢复的判定其实很直接。抽检的 50 张表里科目与金额一一对应,空单元格统一是 null,回查时按 row_no 能直接定位到截图上的行。

补一句。合并单元格本质上是视觉信息不完整,靠提示词只能补救一部分,稳定的做法是让模型输出行列坐标再由程序还原合并关系。拖得越久,排查成本越高,因为现场状态会被后续操作覆盖。

作者 9823189