ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

OCR与RPA在财务自动化中的落地实践:从选型到异常处理

OCR与RPA在财务自动化中的落地实践:从选型到异常处理 月底做对账、处理报销单、核对银行回单这是每个财务人绕不开的日常。活儿本身不难难的是又碎又密。每天对着几十上百张票据把代码、金额、日期一个个敲进系统敲完还得切到另一套系统核对一遍稍微走神就会录错。我做财务自动化项目这几年听到最多的需求就是“能不能把这些全自动了”。这个问题的答案绕不开一对黄金搭档OCR负责“看懂”RPA负责“干活”。财务机器人本质上就是让这俩配合起来把人工读票、录单、核对的操作链条替换成一条自动流水线。这篇内容适合财务数字化负责人、运维人员以及正在考虑上RPA但卡在单据识别这一步的团队我把从选型到落地的完整思路和踩过的坑都整理出来可以直接当作参考方案来用。1. 先把目标想清楚OCR和RPA在财务流程里各自干哪一摊很多团队一上来就急着选工具结果要么买了个OCR识别率很高但没人用要么RPA脚本写了一大堆跑起来却频频报错。问题的根源在于没搞清楚OCR和RPA的职责边界。1.1 OCR负责“读”RPA负责“做”OCR光学字符识别解决的是“把图像里的文字变成结构化数据”这个问题。财务场景里的票据五花八门增值税发票、银行回单、报销单、合同扫描件、电子票据截图这些资料对机器来说就是一张张图片哪怕里面印着再规整的文字系统也读不出来。OCR要做的就是把图片里的关键字段提取出来比如发票代码、发票号码、开票日期、税率、价税合计、购买方名称这些。RPA机器人流程自动化解决的是“把重复操作变成自动化脚本”这个问题。它模拟人操作电脑的行为打开网页、登录系统、点击按钮、填写表单、复制粘贴、下载文件、发送邮件。RPA没有眼睛它操作之前必须拿到已经结构化的数据。单独用RPA流程第一步就卡死了因为发票是图片RPA读不出图片里的数字单独用OCR数据识别出来之后还是得人工复制到ERP里效率提升有限。OCR加RPA才是完整的自动化链条OCR负责“读取识别”RPA负责“录入核对归档”。1.2 评估要不要做自动化先看这三条不是所有财务流程都适合用OCR加RPA硬套。我在项目里一般先问三个问题第一业务量够不够大一天不到十张单据人工录入也就几分钟上自动化反而要维护脚本不划算。第二操作流程稳不稳定系统登录方式、单据格式、填写字段如果三天两头变RPA脚本就得跟着重写维护成本会吃掉收益。第三有没有判断逻辑OCR加RPA擅长处理“有标准答案”的动作比如发票代码是多少、金额是多少、应该填到哪个字段。如果流程里涉及“这笔费用该不该报销”这种需要业务判断的环节机器做不了决策只能做辅助校验。1.3 一个完整的财务机器人通常拆成五个环节读、认、录、校、存这是我对财务自动化流程的拆法。读是获取原始凭证可能是扫描件、拍照件、PDF或者电子发票原文件认是OCR识别把图片转成结构化字段录是RPA把字段写入财务系统或ERP校是二次校验把系统回显的数据跟OCR结果做一次比对不一致就拦截存是把原始凭证、识别结果、操作日志关联归档。很多项目只做了前三个环节结果识别错一张票就直接录进系统后面查账才发现问题所以“校”这个环节我建议无论如何都不要省。2. 财务场景里的OCR选型本地开源、云端API、私有化部署怎么挑OCR工具很多但选错代价很大。同一个识别任务精度差两个百分点在单张发票上可能只是偶尔错一位数字放大到一个月几千张单据就是几十条错账。选型不能只看宣传页上的准确率要结合自家场景来评估。2.1 本地开源方案Tesseract和PaddleOCR的取舍Tesseract是老牌开源OCR引擎轻量、部署简单几十MB的安装包就能跑起来适合标准印刷体、英文、数字为主的场景。但它在中文财务票据上表现一般尤其是表格线复杂、中英文混排、字体多变的发票识别效果不太稳定。Tesseract的错误提示也很有“个性”我后面会专门说一个我们踩过的坑。PaddleOCR是百度开源的中文OCR工具在中文场景的识别效果比Tesseract好不少尤其是对复杂版式的适应性。它把识别拆成了检测、方向分类、识别三个环节先是文本检测模型找到图中所有文字区域再判断每个区域的方向是否需要矫正最后用识别模型输出文字内容。用PaddleOCR处理增值税发票准确率通常比Tesseract高二到五个百分点对表格结构也有一定还原能力。本地方案最大的优势是数据不出门财务数据敏感很多公司不允许把票据图片传到外部接口这时候本地部署几乎是唯一选项。缺点是GPU资源有限的话识别速度上不去而且初始化成本略高得装Python环境、配置模型文件。2.2 云端API和私有化部署速度和合规的权衡百度OCR、阿里云OCR、腾讯OCR这类商用云接口开箱即用识别精度比开源方案更高尤其是它们有针对增值税发票、银行回单的专用识别模板字段直接返回结构化的JSON。调用方只需要上传图片等结果就行不用自己维护模型。缺点有两个一是费用按调用次数计费量大了成本不低二是数据出域票据图片要传到第三方服务器金融、国企等合规要求严格的场景比较难接受。私有化部署的商用OCR比如合合、百度私有化版这些相当于把云端能力搬到内网服务器识别的精度和速度都有保障合规问题也解决了但价格不便宜适合预算充足、数据敏感的集团型公司。2.3 选型对照表一张表看清三种路线方案识别精度部署成本单张成本数据安全离线可用适用场景Tesseract中低极低零高是英文单据、数字识别、轻量试点PaddleOCR中高低零高是中文票据、本地合规要求高的场景云API高零按次计费低否票据类型杂、量不大、无不安全限制私有化商用高高按年授权高是集团财务共享中心、海量票据2.4 图像预处理比换引擎更先做的事很多团队遇到识别率低第一反应是换更强的OCR引擎但真正的问题出在图片本身。财务票据的原始数据质量参差不齐扫描件有阴影和折痕、拍照件有倾斜和反光、电子发票截图的分辨率不足。不做预处理再好的引擎也白搭。我常用的预处理流程是统一转成PNG或者JPG格式分辨率至少调整到300DPI过低的先做超分辨率处理用opencv做角度矫正检测票据边缘后做透视变换让画面摆正再调整亮度和对比度增强文字和背景的差异。这里有个反直觉的点很多人习惯先把图片转成灰度但彩色票据上的红色印章往往会影响识别直接用灰度图反而会把印章压成一块黑斑遮挡底下的文字。我的做法是先用颜色通道分离把红色印章区域单独识别并排除干扰再对剩下的内容做灰度化处理。3. RPA把OCR“接”进来的三种姿势选好OCR接着就是把OCR能力和RPA流程串起来。这里不是简单加一个“调用HTTP接口”的组件就行集成的模式、数据传递的格式、异常处理的分支都得提前设计好否则跑起来三天两头报错。3.1 串行模式一张一张处理逻辑最清晰串行模式是最简单的集成方式RPA逐个读取文件夹里的票据文件调用OCR接口识别拿到结果后写入Excel或ERP处理完一张再处理下一张。流程直白、好排查、好维护适合每天百来张以内、单据格式相对统一的场景。RPA脚本的核心逻辑大致是这样从指定目录获取所有文件循环遍历文件对每个文件先判断格式图片直接用PDF就转成图片再交给OCROCR返回的JSON解析出关键字段写入目标系统的表单并点击保存。3.2 并发模式批处理提速适合共享中心每个财务共享中心每天的票据量可能达到几千张串行处理速度跟不上。并发模式做了两件事RPA侧开多个工作线程或机器人同时消费队列里的文件OCR侧用批量异步接口一批图片提交后轮询拿结果而不是同步等待单张返回。并发模式要特别注意频率限制。云OCR接口基本都有QPS限额比如单账号每秒最多调用5次超出会被限流。我一般会在RPA脚本里做一层简单的令牌限速每调用一次就休眠几百毫秒既不触发限流又不会把并发压得太低。3.3 人机协同模式机器识别加人工抽检兜底再牛的OCR也会有识别错的时候与其追求100%准确率不如在流程里设计一道人工复核的兜底环节。我通常建议按比例做抽检比如每50张里面默认通过随机抽5张人工核对如果识别置信度低于某个阈值比如低于85%自动转人工通道标记为待人工确认。这里的逻辑很像机场安检大部分旅客会顺畅通过安检仪只有扫描图像有异样才需要人工开包检查。完全依赖机器不现实每单都人工核对又浪费了自动化的意义抽检加阈值兜底是最务实的方案。3.4 数据传递格式前后端都省心的字段映射设计OCR识别结果通常是嵌套的JSON结构比如发票的价税合计嵌套在“金额”对象里购买方名称在“购买方”对象里。RPA拿到JSON之后如果一行行去解析字段脚本写起来无比繁琐。我的做法是做一层字段映射表在RPA脚本里预先定义“发票号码”“开票日期”“购买方名称”“价税合计”等业务字段每个字段对应JSON里的一个取值路径。程序启动时加载这张映射表运行中把OCR返回的JSON按映射表提取字段然后统一转成一个扁平的字典对象再传给后续的写入步骤。这样改OCR引擎时只需要改映射表不必动RPA脚本主体。4. 一个完整落地案例从发票扫描到凭证生成一步一步拆理论铺垫够了我拿一个实际做过的发票报销场景来演示整个流程怎么落地。客户是一家做贸易的公司财务部每天要处理大约120张增值税专用发票之前两个会计一整天都在录发票、做进项认证、登记台账偶尔还录错。4.1 流程梳理先画流程图再写脚本处理财务自动化我从来不建议直接打开RPA工具开始“录操作”而是先把流程图理清楚。这段流程的拆分是这样的发票接收业务员把发票拍照或扫描后放进统一文件夹按供应商名称建子目录文件读取RPA扫描文件夹识别出图片和PDF文件PDF转成图片OCR识别逐张提交给OCR引擎识别发票代码、发票号码、开票日期、销方名称、价税合计等字段数据校验跟业务端的报销单电子信息比对发票号和金额对不上就标记异常系统录入把识别字段写入ERP的发票登记单提交后截图回执台账归档把识别结果追加到Excel台账图片移动到“已处理”目录日志入库4.2 关键代码用Python调PaddleOCR识别发票OCR识别环节我用Python写了一个独立服务RPA通过调用这个服务接口来获取识别结果。这样做的好处是OCR逻辑和RPA脚本解耦换OCR引擎时RPA不用改。import json from paddleocr import PaddleOCR import numpy as np from PIL import Image ocr PaddleOCR(use_angle_clsTrue, langch, show_logFalse) def process_invoice(image_path): # 图像预处理放缩到合适尺寸增强对比度 img Image.open(image_path).convert(RGB) img img.resize((max(1200, img.width), max(1600, img.height))) img_array np.array(img) result ocr.ocr(img_array, clsTrue) lines [] for line in result: for item in line: # item[0]是坐标框item[1][0]是文本item[1][1]是置信度 text, conf item[1][0], item[1][1] lines.append({text: text, confidence: round(float(conf), 4)}) return json.dumps({lines: lines}, ensure_asciiFalse)这段代码看起来不长但有一个细节值得注意use_angle_clsTrue这个参数。财务票据在拍照上传时经常是歪的甚至旋转了180度方向分类模型会自动矫正不开启的话识别结果会差很多。4.3 RPA侧脚本读取、识别、录入、归档RPA侧我用影刀做了示例逻辑跟UiPath、金智维这类工具大同小异。核心步骤是这样串的1. 遍历文件夹获取所有待处理文件列表 2. For Each 文件 In 列表 3. If 文件后缀是 .pdf Then 调用PDF转图片组件生成临时图 4. Else 使用原图 5. 调用HTTP组件POST到本地OCR服务JSON参数带图片路径 6. 解析返回的JSON按字段映射表提取发票号码、金额等字段 7. 打开ERP发票登记页面 8. 填写对应输入框每个字段填完截图留痕 9. 点击提交等待页面返回成功提示 10. 把识别结果和操作结果追加写入Excel台账 11. Move 文件到已处理文件夹 12. End For 13. 汇总处理日志发送工作邮件第8步的“截图留痕”建议保留一旦后续出现录入数据对不上的情况可以通过截图追溯当时的画面定位问题。这个习惯帮我们解决过不少纠纷。4.4 异常分支设计别让单张票据卡死整个任务流程跑起来之后最大的风险不是识别错而是某一张异常票据导致整个机器人卡住。我设计的异常处理分支包括文件不是票据比如误投了合同扫描件识别结果里没有发票号码直接移入“非发票”目录并在日志里标注识别置信度低于阈值自动转人工复核ERP系统页面加载超时重试三次仍然失败就发告警邮件并跳过当前单子最后汇总未处理清单。4.5 踩过的坑银行回单的背景底纹这个项目里最头疼的不是发票反而是银行回单。很多银行的回单背景有底纹金额数字和背景颜色相近OCR识别时要么漏一位要么把相邻数字识别成连接符。后面我们专门针对回单做了图像处理先把图像转到HSV色彩空间按明度做阈值过滤把底纹减淡后再识别。这里踩过一次坑之后我才真正意识到预处理步骤比OCR引擎本身更值得花精力。5. 常见问题与排查技巧实录做OCR加RPA项目不会一帆风顺下面是几个高频问题和我的排查思路。5.1 识别率在80%徘徊怎么都上不去排查看图像来源。同一个渠道进来的票可能都有同样的问题比如扫描仪的对比度设得过低、拍照角度普遍倾斜。先做批量的图像质量分析统计每张图片的分辨率、亮度标准差、倾斜角度找到共性规律再针对性处理。还有一个小技巧看错误样本集中在哪些字段。如果总是发票号码后几位错很可能是那部分的字体比较特殊可以单独做模板匹配或者针对该区域做局部放大识别。5.2 “Could not create a primitive... no text detected”报错这个报错是Tesseract的经典问题我们在一个试点项目里遇到过。用了Tesseract 5.3.0版本部署在Windows服务器上跑一段时间后就报“Could not create a primitive”然后exit。排查了很久最终锁定是Tesseract的临时目录权限问题服务账户没有写入临时目录的权限导致引擎初始化失败。解决方法是给Tesseract的临时目录和语言包目录加上服务账户的读写权限同时在调用命令里显式指定临时目录参数tesseract invoice.png output --oem 1 --psm 6 -l chi_sim TESSDATA_PREFIXC:/Program Files/Tesseract-OCR/tessdata TMPDIRD:/ocr_tmp另一个“no text detected”的常见原因是图片质量太差OCR根本找不到文字区域。把图片放大到原来的两倍再识别往往就能解决。5.3 一台机器跑OCR速度太慢瓶颈在哪先分清瓶颈在CPU还是网络。本地OCR主要吃CPU大批量处理建议配GPUPaddleOCR的GPU推理速度比CPU快5到10倍。云端OCR的瓶颈通常在网络和接口QPS限制网络延迟高就改用批量异步接口QPS限制就是脚本里做限速。还有一个容易被忽略的点RPA流程里频繁的网页操作也会拖慢整体速度所以识别和录入不要做成强同步识别一批、录入一批能显著提升吞吐量。5.4 识别出来的数字出现乱码数字和字母混排时最容易出乱码比如发票代码里的字母O和数字0大写字母I和数字1。这个问题的根源在于OCR引擎对相似字形难以区分单纯换引擎不能根治。我的做法是在RPA侧加一层字段级别的规则校验发票号码、税号这类字段有固定的长度和字符集校验不通过就直接判为异常转人工复核。常见问题可能原因排查步骤解决方案识别率低图像质量差、预处理缺失统计错误样本分析共同特征针对性图像预处理局部增强Tesseract报错临时目录权限、语言包缺失检查引擎日志和权限配置显式指定临时目录加权限处理速度慢CPU瓶颈、接口限流监控CPU和接口响应耗时上GPU异步批处理加限速乱码相似字形混淆看错误字符集分布字段规则校验异常转人工5.5 数据一致性校验给自动化加最后一道保险财务管理讲究账实相符自动录入也一样必须建立数据校验机制。最基础的做法是“双读校验”OCR识别完成后取票据图像上关键字段所在位置再做一次小范围的二次识别对比两次结果一致才通过。进阶的做法是“业务规则校验”比如价税合计金额和处理前业务填写的报销金额误差超过0.01元就拦截发票号码不符合票种规则就拦截。有了这些规则OCR偶尔识别错一两张也不会直接污染到账务系统。6. 落地之后还能怎么扩展财务机器人这套“OCR加RPA”的组合远不止能处理发票报销。我后续在客户那边还做了几个方向的扩展银行回单自动下载和回单识别每天自动登录网银下载前一日的回单文件OCR识别后自动生成银行流水台账再跟ERP里的收付款记录自动对账合同关键条款抽取把纸质或扫描版合同的关键要素识别出来归档到合同管理系统的结构化字段里税务申报底稿自动化从各个系统汇数据、识别票据、生成申报底稿。我个人在实际项目中的体会是OCR和RPA的配合核心价值不是把单点功能做到100%完美而是通过流程串联和数据校验让整条链路达到“够用且可控”的状态。每一张票据识别错了人工复核能兜住流程不会断每一次录入操作日志留痕能追溯责任能落到人。想清楚这个定位很多选型上的纠结、技术上的难题反而会迎刃而解。
返回列表