KEEL · 龙骨 · A CURRICULUM FOR THE AI ERA
01. Durable Execution 到底持久化什么? — keel 龙骨
普通 Agent 的“运行状态”通常是一段 Python 对象:进程还在,它就能继续;进程挂掉,系统只能重新问模型。长任务、审批、定时等待和外部副作用不能接受这种语义。
普通 Agent 的“运行状态”通常是一段 Python 对象:进程还在,它就能继续;进程挂掉,系统只能重新问模型。长任务、审批、定时等待和外部副作用不能接受这种语义。
先区分三件事
| 对象 | 内容 | 是否用于恢复 |
|---|---|---|
| Event History | run.started、tool.completed、wake.claimed 等事实事件 |
是,作为事实来源 |
| State Projection | 根据事件计算出的当前状态 | 是,可缓存但可重建 |
| Context | 本次模型调用选择的消息、工具、检索和摘要 | 只是一种运行视图 |
Context Compaction 不能替代 Event History。摘要可以丢失细节,事件历史要保留足够的事实和版本,让 reducer 能重建“运行已经做过什么”。Temporal Workflow Execution把 Event History、Commands 和 Replay 放在 durable workflow 的核心位置;LangGraph persistence也区分 thread-scoped checkpointer 与跨 thread store。
一个 Agent 运行的最小事件
run.started 用户目标、运行版本、作用域
step.requested 需要模型/工具/外部输入
tool.completed 工具真实返回,带 call_id 和 receipt
wakeup.scheduled 下一次推进的原因和时间
wakeup.claimed 哪个 worker 获得处理权
run.resumed 从事件历史继续
run.completed 终态和结果引用
模型输出不是事实事件。它最多是 decision.proposed;只有程序解析、策略通过、工具执行或外部系统确认后,才产生相应的事实事件。
Replay 的工程边界
Replay 不是把旧 prompt 再发给模型。它是用已有事件重新执行确定性的状态转换,直到得到与持久状态一致的 projection。模型调用、随机数、当前时间和外部 API 必须被 activity/adapter 隔离,否则 replay 会产生不同结果。
配套项目的 EventStore 和 RunProjector 会让你:
python courses/advanced/advanced-agent-systems/course/project/examples/01_durable_run.py
python courses/advanced/advanced-agent-systems/course/project/examples/02_replay_after_crash.py
先观察“worker 退出后重新投影”仍得到同一个 WAITING 或 COMPLETED 状态,再引入唤醒。
长期状态如何缩小
事件历史也不能无限增长。生产系统通常需要 snapshot、continue-as-new 或按版本归档,但归档必须保留重建边界和不可变事件引用。不要把“只保留最后一条摘要”当成 durable execution;那会让审计和恢复失去依据。
本章检查点
- 哪些内容是事实事件,哪些只是模型提议?
- checkpoint 丢失时能否从 event history 重建?
- context summary 被改写后,能否证明外部副作用已经发生?