ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

从三单匹配到防重复付款:AP Agent在Grix中的落地全记录

从三单匹配到防重复付款:AP Agent在Grix中的落地全记录 先打个预防针这篇不是讲理论是我自己把一个应付账款场景拆开、揉碎、再在 Grix 里孵化成 Agent 的全过程记录。如果你正在做财务自动化、Agent 项目或者被“三单匹配”“防重复付款”这种事反复折磨这篇文章应该能给你省下不少弯路。主人公是这个应付账款代理AP Agent)。核心任务两件事——把采购订单、入库单、供应商发票这三张单据自动对上以及在付款前拦截掉任何可能重复付款的情况。传统的做法是靠财务人员手工比对单量一上来人眼直接不够用用自动化脚本又扛不住供应商数据格式五花八门。所以我把这个活儿交给了 Agent它能读数据、能调用系统接口、能判断异常还能在发现问题时把流程转给真人处理。整个过程我在 Grix 里完成前后踩了不少坑也沉淀了一些可以复用的方法。这个项目适合谁参考一类是被“单据量大、人手不足、供应商对账扯皮”逼疯的财务或运营同学另一类是正在学 Agent 开发的研发同学——虽然你未必做财务场景但“Agent 怎么对接业务规则、怎么做状态机、怎么防重复执行”这套思路是通用的。下面我把整个孵化过程讲透明包括业务规则怎么拆、Agent 流程怎么搭、防重闭环怎么落地、以及我实际遇到的坑。1. 项目背景与问题定义1.1 三单匹配到底卡在哪先交代业务背景。三单匹配Three-Way Match是应付账款里最经典的一道关卡。所谓三单就是采购订单PO、入库单/收货单GRN、供应商发票Invoice这三张单据。正常情况下业务流程是先下采购订单然后仓库收货生成入库单最后供应商送来发票财务拿着发票去对前面的订单和入库单。听起来很简单但实际操作中全是问题。我接手这个需求的时候公司的财务团队每月要处理几千张发票每个发票都要人工核对“订单号是否存在”“数量有没有超收”“单价和订单价是否一致”还要排查这张发票是不是之前已经付过了。光是核对这一步三个人全职做月底还要加班。更麻烦的是供应商开票格式不统一有的发票号带前缀有的不带日期格式五花八门金额有的含税有的不含税——这些噪声一多人工核对就容易漏。我当时的判断是这个场景非常适合用 Agent 来做而不是写死脚本。原因是业务规则虽然清晰但数据的形态和异常情况太灵活。规则引擎能处理“订单金额等于发票金额”这种精确判断但处理不了“金额差几分钱但可能是税率尾差”“订单号对不上但收货单和发票能对应上”这种模糊场景。Agent 的好处是既能按规则查数据也能综合上下文做判断拿不准的时候还能跳到人工处理流程。1.2 防重复付款为什么是“老大难”如果说三单匹配是效率问题那防重复付款就是风险问题。财务上一张发票被重复支付轻则追款扯皮重则直接影响现金流甚至涉及合规审计。重复付款的情况比想象中常见得多。最常见的几种同一个供应商开了两张票号相同的发票财务第一次没看清第二次又录入了一遍。供应商把同一笔业务拆成两张开票因为“系统里订单号填错了”导致两笔都走了不同订单但实际上是同一笔货。付款审批流里单据先提交到一半被驳回重新提交后流程又走了一遍系统没有做幂等控制。月末集中付款时出纳从系统导出数据和另一张手工表格重复导出了同一批单据。这些坑在做系统对接前特别难防。人眼核对几百行数据第一眼和第二眼的标准很容易不一致。所以防重复付款不能靠“审核仔细一点”必须靠系统级别的闭环同一个发票进入系统后无论从哪个入口进来都能识别出“这东西之前见过”然后把后续动作拦下来。这也是我在 Grix 里设计 Agent 时最重视的一环。1.3 为什么选择 Grix 来孵化这个 Agent坦白说最初也考虑过直接用 Python 写个定时任务或者用 RPA 模拟人点系统。但评估后发现两条路都不够理想。传统 Python 脚本的问题是逻辑可以写得很严谨但数据源一变、字段一调整就要改代码而且异常场景多了之后脚本会变成一堆 if-else维护成本很高。RPA 的问题更明显它模拟的是人的操作路径一旦页面改版或者响应变慢流程就卡死。它本质上还是“固定流程的执行器”不是“能理解和处理业务对象”的智能体。Grix 吸引我的点在于它把 Agent 的“感知-决策-行动”串成了一个可视化流程。我可以在里面创建多个子 Agent分别负责数据清洗、匹配判断、异常分析、记录留痕然后通过工作流把它们编排在一起。它还支持连接外部数据库和 API这对对接 ERP、财务系统非常关键。说白了我要的不是“一段自动化程序”而是一个“能理解业务、能调用工具、能处理异常、还能在关键节点叫人来审核”的数字员工。这个定位正好是 Agent 的强项。2. 三单匹配业务规则梳理与匹配逻辑设计2.1 先把匹配要素拆成最小单元在任何 Agent 项目里第一步都不是写代码或搭流程而是把业务规则整理成机器能理解的结构。我和财务团队开了三次会把三单匹配的规则拆成了下面这张表比对维度采购订单PO入库单GRN发票Invoice匹配标准单据编号PO-2025-00123GRN-2025-00234INV-2025-00123三者通过业务关联字段关联供应商供应商编码A001供应商编码A001供应商编码A001完全一致物料/服务编码物料编码M10001物料编码M10001物料编码M10001完全一致数量采购数量 100实收数量 95开票数量 95开票数量 ≤ 实收数量 ≤ 采购数量单价合同单价 10.00—开票单价 10.00单价误差 ≤ 1%容差金额订单金额 1000.00—含税金额 1085.00金额需按税率换算后匹配税率13%—13%完全一致付款条件月结30天—月结30天付款条件一致这里面的核心原则是数量只允许“超收不放行”金额允许“小额容差”。也就是说你买了 100 个收了 95 个发票开了 95 个这没问题但如果你只买了 100 个仓库收了 110 个这种超收必须拦截——要么补采购流程要么手工确认。金额上则要容忍税差和四舍五入造成的几分钱差异不能动不动就把单据拦下来。2.2 匹配规则要分层不能一把梭梳理完要素之后我设计了三个层级的匹配逻辑第一层是硬校验主要是单据关联关系。一张发票必须能找到对应的采购订单和入库单这三者的业务关联字段要能串起来。串不上的直接进异常池不允许往下走。第二层是数据一致性校验包括供应商、物料、税率这些主数据字段。这一层最简单直接不同字段不一致就说明数据链路有问题。第三层是容差校验主要是单价和金额。这里我给了一个 1% 的单价浮动阈值和绝对值 0.99 元的金额尾差阈值。之所以设置这个阈值是因为日常业务中确实存在汇率波动、供应商四舍五入、税收尾差等情况。这个阈值不是拍脑袋定的而是我统计了过去三个月财务手工处理时能接受的最大差异范围。这三层校验直接决定了 Agent 的决策分支通过就往下走不通过就判断是哪种不通过是数据录入错了还是业务本身有异常然后分流到不同的人工处理队列。2.3 异常单据要分成“可自动修复”和“必须人工介入”一个很关键的设计理念是Agent 不应该只能识别异常还应该能处理一部分异常。比如“订单号填错但其他信息都能对上”这种情况完全可以由 Agent 根据收货单反查真实订单号做一次自动修正而不是直接把单据打回给财务。我在 Agent 里设计了一个异常分级机制P0 级发票找不到任何关联单据或者供应商完全不一致。这种直接挂起转人工。P1 级核心字段不匹配但通过搜索能唯一确定对应订单。这种先自动尝试修复修复成功后仍需保留日志供人工复核。P2 级金额差异在容差范围内。自动通过但在审批流里做标记事后抽检。这套分级机制上线后效果很明显大约 20% 的异常单能被 Agent 自动修复只有真正棘手的才需要人工介入。财务同事的工作量立刻从“逐单核对”变成了“只处理 Agent 解决不了的疑难杂症”。3. 在 Grix 中孵化应付账款代理的完整实操3.1 Agent 角色与职责拆分在 Grix 里创建 Agent 时我没有上来就搞一个“全知全能”的大 Agent而是按职责拆成了四个子 Agent再用一个总控 Agent 编排它们。数据接入 Agent负责从 ERP 系统、财务数据库、Excel 导入表中读取原始单据数据做字段标准化比如统一日期格式、补全供应商编码、清洗发票号。匹配判断 Agent负责执行上面说的三层匹配逻辑输出每张发票的匹配状态、差异明细、置信度。异常处理 Agent接收匹配判断 Agent 输出的异常单按 P0/P1/P2 分级处理能自动修复的修复修复不了的生成给人工的处理建议。防重校验 Agent独立于匹配流程运行对所有进入付款池的单据做重复性校验一旦发现重复立即锁定并通知。这四个子 Agent 各干各的通过标准化的数据结构对接互不干扰。这样做的最大好处是单独升级某一个 Agent 的逻辑不影响整个流程。比如后来我发现数据接入 Agent 的清洗规则不够好只需要改它一个其他三个不用动。3.2 数据接入与字段标准化数据接入是整个项目里最脏最累的活但也是决定成败的一步。供应商发来的发票 Excel 格式千奇百怪有的列名叫“发票号码”有的叫“Invoice No.”有的甚至叫“号码”日期有的填 2025/3/1有的填 2025-03-01还有的填 03/01/2025。我在 Grix 里给数据接入 Agent 配置了一套标准化规则读取文件时先做“列名识别”建立一个同义词映射表把“发票号码”“Invoice No.”“发票号”全部映射到标准字段 invoice_no。统一日期格式为 YYYY-MM-DD处理不了的标记为“格式异常”不丢数据。金额统一转为 Decimal 类型避免浮点数精度问题。这一步看似基础但很关键——用 float 处理金额九成会在某个边界值上出问题。发票号统一去除空格和特殊符号保留字母数字。因为很多供应商喜欢在发票号里加横杠或点复制粘贴的时候特别容易引入不可见字符。这里要特别提醒一句清洗逻辑里千万不要在原始数据上直接修改务必保留一份“原始快照”。后面出了问题你能拿着快照去对比是 Agent 洗错了还是源数据本身有错。3.3 核心匹配流程的 Grix 编排在 Grix 里我通过可视化编排把上述逻辑串了起来。完整流程大致是总控 Agent 收到任务触发信号定时触发或消息触发后唤醒数据接入 Agent。数据接入 Agent 拉取指定时间范围内的 PO、GRN、Invoice 数据标准化后写入中间表。匹配判断 Agent 依次执行三层校验。每一条校验结果都记录到“匹配明细表”包括匹配项、期望值、实际值、是否通过、差异原因。匹配状态为“全部通过”的单据流转到防重校验 Agent 做重复性检查。有异常的进入异常处理 Agent进行分级修复或人工队列分发。最终所有单据的状态聚合输出为“通过”“挂起”“转人工”三类并由总控 Agent 生成一份日报。第 3 步是最核心的。我在 Grix 里为匹配判断 Agent 配置了三个工具一个是查 PO 数据的接口一个是查入库单的接口一个是查历史发票的接口。Agent 拿到发票后会先解析发票上的采购订单号去 PO 接口验证再拿 PO 号去入库单接口查收货记录最后拿供应商和开票日期去历史发票库查重。这个过程里我刻意没有让 Agent 一次性把所有数据全 load 进上下文而是每一次只取最小必要信息。比如匹配下单号就只查一个单号字段比金额就只取金额相关字段。这样既省 Token也能减少 Agent 因上下文过大而产生的“幻觉”——它看到的数据越少越不容易自己编造不存在的关联关系。3.4 防重指纹与状态锁设计防重复付款不能只靠“查一遍”必须在设计上确保同一笔业务无法在系统里被处理两次。我借鉴了程序开发里的“幂等”思路给每张发票算了一个防重指纹。防重指纹由这几个字段拼接后做哈希得到供应商编码、发票号、开票日期、含税总金额。把这四个字段拼成一个字符串比如A001|INV-2025-00123|2025-03-01|1085.00然后做 MD5。理论上同一张发票无论从哪个渠道进来生成的指纹都一样。有了指纹之后防重校验 Agent 的检查逻辑就变得非常清晰在数据接入阶段算指纹在付款审批前再查一次“这个指纹是否已存在”如果存在直接锁定单据不允许进入下一步。同时我把指纹还做成了数据库表的唯一索引这样就等于上了双保险——即使 Agent 逻辑出现 bug 漏判了数据库层面也会拒绝重复插入。这里有个细节指纹字段不能只用发票号。因为有些供应商会重复使用发票号但开票日期、金额不同反过来有些供应商同一张发票开两版金额一样但日期不同。四字段组合能最大程度降低碰撞概率。实际项目中我遇到过一次两个供应商都叫“XX贸易”但编码不同光用名称做指纹差点撞了换成编码后问题解决。4. 防重复付款闭环的落地细节4.1 防重校验要嵌进付款的每一个入口很多人会以为防重复付款就是在付款前查一次有没有重复。实际上远远不够。重复单据可能从不同入口进来而且每个入口的处理状态不同——有的在草稿箱、有的在审批中、有的已完成付款。如果只在最后一个环节拦截前面已经错误创建的多张单据会造成各种脏数据甚至可能绕过拦截。我在 Grix 的流程里把防重校验做成了三个触点第一个触点在数据接入时。发票一进来就计算指纹然后和历史记录比对。如果发现历史库里已经有相同指纹且状态为“已支付”这张发票直接进黑名单连匹配都不用做。第二个触点在匹配完成后。这时候 Agent 已经对发票做了完整的业务校验再次检查指纹防止同一批次数据里出现重复导入。第三个触点在付款指令发出前。确认单据状态是“待付款”且指纹唯一才能生成付款请求。三触点设计下来基本能做到“想重也重不了”。因为每一层都有一把锁单点失效不至于全线崩溃。4.2 审批流与状态机的联动防重不能只靠 Agent 自己判断要跟业务系统的状态机联动。我把单据状态定义为待匹配、匹配中、匹配完成、待付款、付款中、已付款、已驳回、已挂起。每个状态之间的流转都要经过 Agent 校验不允许跳状态。比如“待付款”状态只能由“匹配完成”状态流转而来且流转时强制做防重校验。“已付款”状态一旦写入该单据的指纹在所有后续校验中直接命中。这套状态机的思路实质上是把 Agent 的“判断”变成了业务流程里的“硬约束”——不管 Agent 下次怎么想状态机都不允许它把一张已付款的单据再送回付款队列。在 Grix 里我通过一个全局状态表来维护所有单据的当前状态每个子 Agent 在操作前都先查询状态确认前序步骤已完成才继续。曾经有一次异常处理 Agent 因为编排问题重复执行了修复操作但状态机在入口处挡住了第二次执行避免了误修复。4.3 与网银/ERP 执行层的安全接口约定防重复付款的闭环最后一步是付款指令。如果只是 Agent 内部判断没有重复但实际操作时还是把付款文件发给了银行那前面的功夫就白费了。所以我在 Agent 和付款执行系统之间强制加了一层“唯一批次号”校验每一批付款指令生成时都带一个 UUID执行系统收到指令后先检查这个批次号是否处理过处理过就直接返回“重复批次已拒绝”。这个完全参考了接口幂等的设计思想。可能有人觉得一个内部系统没必要这么谨慎但实际项目中我见过太多因为接口重试导致重复付款的案例。尤其是网络超时后程序自动重发如果接口没有幂等机制同一笔付款可能被发两次。这个教训是用钱买来的。所以无论你是对接 ERP 还是直连网银幂等校验真的不能省。Grix 本身支持配置 API 调用规则我在付款指令这个节点上配置了“失败自动重试但重试使用相同批次号”的机制而不是每次生成新批次号。这个细节很简单但对账的时候能救命。5. 踩坑实录与排查技巧5.1 数据源字段不一致同一个供应商三种叫法第一个大坑出现在数据源字段匹配上。我们的 ERP 系统里供应商叫“供应商编码”采购系统里叫“vendor_code”而供应商传来的发票 Excel 里叫“Vendor ID”。三个系统三种叫法数据接入 Agent 差点全认成不同的字段。这个问题靠配置同义词映射表解决。我把所有字段名汇总建立了一张映射表把同语义字段归并到标准字段。也因为这个教训我后来在项目里强制规定所有子 Agent 之间传递的数据都用标准字典不允许直接使用源系统的原始字段名。这样各系统之间哪怕字段命名天差地别在 Agent 内部也是统一的。5.2 金额容差踩雷汇率尾差导致误拦截上线第一周防重和匹配 Agent 都误拦了一批正常单据。排查发现是金额容差的阈值设置不合理。当时我设的金额差异阈值是 0.01 元但实际业务里供应商开票时由于汇率换算产生的尾差最高能到 0.5 元。0.01 的阈值意味着供应商只要凑整差了几分钱单据就会被拦下来。后来我把金额容差调整成分层的单价差异允许 1%整单金额差异允许绝对值不超过 0.99 元。同时加了“容差通过需记录原因”的审计日志。这样既不会放过真正的大额差异也不会让小额尾差卡住流程。这里有句心得容差阈值一定来源于业务真实数据不要靠猜。最好先跑一段时间的“影子模式”让 Agent 在后台计算匹配结果但不影响业务然后拿着结果数据和财务人工结果对比根据差异分布来设定阈值。5.3 Agent 幻觉把不存在的入库单“脑补”出来这个坑最有意思也最值得所有做 Agent 的人警惕。在测试阶段匹配判断 Agent 在处理一张订单号不匹配的发票时居然自己“脑补”出了一个入库单号然后判定匹配通过。后来查日志发现原因是它在查询入库单接口时接口返回了空结果但 Agent 在生成回复时受到了上下文里其他单号的影响虚构了一个看似合理的编号。这个问题非常隐蔽因为结果看起来“合理”但数据完全没有依据。我后来加了一道硬性校验Agent 查询结果如果为空必须显式返回“未找到”并且把查询条件原样记录到日志。任何“推断出的单号”都不允许写入业务字段。此外我对 Agent 的每个决策都要求输出置信度置信度低于 0.95 的一律转人工复核。这套机制后来成了我所有 Agent 项目的标配。5.4 常见问题速查表现象可能原因排查方法解决方案发票重复标记指纹字段选择不合理碰撞率过高检查指纹命中明细确认重复单据是否真实重复增加指纹字段维度比如加上“供应商税号”匹配通过但付款被拦防重 Agent 与状态机数据不同步检查状态表中“待付款”是否重复写入对关键状态加唯一索引防止并发写自动修复错误订单Agent 在查询结果为空时虚构关联查看日志中查询条件与返回结果显式返回“未找到”置信度低于阈值转人工金额明明不一致却通过容差配置过宽检查容差参数是否是全局覆盖了分层规则按校验层级独立配置容差数据源字段错乱同名字段在不同系统中含义不同检查标准化映射表是否匹配了错误字段重新梳理字段词典建立源字段快照定时任务重复执行触发机制没有做任务幂等检查任务执行记录中同批次是否运行多次任务ID唯一约束重复触发直接跳过6. 上线效果与后续扩展项目上线两个月后我拉了一组数据对比。此前的数据是三张单据靠人工核对每月几千张发票三个人做满工作量匹配准确率大概在 97% 左右但月底总有几个对不上账的疑难杂症要花一两天专门处理。现在 Agent 跑下来全自动处理的占比大约在 78%剩下 22% 因为各种原因是 Agent 主动转人工的——这个比例完全符合设计预期我们没有追求 100% 自动化因为有些业务异常按公司制度本来就要求人工介入。更关键的指标是防重复付款。上线两个月Agent 拦截了 7 起可能的重复付款每一笔都对应真实的重复发票或重复审批流。这些案例放在以前很可能就在月底大批量付款时漏掉了。因为 Agent 会在每个触点做防重校验只要有一个指纹碰撞就会停下来所以财务同事现在最常说的一句话是“有 Agent 在月底终于不用提心吊胆了”。在 Grix 里维护这套东西的体验也不错。业务规则变了直接在匹配判断 Agent 的配置里改规则参数就行供应商 Excel 格式变了给数据接入 Agent 加一条清洗规则即可。整个过程不需要改一行代码也不需要停机发布。对一个长期演进的业务系统来说这是最舒服的状态。后续想扩展的方向一个是把发票验真也并进来对接税务系统的发票查验接口这样 Agent 能在三单匹配之前先确认发票真实有效另一个是加一个对账 Agent让它把已付款数据从网银导出来和应付账款台账做自动对账进一步把“付款后”的流程也闭环起来。这些方向都在 Grix 里试了思路和这次做 AP Agent 类似先定业务规则再拆 Agent 职责最后编排校验逻辑。最后分享一个我自己的体会做 Agent 项目最忌讳一上来就动手搭流程。先把业务规则吃透把边界条件列全想清楚哪些交给规则、哪些交给模型判断、哪些必须转人工这三类分清楚了后面的路会顺很多。如果业务本身都想不明白再强的 Agent 也填不了逻辑的坑。
返回列表