AI Agent 的取消机制:为什么停止按钮不够用

停止按钮的局限

在开发 AI Agent 时,一个常见的做法是提供一个“停止”按钮,让用户或系统可以中断正在进行的任务。但在真实场景中,这个按钮往往不够用。正如一篇技术文章所指出的,停止按钮并不是一个取消协议。

在简单的玩具级 Agent 中,“停止”可能意味着设置一个布尔值,然后等待循环退出。但在真实的 Agent 中,工作可能已经被排队、被另一个 worker 认领、正在浏览器会话中执行,或者正在等待一个外部副作用的发生。如果取消没有被表示为持久化状态,那么一次重启可能会复活操作者以为已经停止的工作。

取消契约的核心问题

文章提出了一个关键问题:不是“进程是否收到了 SIGTERM?”,而是“每一层能否证明这次运行是否可能开始新工作,进行中的工作是否必须完成,以及外部副作用如何处理?”

这意味着,取消机制需要被设计成一个契约,而不仅仅是一个按钮。这个契约需要明确:

  • 哪些工作可以被取消,哪些必须完成?
  • 取消后,已经排队或正在执行的任务如何处理?
  • 如何确保取消状态是持久的,不会因为重启而丢失?

设计更健壮的取消机制

为了应对这些挑战,文章建议将取消表示为持久化状态,而不是一个瞬时的信号。这意味着,Agent 的每个层都需要能够查询和响应取消状态,并且取消状态需要被存储,以便在重启后仍然有效。

例如,如果一个任务被取消,但它的一个子任务已经在另一个 worker 上执行,那么取消契约需要定义这个子任务是否应该被终止,或者允许它完成并记录结果。同样,如果 Agent 正在等待一个外部 API 的响应,取消契约需要定义是否应该忽略这个响应,或者如何处理它。

实际案例的启示

文章虽然没有提供具体的案例,但我们可以从常见的 Agent 架构中看到类似的问题。例如,一个自动化测试 Agent 可能启动了多个浏览器会话,如果用户点击停止,这些会话可能不会立即终止,而是继续运行直到超时。如果没有持久化的取消状态,重启 Agent 后,这些会话可能会被重新接管,导致重复操作。

另一个例子是,一个数据处理 Agent 可能已经将一批任务发送到消息队列,如果取消,这些任务可能仍然会被 worker 消费。取消契约需要定义是否应该从队列中移除这些任务,或者允许它们完成但标记为“已取消”。

结论

停止按钮只是表面上的控制,真正的取消机制需要深思熟虑的设计。将取消表示为持久化状态,并明确每一层的责任,是构建健壮 Agent 的关键。这不仅关乎用户体验,也关乎系统的可靠性和安全性。

参考来源