切换主题

Agent 状态机设计:为什么复杂任务不能只靠 Prompt

Easton editorial illustration: large Agent state recorder, coral failure beacon, checkpoint rewind handle, recovery status strip
8
核心状态字段
state、event、guard、action、checkpoint、retry、compensation、terminal。
4
记录对象
state snapshot、event log、trace、audit log。
3
恢复动作
resume、retry、compensate。
数据来源: 本文工程清单基于 LangGraph、Temporal、OpenAI Agents SDK、AWS Step Functions 和 Stately 官方文档整理;API 命名和产品行为发布后仍应以官方文档为准。

"LangGraph Persistence 文档把 checkpoint 用于 thread-scoped graph state snapshot,并说明它支撑 conversation continuity、human-in-the-loop、time travel 和 fault tolerance。"

报表 Agent 在第 5 步发邮件前失败了。运维重跑任务,Agent 从第 1 步重新执行,生成了新报表,覆盖了前一次已审批版本。审批状态丢失,审批人签字的记录被新结果替换,没有任何日志能证明第一版报表经过了审批。

这不是数据库事务回滚,也不是消息队列重试。Prompt 里只剩一句”继续处理”,模型重新推理整个流程,完全不知道第 1-4 步已经产生过副作用:调用了审批接口、生成了报表、写入了临时文件。失败点在第 5 步,但副作用从第 2 步就开始了。

真正的问题不是”模型能力够不够”,而是任务进度藏在 prompt 自然语言里,根本没有可恢复的状态快照。Prompt 携带的 messages 只是模型上下文,不是执行事实。

要把这类事故修好,不能只在 prompt 里补一句”继续前先检查进度”。更稳的做法是把当前节点、已发生副作用、下一步动作和失败补偿写进可恢复的状态表。

事故关键点

报表 Agent 执行流程:

步骤操作副作用幂等性
第 1 步数据查询调用数据库,查询用户数据幂等(读操作)
第 2 步报表生成调用报表生成工具,生成 PDF不幂等(覆盖文件)
第 3 步审批等待发送审批请求,等待人工批准幂等(接口支持)
第 4 步审批通过收到 approve 事件幂等(查询状态)
第 5 步发邮件调用邮件 API,发送报表失败(超时)

失败原因:第 5 步邮件发送超时(外部 API 限流),任务被标记为 FAILED。

重跑逻辑:从 prompt 里读取”当前进度”,prompt 只有一句”审批通过,继续处理”。实际执行:重新从第 1 步开始 -> 第 2 步重新生成报表(覆盖已审批版本)-> 第 3 步再次审批 -> 第 5 步发送成功。

业务影响:已审批报表被替换,审批记录不一致;用户投诉第一次审批的报表内容和最终收到的报表内容不一致;审批流程浪费,审批了两个版本但只有一个版本真正发送。

反模式识别表

判断你的 Agent 是否命中这些反模式:

反模式表现隐患修正方案
进度写在 Prompt”当前在第 3 步” 自然语言摘要重启后丢失,无法恢复用 State 字段记录当前节点
Trace 当成 State有完整 Trace 就以为有状态Trace 不记录下一步决策State 记录下一步应该做什么
Retry 无幂等检查失败就从头重跑副作用重复执行幂等键 + 已执行检查
审批后 Resume 无检查直接继续执行未回到正确执行点checkpoint + thread_id

1. 状态机基础:State、Event、Transition、Guard、Action

状态机不是所有 Agent 的必要架构。简单客服问答用 messages 数组就够了,但复杂任务—多步骤、有审批、有外部系统调用、失败后需要恢复—必须把任务进度显式化。

1.1 核心术语定义表

状态机基础术语来自 Stately 官方文档:

术语定义Agent 示例来源
State(状态)机器所处模式,对应唯一语义意图INIT、PLAN_READY、TOOL_RUNNING、APPROVAL_PENDING、FAILED、COMPLETEDStately state machines
Event(事件)触发状态变化的外部信号timeout、approve、reject、retry、resume、task_receivedStately state machines
Transition(转移)状态之间的允许路径,确定性映射INIT -> PLAN_READY(event: task_received)Stately state machines
Guard/Condition(守卫)进入某状态的前提检查”预算充足”才能进入 TOOL_RUNNINGStately state machines
Action(动作)转移时执行的操作进入 TOOL_RUNNING 时调用工具Stately state machines
Checkpoint(快照)状态快照,用于恢复LangGraph checkpointer 保存 graph stateLangGraph Persistence

