Agent 状态机与终止条件

一、状态机与终止条件是最能区分工程深度的话题

很多校招生在 Agent 面试里会把注意力集中在 prompt、规划和工具上,但真正懂工程的面试官通常还会问一个看似不起眼、实则非常关键的问题:你的 agent 怎么知道什么时候该停?任务中断后怎么恢复?为什么它不会死循环?\
这就是状态机与终止条件。

从系统视角看,一个 agent 只要进入多步运行,就不再是一次函数调用,而是一个持续演化的状态系统。只要是状态系统,就必然有:

  • 当前处于什么阶段;
  • 下一步允许去哪里;
  • 哪些条件下停止;
  • 出错后如何回退或挂起;
  • 被人工中断后怎样恢复;
  • 失败和成功如何判定。

如果这些东西不显式建模,系统初期可能还能跑 demo,但一旦接入真实工具、异步任务、审批流、长任务和多 agent,很快就会出现下面这些问题:

  • 在两个工具之间反复跳;
  • 因一次暂时失败而无休止重试;
  • 中途崩掉后无法从上一步继续;
  • 人类审批后不知道恢复到哪一步;
  • 完成标准模糊,明明该停了却还在探索;
  • 状态混乱,日志里看不出任务到底发生了什么。

所以这道题真正考的是:你能不能把 agent 当成一个可控的运行系统而不是一个会自己想的 prompt。

二、为什么 Agent 一定要有显式状态

1. 多步任务天然有阶段

例如一个企业知识 agent 可能经历:

  • 初始化;
  • 澄清需求;
  • 规划;
  • 检索;
  • 工具执行;
  • 验证;
  • 等待审批;
  • 汇总输出;
  • 结束。

如果没有显式状态,系统就很难判断当前应该做什么、能做什么、不能做什么。

2. 状态决定可恢复性

当一个长任务执行到一半失败,如果你不知道已经完成了哪些步骤、哪些产物已经落库、哪些审批已通过,就无法安全恢复。

3. 状态是治理的抓手

权限、预算、超时、审批、人工介入、日志审计,都需要以状态为依附。\
例如等待审批状态就天然意味着不能继续自动执行高风险动作。

4. 状态是防循环和防越界的重要手段

系统不能只靠模型自己判断该停了。\
程序层必须有明确边界:某些状态下只允许某些动作,某些条件下必须终止或升级。

三、什么是 Agent 状态机

一个简洁但很有力的定义是:\
Agent 状态机就是把 agent 运行过程表示为一组离散状态以及状态之间在特定条件下的转移规则。

这不是说 agent 要做成非常僵硬的传统有限状态机,而是说:\
即使内部某些步骤由模型自由决策,系统外层仍应有明确的阶段与转移控制。\
这就是局部自治,外层受控。

典型状态示例

  • INIT:初始化与鉴权;
  • CLARIFYING:向用户补充询问;
  • PLANNING:生成或更新计划;
  • EXECUTING:调用工具或执行子任务;
  • WAITING_HUMAN:等待审批或输入;
  • VERIFYING:检查结果与约束;
  • REPLANNING:原路径失效后的重规划;
  • COMPLETED:成功结束;
  • FAILED:失败终止;
  • CANCELLED:被用户或系统取消;
  • TIMEOUT:超时收束。

这些状态不一定每个系统都要有,但你最好能说明:状态是服务于控制目标的,不是为了画图好看。

四、终止条件为什么不能只写max_steps

很多初学者会说给个最大步数就好了。当然最大步数是必要的,但远远不够。\
因为真正健康的 agent 终止条件应该是多维的

1. 成功终止

最理想的终止条件是任务已经满足成功标准。\
例如:

  • 所需字段已全部收集;
  • 验证器确认答案完整;
  • 高风险动作已审批并成功执行;
  • 结果已落库并通知成功。

2. 失败终止

当任务已不可继续推进,应明确失败。\
例如:

  • 必要资源不可用;
  • 权限不足且无法升级;
  • 多次修复无效;
  • 输入本身不合法。

3. 预算终止

包括最大步数、时间预算、token 预算、费用预算。\
这些都是防止无限探索和资源失控的硬边界。

4. 风险终止

