这是一篇真实业务自动化项目复盘。项目重点不是“为了用 AI 而用 AI”,而是把新媒体推广报销中最耗时、最容易漏看的环节拆开:RPA 负责取数和执行,AI 负责看图,规则负责裁决,财务只处理机器无法确定的异常。


一、业务背景:为什么这个流程值得自动化

电商公司新媒体部门的推广报销,并不是简单看一眼金额就能审批,一张报销单通常会包含多天推广费用,每天还有发文数量、带图评论数量、不带图评论数量、推荐人数、爆文奖励等业务明细。运营人员还会上传支付记录截图,一张截图里可能包含十几条甚至几十条流水。

人工审批时,财务需要打开附件、查看日期、筛选支出、排除收入、逐行相加,再和审批表单、Excel 明细、实际发文任务量做交叉核对,这个过程人工可以完成,但问题很明显。

首先,信息分散。审批字段在飞书审批中,报销明细在 Excel 附件里,支付截图嵌在 Excel 单元格里,发文任务量又在另一张表格中。审批人员每次都要在多个入口之间来回切换。

其次,图片属于非结构化数据。普通 RPA 擅长点击、下载、读取表格,但支付截图里的流水明细并不是标准表格。直接 OCR 也容易漏掉负号、日期和金额。

最后,报销审批会触发真实业务动作。自动化不是生成报表,错了最多重新跑一次。审批一旦误批,就会进入真实财务流程。因此这个项目不能只追求“自动通过率”,还必须明确哪些情况可以自动驳回,哪些情况必须交给人工复核。

最终采用的原则是:

正常单据自动通过,确定性错误自动驳回,不确定风险交给人工,系统异常保留待处理。


二、整体方案:RPA 执行,AI 看图,规则裁决

这个项目的核心链路可以概括为:

飞书审批产生报销单,审批数据同步到飞书多维表;影刀 RPA 从多维表筛选待办记录,下载报销 Excel,清洗明细数据,提取嵌入图片;视觉大模型识别支付截图里的目标日期和支出金额;最后由确定性规则判断通过、驳回还是转人工复核,并通过 Python 调用飞书审批接口执行动作。

这里有一个关键设计取舍:

AI 不直接决定“同意”还是“驳回”。

AI 只做它更适合做的事情:从支付截图中识别日期、金额、收入支出方向,把图片信息转成结构化结果。真正的审批判断,仍然交给规则层处理。这样做有两个好处:

第一,可解释性更强。每一笔审批结果都能追溯到具体规则,而不是一句“AI 判断通过”。

第二,问题更容易排查。AI 识别错了,可以优化提示词或输出协议;规则判断错了,可以调整规则;接口执行失败,可以单独补偿。

RPA 负责搬运和执行,AI 负责看图和理解,规则负责裁决,飞书审批 API 负责落地动作。


三、系统架构:多维表不是终点,而是结构化待办池

很多业务自动化项目一开始会纠结“到底从哪个系统取数”。在这个流程里,生产环境并不是直接从飞书审批应用读取所有字段,而是从同步了审批数据的飞书多维表中读取。

多维表在这里的角色不是审批系统,而是一个结构化待办池。它把审批单里的关键字段同步出来,RPA 可以按条件筛选:

申请状态 = 审批中
当前处理人 = 指定财务人员
报销类型 = 小红书运营岗报销费

生产流程读取的核心字段包括:

申请编号
报销文档
费用明细_金额
发起时间
发起人
付款截图、付款码

其中几个字段比较关键。

申请编号 用于下载文件命名、日志标识和异常提醒。

报销文档 提供 Excel 附件下载入口。

费用明细_金额 是审批表单中的申报总金额,需要和 Excel 合计金额做对比。

发起时间 会被转换成“开始时间到开始时间 + 1 秒”的窗口,用于后续反查审批实例。

发起人 用于查询该员工的实际发文任务量。

内部会把单条记录整理成类似结构:

[
  申请编号,
  审批表金额,
  Excel附件对象,
  付款截图字段,
  发起时间,
  发起时间 + 1秒,
  发起人
]

四、主流程生命周期:从初始化到日志收尾

整个自动化不是只跑一个审批脚本,外层还有一套完整运行生命周期。

主入口会先解锁 Windows 屏幕,把鼠标移动到固定位置,再显示屏幕保护层,提示当前设备正在执行自动化任务。这个设计不是为了技术炫技,而是为了避免有人误操作正在运行的浏览器或 Excel。

