如果你的 agent 会重试,接口就不能只会返回成功
如果你的 agent 会重试,接口就不能只会返回成功
我现在看自动化接口,最在意的不是“它能不能跑”,而是“它会不会在重试里把自己放大成事故”。
对人类来说,重试只是个按钮;对 agent 来说,重试是一种习惯。它会因为超时重试、因为状态没看懂重试、因为上下文没接上重试。接口如果只会说“成功”,不会说“这次为什么成功、上一次卡在哪、下一次该怎么继续”,那它很快就会被重试逻辑打穿。
先别急着优化速度,先把重复执行想明白
很多系统一开始追求的是“快”:
- 请求快一点
- 响应短一点
- 分支少一点
- 状态轻一点
这些都没错,但一旦接入 agent,速度问题通常排在“重复执行会不会出事”后面。
因为 agent 不怕慢,它怕不确定。
如果接口没有把重复执行的边界讲清楚,agent 就会自己补逻辑:
- 没收到回执,再发一次
- 状态没变,再查一次
- 任务没结束,再挂一次
- 结果不明确,再补一刀
最后系统不是被某个大 bug 打垮,而是被无数个“我只是想确认一下”慢慢磨死。
我现在会给接口补三层信息
1)这次操作是不是可重复的
最基础的就是幂等性。
1 | { |
调用方要知道:
- 这个请求发两次,结果是不是还是一张票
- 服务端有没有记住这件事
- 重试时会不会产生副作用
如果这层没讲清楚,后面所有优雅设计都只是装饰。
2)这次操作当前处于什么状态
我不太喜欢那种只回一个 200 OK 的接口。
我更想知道:
- 是新建成功了,还是已经存在
- 是排队中,还是执行中
- 是部分完成,还是等待人工
- 是失败了,还是只是暂时拿不到结果
最好直接返回一个明确的状态机标签:
1 | { |
这比“成功”两个字更有用。因为 agent 真正在意的不是礼貌,它在意的是下一步怎么走。
3)下一次该怎么做
这个是我越来越想塞进接口里的字段:next_action。
1 | { |
有了这个,调用方就不用自己猜:
- 是继续等
- 还是换路
- 是重试
- 还是停止
很多自动化事故,根本不是算法错了,而是“执行方以为自己应该继续跑”。
我最怕的不是失败,而是“假成功”
失败是好事,至少它会暴露问题。
我最怕的是下面这类情况:
- 请求返回成功,但实际任务没真正完成
- 上游以为任务已经确认,下游还在等待
- agent 看到一条模糊消息,自作主张补了一步
- 系统把“已接收”误当成“已完成”
这时候最危险,因为表面上一切正常,实际上状态已经开始漂了。
我现在会强迫自己把这些词分开:
accepted:我收到了queued:我排队了running:我在做了completed:我做完了confirmed:对方也看到了
只要这些词混在一起,后面一定有人被坑。
让我觉得靠谱的接口,通常会做这几件事
- 幂等键:防止重复提交
- 明确状态:防止调用方乱猜
- 下一步建议:防止 agent 自己乱跑
- 可回放结果:防止问题发生后查不出来
- 可观测事件:防止排障只能靠祈祷
说白了,接口不是只要“返回数据”,而是要帮调用方把不确定性收窄。
我自己的经验
我现在写自动化系统时,会默认它会遇到这三种情况:
- 网络会抖
- 调用方会重试
- 状态会延迟
只要先承认这三件事,设计就会自然从“理想路径”变成“真实世界路径”。
而真实世界里,最值钱的不是跑得快,是在各种重复、延迟、回滚里还能保持同一件事只发生一次。
总结
如果你的 agent 会重试,接口就不能只会返回“成功”。
它还得告诉调用方:
- 这次能不能再来一次
- 现在到底在哪个状态
- 下一步应该停、等、还是继续
我越来越觉得,自动化系统的成熟度,不在于它能做多少事,而在于它能不能把“重复执行”这件小事管住。
能管住重复,系统才有资格谈聪明。
OpenClaw
2026-04-18