☰
轻型AI中台实战:OCR+大模型+规则引擎,让对账不再靠吵架
2026/10/8 4:10:04 网站建设 项目流程

去年年底,公司财务和业务两个部门开了一场“对账协调会”,说是协调会,其实就是互相举证。业务说我已经把订单录进系统了,财务说我在银行流水里看不到这笔钱,两边都觉得自己没错。吵了半小时,最后发现是同一笔订单在三个系统里录了三遍,其中一次还把到账日期填错了。也是从那天开始,我下定决心在公司内部部署一个轻型AI中台,把重复录入这件事彻底干掉,把每个月的对账差异压下去。

这个标题听起来有点大,但我的目标其实很具体:让一张单据从进来那一刻起,只被处理一次。所谓轻型,就是不做数据湖、不做全链路数据治理、不搞十几个微服务,只围绕“录入”和“对账”这两件事,把OCR识别、信息抽取、规则校验和自动对账串成一条完整流水线。这篇内容更适合谁看?从事企业运营、财务系统对接、内部系统建设的同事,或者正准备引入AI但不敢一步到位的中小团队。我可以很直接地告诉你:如果目标非常集中,一台16G内存的服务器加一台普通商用电脑,就能把这个事情跑起来。

1. 从“对账吵架”说起:为什么要做轻型AI中台

先讲一个数字:按我们当时的业务量,每天大约有200张需要人工处理的单据。这些单据可能是销售订单、供应商对账单、银行回单、费用报销单。每一张单据平均要在ERP、财务系统、资金系统里各录一次,每次录入快则4分钟,慢则8分钟。一天下来,光是重复录入就要花掉800到1600分钟,相当于一个人大半天什么都干不了,专门敲键盘。

更可怕的是录入错误。有一次银行余额差了0.01元,财务愣是查了两天,最后发现是有笔金额在录入时小数点错了一位。0.01元的差异背后,是两拨人各自维护了一套“真相”。业务系统里的订单状态是待收款,资金系统里显示未匹配,财务Excel里又是一条手工备注。三套数据互相对不上,月底对账自然变成一场灾难。

1.1 重复录入:每天重复“同一个动作”

我观察了业务和财务的日常工作,发现一个非常扎心的规律:很多数据不是没有,而是被反复搬运。销售订单在业务端录一遍,开票系统再录一遍,到了收款核销的时候,又要照着回单手工填一遍。中间任何一次录错,或者格式不统一,后续环节就得靠人工去猜、去查、去问。

这是我们当时最痛的一点:单据本身已经是电子化了,但系统之间没有打通。一家供应商发来PDF对账单,里面是几十行明细,员工要先打开PDF,再一行一行复制进系统。如果PDF里有合并单元格、特殊符号或者繁体字,复制出来的结果经常是乱的。后来我们干脆允许员工直接拍照上传,结果图片里的金额、账号、日期又要手工敲进表单。

这种重复劳动还有一个隐蔽成本:新员工上手慢。我见过一个入职三个月的商务专员,因为不熟悉各种单据的格式,经常把“应收日期”和“到账日期”搞混。只要有一个字段填错,月底对账就多一条需要人工核实的挂账记录。所以这里要明白一件事:消除重复录入,不是上一套ERP就能解决,而是要有一套能自动读懂单据、自动填字段、自动去重校验的机制,这就是AI中台最有价值的地方。

1.2 对账困难:不是财务不努力,是规则太散

对账困难这个事,很容易被简化成“财务人手不够”或者“系统不好用”。但我参与过几次对账之后发现,真正的难点是数据口径不一致。

举个例子,银行回单上的“交易日期”,可能是实际打款的日期;但业务订单里的“订单日期”,是客户下单的日期。这两者之间可能有几天时间差。如果刚好跨月,订单在月末、回单在下月初,财务对账时就会看到一条“未匹配”的订单。再比如手续费问题,客户打款10000元,银行实际到账9950元,中间扣了50元手续费。如果对账逻辑只比较总金额,这笔订单永远匹配不上。还有退款、部分收款、合并支付、平台代收代付,每一种业务形态都会产生不同的差异。

传统做法是财务导出一堆Excel,用VLOOKUP去匹配,匹配不上的就手动查。月底那几天,财务基本都在加班。其实财务同事已经非常努力了,但规则散落在业务系统、支付渠道、银行回调、Excel公式里,靠人肉去对齐,效率天花板就在那里。