确定性原则:同一 State + Event 组合应指向唯一下一状态,避免歧义。有限状态集:状态机不是无限流程图,而是有限可达状态 + 明确转移规则。

1.2 Trace vs State vs Audit 对照表

Trace、Audit Log、State Snapshot 解决三个不同问题:

概念解决什么问题是否是业务状态是否决定下一步Agent 示例
Trace(追踪)观测与诊断骨架不是不决定OpenAI Agents SDK trace(workflow_name、trace_id)
Audit Log(审计日志)合规记录,审计追溯不是不决定权限模型的审计字段(actor、traceId、action、result)
State Snapshot(状态快照)决定下一步的当前状态决定LangGraph checkpoint(当前节点、已执行步骤、下一步应该做什么)

核心区分:Trace 帮助观测”发生了什么”,但不是业务状态本身。Audit Log 记录合规历史,用于审计追溯。State Snapshot 决定”下一步应该做什么”,是恢复的核心依据。三者不能互相替代:有 Trace 不等于有 State;有 Audit 不等于可恢复。

2. LangGraph 如何做状态持久化

Checkpoint 不是 prompt 里的自然语言摘要,而是可恢复、可检查、可回放的状态快照。LangGraph persistence 文档把 checkpoint 定义为 graph state snapshot,包含完整状态和下一步待执行节点。

2.1 Checkpointer 与 Thread State

核心机制(来源:LangGraph Persistence 官方文档):

  • Checkpointer:保存 thread-scoped 状态快照(graph state snapshot)
  • Store:保存跨线程长期数据(application-defined store)
  • Thread_id:恢复具体线程状态的唯一入口
  • 四类用途:conversation continuity、human-in-the-loop、time travel、fault tolerance

LangGraph persistence 把短期 thread-scoped 状态交给 checkpointers,把跨线程长期数据交给 stores。Checkpoint 包括 state snapshot 和 application-defined store。Thread_id 是恢复入口,相同 thread_id 可以从暂停点继续。

LangGraph checkpoint 包含 graph state、下一步待执行节点列表、checkpoint_id、时间戳、版本号。敏感数据不进 checkpoint:某些 graph state 字段可能包含敏感信息,需要显式配置不保存。

2.2 Interrupts 与恢复机制

核心机制(来源:LangGraph Interrupts 官方文档):

  • interrupt():在图节点内动态暂停执行,保存 graph state,等待外部输入
  • 恢复方式:使用同一个 thread_id 和 Command(resume=…)
  • 常见模式:审批、review/edit、tool call review、human input validation
  • 幂等副作用警告:interrupt 前的副作用必须是幂等的,因为恢复时节点会从调用 interrupt 的节点开头重新执行

审批暂停必须是状态机的一种暂停状态,而不是让模型”记得等人批准”。恢复需要同一个 thread cursor。

恢复时使用同一个 thread_id 和 Command(resume=…)。幂等副作用是恢复的前提条件:如果审批前有副作用(如调用外部 API),必须确保幂等,否则恢复时节点重新执行会重复调用 API。

3. 工程类比:Temporal Durable Execution

长任务可靠性不是新问题。Temporal durable execution 提供了成熟范式对照。

3.1 Durable Execution 定义

核心概念(来源:Temporal Durable Execution 官方文档):

  • Durable Execution 定义:workflow execution 在失败、崩溃或服务中断时仍能保留 state/progress
  • Event History:记录每一步状态,失败后可从最后记录事件恢复
  • 三特性:Resumable(可恢复)、Recoverable(可恢复执行)、Reactive(可响应)

长任务可靠性来自 event history 和可恢复执行,而不是单次进程内存或 prompt 上下文。Agent 状态机需要类似机制:checkpoint/event log + 业务状态,而不是只靠模型重新推理。

Temporal 的 Event History 和 LangGraph 的 checkpoint 概念相似:记录执行历史,支持从失败点恢复。区别在于 Temporal 是完整的 workflow 引擎,LangGraph 是 Agent 状态管理框架。Agent 开发者可以从 Temporal 的设计中学到:durable execution 需要结构化状态历史,而不是依赖进程内存或模型上下文。

4. 状态表设计模板:可复制的 Agent State Table

状态机概念抽象,落地需要具体状态模型。以下提供三套模板:状态表、事件表、事故驱动状态表实例。