随后流程会记录开始时间,执行初始化流程,再进入正式生产流程。生产流程结束后,会导出影刀运行日志,并向流程日志表写入“已完成”。如果出现全局异常,则导出日志、发送飞书告警、写入“失败”记录。最后不管成功还是失败,都会关闭 Chrome 页面,并关闭屏幕保护层。

初始化流程主要做两件事:准备目录和清理空间。

D:\RPA_Data\Process_Hub\费用审批\下载数据
D:\RPA_Data\logs

如果目录占用超过 1000MB,会执行清理。这里不是永久删除,而是移动到回收站,避免日志或附件误删后无法追溯。


五、生产流程拆解:从待办记录到审批动作

生产流程可以拆成六段。

1. 取数

RPA 从多维表读取待审批记录。如果没有符合条件的数据,流程直接结束。

2. 下载附件

每条记录里都有 Excel 报销文档链接。RPA 打开链接并下载到固定目录,下载文件以申请编号命名。

下载配置包括:

覆盖同名文件
等待下载完成
最长等待 300 秒

如果第一次下载失败,会随机等待 5 到 10 秒后重试一次。连续失败则跳过当前单据,让它继续保留在审批中,避免一个附件问题卡住整个批次。

3. 读取和清洗 Excel

模板底部通常会有备注说明,运营人员有时还会删除有效数据和备注之间的空行,所以不能简单读取全部区域后直接计算。

流程会保留表头,从第二行开始,只保留第一列能解析为日期的行,再把不同格式的日期统一成 YYYY-MM-DD

4. 确定性金额校验

先计算 Excel 有效行金额合计,再和审批表单里的申报金额对比。

如果金额不一致,直接驳回,并提示检查总金额或表格格式。

5. 逐日报销行校验

每一行会核对三类信息:

发文任务量
业务计价公式
该行对应的支付截图金额

6. 执行审批

如果所有行都通过,调用审批接口同意。

如果确定存在格式或规则问题,自动驳回。

如果金额差异较大但不适合机器直接判断,发送消息给财务人员,保留人工复核。


六、Excel 数据清洗:先把表格变成可信输入

这类项目不能一上来就调用 AI。AI 之前一定要先做确定性清洗,否则模型再强也会被脏数据拖垮。这个项目里,Excel 处理主要分三步:

1. 过滤无效行

模板底部有备注说明,而且备注行可能和有效数据挨在一起。

流程使用 filter_rows_by_date_column_skip_header(),始终保留表头,从第二行开始只保留第一列能解析成日期的行。

这样可以避免把模板说明当成报销明细。

2. 统一日期格式

实际填表时,日期可能是日期对象,也可能是字符串,例如:

datetime 对象
YYYY年MM月DD日
YYYY/MM/DD
YYYY-MM-DD
YYYY.MM.DD

流程会统一转换成:

YYYY-MM-DD

3. 金额四舍五入

金额合计不是直接用浮点数相加,而是通过 DecimalROUND_HALF_UP 处理到 2 位小数,报销金额这种场景,不适合把浮点误差留到审批判断里。


七、三层金额校验:不要只靠一个总金额

这类报销流程最怕的是只看总金额。总金额对了,不代表每天的明细、任务量和支付截图都对。因此流程里做了三层校验。

第一层:审批表单金额和 Excel 合计

审批表单申报金额 == Excel所有有效数据行第3列合计

如果不一致,直接驳回,没有金额容差。

因为这是表单和附件之间最基本的一致性校验。

第二层:Excel 行金额和业务计价公式

规则金额 = 发文数量 × 5
         + 带图评论数量 × 0.8
         + 不带图评论数量 × 0.5
         + 推荐人数 × 2
         + 爆文奖励金额 × 5

如果规则金额小于 Excel 行金额,说明该行申报超过了规则上限,自动驳回。

这里有一个细节:这不是严格相等校验,而是非对称校验。

规则金额 >= Excel 行金额:允许继续
规则金额 < Excel 行金额:自动驳回

业务上允许存在少报或其他合理情况,所以规则金额大于 Excel 金额时不拦截。但 Excel 金额不能超过规则允许的上限。

第三层:AI 截图金额和 Excel 行金额

AI金额 >= Excel金额:通过

AI金额 < Excel金额,且差额 < 10元:通过

AI金额 < Excel金额,且差额 >= 10元:提醒财务人工复核

AI返回非数字:按截图存在其他日期处理,自动驳回

这个设计没有追求“绝对自动化”。

确定错的自动驳回,不确定的交给人工。这样财务更容易接受,后期也更好维护。


