AI Agent 为什么会重复执行任务?怎样避免重复发消息、建工单和写数据?
AI Agent 重复执行任务,常见起点是“动作已经生效,调用方却没有拿到明确回执”。网络超时、进程重启、用户重复点击或任务恢复,都可能再次触发同一工具。处理这类问题需要稳定的业务操作编号、写入端查重、可查询的执行状态和明确的重试规则。
ZGI 提供 Agent、Workflow、Tools 与可自托管的运行环境,可用于把一次业务动作拆成可检查的步骤,并保留审批与运行边界。防重复的约束仍要落在真正产生副作用的接口和数据库中。提示词里写一句“不要重复执行”,挡不住超时后的再次调用。
重复经常发生在回执不确定时
发送消息的接口返回超时,消息可能已经送达,只是响应没有回来;创建工单的节点重启后恢复,系统可能重新执行已经完成的步骤;两个定时任务同时领取同一条数据,也会各自发起一次写入。
模型还会带来另一种重复。工具描述相近、成功条件含糊,或执行结果没有进入下一轮上下文时,Agent 可能认为任务尚未完成,再次调用同一个工具。这里需要工具选择测试和终止条件,但它们无法替代写入端的程序约束。
可以把工具按副作用分成三类:
|
类型 |
例子 |
重复处理 |
|---|---|---|
|
读取 |
查询订单、读取文档 |
通常允许限次重试 |
|
可幂等写入 |
按固定主键更新状态 |
使用同一操作编号重试 |
|
容易重复产生副作用的动作 |
发消息、扣款、追加记录 |
先查结果,无法确认时转人工 |
给一次业务动作分配固定身份
任务第一次准备写入外部系统时,先生成业务操作编号。后续自动重试、人工重试和任务恢复继续使用同一个编号。编号需要关联调用人、目标对象、关键参数、当前状态和外部结果标识。

概念示意图:首次请求通过查重闸门执行,携带相同任务编号的后续请求直接读取已有结果。
接收端收到请求后,先检查这个编号。还要防止并发请求同时穿过查重环节,具体可结合事务、唯一约束或下游接口提供的幂等能力处理;已经成功时,返回之前的结果;仍在处理中时,返回可查询状态。相同编号携带不同关键参数,需要拒绝执行并报告参数冲突。
只给参数做哈希并不总能代表同一业务意图。两次内容相同的通知,可能确实需要分别发送。由调用方生成操作编号,可以明确表达“这是上一次的重试”还是“一次新的任务”。
重试前先确认错误类型
参数错误、权限不足和业务规则冲突,继续重试通常不会改变结果。限流、短暂网络故障和服务端临时错误,可以在次数上限内退避重试。超时处在两者之间,程序先用业务操作编号查询结果,再决定继续等待、补发请求或交给人工。
任务状态至少要区分“准备执行、处理中、成功、明确失败、结果未知”。“结果未知”不能直接改成失败,因为外部动作可能已经完成。把它单独留下,才能安排对账任务去查询消息 ID、工单号或写入记录。
在 ZGI 中,可以用 Workflow 安排确认、工具调用和结果核对,并让高风险动作经过审批。工具适配层负责传递同一个业务操作编号,下游接口或数据库负责查重。这样的分工能把 Agent 的动态判断留在运行链路里,同时让写入结果受到确定性规则约束。
上线前做五类故障测试
对同一任务连续提交两次,确认只生成一条业务记录;让工具完成写入后丢失响应,再触发恢复;在节点执行后重启进程;让相同编号携带不同参数;人工点击重试并核对返回结果。每次测试都要检查 Agent 运行记录和下游业务数据,页面显示“成功”还不够。
能查到操作编号、每次尝试和最终业务结果后,重复执行才有清楚的处理入口。遇到无法确认的结果时,可以先停下来核对,再决定是否重试。
GitHub:https://github.com/zgiai/zgi
Gitee:https://gitee.com/zgiai/zgi
更多推荐



所有评论(0)