4.1 状态表模板(可执行步骤块)

模板结构:

State(状态)Event(触发事件)Guard(守卫条件)Action(必须动作)Next(下一状态)
INITtask_received初始化上下文、记录开始时间PLAN_READY
PLAN_READYplan_generatedplan_valid生成执行计划、记录工具序列TOOL_RUNNING
TOOL_RUNNINGtool_completedbudget_sufficient调用工具、记录结果、更新预算APPROVAL_PENDING 或 COMPLETED
APPROVAL_PENDINGapproveapproval_required发送审批请求、记录审批人COMPLETED
APPROVAL_PENDINGreject记录拒绝原因、通知用户FAILED
FAILEDretryretry_count < max检查幂等、回退到上一个 checkpointTOOL_RUNNING 或 APPROVAL_PENDING
COMPLETED记录完成时间、清理资源Terminal

模板说明:State 列定义所有可达状态(INIT、PLAN_READY、TOOL_RUNNING、APPROVAL_PENDING、FAILED、COMPLETED)。Event 列定义触发转移的事件(task_received、approve、reject、retry)。Guard 列定义进入某状态的前提检查(budget_sufficient、retry_count < max)。Action 列定义转移时的必须动作(调用工具、记录结果、发送审批)。Next 列定义下一状态(确定性转移)。

4.2 事件表模板(补充状态表)

模板结构:

Event(事件名称)触发条件前置状态要求后置状态是否产生副作用
task_received用户提交任务INITPLAN_READY不产生
plan_generatedLLM 生成了执行计划PLAN_READYTOOL_RUNNING不产生
tool_completed工具执行完成TOOL_RUNNINGAPPROVAL_PENDING 或 COMPLETED产生(调用外部 API)
approve审批人批准APPROVAL_PENDINGCOMPLETED产生(发邮件、扣预算)
reject审批人拒绝APPROVAL_PENDINGFAILED不产生
retry失败重试请求FAILEDTOOL_RUNNING 或 APPROVAL_PENDING需幂等检查
timeout执行超时TOOL_RUNNINGFAILED不产生

事件表说明:前置状态要求明确事件只能在哪些状态上触发。是否产生副作用标记哪些事件需要幂等或补偿。

4.3 事故驱动状态表实例(从报表覆盖事故推导)

完整示例:报表 Agent 状态表(从事故开场推导)

StateEventGuardActionNext幂等/补偿检查
INITtask_received初始化 thread_id、记录开始时间QUERY_RUNNING不需要
QUERY_RUNNINGquery_completed查询数据、保存结果到 stateREPORT_GENERATING不需要
REPORT_GENERATINGreport_generated生成报表、保存报表 ID 到 stateAPPROVAL_PENDING幂等检查:如果报表已存在,跳过生成
APPROVAL_PENDINGapprove记录审批人、审批时间EMAIL_SENDING不需要
APPROVAL_PENDINGreject记录拒绝原因FAILED不需要
EMAIL_SENDINGemail_sent发送邮件、记录邮件 IDCOMPLETED幂等检查:如果邮件已发送,跳过
EMAIL_SENDINGtimeoutretry_count < 3记录失败、检查幂等EMAIL_SENDING(重试)或 FAILED幂等键:email_id + thread_id
FAILEDretryretry_count < max检查幂等、从上一个 checkpoint 恢复QUERY_RUNNING 或 REPORT_GENERATING 或 EMAIL_SENDING根据 checkpoint 决定恢复点
COMPLETED记录完成时间、清理资源Terminal不需要

事故复盘修正:第 5 步失败(EMAIL_SENDING -> timeout)-> 应从 EMAIL_SENDING 恢复,而不是从 QUERY_RUNNING 恢复。需要 checkpoint 记录当前节点(EMAIL_SENDING)、已执行步骤(QUERY、REPORT_GENERATED、APPROVAL_APPROVED)、下一步应该做什么(EMAIL_SENDING)。幂等检查:报表生成、邮件发送需要幂等键,避免重复执行。

5. 幂等与补偿:恢复不只是 checkpoint

有 checkpoint 不等于能安全恢复所有副作用。恢复还需要幂等性、事务、补偿和外部系统状态检查。

5.1 幂等与补偿概念

