在智能体系统里,补偿事务指的是一种「往前走、不行就反向退」的回滚安排:一段自动化流程跑到中途失败时,系统不做整体撤销,而是按事先设计好的反向操作,把已完成的步骤逐一退回,让业务状态尽量回到起点附近。像扣子这类编排平台在串联多个系统时,这个设计几乎绕不开。
生活化类比是网购后取消订单:下单后商家扣了库存、发了券,此时取消并不是把数据库倒回昨天,而是补回库存、作废优惠券、原路退款。这个类比失效的地方在于:智能体流程里每一步反向操作本身也可能失败,并发场景下退回动作还会波及其他任务,所以补偿逻辑必须把「退的时候出岔子」提前想进去。
回滚发生在哪一步
拆开看一次完整补偿:流程先按既定路径推进,每完成一步就把「已做动作加对应反向操作」压进一条执行记录;某一步失败后,编排器停止前进,从记录里按后进后出的次序弹出反向操作逐个执行。进来的是失败信号与执行记录,中间发生的是逐条调用反向接口,出去的是一份回滚报告,写明哪些退干净了、哪些还挂着。
顺序为什么不能乱
补偿必须逆序执行。先做的动作往往被后面的步骤依赖:先创建的文档被后续步骤改写过,如果按正序先「还原创建」,会留下一个改了一半的残件;逆序则保证依赖新状态的动作先被撤掉,老状态才安全。编排平台之所以完整保留每一步的先后关系,就是为这一刻准备的。
补偿和撤销有什么不同
撤销假设整个系统能瞬间回到某个时间点,像数据库事务那样;补偿不指望这种全局能力,只要求每一步都配了对称的退法。现实里大量外部系统没有整体快照,调用过的第三方接口、发出去的消息、写过的文件,都只能靠再调一次对方的反向接口来退。分支设计也会影响补偿范围:条件越多,走到半途的路径越多,要准备反向操作的地方就越多,判定细节可看这篇工作流的分支条件是怎么定的?机制细节全梳理。
撤销和补偿摆在一起,差别集中在四件事上。
| 维度 | 撤销(整体回滚) | 补偿(反向操作) |
|---|---|---|
| 前提假设 | 系统能瞬间回到某个时间点 | 每一步都配了对称的退法 |
| 依赖什么 | 数据库事务那类全局能力 | 再调一次对方的反向接口 |
| 执行次序 | 回到时间点,不逐步执行 | 逆序执行,后进后出 |
| 失败风险 | 一次到位 | 反向操作本身也可能失败,要重试且幂等 |
| 外部系统 | 大量外部系统没有整体快照 | 接口、消息、文件都能逐个退 |
失败到一半该怎么办
反向操作自己也可能失败,比如网络抖动让退库存的请求没送达。工程做法是给每条反向操作配重试,并让它本身幂等——重复执行也不多退一次,原理见幂等是靠什么实现的?幂等键,每一步都讲透。补偿产出的回滚报告也要过一道格式检查,防止坏数据混进日志,做法参考输出校验是怎么防乱格式的?从原理到落地。若补偿持续失败,就冻结现场转人工,同时靠长时任务看哪些监控指标?内部门道在这里的指标及时告警。
补偿事务速查表
- 每步成功后立刻登记对应的反向操作
- 失败时按后进后出的次序执行补偿
- 反向操作要可重试、幂等
- 补偿持续失败就冻结转人工并告警
一句话记住:先想好怎么退,再决定怎么走。
顺带一提,在腾讯元宝里创建的智能体同样遵循这套思路:动作越重,越要先备好退路。把「失败后能否退干净」也设计成评测用例,纳入Agent 评测是怎么打分的?完成率,回滚才算完整,而不是只测顺利路径。下次设计流程时,先问自己一句:每一步退得回去吗?
还有一种情况值得单独提醒:有些动作天生不可逆,比如已经发出的通知。这类步骤在设计时就该放在流程最后,或改成草稿态等确认后再发,从源头减少需要补偿的地方。
关于补偿事务的三个常问问题
- 为什么不用数据库事务直接回滚?:它面对的常是控制不了的外部系统,对方没提供整体回滚能力,只能按接口逐个退。
- 反向操作由谁来写?:通常由封装工具的一方一并实现,有创建就该有删除,有写入就该有还原。
- 补偿执行期间新任务能进来吗?:一般先把相关资源加锁或打标记,避免新旧操作交叉,退干净再放行。


