如果 Agent 只调用一次模型,成功与失败两个状态或许已经足够。加入工具后,任务可能停在模型响应、等待授权、工具执行、结果回填等不同位置。

状态机是有限状态和合法转移组成的模型。它不负责让模型推理得更好,而是让运行时知道当前处境、下一步允许发生什么,以及中断后从哪里恢复。

一个带工具循环、校验和失败终态的 Agent 状态图

一条工具轨迹至少有这些状态

状态含义可以转向
assembling正在组装上下文model_running
model_running等待模型响应validatingcompletedfailed
validating校验工具调用authorizingfailed
authorizing判断或等待权限tool_runningdenied
tool_running工具已经开始recordingunknown
recording保存结果model_running
completed任务完成终态
failed不可继续终态或人工恢复

这里最容易遗漏的是 unknown:进程中断后,运行时不能确认外部动作是否完成。它既不是明确失败,也不能直接当作成功。

对话历史不能替代状态

对话历史可以包含“模型要求调用工具”,却不一定能证明:

  • 参数是否通过校验。
  • 用户是否已经批准。
  • 工具进程是否真正启动。
  • 外部服务是否已经接受请求。
  • 结果是否持久化。

如果只在内存中维护这些信息,CLI 退出后就会丢失。恢复时重新播放对话可能再次执行同一个工具。

状态转移要与事件写入绑定

运行时每次转移都应记录前一状态、后一状态、原因和关联标识。工具开始前先持久化 tool.started,完成后记录 tool.completed,然后再把结果回填给模型。

这仍然不能让本地日志与外部系统形成一个原子事务。原子事务指一组操作要么全部成功,要么全部失败。外部 API 往往不参与本地事务,所以有副作用的工具还需要幂等键或结果查询接口。

三个中断点能暴露不同问题

中断位置恢复时要回答的问题
模型返回前请求是否可以安全重发
工具完成前工具是否仍在运行
工具完成、结果记录前外部动作是否已经发生

第三种最危险。若把“未记录结果”理解为“未执行”,恢复后会再次产生副作用。

计划、目标和状态不是同一件事

目标描述用户希望得到什么;计划描述准备采用哪些步骤;状态描述运行时当前位于哪个可执行阶段。模型可以修改计划,却不能把 tool_running 直接改成 completed

状态转移由运行时根据事件确认。模型输出只能提出下一步候选动作。

状态机的验收方法

在每个边界强制终止进程,再从持久化记录恢复。检查:

  • 是否从合法状态继续。
  • 已完成的只读结果是否复用。
  • 未知副作用是否先查询。
  • 等待授权是否仍保持等待。
  • 终态任务是否不会再次运行。

最终回答正确只能证明某次顺利路径成立。状态机要通过的是中断路径。

版权声明: 如无特别声明,本文版权归 sshipanoo 所有,转载请注明本文链接。

(采用 CC BY-NC-SA 4.0 许可协议进行授权)

本文标题:08. Agent 为什么需要状态机

本文链接:https://www.sshipanoo.com/blog/ai/agent-runtime-lab/08-Agent为什么需要状态机/