八、发文任务量校验:把审批和真实业务数据连起来

这个项目不是只看报销表本身,还会反查新媒体人员的实际发文任务量。

当 Excel 里某一天填写了发文数量,流程会根据报销申请人找到对应的个人任务表,再按日期统计当天实际出现次数。如果实际发文次数少于 Excel 申报数量,则自动驳回。

这里也做了一些业务兼容处理。总任务量表里会维护员工姓名和个人表格链接。流程先读取总表,建立“员工姓名 → 个人表格链接”的字典,再从个人表格链接里解析 spreadsheet ID。接着根据报销日期定位当月工作表,读取个人表中的发文记录。

日期匹配也做了兼容。飞书表格里有时会存 Excel 日期序列号,有时会存 X月X日 这种中文日期。所以流程会同时生成两种格式:

Excel 日期序列号
X月X日

优先按日期序列号统计,找不到再按中文日期统计,月初报销时,数据也可能还在上个月工作表里,所以当月表找不到时,还会切到上个月工作表再查一次。把“费用审批”从单纯看票据,变成了和实际运营动作做交叉验证。


九、Excel 图片提取:这个坑比 AI 调用更关键

很多 AI + RPA 项目容易把重点放在模型接口上,但这个流程里更关键的工程细节,反而是如何把 Excel 单元格里的支付截图稳定提取出来,报销模板里,业务明细在 A-H 列,账单截图横向放在后面的单元格里。

例如:

第一天截图:I2
第二天截图:J2
第三天截图:K2

RPA 不是直接拿上传图片,而是从 Excel 附件里定位图片单元格,再把图片提取成本地文件,最后转 Base64 传给视觉模型。

图片列映射大致如下:

{
    1: "I",
    2: "J",
    3: "K",
    4: "L",
    5: "M",
    6: "N",
    7: "O",
    8: "P",
    9: "Q",
    10: "R"
}

普通浮动图片可以通过 openpyxl 遍历工作表的 ws._images,再根据图片锚点的行列判断是否在目标单元格,如果匹配,就读取图片二进制,并用 Pillow 保存成本地图片。但 WPS 的 DISPIMG 图片不是这样存的,需要另一套逻辑:

读取目标单元格公式
→ 正则提取 DISPIMG("图片ID")
→ 把 xlsx 当作 zip 包打开
→ 解析 xl/cellimages.xml
→ 找到图片 ID 对应的 r:embed
→ 解析 xl/_rels/cellimages.xml.rels
→ 找到真实媒体路径
→ 从 xl/media 读取图片
→ 保存成本地图片

实际业务里,用户不会关心自己插入的是普通图片还是 WPS 嵌入图片,他们只会认为“截图已经放进表格了”,如果自动化流程只能识别其中一种,业务环境就很容易出现大量失败。


十、视觉模型怎么用:只让它输出金额或日期异常

AI 模块的输入很简单:本地图片路径和目标日期,流程会把图片转成 Base64,然后调用视觉大模型。

图片转 Base64 后,会拼成多模态接口常用的 data URL:

data:image/{ext};base64,{base64内容}

Prompt 的重点不是让模型写解释,而是让模型严格完成几件事:

只看截图右侧流水明细
只识别目标月日,忽略年份和时间
只统计带负号的支出金额
带正号的收入不统计
负数金额转成正数后求和
发现其他日期时,不输出金额,输出其他日期

当前输出被设计成一个简单的“双态纯文本协议”。

正常金额返回:

1568.50

发现其他日期返回:

2月6日

或者:

2月6日,2月8日

RPA 只需要判断返回值能不能转成数字,就能进入不同分支,能转成数字,就当作截图金额进入金额比较,不能转成数字,就视为截图里存在其他日期,自动驳回,这个设计的优点是实现简单,影刀流程里也容易判断。但缺点也明显:它很依赖模型严格按要求输出。如果模型返回“合计金额为 1568.50”,RPA 就可能把它当成非数字文本,因此后续更稳的做法,是让模型返回结构化 JSON,例如:

{
  "status": "ok",
  "amount": 1568.50,
  "other_dates": [],
  "confidence": 0.96,
  "items": []
}

从工程角度看,AI 模块还可以继续补强:

HTTP 请求检查状态码
区分余额不足、限流、超时和服务端错误
返回结构做字段校验
审批场景降低随机性参数
异常结果进入人工复核或重试机制

审批场景不适合过度依赖模型自由发挥,输出越结构化,后续流程越稳定。


十一、审批动作:为什么要重新调用飞书审批接口

