滴滴这 80 个亿的罚单砸下来,我第一反应是去翻硬盘里 2018 年的项目文件夹。找到了,那个叫“出行数据合规清洗”的玩意儿。当时甲方爸爸的原话是:“不管用什么方法,把司机端和乘客端这几年的线下纸质报销单、手写调度表,全部给我电子化、结构化,要能对接审计系统。” 那会儿哪有什么现成的 SaaS,就是硬上。
我们试过 Tesseract,中文手写体识别率惨不忍睹,稍微有点连笔或者纸张褶皱就直接乱码。后来转向 PaddleOCR,2.0 版本刚出来,号称对中文场景优化。第一步是预处理,这步太关键了。扫描件普遍有阴影、倾斜、背景网格线。我们用 OpenCV 做灰度化、二值化(OTSU 自适应阈值),然后做透视矫正。最难搞的是那种复写纸第三联,字迹淡得跟鬼一样,常规的锐化和对比度增强根本没用,最后是用了局部直方图均衡化 CLAHE,才把笔画抠出来一点点。
识别引擎本身只是开始。PaddleOCR 的默认模型对印刷体还行,但对我们这种五花八门的手写单据,必须自己搞数据微调。没有现成数据集,我们就自己造孽。找了几个实习生,人工标注了大概 8000 张关键字段的切片图片,日期、金额、车牌号、签名。训练环境也折腾,显卡不行,只能用 Paddle 的分布式训练在阿里云上跑,光调超参就废了一周,学习率设大了就震荡,设小了又半天没动静。最后发现,在识别后处理里加规则比死磕模型提升更直接。比如日期字段,用正则表达式强制匹配“年/月/日”格式,把模型误识别的“2021年13月”这种离谱结果直接过滤报警,让人工复核。
真正要命的是批量处理的速度和稳定性。一开始用单线程跑,一万张单据要跑一晚上,还动不动内存泄漏崩掉。后来改成用 Celery 搭分布式任务队列,每个 worker 处理一个图片,识别结果扔到 Redis,最后再统一入库。中间还遇到图片服务器带宽被打满,OCR服务 API 调用频率过高被限流,各种坑。那时候满脑子都是“队列”、“重试机制”、“熔断降级”,晚上做梦都是日志报错。
现在回头看,滴滴当年那种疯狂补贴、地推,用纸质单据和线下灰色操作来换增长的模式,跟我们那个项目本质上是一回事:用人力、用不规范的临时方案,去填一个因为速度太快而根本来不及做基建的大坑。他们填的是市场规模的坑,我们填的是数据合规的坑。最后的结果呢?我们那个项目勉强验收了,但后续维护成本极高,每次审计都要专门派人守着系统,因为总有那么百分之几的异常单据要人工处理。滴滴今天这 80 亿,就是当年所有那些“勉强验收”、“后续再说”的技术债和运营债,一次性的总清算。
技术永远在给业务野心擦屁股。PaddleOCR 再厉害,也识别不了“增长压倒一切”这种企业文化在代码里埋下的雷。我们调参调得再细,也解决不了业务方为了冲数据,默许线下伪造单据的根本性漏洞。系统报警了,提示某司机一天签了 300 张手写调度单,可能吗?业务方说:“别管,那是重点司机,特殊处理。” 得,规则白写了。
今天这新闻出来,团队里以前跟过那个项目的兄弟在群里发了条消息:“哥,当年咱们要是坚持把那套异常单据的自动审计规则强行上线,哪怕跟业务方拍桌子,会不会现在能少赔点?” 我回了个苦笑的表情。谁知道呢。技术人的天真就在于,总觉得代码和逻辑能规训现实。其实在暴力增长的时代,技术只是燃料,不是刹车。