当系统判断继续执行风险过高,如证据冲突、工具异常、副作用动作缺审批、越权可能性存在时,应停止或升级给人类。

5. 人工终止

用户取消、审批驳回、管理员中断。\
这类终止必须是一级公民,而不是靠把一段话放进上下文让模型自己理解。

6. 无进展终止

如果连续若干步没有实质进展,例如重复查询、重复失败、重复在同一页面兜圈子,也应停止或重规划。\
这是防循环的关键。

五、如何定义完成:这是面试里的隐藏难点

很多 agent 死循环,不是因为工具有 bug,而是因为完成这个概念没有被定义清楚。\
例如让 agent 帮我调研一下,如果没有明确:

  • 调研哪些维度;
  • 需要多少个来源;
  • 结果输出到什么粒度;
  • 是否必须交叉验证;\
    那系统就很难知道什么时候算够了。

所以一个成熟设计会在任务入口就定义 success criteria,例如:

  • 至少 3 个可信来源;
  • 覆盖价格、功能、市场定位三类字段;
  • 输出一份表格和一段总结;
  • 若有冲突信息必须标记不确定。

面试时非常加分的一句话是:\
终止条件的前提是成功标准显式化,否则 agent 只会不断探索而不知道何时足够。

六、状态机设计中的几个关键实践

1. 状态与动作解耦

状态表示系统此刻处在哪个阶段,动作表示当前阶段可以采取什么操作。\
不要把状态和动作混成一锅,否则图会非常乱。

2. 状态转移最好显式化

即使内部由模型决定某些分支,最终也最好映射到显式事件,例如:

  • tool_call_succeeded
  • tool_call_failed
  • approval_granted
  • approval_rejected
  • budget_exceeded
  • goal_satisfied\
    这样才能做可靠控制和回放。

3. 给每个状态定义不变量

例如:

  • WAITING_HUMAN 状态下,不允许继续执行高风险动作;
  • COMPLETED 状态下,只允许查询日志,不允许修改结果;
  • FAILED 状态下,如果要重试,必须经过新事件触发。\
    不变量是治理层的重要抓手。

4. 保存检查点

在状态迁移关键点保存检查点,尤其是:

  • 规划完成后;
  • 高风险动作前后;
  • 审批前后;
  • 阶段产物落库后。\
    这样系统崩溃或被中断后才能恢复。

5. 支持挂起与恢复

长任务、异步任务、人类审批,都意味着不是一路跑到结束。\
状态机必须支持挂起,并在恢复时知道从哪里继续。

七、如何防止 Agent 死循环

这是非常高频的工程追问,必须答透。

1. 最大步数只是底线,不是全部

必须有,但不能只依赖它。

2. 检测重复动作

如果连续出现相同工具、相似参数、相同失败结果,要触发去重或升级。

3. 跟踪进展指标

例如:

  • 新获取了多少有效证据;
  • 是否推进了任务图;
  • 是否减少了不确定性;
  • 是否完成了新的子任务。\
    如果若干轮都没有进展,就停止或 replanning。

4. 摘要失败历史

让模型显式知道已经尝试过什么,为什么无效,可以减少重复犯错。

5. 引入 verifier

由规则或第二模型判断:当前是否应该结束、重试、换路、还是交给人。

6. 对高风险动作引入审批或 dry-run

这能避免 agent 因为不确定而反复尝试真实动作。

八、异步任务、长任务与 Durable Execution

很多真实任务不是秒级完成的,例如长时间网页操作、数据管道、审批流等待、批量测试。\
这时状态机必须和 durable execution 结合。

1. 什么是 durable execution

可以理解为:任务在中断、进程重启、等待外部事件后,仍能从保存的状态继续执行,而不是从头开始。

2. 为什么需要它

  • 等待人类审批;
  • 等待外部系统回调;
  • 长耗时工具运行;
  • 服务重启或容器迁移;
  • 需要跨天执行。

3. 需要保存什么

  • 当前状态;
  • 历史事件;
  • 中间产物引用;
  • 已执行副作用动作记录;
  • 预算消耗;
  • 待恢复入口。

4. 恢复时要防什么

最重要的是防止副作用重复执行。\
如果一个邮件已经发出,恢复时不能再发一次;\
如果一个工单已经创建,也不能因为状态丢失再创建一遍。\
所以 durable execution 必须和幂等机制结合。

