返回 AI 测试工程师强化支线
Phase 02 / AI Application Quality 02

多模态、OCR 与文档智能测试教程

让发票图片、扫描 PDF 和跨页流水从 OCR 一直走到数据库:字段有证据、金额能对平、低质不猜测、失败可转人工。

11 个章节金融单据 ETL 案例识别 + 规则 + 入库对账
01

从一张金融单据走完整条 ETL 链

贯穿案例

案例:费用报销文档智能流水线

财务每天接收发票图片、扫描 PDF、行程单和跨页银行流水。系统要完成上传校验、图像预处理、OCR、版面与表格恢复、字段抽取、金额规则校验、人工复核、入库以及与报销单对账。贯穿字段包括发票号码、开票日期、购买方、未税金额、税额、价税合计和币种。

五层测试对象

验证什么保留证据典型缺陷
接入与预处理文件类型、页数、方向、倾斜、清晰度和去噪原文件哈希、逐页影像、质量分PDF 漏页、旋转未矫正
OCR印刷体、手写体、中英文和特殊字符文字块、坐标、逐字置信度0/O、1/l、小数点混淆
版面与表格阅读顺序、表头、单元格、跨页续表版面块、行列关系、页码表头错位、跨页行断裂
字段与规则字段定位、归一化、合计和跨字段关系原文片段、字段值、规则结果税额抽错、日期猜测
入库与对账类型转换、去重、关联和总账一致性批次 ID、行数、入库值、对账差异重复入库、金额单位错误
最终字段错误不等于 OCR 引擎错误。文字可能识别正确,却在版面恢复、字段映射或入库环节被写错;测试必须让每一层都可回放、可定位。
02

图片、PDF、版面与跨页表格要组合覆盖

测试矩阵

金融单据测试矩阵

维度取值关键判断
载体JPG/PNG、单页 PDF、多页扫描 PDF、文本 PDF抽页、渲染和 OCR 路由是否正确
图像质量清晰、低 DPI、模糊、过曝、阴影、折痕、旋转何时增强,何时拒绝并转人工
版面单栏、多栏、票据拼图、印章覆盖、页眉页脚阅读顺序与字段归属不串位
表格合并单元格、多行表头、空格、跨页续表列语义延续、行不重不漏
内容印刷、手写、中英混排、特殊符号字符切分与币种、负号、小数点正确
业务字段金额、日期、税号、账号、合同号格式、合计和跨文档关联成立

跨页表格必须单独建场景

  • 第 1 页只有表头,第 2 页继续数据行:续页仍继承正确列名。
  • 分页处一行被拆成两半:合并后只产生一条交易记录。
  • 每页重复表头与小计:重复表头不入库,小计不冒充明细。
  • 末页总计与各页小计并存:总计只参与校验,不重复计入金额。

低质边界要形成梯度

分辨率、模糊、压缩与遮挡不应只准备“好/坏”两张图,而要形成可重复的等级,观察 P0 字段从哪一级开始失真,以及系统是否在边界外停止猜测。

03

先建立人工精标的真理标准库

没有尺子就没有准确率

金标最小内容

内容要求
原始样本脱敏后保留版面、字体与干扰特征
字段答案人工逐字段核对,保留原文位置
可读性标签可读、部分可读、不可读
字段等级按业务影响划分 P0/P1/P2
等价规则日期、金额和空值如何归一化
审核记录标注人、复核人、版本与争议结论
字段清单和标注口径应先确认再批量精标。中途频繁改字段,会让已完成样本失去可比性并带来大规模返工。
04

按真实分布与困难类型分层抽样

避免漂亮样本偏差

样本覆盖维度

维度例子
业务类型合同、证照、流水、法院文书、还款记录
文件格式Word、PDF、图片、扫描件
模板版式机构模板、旧版、新版、长尾格式
文件质量清晰、干扰、特殊版式
字段类型金额、日期、长文本、表格和印章
客户或来源分布规范归档与混合归档场景

拿不到预分类文件时

不要只挑容易识别的文件。可以选择若干具有代表性的来源单位或批次,对真实分布全量抽取,再从中抽样精标,并明确抽样范围与置信边界。

05

字段准确率、召回率与整单通过率要分开

平均数会掩盖 P0 错误

核心指标

