客户给了一批真实单据,让 AI 把出口报关单录出来。"抽得准不准"这件事, demo 里看两票感觉都挺好,但要上生产,得有一个自己都不敢质疑的数。 这篇记录我怎么把这个数做出来,以及做出来之后发现的第一个问题不在模型,而在尺子。

先给测量工具做评测,再谈模型准不准。尺子歪的时候,所有差异都是假差异。

01 · 拿什么当标准答案

每一票的输入是客户发来的一堆文件:发票、装箱单、托书、有时还有压缩包。 标准答案是报关行已经申报出去的预录入报关单——那是真实过关的版本,不是谁拍脑袋写的。 对拍按逐格来:18 个表头字段,加上每一项商品的 9 个字段,一格一格比。

除了"逐格一致率",我另加了两列。商品行 我/答:我方抽出几行、答案里几项,不相等说明拆合并方式不同。 要素填错:申报要素里我方填了但填错的格数——填空不算,空着只是让报关员补一格, 填错才会写进真实申报单。这一列才是危险指标。

02 · 第一轮:17 票 66%,还有三票要作废

分档票数逐格一致率说明
581% – 87%单商品或结构规整的票
766% – 79%多商品行,拆合并方式与答案不同
254% – 57%一票把 2 项商品拆成了 12 行
作废318% – 22%真实单据在 rar 里没解开,抽取只看到舱单

合计 436 / 665 = 66%。最后三票我直接标了"成绩不算数":输入不完整时的分数, 既不能说明模型差,也不能拿来平均。评测里最容易自欺的地方,就是把这种票悄悄算进分母里让平均数好看一点, 或者悄悄剔掉让平均数更好看一点。两种都不行,写清楚原因放在表里。

03 · 先修尺子:答案解析器 20 票全错

第二轮拿到更多真实申报单,我先跑了一遍答案解析器,结果 20 / 20 全部解析错: 发货人全空,一半的票成交数量抠不出来。也就是说第一轮对拍里相当一部分"差异"根本不是抽取错, 是尺子错。

报关单 PDF 抽出来的正文是等宽两段式,两块规律不同,混用一种解法必错: 表头是"标签行 / 取值行"成对、左对齐,按标签起始列切取值行;商品行一项占 2 到 4 行、行数不固定, 只能按词元形态分类,列位置只用来消歧。三个具体的坑:

  • 列锚点不能从表头行算。PDF 抽出的文字里,表头与数据行整体错开约一列,锚点只能从数据行自己取。
  • 「数量及单位」有 2 项或 3 项,取决于有没有法定第二单位;顺序恒为法定第一、可选的法定第二、成交,所以取首尾。
  • 规格型号不能按空白切词再拼,否则 松木 PINUS RADIATA 会被拼成一坨,把本来对的值判成错。

评分工具同期改了两处:申报要素改成逐格评分,整串比太粗,改对一格仍显示"不同"; 归一化不再无条件按数值比较,否则海关代码 0110 会被压成 110, 一边有前导零一边没有也假装一致。

04 · 六条口径,每条带样本量

尺子修好后,真正的差异露出来了。我给每条修正规则都数了样本, 只落实零例外的那一侧,有反例的一律不自动改:

  • 单价 = 总价 ÷ 数量取 4 位(44/44)。发票印的是谈价 12.68,报关单要求乘起来对平,报的是 12.6835。照抄发票两边永远对不上。
  • 成交计量单位以单据为准,不必是法定单位(17/44 就不是)。这一条推翻了三天前按单票判例写下的"不是法定单位就换算"——那条规则会把 17 项全部改报成千克,是会写进真实申报单的错。
  • 成交单位等于法定第一单位时,法定第一数量等于成交数量(27/27)。法定第二那条只有 18/20 成立,不实现。
  • 品牌写「无品牌」则品牌类型必为 0(19/19)。反向不成立:有品牌名时 22 次是 3、3 次是 0,交给人判。
  • 只写一个「无」字的要素补成完整说法,平台校验明说不可仅申报单个文字;其他写法一律原样透传。
  • 13 位商品编号取前 10 位。不归一会让要素模板、法定单位、平台模板三处同时静默落空,表现成"要素怎么全是空的",根因藏在编号上。

另加一条确定性校验:表头净重、毛重与各商品行之和对不上就告警,不自动改。 它抓的是"漏抄一位"——实测一票表头 775.22、行内 7756.22,两边格式都合法, 下游零报错,只有到平台申报那一步才会被拒。

05 · 结果:54% 到 67%,零额外模型调用

同一批票的一致率从 54% 提到 67%。这一轮全部是改解析与口径代码, 用历史保存的 result.json 离线复算,没有多花一次模型调用。 这也是我坚持把每一票的原始抽取结果落盘的原因:评测应该便宜到可以随手跑。

06 · 顺带的实验:AI 复核 AI 值不值

很多人的直觉是"再让模型看一遍总不会更差"。我用同一套业务规则让模型对最终 JSON 做二次复核, 每票跑两遍看提议稳不稳,再对答案打分:

实验基线错格复核后错格修对改坏
整体复核(312 格)121110
地址折行复核(40 格)141714

整体复核净收益是修对 1 格,几乎白跑;折行专项复核则修 1 破 4,越复核越差。 另一组重复 3 次的稳定性测试里,输出完全一致的比例只有 53%。 结论不是"复核没用",而是复核不是免费午餐,上线前必须先量它的净收益

07 · 收尾

这轮做完,我对"评测"这两个字的理解变了:它不是最后跑一遍看分数, 而是先怀疑尺子、再怀疑输入、然后才轮到怀疑模型;每条规则带样本量, 每个作废的样本写清原因。数字不好看没关系, 不自欺的 67% 比自欺的 90% 值钱得多