九、状态机与 Human-in-the-Loop 的关系

这是很强的结合点。\
HITL 本质上会引入一个非常重要的状态:WAITING_HUMAN。\
它说明系统当前不能继续自动推进,而必须等待某个事件。\
审批通过会触发恢复,驳回会触发取消或重规划,编辑会触发状态更新后继续。\
所以你可以说:\
没有状态机,HITL 很容易沦为前端弹个框;有了状态机,HITL 才能成为 runtime 的一等机制。

十、Mermaid 图:状态机与终止路径

stateDiagram-v2
    [*] --> INIT
    INIT --> CLARIFYING: 信息不足
    INIT --> PLANNING: 信息充分
    CLARIFYING --> PLANNING: 补充完成
    PLANNING --> EXECUTING: 计划通过
    EXECUTING --> VERIFYING: 步骤完成
    VERIFYING --> EXECUTING: 仍需下一步
    VERIFYING --> WAITING_HUMAN: 命中审批点
    WAITING_HUMAN --> EXECUTING: 审批通过/编辑后恢复
    WAITING_HUMAN --> REPLANNING: 审批驳回但允许重做
    EXECUTING --> REPLANNING: 路径失效/无进展
    REPLANNING --> EXECUTING: 新计划生成
    VERIFYING --> COMPLETED: 达成成功条件
    EXECUTING --> FAILED: 不可恢复错误
    EXECUTING --> TIMEOUT: 超时/预算耗尽
    WAITING_HUMAN --> CANCELLED: 用户取消
    FAILED --> [*]
    COMPLETED --> [*]
    TIMEOUT --> [*]
    CANCELLED --> [*]

十一、高频面试题与参考回答

题 1:为什么 Agent 需要状态机?

参考回答:\
因为多步运行意味着系统有阶段、有转移、有暂停与恢复需求。状态机能把这些阶段和允许的转移显式化,从而支持控制、治理、恢复和调试。

题 2:终止条件只设置 max_steps 够吗?

参考回答:\
不够。还需要成功判定、失败判定、预算限制、风险终止、人工终止和无进展终止等多维条件。

题 3:如何定义任务完成?

参考回答:\
要在任务入口显式定义 success criteria,例如覆盖范围、最少证据数、结果格式、校验要求,而不是让模型自己猜什么时候算够。

题 4:Agent 为什么会死循环?

参考回答:\
常见原因包括完成标准不清、缺乏进展感知、重复工具调用、错误历史没有被总结、没有无进展终止和重规划机制。

题 5:如何防止死循环?

参考回答:\
最大步数、时间和费用预算只是底线;还要检测重复动作、跟踪进展、总结失败历史、加入 verifier,并在必要时重规划或升级人工。

题 6:状态机和工具调用有什么关系?

参考回答:\
状态机决定在什么状态下允许什么工具动作,以及动作成功或失败后状态如何转移。工具调用不是散点事件,而应纳入状态演化框架。

题 7:什么是 durable execution?

参考回答:\
是在长任务、中断、等待审批或系统重启后,能基于持久化状态从正确位置继续执行的能力,而不是从头重跑。

题 8:恢复执行时最容易出什么问题?

参考回答:\
副作用动作重复执行,所以必须结合检查点、幂等键和已执行动作日志。

题 9:Human-in-the-Loop 为什么需要状态机支持?

参考回答:\
因为审批意味着系统进入等待状态,审批结果会触发恢复、回退或取消。没有状态机就很难可靠处理中断和恢复。

题 10:一句话总结你对状态机与终止条件的理解?

参考回答:\
它们是把 agent 从会跑的 demo变成可控的生产系统的关键基础设施。

十二、面试速记版

  • Agent 一旦多步运行,就必须显式管理状态。
  • 状态机解决阶段、转移、挂起、恢复、治理和回放问题。
  • 终止条件应是多维的,不只是 max_steps。
  • 成功标准不清是死循环的重要根源。
  • Durable execution 让长任务和审批流可恢复。
  • 状态机是 HITL、重试、回滚、审批和幂等的共同基础。
  • 这是区分会写 prompt和懂系统工程的关键题。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