定义:

  • 幂等(Idempotent):多次执行结果相同,不会重复产生副作用
  • 补偿(Compensation):撤销已发生副作用,恢复到一致状态
  • 事务回滚:原子性操作,失败时自动回滚
  • 外部系统状态检查:恢复前检查外部系统状态,避免重复操作

状态一致性三支柱:幂等性标识(action_id + schema_hash)、状态快照链(snapshot + prev_hash + delta)、补偿动作注册(undo_op)。

5.2 幂等与补偿判断清单

判断哪些操作需要幂等、哪些需要补偿:

操作类型是否需要幂等是否需要补偿幂等键设计补偿方案
数据查询(无副作用)不需要不需要--
报表生成(覆盖文件)需要需要report_id + thread_id删除旧报表、恢复审批版本
邮件发送(外部 API)需要困难email_id + thread_id发送撤销邮件(部分场景)
扣减库存(数据库)需要需要inventory_id + order_id增加库存(补偿扣减)
创建工单(外部系统)需要需要ticket_id + thread_id关闭工单(补偿创建)
扣减预算(内部状态)需要需要budget_id + thread_id增加预算(补偿扣减)
发送审批请求(无副作用)不需要不需要--

判断逻辑:是否产生外部副作用决定是否需要幂等。可撤销的操作需要补偿。跨系统调用时幂等键应包含外部系统标识。原子操作可以事务回滚。

恢复不只是 checkpoint,还需要幂等、事务、补偿和外部系统状态检查。有 checkpoint 就能安全恢复所有副作用的说法不准确。

6. Agent 任务状态清单:可恢复 vs 不可恢复

不是所有 checkpoint 都能恢复。Terminal state 是 workflow execution 的终止状态:完成、失败、超时、取消。Terminal state 无法恢复,只能重新执行或补偿。

6.1 状态分类表

状态类型是否可恢复恢复条件恢复方式示例
Failed(失败)可恢复retry_count < max从上一个 checkpoint 恢复工具调用超时
Retry(重试)可恢复幂等检查通过从失败节点重新执行邮件发送失败
Compensation(补偿)部分可恢复补偿方案存在执行 undo_op扣减库存失败
Approval Pause(审批暂停)可恢复approve/reject 事件Command(resume=…)审批等待
Terminal(终态)不可恢复无恢复路径COMPLETED、FAILED(retry_count = max)

状态清单说明:Failed 状态可通过 retry 恢复(如果 retry_count < max)。Retry 状态需要幂等检查,从失败节点重新执行。Compensation 状态部分可恢复(如果补偿方案存在)。Approval Pause 状态可恢复(通过 approve/reject 事件)。Terminal State 终态不可恢复(COMPLETED 或 FAILED 达到最大重试次数)。

7. 下一步延伸阅读

状态机设计只是起点。状态建模需要结合具体业务场景,不同的任务有不同的状态粒度和恢复策略。

系列上下游导航

文章关系链接
Human-in-the-loop Agent 设计:哪些步骤必须人工审批审批暂停细节/blog/zh/posts/ai/20260707-human-in-the-loop-agent-approval-design/
Agent 成本控制:模型路由、工具预算与失败重试怎么设计预算、重试策略/blog/zh/posts/ai/20260707-agent-cost-control-model-routing-tool-budget-cache-retry/
LangGraph 状态管理实战:2026年 Agent 架构最佳实践LangGraph 状态管理/blog/zh/posts/ai/20260424-langgraph-agent-architecture/
AI Agent 监控告警与失败恢复:从日志到状态机的设计实践监控、恢复/blog/zh/posts/ai/20260527-ai-agent-monitoring-recovery/
LangGraph vs AutoGen 状态追踪框架对比/blog/zh/posts/ai/20260526-langgraph-autogen-state-tracking/
Agent 评测数据集与回归测试:如何避免”改一处坏全局”评测、回归测试预告,同系列下一篇

外部参考资料

高置信度来源:

来源置信度主题链接
LangGraph Persistence 官方文档highCheckpointer、Store、Thread State、Checkpointhttps://docs.langchain.com/oss/python/langgraph/persistence
LangGraph Interrupts 官方文档highinterrupt()、Command(resume=…)、thread_idhttps://docs.langchain.com/oss/python/langgraph/interrupts
Temporal Durable Execution 官方文档highEvent History、Durable Execution、Resumable/Recoverablehttps://docs.temporal.io/temporal
OpenAI Agents SDK Tracing 官方文档highTrace、Span、workflow_name、trace_idhttps://openai.github.io/openai-agents-python/tracing/
AWS Step Functions State Machines 官方文档highState Machine、Flow State、Task State、StartAt、Nexthttps://docs.aws.amazon.com/step-functions/latest/dg/concepts-statemachines.html
Stately: State machines and statechartsmediumState、Event、Transition、Guard、Action、Hierarchyhttps://stately.ai/docs/state-machines-and-statecharts