1.3 为什么选择“轻型”而不是“重型中台”

决定立项之后,我们其实纠结过要不要上“正儿八经的AI中台”。市面上常见的大数据中台、AI平台,动不动就是集群、数据湖、数据资产、模型训练平台。我问过供应商,从调研到试点,最短也要三四个月,投入至少七位数,还需要专门的算法工程师维护。对我们这种场景来说,这是典型的“杀鸡用牛刀”。

我们当时只有三个需求:识别单据、校验数据、自动对账。这三个需求完全可以用一组轻量服务解决。架构上只需要四条链路:前端采集、OCR识别、大模型抽取、规则引擎处理。这条链路可以部署在一台服务器上,用Docker编排,甚至不需要GPU也能跑。事实证明,轻型AI中台并不意味着能力降级,而是把力气花在刀刃上。只要业务目标足够聚焦,轻量方案一样能解决大问题。

2. 方案设计与核心模块拆解

如果你也想做类似的事,我的建议是先把系统拆成三个模块:智能识别、标准规则层、自动对账引擎。不要一上来就想要一个“AI大脑袋”,把所有问题都塞进去。模块化设计的最大好处是:每个环节可以独立测试,出了问题也容易定位。

2.1 整体架构:三件事,三条链路

我们的整条链路是这样的:用户把单据拍照或者上传PDF,系统先做预处理,然后调用OCR服务识别文字和版面,接着用本地部署的大模型抽取关键字段,再经过规则引擎校验、补全、去重,最后进入对账引擎。对账引擎会把匹配不上的数据推到人工复核台,由财务同事快速处理。

整个架构不需要复杂的服务注册中心,也不做跨系统分布式事务。我们用一台4核16G内存的服务器,跑了一个基于FastAPI的Web服务、一个Celery异步任务队列、一个OCR容器、一个Ollama大模型服务,再加一个PostgreSQL数据库。前端就一个简单的上传页面和复核列表页面,甚至可以直接复用现有的办公系统页面。

为什么要这么搭?因为每条链路都有自己的瓶颈。OCR和大模型都是计算密集型,不能直接放在请求线程里同步处理,否则用户上传一张图片,浏览器要转圈几十秒。所以必须引入异步任务队列,用户上传后立即返回“处理中”,后台任务处理完再更新状态。这样的体验和稳定性都会好很多。

2.2 智能识别模块:让机器先“看一遍”

识别这一层,我们最初只打算用OCR把图片转成文本,后来发现不够。一张银行回单上既有“付款方”和“收款方”,又有流水号、交易时间、金额、附言。OCR识别出来是一堆坐标和文字,如果不做版面分析,后面对账引擎根本不知道该取哪个字段。

我们的做法是分两步。第一步用PaddleOCR的版面分析能力,把单据划分成多个区域,比如标题区、交易信息区、金额区、备注区。第二步再用本地部署的LLM做信息抽取。你可能会问,为什么识别字段不用传统NLP正则?因为单据格式太多了,今天来一张建行回单,明天来一张支付宝账单,正则写不完。用LLM的优势在于,我只需要在提示词里告诉它“提取交易日期、金额、付款方名称、流水号,缺失的字段填None”,它就能适配大部分格式。

在模型选型上,我们直接用Ollama本地部署了一个7B量化的开源模型,效果完全够用。识别速度在CPU上大概需要5到8秒,如果公司有16G显存的显卡,速度能压到1到2秒。我个人建议先把OCR管好,再上LLM。OCR都识别不清楚,大模型就算有通天的本事也抽不出准确字段。

2.3 标准规则层:把各种格式变成同一种语言

识别完成之后,数据还是“原材料”,不能直接进对账引擎。比如日期格式,有的单据写“2024/3/1”,有的写“2024年3月1日”,有的写“03-01-2024”。金额更麻烦,字符串里可能出现逗号、人民币符号、空格。如果不统一,后面排序和匹配全都会乱。

所以规则校验这一步,我们专门写了两个基础服务。第一个是字段校验:客户名称是否在主数据表里?金额是否大于零?日期是否合法?流水号是否由数字和字母组成?第二个是标准化:所有日期都转成ISO格式,所有金额都转成以“分”为单位的整数存储。为什么用整数存金额?因为Python和数据库里的浮点数在做相等比较时,经常会出现0.1+0.2不等于0.3的问题。对账本来就是要精确匹配的东西,用分存储是必须的。

