跳转到内容

Agent Runtime:状态图、检查点与幂等

审批请求已经发出,进程却在远端提交成功、本地 checkpoint 落盘前中断。重启后到底该重试、查询,还是等人工?这不是模型推理题,而是 Runtime 的状态语义。

Agent 在演示中跑 30 秒,在真实流程中可能等待人工数小时、跨服务失败、协议更新或工具限流。如果所有状态只在模型上下文里,进程一重启就丢失;如果盲目重跑,又可能重复产生副作用。

ReAct 展示 reasoning/action 循环,适合解释 Agent 基本机制。S29 生产系统进一步把循环变成显式图。LangGraph 的官方定位包括有状态、长运行工作流、durable execution、人审和 memory。S23 关键不是采用某框架名称,而是把状态、转移、检查点和中断语义写成代码。

状态包含 task id、输入版本、当前节点、Evidence refs、预算、已执行 tool calls、审批、错误和输出。节点必须声明:纯计算还是有副作用、超时、重试策略、幂等键和补偿动作。

检查点在重要状态转移后持久化。恢复时比较输入/工具/模型版本:如果不兼容则迁移或从安全节点重跑,不能悄悄用新模型续旧轨迹。外部写操作用 idempotency key,状态先标 pending,执行器确认后标 committed;超时不能简单等同失败,因为远端可能已成功。

循环必须有预算:最大步骤、工具调用、token、时间和成本;超限进入 needs_review,而不是继续自我反思。

方案 适合 风险
while-loop Agent 原型、短任务 状态隐式、难恢复
LangGraph 显式状态、检查点、人审 S23 仍需自己定义幂等和医疗合同
工作流引擎 + Agent node 强 SLA/长流程 集成和心智成本高
事件溯源 审计/重放 PHI、存储和 schema 演进压力

先让失败在 checkpoint 前发生,检查恢复是否重复提交

Section titled “先让失败在 checkpoint 前发生,检查恢复是否重复提交”
Terminal window
python3 labs/run_lab.py --lab 18

实验运行一个 5 节点状态机,在第三节点故意失败,序列化 checkpoint 后恢复;同一幂等键的提交动作只计一次。输出包含恢复前后事件。读输出时只问两件事:恢复是否从可解释的节点继续,以及提交 ledger 是否仍只有一条,不要只看程序最终退出为 0。

贯穿实例:一次跨小时的人审任务

Section titled “贯穿实例:一次跨小时的人审任务”

协调员发起筛选后,runtime 保存 TaskCreated 与输入 snapshot。协议、FHIR 和影像节点并行构建 Evidence;Eligibility 生成草案;Safety Verifier 发现一条协议歧义,状态进入 waiting_for_protocol_review。数小时后审核者在工作台补充解释,runtime 从 checkpoint 继续,而不是重跑所有工具。

恢复前先执行 compatibility check:协议仍是相同冻结版本,patient authorization 未过期,工具 manifest 与 policy 可读,模型 route 是否允许续跑。如果授权过期,任务保持暂停;如果协议已更新,旧任务可按旧版继续或由人决定重新评估,不能自动换版。

把消息列表当全部 state 是常见错误。推荐显式字段:task/context/version、current node、protocol/patient snapshot、evidence refs、criterion progress、pending approvals、tool call ledger、budget、errors、outputs。聊天消息只是可选展示,不是唯一事实。大对象存引用,避免 checkpoint 膨胀和 PHI 扩散。

状态更新采用小 patch 或 reducer;并行 worker 只能 append 自己的 Evidence,不能覆盖其他 worker。merge 检测 id/hash 冲突。每个 node 输入输出有 schema version,便于局部重放。

纯节点根据输入计算输出,可安全重试;读节点访问外部系统,需 patient scope、timeout、分页和 snapshot;写节点有副作用,必须审批和幂等;human node 持久中断。节点不要隐藏多个不可观测动作,否则 checkpoint 只能停在大黑盒前后。

retry 只针对可重试错误:网络超时、429、某些 5xx;schema/权限/医学歧义不应自动反复。退避、最大次数和 deadline 写进 manifest。错误分类决定 retry、fallback、human review 或 terminal fail。

调用写工具超时,远端可能已经提交。runtime 不能看到超时就再发一个新请求。写请求携带稳定 idempotency key,远端支持时返回同一结果;不支持时用业务唯一键、outbox/inbox 和对账。exactly once 是端到端设计成果,而非消息队列开关。

