← 全部文章

Agent 卡住了,重启为什么不一定管用?

一次部署丢掉工具响应后,Agent 可能一直等下去。重启之前,先查清操作有没有发生,以及哪条回执还没送到。

Agent 半天不回话,重启一下,是很自然的反应。但如果它等的东西已经丢了,进程重新启动,也可能只是接着等。

Every 工程师 Paridhi Agarwal 在 10 月 8 日发表的文章里提到一个具体故障:团队部署更新时,自己的服务器有时会在返回工具响应前退出。托管在 Anthropic 的 Agent 会话还活着,于是一直等。发新消息、尝试中断都没让它恢复,最后要给所有未完成请求补上响应。

这是他们对自家故障的描述,文章没有给出故障发生的确切日期。值得留意的是,服务重启和会话继续运行,在这里恰好凑成了一个死等。

它到底在等什么

自定义工具调用要经过接入方的服务执行,再把结果送回会话。执行和回传之间,多了一段可能断开的路。

Claude Managed Agents 的事件文档写得很具体:会话暂停后会列出阻塞它的事件 ID,全部处理完才恢复运行。中断请求被接口接收,也只表示进入队列;工具仍在运行时,中断可能要更久才生效。

因此,看到请求成功送达,还不能认定 Agent 已经停下。排查时得找到那次调用,看看谁负责回答、回答有没有被接收。

最麻烦的是:事情可能已经做了

假设工具负责发一条消息。消息已经发出去,服务却在回传结果前退出。从会话这边看,仍然没有结果。

这时把调用再跑一遍,可能会多发一条。换成创建工单或提交订单,重复执行的代价会更大。没有回执,只能说明当前拿不到结果,不能据此断定操作没发生。

所以恢复之前,要尽量分清三种情况:

  • 确认还没执行,可以安排执行
  • 确认已经执行,找回结果并补回响应
  • 无法确认,先查下游记录,必要时交给人处理

第三种最容易被一个“失败”状态盖过去。直接把它当失败重试,看起来恢复得很快,却可能把重复操作留给用户收拾。

给未完成的调用留个收尾办法

沿着这个故障往下想,接入层至少值得检查几件事。这些是工程上的建议,Every 的文章并没有声称他们实现了下面整套方案。

接到调用时,保存会话 ID、调用 ID 和处理状态。操作完成后,把结果存下来,再尝试回传;回传失败时,重送已有结果,避免重新做一次操作。若下游支持幂等键,让同一次业务操作在重试时沿用同一个键。

不过,把结果写进本地存储,也不能消除所有空隙。下游已经成功、本地还没记下来的瞬间,服务仍可能退出。这种情况要靠下游查询或幂等能力核对,不能只靠本地标记猜。

部署前也可以先停止接新任务,给在途调用留时间收尾。超时没完成的调用要有可接管的记录,不能随着旧进程一起消失。

下次遇到 Agent 卡住,可以先问一个更具体的问题:它正在等哪一次调用的结果?找到那条记录,再决定补回响应、重新执行,还是请人确认。重启仍然有用,只是它替不了这一步判断。