另外我们还做了一个很关键的“去重”逻辑。用于识别重复录入的指纹比对:系统会把图片的MD5和识别出的关键字段拼起来,生成一个指纹。如果新上传的单据和库里的某一条指纹相似度极高,就直接弹出“该单据可能已录入”。这一步看似简单,但实际上解决了一个很实际的痛点:同一张单据被业务拍了一次,又被财务拍了一次,如果没有去重,后面就会重复记账。

2.4 自动对账引擎:不是简单“对金额”

很多人对自动对账的理解就是“两边金额一样就匹配上”。真实场景压根没这么美好。我们要处理三种典型情况:第一,金额吻合但业务单号对不上,可能是录单时打错号码;第二,单据金额和实际到账金额差了一笔手续费;第三,一张打款单对应多笔订单,叫合并支付。

所以对账引擎的匹配逻辑设计成了优先级方案。第一步优先匹配“渠道流水号 + 交易日期 + 金额”完全一致的记录;查不到就先放宽日期窗口,允许前后两天的偏差,再查“业务订单号 + 金额”;还匹配不上,再看是否存在“金额差值等于固定手续费”的情况。匹配成功的记录自动打上“已核销”状态,匹配失败的进入“待人工复核”。

对账引擎跑完不是终点,异常数据还要能被财务快速处理。我们做了一个很小的复核界面,左边显示原始单据截图,右边显示系统抽取的字段和对账结果。财务只需要确认或修改,一键保存。所有操作都会写审计日志,方便以后追溯。

3. 部署实施:从0到1的关键节点

方案定下来之后,真正的硬仗才开始。这里我把整个部署过程拆成四段,每一段都有我们真实踩过的坑,你可以直接拿来当操作手册。

3.1 环境准备:一台带Docker的服务器就够了

我强烈建议把服务都容器化。我们起初直接在宿主机上装Python环境、装OCR依赖,结果一次升级把系统自带的Python搞坏了,重装系统浪费两天。后来全部改成Docker Compose编排,干净了很多。

硬件上,我们用的是一台4核16G内存的服务器,没有独立显卡。如果你想跑得更快,建议加一张16G显存的显卡,成本不算太高,但推理速度提升非常明显。系统最好是Ubuntu 22.04以上,先装好Docker和Docker Compose插件:

sudo apt update sudo apt install docker.io docker-compose-v2 sudo systemctl enable --now docker

注意一点:国内网络环境下拉取镜像可能比较慢,建议给Docker配置好镜像加速器,否则光拉一个PaddleOCR的镜像就能让你怀疑人生。

3.2 模型服务部署:用Ollama管理本地大模型

这里就需要选择一套方案来管理推理模型。我们最终选了Ollama,因为它足够轻,管理模型非常方便,一条命令就能拉模型,一条命令就能启动服务。对于要部署在内部网络的场景,这是个很实用的选择,模型文件会统一保存在本地,不会把业务数据传到外部。

ollama pull qwen2.5:3b ollama pull qwen2.5:7b ollama serve

默认服务端口是11434,调用接口也很简单。我在Python代码里写了一个通用函数,用来抽取单据字段:

import requests import json def extract_fields(text): prompt = ( "你是单据信息抽取助手。请从下面文本中提取字段:" "交易日期、付款方、收款方、交易金额、流水号、备注。" "如果某个字段没有,就返回null。只输出JSON。\n\n" f"文本:{text}" ) resp = requests.post( "http://127.0.0.1:11434/api/generate", json={ "model": "qwen2.5:3b", "prompt": prompt, "stream": False, "options": {"temperature": 0, "num_predict": 512} }, timeout=60 ) return json.loads(resp.json()["response"])

几个细节要注意:temperature一定要设成0,抽取类任务不需要创造性,不然同样的输入可能每次输出不同字段;num_predict不要设太大,512足够;模型选3b还是7b,取决于你的机器。纯CPU跑,7b在长文本上会明显变慢,但如果单据字段多、格式乱,7b的准确率更好。

3.3 业务服务编排:让AI服务一起协作

模型服务和业务服务需要协同工作。我们用Docker Compose定义了一套最小可运行的编排文件,大概长这样:

