乐于分享
好东西不私藏

#AI学习#学会不要被AI牵着鼻子走?基于发票识别统计软件的更新测试

#AI学习#学会不要被AI牵着鼻子走?基于发票识别统计软件的更新测试

学会不要被AI

牵着鼻子走

#基于发票识别统计软件的更新测试#

PART 1

写在最前面

上周有对这个软件感兴趣的小伙伴,问我要链接分享下。原本只是自己做着玩玩的,对于速度准确度啥的都没有太高要求,后面想想如果分享出来,还是尽量做到识别的效果更准确点好,所以趁着假期这两天又改了几版。链接放在文章最后了(有百度网盘和夸克网盘),感兴趣的伙伴可以去下载来试试(压缩包里有操作手册),不过还是那句话,受制于OCR识别模型的大小,软件并没有到尽善尽美的程度,感受一下就行。

PART 2

前情提要与本次优化

上周在deepseek的帮助下,做出来一个能够识别并统计发票的软件。在实操过程中,陆续发现了一些问题,主要包括:识别速度不够快、部分类别发票信息识别有误(尤其是通行费发票)。

有一天我突发奇想,问了deepseek一个问题:

“之前我试过把一个几十页的PDF发票集合发给你(DeepSeek)来识别和统计,速度和准确率都非常高,我想知道你是怎么做到的呢?”

Deepseek是这样回答的:

我(DeepSeek)是“天生”的文档专家,而不是单纯做OCR。传统的OCR流程是:“看图识字”。它把发票当成一张照片,一个像素一个像素地去猜是什么字,对模糊、倾斜、打印体变形非常敏感,容易出错。而我在处理你发来的PDF发票时,做的其实是:“结构化解构 + 知识推理”。

PDF解析器:我先把PDF里的文字层(如果发票是电子生成的,本身就带有矢量文本)直接提取出来,这保证了“零误差”。即使面对扫描件:我的多模态大模型经过了海量发票、表格、单据的训练。我脑子里有“发票应该长什么样”的认知。就算“税额”两个字被水印盖住了一半,我可以通过周围的“¥”、“合计”、“税率13%”等上下文,像人一样“猜”出那就是税额,并自动补全。对比图可以看得更清楚:

对比维度

本地EasyOCR方案

VS

云端大模型方案(如DeepSeek)

数据安全

⭐⭐⭐⭐⭐ 极高(数据不出本地)

⭐⭐ 较低(需上传公网)

处理速度

⭐⭐ 较慢(受CPU限制)

⭐⭐⭐⭐⭐ 极快(云端高并发)

复杂版面理解

⭐ 较弱(依赖坐标裁剪)

⭐⭐⭐⭐⭐ 极强(理解表格逻辑)

纠错与容错

⭐ 只认像素,错了就错了

⭐⭐⭐⭐⭐ 结合上下文自动修正

成本

一次性开发,之后免费

按Token/页数计费

01

PDF解析器

从deepseek的回答中,我抓到一个关键词是PDF解析器,它把PDF里的文字层(如果发票是电子生成的,本身就带有矢量文本)直接提取出来,这样就避免了全部使用OCR去识别。

于是我考虑把发票文件区分为PDF和图片格式,如果是PDF就考虑使用提取的方式,如果是图片则使用OCR。经过多个版本的测试,发现电子普票和电子专票可以直接提取,但是如果遇到通行费电子发票则不行。不管是地方财政部监制的收费公路车辆通行费票据,还是国税总局监制的通行费电子发票,都不能使用PDF提取,因为它们的发票版面排布没有规律可循。所以对这类通行费发票,还是采取OCR识别的方式。

02

 OCR识别精度替代

此外因为考虑到本地化软件大小的问题,OCR模块没有办法选择精度很高的paddleocr,只能退而求其次选择相对轻量级的easyocr,这就导致了一些发票内容识别的精确度不高。在多个版本的测试中,出现过发票金额为0、很奇怪的不知道哪儿来的数字等等,后面我又陆续让deepseek增加了一些判断条线,比如引入大写金额转换小写金额,实在抓不出来就写0,然后对于0金额给用户提示去复核等。

PART 3

不要被deepseek牵着鼻子走

在上述调试过程中,我发现了deepseek很让人头疼的一点(因为没有用其他的大模型,所以只说它,不排除这是AI的通病)。

可以看到下面图片里有调试了很多的版本,其实一开始我就在一个main.py文件中调整,每次deepseek给我一条更新意见,我就直接在main.py文件中修改。后来才发现被坑了。修复完一个新的bug,返回测试的时候,发现怎么前一个bug又回来了?反复几次才知道deepseek会为了解决眼前的问题,而找到一个省力的方式,简单来说就是头疼医头脚疼医脚。后面我就换了一种方式跟它沟通,如果哪里需要更改,我就把目前最新的版本发给它,让它在这个版本上,只针对某一块需要调试的地方进行修改,其他地方不允许动。