生产流程从多维表读取待办,但最终审批动作不是更新多维表字段,而是重新调用飞书审批接口。原因很简单:

多维表只是同步镜像,不是审批系统本身。

真正的“同意”或“驳回”,必须落到飞书审批实例和审批任务上,审批子流程接收这些参数:

starttime
endtime
status
comment
userid_approval

由于生产流程没有直接拿到审批实例 ID,所以使用发起时间到“发起时间 + 1 秒”的时间窗口反查审批实例并且和申请编号做组合校验。

查到实例后,再获取审批详情,遍历 task_list,找到当前审批人的任务 ID,最后调用 Python 审批模块。

Python 审批模块使用飞书审批 SDK,核心动作是:

client.approval.v4.task.approve(request)
client.approval.v4.task.reject(request)

同意和拒绝都需要这些关键参数:

approval_code
instance_code
user_id
task_id
comment
user_id_type = user_id

十二、异常处理:生产流程最重要的是不误批

自动化流程跑得通不难,难的是异常时怎么处理。

这个项目的异常处理大致分为四类:

1. 确定性业务错误

例如:

审批表金额和 Excel 合计不一致
发文数量大于实际任务量
业务计价金额不足
截图里存在其他日期

这类问题可以自动驳回,并给出明确原因。

2. 不确定金额差异

例如 AI 识别金额小于 Excel 金额,且差额达到阈值,这种情况不自动驳回,也不自动通过,而是发送飞书消息给财务人员,保留人工复核。

3. 单据级系统异常

例如:

下载连续失败
AI 连续返回空值
图片提取异常

这类问题会跳过当前单据,让它继续保持待审批状态,不影响后面的单据继续处理。

4. 主流程全局异常

例如初始化、浏览器或整体流程出错,此时会导出运行日志,发送告警,并写入失败日志。

这套策略背后的原则很简单:

能确定错,就自动驳回;不能确定,就交给人;系统自己不稳定,就不要擅自审批。


十三、审批反馈话术:让业务知道为什么被驳回

自动化审批不能只给一个“失败”或“驳回”,对业务来说,最重要的是知道为什么,流程里常见的审批意见包括:

经AI核查,审批通过
审批表单金额与Excel金额不一致,请检查总金额或者表格格式是否符合规范
第X行的发文数量与笔记任务量表格不匹配
第X行的总金额与明细不一致,请检查核对
AI未能够提取到支付截图,请确保图片是否嵌入到单元格内
支付截图内可能存在其他日期的截图记录

金额差异达到阈值时,不会直接驳回,而是给财务人员发送提醒,提醒内容包括:

单据编号
第几行
Excel 金额
AI 识别金额
预设阈值

这样财务人员接手时,不需要重新从头排查。


十四、数据闭环:自动化价值不只是省点击

如果只把这个项目理解成“自动点审批”,其实低估了它的价值,它真正串起来的是一条业务闭环:

飞书审批产生单据
→ 多维表形成结构化待办
→ RPA 下载并解析附件
→ AI 识别支付截图
→ 规则引擎做交叉校验
→ 异常消息推给财务
→ 审批 API 执行真实动作
→ 日志记录流程成功或失败

闭环对业务的价值主要有三点:

第一,财务不用再逐单、逐图、逐行重复核对,可以把精力放在真正异常的单据上。

第二,审批结果更可解释。每一次驳回都能说明是表单金额不一致、任务量不匹配、计价规则不符,还是截图日期异常。

第三,流程具备扩展空间。后续如果要接入更多报销类型,不一定要重写整套流程,而是可以复用“多维表待办池 + RPA 附件处理 + AI 识图 + 规则校验 + 审批 API”的框架。


十五、总结

这次项目的核心价值,不在于让 AI 直接做最终判断,而在于把 AI、RPA 和规则拆成清晰的分工。

RPA 稳定执行流程,负责取数、下载、读取、循环和调用接口。

AI 处理图片理解,把支付截图里的非结构化流水变成金额或日期异常。

规则层掌握最终裁决权,保证审批结果可解释,财务人员只处理机器不确定的异常。

这不是一次简单 OCR,也不是一个纯 RPA 点击脚本,而是一条从审批数据镜像、附件解析、视觉理解、规则校验到真实审批动作的闭环。

实际做业务自动化时,最重要的一点是:不要为了“全自动”而全自动。

真正适合生产环境的流程,应该是:

正常单据自动通过
确定性错误自动驳回
不确定风险交给人工
系统异常保留待处理

这样业务才敢用,流程也能长期维护。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