MedAgent Forge 默认没有 EHR 正式写工具,内部工作单草稿仍需要幂等。key 可由 task + action + target + input hash 构成;输入变化则产生新版本,不覆盖旧草稿。审批绑定具体 diff,批准后 arguments 被修改需重新审批。

checkpoint 优化恢复,audit event 优化追溯。checkpoint 可压缩或淘汰,audit 依据保留政策不可变。二者都不存无必要的长思维链/原始 PHI;使用 Evidence refs、hash 和结构化决策。OpenTelemetry trace 关联 task/step/tool,但受采样和脱敏策略管理。S27

LangGraph 提供 checkpointer、interrupt 等机制,S23 仍需团队定义 transaction boundary、幂等、版本兼容和数据保留。框架恢复到某节点,不知道该节点是否已在外部系统产生效果。每个 side-effect node 要写 crash matrix:调用前崩溃、远端成功响应前崩溃、checkpoint 前崩溃如何处理。

预算是 state:每次 model/tool 扣 token、调用、时间和估算成本。循环检测可用重复 state/action hash;达到阈值进入 review,并输出已尝试路径。禁止 Agent 用“再思考一次”无限延长。对并行 worker 分配子预算,orchestrator 不可透支总预算。

在每个 node 前后注入 crash;模拟 429、超时、半成功、重复回调、乱序消息、过期 approval、schema 升级和 worker 并发。验证最终状态、外部副作用数量和审计完整。实验章只演示本地文件 checkpoint;完整实现需数据库和真实 adapter 故障注入。

状态更新与 outbox event 在同一事务提交,worker 成功消费后记录 inbox/dedupe;外部调用不能与本地数据库形成真正原子事务,因此依赖幂等和对账。锁策略尽量短,长模型调用不占数据库锁。任务领取用 lease/heartbeat,worker 崩溃后 lease 到期可恢复,仍检查 side effect ledger。

interrupt 生成 approval/review request,包含输入 hash、可选动作、过期和所需角色。重复打开不生成新请求;批准后 command 校验版本并唤醒任务。任务被取消或协议过期时,请求失效,晚到审批不能复活旧 action。

状态 schema、node graph 和工具都会升级。部署前用历史 checkpoint 做 read/migrate/replay 测试;破坏性 graph 变更允许旧任务在旧 worker drain,或显式迁移到安全节点。绝不让新代码把未知字段丢掉后继续。

把实验的失败点移动到“远端提交成功、本地 checkpoint 前”,说明为何本地 committed set 不足;设计远端 idempotency/查询确认。再让 approval 在恢复期间过期,预期应暂停重新授权,而不是沿旧 state 自动执行。

外部 API 只提交 command(创建、取消、批准),不允许客户端任意覆盖 state;读取返回按角色裁剪的 projection。worker 通过内部队列领取 node,所有状态转移由 runtime 验证 expected version。这样前端、模型和 tool 都不能跳过 verify/human gate。

取消也是状态机:停止新节点、传播 cancellation、等待/标记在途 tool、对账副作用、写终态。强杀进程不是取消语义。任务过期、患者授权撤回或协议撤回可以触发同一安全取消流程。

运维能按 task id 查看节点/错误/预算而不打开 PHI;可以重试被分类为 retryable 的节点、暂停 route/tool、批量 drain 旧 graph。任何人工“修状态”走审计 command,不直接改数据库。运行时健康看卡住时长、重试、orphan、checkpoint lag 和 policy denial。

保存 checkpoint 不等于拥有正确恢复策略。每个外部副作用都要能解释“请求是否已到远端”和“下一步为何不是盲目重试”。

  • checkpoint 只保证保存,不保证状态语义正确。
  • exactly-once 通常是业务协议,不是网络天然保证;需要幂等和对账。
  • 保存完整 prompt/response 可能泄露 PHI,应记录最小必要字段或受控引用。
  • 框架 upgrade 后历史 checkpoint 是否可读必须专门测试。

以下参考资料分别用于理解循环的起点、状态图能力和遥测边界。它们不替项目决定幂等键、数据保留或人工审批语义。

  • S29 ReAct:回看 reasoning 和 action 交替的历史脉络,理解为何生产运行时还要补状态。
  • S23 LangGraph:查看有状态图、检查点和中断机制的官方能力边界。
  • S27 OpenTelemetry:设计最小必要 trace、metrics 和 logs 时的规范入口。