PART 4

更新和调试内容回顾

从6月13号版本到现在,这周主要更新和调试的内容总结如下:

>一、PDF处理流程优化

| 优化点 | 说明 |**电子发票直接提取** | 使用 `pypdf` 直接提取内嵌文字,跳过OCR,速度从10-30秒降为<1秒 |**通行费强制OCR** | 检测到“通行费”关键词,不走直接提取(乱序),强制走简化OCR |**逐页处理** | PDF按页独立识别,每页生成一条记录,文件名标注页码 |**智能路由** | 先直接提取,若无效则回退OCR,通行费独立走简化OCR |

>二、parse_invoice 识别逻辑迭代

| 迭代 | 内容 |**类型识别优先** | 通行费优先识别,避免被误判为电子发票 |**通行费分支** | 精确标签匹配(交款人、票据代码、票据号码、开票日期、小写) |**电子发票备选提取** | 当“购买方信息”区域截取失败时,用 `company_patterns` 匹配含“有限公司”等关键词的公司名 |**税号备选提取** | 提取所有15-20位字符,排除20位纯数字(避免误取发票号码) |**大写金额转小写** | 新增 `chinese_to_float` 函数,将中文大写金额转为数字 |**大写匹配正则优化** | 从 `[((]大写[))]\s*([...]+)` 改为 `[((]大写[))].*?([...]+)`,允许中间隔有换行或括号 |**价税合计兜底** | 小写和大写均匹配不到时,回退到“从所有两位小数中筛选有效值(1-1000万),取最大值” |**符号修正** | 公司名中 `〈` → `(``》` → `)` |

>三、OCR 优化

| 优化点 | 说明 |**简化OCR vs 增强OCR** | 通行费用简化OCR(无预处理、无投票),速度快;电子发票/图片用增强OCR(预处理+投票),准确率高 |**通行费强制OCR** | 直接提取的通行费文本乱序,强制走OCR后标签和值重新在同一行,可被精确匹配 |

>四、功能新增

| 功能 | 说明 |**价税合计为0警告** | 识别完成后,统计框底部显示价税合计为0的发票列表,提醒人工复核 |**混合PDF支持** | 同一PDF中既有电子发票又有通行费,逐页独立判断处理方式 |**文件名列** | Excel台账中增加原始文件名列 |**处理耗时显示** | 识别完成后显示本次处理耗时 |

>五、打包优化

| 优化点 | 说明 |**poppler路径** | 支持从 EXE 同目录的 `poppler/Library/bin` 自动加载,用户无需手动配置PATH |**模型路径** | 支持从 EXE 同目录的 `models` 加载 |**图标** | 支持自定义 `.ico` 图标 |**控制台** | 保留控制台窗口(激活需要输入授权码) |

>六、关键问题解决记录

| 问题 | 原因 | 解决方案 || 电子发票价税合计为0 | 大写匹配正则要求紧挨中文金额,但实际隔有 `(小写)` 和换行 | 正则改为 `[((]大写[))].*?([...]+)` || 大写金额识别为710.50而非720.50 | `chinese_to_float` 解析“贰拾”逻辑错误 | 重写函数,分整数、角、分三部分解析 || 通行费购买方名称为空 | 直接提取文本标签和值分离 | 强制通行费走OCR || 混合PDF只识别第一张 | 未逐页处理 | 改为逐页独立识别 || 价税合计取到1215.23 | 兜底逻辑从所有小数中取最大值,误取时间戳 | 增加合理性过滤(1-1000万),并保留大写转换作为优先手段 |

>七、当前版本性能对比

| 场景 | 6月13日版本 | 当前版本 || 电子发票单张 | 10-30秒(OCR) | <1秒(直接提取) || 通行费单张 | 10-30秒 | 5-10秒(简化OCR) || 17页混合PDF | 5-10分钟 | 20-30秒(逐页智能路由) || 价税合计提取 | 依赖小写,失败时为0 | 小写 → 大写 → 小数筛选,三重保障 |

PART 5

总结

在使用AI的过程中,我们会慢慢发现有些地方它提供的信息并不准确,这时候要敢于质疑它,并且把你的想法坚定地灌输给它,让它想办法去执行;同时观察它为了完成你交代的任务,是不是会放弃一些别的重要选项。在这两周的vibe coding过程中,我有一种强烈的感觉,人类的思考过程是非常宝贵的,我们不能指望AI完全替代人类的活动(至少目前不行)

PART 6

下载链接

1、百度网盘链接:

https://pan.baidu.com/s/14hGlqvxd3f_S49eul6JyWg?pwd=pyd5 

提取码: pyd5

2、夸克网盘链接:

https://pan.quark.cn/s/73f47f9f8913

END