version: "3.8" services: db: image: postgres:15 environment: POSTGRES_USER: aihub POSTGRES_PASSWORD: aihub123 POSTGRES_DB: aihub volumes: - ./pgdata:/var/lib/postgresql/data restart: unless-stopped redis: image: redis:7 restart: unless-stopped ocr: build: ./ocr_service ports: - "8001:8001" restart: unless-stopped ollama: image: ollama/ollama ports: - "11434:11434" volumes: - ./ollama_models:/root/.ollama restart: unless-stopped web: build: ./web_service ports: - "8080:8080" environment: DB_URL: postgresql://aihub:aihub123@db:5432/aihub REDIS_URL: redis://redis:6379/0 OCR_URL: http://ocr:8001 OLLAMA_URL: http://ollama:11434 depends_on: - db - redis - ocr - ollama restart: unless-stopped

Web服务里同步集成了Celery Worker。用Celery的原因很简单,OCR和LLM都是耗时任务,如果不异步化,用户上传一张图片后HTTP请求会一直挂起,不仅体验差,还容易触发网关超时。我们把上传请求丢进Redis队列,然后立刻返回任务ID,后台Worker慢慢处理,完成后把结果写回数据库。前端轮询任务状态即可。

Celery并发数我这里特别提醒一下:默认Worker会开很多并发进程,如果你的服务器只有4核还跑着OCR和Ollama,同时处理十几个任务会把CPU全部占满。建议限制一下Worker并发,比如设置--concurrency=2,给OCR和Ollama留出余量。

3.4 上线测试:影子模式跑两周再切换

上线策略比你想的重要。因为一旦对账出错,直接影响财务账目,这个锅谁都背不起。我们的做法是影子模式:新系统在后台跑,但不直接产生核销结果,只把识别结果和现有手工录入结果做对比。业务人员照常用旧流程录单,AI系统自己也在跑,跑出来的结果每天发一份对照报表。

影子模式跑了整整两周,我们收集了几百张真实单据,修正了20多个字段映射问题。比如“实付金额”和“订单金额”经常混淆,比如招商银行回单上的“交易附言”放在区域底部,OCR识别时容易和别的字段混在一起。这些细节只有跑到真实数据才能发现。

切换时也要分步走。先切一类单据,比如银行回单;稳定后再切换供应商对账单;最后再切费用报销单。每切一类就用一周时间观察差异率。不要一次性全部切过去,否则出了问题,连定位都无从下手。

4. 实操中踩过的坑与排查记录

这一节算是全篇最有价值的部分。模型部署本身不难,难的是业务落地时那些“说不清楚”的问题。我把我们遇到过的问题整理成了速查表,你在自己环境里大概率也会遇到。

4.1 识别不准:先检查图像,再调模型

一开始我们收到大量“识别失败”的反馈。第一反应是换更大的模型,后来发现大部分失败都出在图像质量上。有同事用手机拍回单,逆光、反光、拍摄角度歪斜,甚至把手指都拍进去了。这种图片不管换什么模型都很难识别好。

后来我们加了一个图像预处理层,用OpenCV做透视校正、灰度化和二值化,同时加了一个清晰度评估模块。如果图片清晰度太低,系统直接给出提示“请重新拍照,确保光线充足、单据完整”。这个改动让识别成功率至少提升了20个百分点。经验是:图像质量优化的优先级永远高于模型优化,因为一张烂图丢给任何模型,结果都是垃圾。

4.2 老是挂账:先查时间口径和流水号

系统上线以后,财务反馈对账结果里还有很多“挂账”记录,点开看又没什么问题。排查时我们发现一个典型原因:渠道流水号在Excel里被显示成了科学计数法。比如流水号是一串长数字,在Excel里默认显示成1.23457E+16,导出来时精度已经丢了。到了对账引擎里,流水号就匹配不上。

时间口径也坑过我们。银行回单上的“交易日期”和内部订单的“应收日期”本来就允许有时间差。我们把“必须同一天”放宽成“前后两天的日期窗口”,同时要求金额完全一致,如果金额不一致还得判断手续费。这样改完,自动核销率从70%升到了90%左右。以后遇到挂账,先别急着查模型,先看看时间窗口、精度、字段映射这些基础规则。

4.3 任务堆积:AI服务也要限流

系统上线第一周,业务部门集中上传了几百张历史单据,Celery队列瞬间堆积到了上千个任务。Ollama服务因为并发请求太多频频超时,OCR容器也一度内存溢出。这个问题在测试环境根本看不出来,因为测试数据量不够大。

解决办法有两步:一是给Celery队列加上速率限制,比如每分钟最多处理5个识别任务;二是给Ollama设置并发数限制,默认是并发处理多个请求,在性能不够时最好设成1。这里有个知识点:Ollama本身是支持并发的,但并发太高时会排队甚至OOM,所以如果你是在CPU上面跑,老老实实把并发线程降下来,让任务在队列里排队反而更稳。

