既然手工录入太慢,我就用多模态 Agent 重构了“报表扫描仪”,这玩意儿本质上是个缝合怪,但能救命。客户扔过来一箱2019年的纸质入库单,要求三天内把几千条数据进系统,财务那边等着对账。手工录?两个人不吃不喝也干不完,还保证不了准确率。报价的时候我手都在抖,不是激动,是怕砸手里。
以前这种活我肯定外包,或者让团队里的小孩去折腾Tesseract,但现在团队散了,就剩我自己。时间就是金钱,在这里不是鸡汤,是血淋淋的止损线。超时一天,尾款可能就没了,信誉也跟着打折。我翻了一遍手头的技术栈,PaddleOCR是开源的,但文档里那些“轻松实现”的案例跟实际业务差着十万八千里。真实场景的扫描件,有折痕、有圆珠笔洇墨、有那种针式打印机打出来的断断续续的虚线,还有财务用红笔划的勾和批注。这些噪音不处理,直接扔给OCR,识别率能掉到没法看。
我的策略是暴力管道,先做图像预处理这条线。用OpenCV,不是搞什么高大上的算法,就是最土的办法:灰度化、二值化、然后用形态学操作去噪点。关键是那个自适应阈值算法,得根据整张图片的亮度动态调,不然有些背景发黄的旧单据,字和背景就糊在一起了。这个参数调了我一晚上,试了高斯加权和均值法,最后发现对于这种光照不均的扫描件,用个稍微大一点的核做高斯模糊再阈值化,效果反而更稳定。每张图处理时间增加了0.3秒,但识别率从预估的70%拉到了85%以上,这买卖划算。
然后就是OCR引擎本身。PaddleOCR的轻量版模型速度快,但对付手写体和奇葩字体拉胯。我切了个分路:先用轻量模型跑全图,拿到一个初步的文本检测框和识别结果;然后针对金额、日期这些关键字段所在的区域(位置基本上是固定的),用它的服务器版大模型再识别一次。相当于重点区域二次校对。这里有个坑,PaddleOCR的Python接口,默认不是多线程的,同步处理几千张图能等到天荒地老。我开了个线程池,把图片预处理和OCR识别拆成两个阶段任务往里丢,同时要控制并发数,不然内存能爆掉。还得处理那些识别失败、框体重叠的异常情况,写了个简单的规则去合并和去重相邻的文本框。
识别出来的文本是一堆零散的字符串,怎么把它变成结构化的数据?这才是Agent思维的核心。我设计了一个简单的逻辑层:基于规则和少量关键词匹配。比如,先找“金额”、“合计”、“大写”这些锚点词,它们附近的数字字段大概率就是总价;日期字段有固定的格式,用正则表达式去捞。但最恶心的是商品明细,一行里混着品名、规格、单位、数量、单价,用空格或制表符隔开,OCR识别时还可能把空格漏了或者多加了。我写了个解析器,先尝试按常见分隔符切分,如果切出来的字段数不对,就根据数字和中文的分布模式去“猜”边界,比如连续数字后面跟着“kg”“个”之类的,大概率是一个字段的结束。这里没有百分百的准确率,我设置了一个置信度阈值,低于85%的条目单独拎出来,最后人工复核,大概也就几十条,半小时搞定。
整个流程串起来,用n8n做了个可视化的工作流,从扫描仪文件夹监听新文件开始,预处理、OCR、解析、结果写入Google Sheets,全自动。跑起来那一刻,听着风扇狂转的声音,不是成就感,是后怕。如果我没在2021年把那堆管理破事扔掉,重新捡起这些技术细节,如果我没在ChatGPT出来前就逼自己习惯用代码解决这种脏活累活,今天这个单子我接不住,或者接了也是亏到死。技术焦虑永远都在,但焦虑的源头变了。以前怕不会最新的框架,现在怕不能把已知的技术,用最低成本、最快速度组合成一个能赚钱的解决方案。Agent不是魔法,是把一堆不完美的工具,用流程和逻辑缝合成一个能替你干脏活的影子。