指标定义使用方式
字段准确率正确抽取字段数 / 实际输出字段数惩罚错值和无证据多抽
字段召回率正确抽取字段数 / 金标应有字段数发现字段漏抽;按字段类型分别统计
字段 F12 × 准确率 × 召回率 / (准确率 + 召回率)需要同时兼顾错抽与漏抽时使用
整单通过率全部必需字段和业务规则均通过的文件比例反映能否自动直通入库
表格还原率结构与单元格对应全部正确的表格比例单独评估跨页和复杂表头
入库一致性审核后字段与最终落库一致的比例确定性 ETL 目标应为 100%
人工复核率进入人工队列的文件比例同时看误放行和过度拦截
字段指标计算例
// 金标应有 100 个金额字段;系统输出 98 个,其中 95 个值与证据都正确。
precision = 95 / 98;          // 96.94%
recall = 95 / 100;            // 95.00%
f1 = 2 * precision * recall / (precision + recall); // 95.96%

// 仍要单列 P0 错误:任何一张发票把 1,000.00 识别成 10,000.00 都可硬失败。

门禁示例

层级候选门槛硬失败
P0 金额/账号准确率与召回率均达到项目高风险基线金额数量级错、跨租户数据、无证据补值
P1 日期/税号按字段与困难子类不低于基线非法日期被静默归一化
整单直通通过率达到财务容量目标未通过规则却自动入库
ETL 入库审核结果到落库一致性 100%漏行、重复行、单位或币种变化
阈值不是行业通用常数,应由样本规模、人工兜底和业务损失共同确定;报告必须同时给样本量和置信边界。
06

金额、日期、合计与跨页结构都要确定性校验

从便宜检查开始

自动校验梯度

校验金融单据示例失败动作
记录数与文件哈希上传 20 份、逐页处理 57 页、最终仍为 20 份漏页或重复立即阻断
格式与范围日期可解析、税号校验位、金额最多两位小数标记字段失败
金额恒等式未税金额 + 税额 = 价税合计,允许约定舍入差P0 冲突转人工
明细合计Σ(数量 × 单价) 与票面合计一致保留差额与行号
日期逻辑开票日不晚于报销日,且在会计期间异常进入业务复核
跨页连续性页码、列头、交易日期和余额衔接缺页或断表阻断入库
去重发票代码+号码+金额+日期或业务唯一键重复件进入合并队列
金额与日期校验示意
const moneyOk = Math.abs(netAmount + taxAmount - grossAmount) <= 0.01;
const detailOk = Math.abs(
  lines.reduce((sum, line) => sum + line.quantity * line.unitPrice, 0) - grossAmount
) <= 0.01;
const dateOk = issuedAt <= reimbursedAt && accountingPeriod.includes(issuedAt);

route = moneyOk && detailOk && dateOk ? "AUTO_PASS" : "HUMAN_REVIEW";

双模型交叉校验

对 P0 字段或高价值文件,可以让不同模型独立抽取并比较差异。它不能证明谁正确,但能把单模型“自信地错”变成可见的复核候选;最终仍以原始影像和人工金标裁决。

07

同时防合理补全与数据污染

看不清就要停

幻觉与污染探测集

输入合格行为不合格行为
金额被印章完全遮挡低置信或转人工根据上下文猜出金额
日期缺一位返回不可确定并保留原始片段补成完整日期
表格空单元格保持空值填入邻近行的合理值
正文与表格金额冲突输出冲突证据并转复核静默选择其中一个
PDF 隐藏文本层与可见影像不一致标记来源冲突,以受信策略裁决直接采信隐藏层
样例附件夹带与字段无关的指令文本作为单据内容处理或隔离改变 Schema、路由或泄露其他文件
历史缓存混入其他租户字段拒绝结果并告警把污染字段写入当前报销单
字段只有在影像中存在可读证据时才算正确。不可读输入输出了一个“碰巧正确”的值,也应记为幻觉风险;外部文档和 OCR 文本是数据,不是可信系统指令。
08

主动注入漏页、断表、慢模型与脏数据

失败安全

失败注入清单

注入点预期行为禁止行为
上传重复或截断 PDF文件哈希/页数校验失败,批次隔离把部分页当完整单据入库
渲染服务漏第 2 页页码与清单对不上,停止该文件跨页表格静默少一页
OCR 超时或返回半截 JSON有界重试,仍失败则转人工解析默认值并继续直通
版面模型把重复表头当数据规则识别并标记候选重复行写入伪交易记录
金额字段低置信且合计恰好相等仍依据证据与阈值转复核用合计关系反推并假装识别成功
人工队列不可用停止自动放行,保留待处理状态降低 P0 门槛维持吞吐
入库提交后响应超时按批次与业务键回读确认盲目重试造成重复行
故障场景断言
given({ pdfRenderer: "drop_page_2", ocr: "ok", database: "ok" });
const run = await processBatch("BATCH-0810");

