代理交易超时后,先对账再决定重试
文章指出交易请求超时只代表结果未知,不能据此判定失败并直接重试。建议分离编排器、持久化交易账本和对账引擎,保留交易标识,通过状态查询或幂等键确认结果。
AI 深度解读
AI Agent 发起转账后,支付服务商已经处理,系统却迟迟收不到回执。此时一次超时,可能把自动重试变成重复扣款。作者的核心主张是:超时只能证明没有及时收到结果,不能证明交易失败。
这篇短文讨论的是架构边界,没有给出实现代码或实测数据。它值得程序员读的地方,在于指出了一条自动化边界:Agent 可以决定发起什么操作,但资金执行需要确定的规则、持久化状态,以及能在进程重启后继续工作的恢复机制。
超时之后,交易应该进入什么状态
作者描述的流程很常见:Agent 请求转账,编排器校验请求并选择服务商,服务商完成处理,但响应丢失或延迟,最终编排器超时。
问题出在最后一步。如果系统把超时直接记成失败,再执行一次,就可能产生两笔真实交易。
超时后的正确结论是「结果未知」,而不是「执行失败」。
作者建议把这种不确定性显式记录为 OUTCOME_UNKNOWN。它不能只是日志里的一条报错,而应当成为后续执行必须检查的交易状态。
接下来的动作也不是立即重试,而是保留原交易身份,使用已有的交易引用或幂等键查询服务商,再根据核实结果决定是否允许执行。幂等键的作用,是让服务商识别多个请求是否属于同一次操作;但原文没有说明任何服务商的具体支持方式,不能据此假设传了一个键就绝对安全。
这套流程的重点,是先查清上一笔发生了什么,再决定下一步。
为什么编排器不能独自保管交易历史
作者把系统分成三个职责:
- 编排器负责协调执行、应用策略和发起操作。
- 交易账本负责持久保存交易身份、执行状态和已确认结果。
- 对账引擎负责调查未解决的操作,确认真实结果。
这里的对账(Reconciliation),可以理解为拿本地记录与服务商记录逐笔核实,补齐尚未确认的结果。
拆分的理由是恢复能力。编排器可能崩溃、重启,交易结果却不能跟着进程内存一起消失。即使最初发起请求的进程已经退出,系统也应该知道还有哪笔交易需要核查。
并发还会放大风险:多个 worker 可能同时发现一笔未解决交易,又同时尝试重试。因此,作者提出需要原子状态转换和持久化执行认领。前者防止多个执行者同时把状态改成可执行,后者记录谁已经取得本次执行资格。
不过,作者没有提供状态机、数据库设计或认领失效后的处理方案。这些是架构要求,还不是一份可以直接照搬的实现。
我的判断
我赞同作者把资金执行约束放在 Agent 决策之外。模型可以提出操作,是否允许执行、是否允许再次执行,应当由明确的状态和规则控制。让 Agent 根据一次超时自行判断「再试一下」,缺少可核查的依据。
与直接自动重试相比,这套思路更重视避免重复交易;与关闭所有重试相比,它又保留了通过对账恢复流程的可能。但作者没有给出对照数据,也没有展示实际运行结果,因此不能据此判断恢复速度、吞吐或维护成本。
文章最难的部分,作者也仍以问题形式提出:未解决状态是否全部归账本管理?重试资格由谁控制?服务商既没有可靠幂等能力,也不能查询交易状态时怎么办?账本暂时不可用时,可用性与资金安全如何取舍?
这套方案成立的关键前提,是系统有办法找回交易的真实结果。
如果这个前提不成立,单独增加一个 OUTCOME_UNKNOWN 状态,只能让系统诚实地记录不确定性,不能自动消除风险。原文没有给出这种情况下的最终处理规则,落地团队仍需补齐。
能拿来做什么
- 如果你用 Node 编写 Agent 工具或转账编排服务,先检查异常处理:不要让请求超时直接触发重新转账,应当先持久化结果未知状态,再进入核查流程。
- 把交易身份保存在持久化记录中,并让后续查询与恢复沿用它。排查进程重启后,是否仍能定位原请求和服务商侧记录。
- 多个 worker 共同处理交易时,把执行资格检查做成原子操作,并保存认领记录,避免每个 worker 都独立判断「可以重试」。
- 接入资金服务商前,确认其幂等和状态查询能力;对能力缺失、账本不可用这两类情况,提前写清暂停执行与后续处理规则。