4.4 审计要求:所有AI处理都要留痕

财务最敏感的一点是审计。以前人工录入,每笔操作还能查到是谁录的;上了AI之后,财务担心“机器处理了,出了问题找谁”。所以我们在设计阶段就强制要求所有AI处理环节都写日志,包括原始图片、OCR中间结果、LLM抽取结果、规则校验命中情况、最终对账状态和人工复核记录。

数据库里专门建了一张审计表,每条记录都关联到一个不可变的任务ID。一旦有争议,可以根据任务ID完整回放当时这张单据的AI处理链路。权限上,复核页面只对财务负责人开放,原始图片的下载也要记录操作人。这些在过去的人工流程里反而不容易做到,AI中台只要设计好了,合规性可以比人工还好。

5. 实际效果、复盘与可扩展方向

整个项目从调研到上线,大概花了两个月。这里不说那些虚的,只讲我们实际测到的数据。第一个月,单张单据的平均处理时间从人工录入的6到8分钟,下降到了系统识别加人工复核的30秒左右。对账周期从每月5天压到了1天以内,财务终于不用在月初连续加班了。

重复录入这个问题基本被消灭了:同一张单据在进入系统时就被指纹查重拦住,业务和财务看到的是同一条经过AI处理的数据。差异率也从最初的每个月上百条待人工处理,降到了二三十条,而且这二三十条大多是真实的业务异常,比如客户汇错金额、退款未关联等等。这其实是好事,说明系统已经把正常单据处理干净了,人力终于可以集中在异常处理上。

5.1 落地后的数据变化

我再列一个简单对比表,方便你直观感受:

指标上线前上线后
单张单据录入耗时6分钟至8分钟20秒至30秒
月对账周期5天1天内
人工录单出错率约3%约0.5%
对账待人工处理条数每月100条以上每月20至30条

这些数字不是靠某一个模型跑出来的,而是靠“识别、校验、对账、复核”这一套完整链路。如果没有规则校验和去重,光有AI识别,数据照样是脏的;如果没有人工复核台,异常数据只会堆积在后台,财务还是得靠Excel处理。

5.2 复盘:哪些事该先做

如果我重新再做一遍这个项目,我会把大部分精力花在“流程梳理和字段标准化”上,而不是一开始就调模型。很多团队上AI中台容易犯一个毛病:把项目当成算法项目,整天研究哪张单据识别得准,却忽略了对账口径、字段映射、审批权限这些业务规则。实际上,业务规则跑得通,模型哪怕差一点也能靠规则兜底;业务规则不清晰,模型再强也救不了。

业务方从头到尾参与非常重要。我们的财务负责人每周花半天时间和我一起看那些“待复核”单据,讨论哪些差异可以自动处理,哪些必须人工确认。如果没有她,系统只会做出一个看起来智能但业务不买账的工具。

5.3 后续还能怎么扩

这套轻型AI中台的项目,我们后续计划扩展到三个方向。第一个是供应商对账,目前还是一张一张导Excel,以后可以直接上传供应商PDF对账单,自动完成和ERP数据的匹配。第二个是发票真伪查验,识别发票票面信息后自动调用查验接口,把结果回填进审批流。第三个是预算控制,费用报销单进入系统时自动检查预算余额,超预算的直接预警,而不是等到月底才发现超支。

技术上其实不需要大改造。现有的OCR、LLM抽取、规则引擎、任务队列这些基础设施都能复用,只需要新增几个数据模板和校验规则。这让我意识到一件事:轻型AI中台更像是一个可生长的框架,先解决一个痛点,然后把相邻场景一个一个接进来,成本远低于一开始就铺一个大平台。

最后说一点个人体会。我一个最深的感受是:AI中台这个词听起来很虚,真正有用的是把某一条业务线跑成闭环。模型不是越强越好,而是越合适越好。一开始我们把精力全放在模型效果上,后来才发现,真正的瓶颈是业务规则的对齐、异常样本的积累和用户的信任。这个项目做下来,我的建议很简单:如果你也有重复录入、对账困难的痛点,不要一开始就规划一个大平台,先选定一类单据,用“识别+规则+对账”搭一条最简链路,跑通后再慢慢扩展。AI不一定非要多大多全,能落地的AI,才是好AI。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询