状态机不是所有 Agent 的必要架构,但复杂任务必须显式化。下一步不是引入更多框架,而是根据业务场景设计合适的 State、Event、Transition、Guard、Action,把任务进度从 prompt 自然语言搬到结构化状态。

设计复杂 Agent 的状态机

把复杂 Agent 任务拆成显式 state、event、guard、action、checkpoint、retry、compensation 和 terminal state,避免把任务进度只藏在 prompt 里。

⏱️ 预计耗时: 45 分钟

  1. 1

    步骤 1: 列出风险点

    列出任务的外部副作用、人工暂停点、失败点和终止条件。
  2. 2

    步骤 2: 定义最小状态集

    定义 pending、running、waiting_approval、retrying、compensating、succeeded、failed、cancelled 等最小 state 集合。
  3. 3

    步骤 3: 绑定事件和下一状态

    为每个 state 写清允许接收的 event,以及 event 后的 next state。
  4. 4

    步骤 4: 补上守卫条件

    为危险 transition 添加 guard,包括权限、预算、审批、幂等键和外部资源状态。
  5. 5

    步骤 5: 隔离工具动作

    把工具调用放到 action 层,并记录 input 摘要、output 摘要、traceId 和副作用结果。
  6. 6

    步骤 6: 定义失败策略

    为失败定义 retry policy、terminal state 和 compensation policy。
  7. 7

    步骤 7: 保存恢复依据

    为恢复定义 checkpoint 或 event log,并把 prompt 只当作临时上下文,不当作唯一事实源。

常见问题

执行到第 5 步失败,重跑从第 1 步还是从 checkpoint 继续?
取决于副作用是否幂等、checkpoint 是否足够。无副作用任务可以从头重跑;有副作用且幂等时应从 checkpoint 继续;有副作用但不幂等时先补偿,再恢复;没有 checkpoint 时只能从头重跑,并承担重复副作用风险。
任务状态存 prompt、数据库、LangGraph checkpoint 还是队列 job?
简单任务可以把 prompt 当临时上下文;复杂任务需要 checkpoint 或 event log 加业务状态;生产级 Agent 通常用 LangGraph checkpoint 保存 thread state,用业务数据库保存订单、审批、权限和计费事实。队列 job 适合异步调度,但仍需要额外状态管理。
状态机和 workflow/流程图有什么区别?
状态机强调有限可达状态、确定性转移、守卫条件和 action;workflow 更强调执行步骤序列。Agent 需要状态机核心概念,但不一定需要完整 statechart 的层级和并发能力。
审批后怎么保证 Agent 回到同一个执行点?
使用同一个 thread_id 和 checkpoint 恢复,例如 LangGraph Interrupts 文档中的 Command(resume=...) 模式。checkpoint 要记录当前节点、已执行步骤和下一步动作,并确保 interrupt 前的副作用具备幂等性。
retry 和 compensation 写在 prompt 还是状态转移规则?
写在服务端状态转移规则里,而不是 prompt。retry_count、max retry、幂等键、undo_op 和 terminal state 都应可测试、可审计、可恢复;prompt 只适合参与判断,不适合作为可靠性规则的唯一载体。
简单客服 Agent 是否需要状态机?
单轮 FAQ 问答通常不需要重型状态机;一旦客服 Agent 涉及订单查询、创建工单、退款审批、支付或外部 API,就需要显式状态、checkpoint、幂等和补偿。

14 分钟阅读 · 发布于: 2026年9月17日

当前属于系列阅读第 22 / 22 篇

AI Agent 工程化专题:架构、工具调用、评估与恢复

如果你是从搜索进入这篇文章,建议顺手补上上一篇或继续下一篇,这样更容易把同一主题读完整。

查看系列总览

相关文章

BetterLink

想持续收到这个主题的更新?

你可以直接关注作者更新、订阅 RSS,或者继续沿着系列入口往下读,避免下次又回到搜索结果重新找。

关注公众号

评论

使用 GitHub 账号登录后即可评论

Easton BlogEaston Blog