expect(run.files[0].status).toBe("BLOCKED");
expect(run.files[0].errorCode).toBe("PAGE_COUNT_MISMATCH");
expect(run.databaseRowsWritten).toBe(0);
expect(run.audit.originalFileHash).toBeDefined();
09

用中间证据定位,并按风险进入人工复核

降级有人机边界

定位路径

证据判断处理
OCR 文字正确,表格结构错误版面/表格恢复问题保留文字块,重跑结构模型
结构化结果正确,最终入库错误字段映射、单位或数据链路问题阻断批次并修复确定性 ETL
批量错误,单文件重跑正确并发、截断或状态串扰降并发并回放失败批次
相同输入多次结果漂移模型参数、版本或非确定性问题锁定版本,提升复核率
低置信样本未进入人工队列复核路由或阈值配置问题停止直通并补回漏审样本

自动、降级与人工边界

情况允许不允许
非关键描述字段低置信保留原文,允许稍后补录影响 P0 合计或账号判断
P0 字段缺失/冲突展示原图位置并转财务复核模型猜测或用默认 0
模型/规则不可用批次排队、明确失败或人工录入跳过规则直接入库
人工队列饱和保持待处理并告警容量降低金额门槛自动放行

人工复核记录至少保留

  • 原始文件、页码、坐标和脱敏版本。
  • 模型、Prompt、解析器、Schema 与规则版本。
  • 各层中间输出、置信度、规则冲突和候选值。
  • 人工裁决、修改前后值、原因、审核人与时间。
10

从抽取结果一直对账到最终数据库

端到端 ETL

端到端数量与金额对账

关口应相等的对象差异说明
接入上传文件数 = 成功 + 拒绝 + 待处理任何文件都不能无状态消失
分页声明页数 = 渲染页数 = OCR 页数加密/损坏页需显式记录
抽取字段记录 = 通过 + 复核 + 拒绝不得丢弃低置信字段
入库已审核业务键数 = 新增 + 已存在幂等命中新增与重复可解释
金额审核通过单据总额 = 数据库本批净新增总额币种、正负号和小数单位一致
下游数据库批次总额 = 报销系统/总账接收总额异步失败可重放且不重复
批次对账报告 JSON
{
  "batch_id": "BATCH-0810", "source_files": 20, "source_pages": 57,
  "accepted": 14, "human_review": 5, "rejected": 1,
  "reviewed_business_keys": 19, "inserted": 18, "idempotent_hits": 1,
  "approved_amount": "126430.55", "inserted_amount": "126430.55",
  "currency": "CNY", "difference": "0.00",
  "model_version": "ocr-v7", "schema_version": "invoice-v4",
  "reconciliation_status": "PASS"
}

回流闭环

  1. 线上对账差异先冻结批次,保留原文件与全链路证据。
  2. 定位为 OCR、版面、字段、规则或入库类别。
  3. 人工裁决形成金标,加入困难样本或失败注入集。
  4. 修复后回放原批次,使用业务键幂等写入。
  5. 比较版本差量并通过门禁后再恢复自动直通。
11

搭建一套金融单据文档智能评估

练习与交付清单

练习

  1. 选择一类脱敏发票或流水,确定字段 Schema、P0 字段和舍入口径。
  2. 覆盖图片、文本/扫描 PDF、复杂版面、跨页表格和低质梯度样本。
  3. 完成双人精标、可读性标签与字段证据坐标。
  4. 计算字段准确率、召回率、F1、整单通过率和人工复核率。
  5. 实现页数、格式、金额/日期、跨页连续性、去重和入库对账检查。
  6. 注入漏页、半截 JSON、脏数据、队列不可用和提交状态未知。
  7. 输出字段、困难子类、版本差量、人工裁决与批次对账报告。

样本与金标

真实分布分层
跨页与低质覆盖
字段有证据坐标
污染样本隔离

质量与门禁

准确率召回率拆分
P0 硬失败
合计日期有规则
不可读不猜测

ETL 与治理

每层证据可回放
复核有边界
入库幂等
批次金额对平