ai / 20260727
08. Agent 为什么需要状态机
对话记录描述模型看过什么,状态机描述运行时已经做到了哪一步
如果 Agent 只调用一次模型,成功与失败两个状态或许已经足够。加入工具后,任务可能停在模型响应、等待授权、工具执行、结果回填等不同位置。
状态机是有限状态和合法转移组成的模型。它不负责让模型推理得更好,而是让运行时知道当前处境、下一步允许发生什么,以及中断后从哪里恢复。
一条工具轨迹至少有这些状态
| 状态 | 含义 | 可以转向 |
|---|---|---|
assembling | 正在组装上下文 | model_running |
model_running | 等待模型响应 | validating、completed、failed |
validating | 校验工具调用 | authorizing、failed |
authorizing | 判断或等待权限 | tool_running、denied |
tool_running | 工具已经开始 | recording、unknown |
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为什么需要状态机/