Skip to content
预计 1 分钟右侧目录可快速定位

昨天保存的 Run,今天的新代码还能恢复吗:State Schema Versioning 与 Migration ​

前置:哪些信息能用于恢复:Memory、RAG、Event Log 与 Crash Recovery
核心问题:昨天按旧 schema 保存的 Run,今天用新代码恢复时怎样识别版本、迁移状态并拒绝不兼容数据?

一个常被忽略的长任务故障 ​

周五晚上 Run 在这里暂停:

json
{
  "schema_version": 3,
  "status": "WAITING_APPROVAL",
  "tool_call": {"name": "deploy", "args": {"env": "prod"}}
}

周一服务升级后,deploy Tool 的参数变成:

text
environment + region + change_ticket

如果新代码直接把旧 checkpoint deserialize 后继续,风险比“读取失败”更大:它可能成功读取,但用新的语义解释旧状态。

所以 durable execution 必须同时回答:状态保存了什么版本?当前 Runtime 是否有资格继续它?

区分四种 Version ​

不要只放一个模糊的 version:

text
state_schema_version   → Run/Node/Checkpoint 数据结构
plan_schema_version    → StructuredPlan / Graph contract
tool_schema_version    → 已批准/待执行 Tool 参数契约
runtime_build/version  → 解释这些状态的代码版本

RunManifest 记录“当时运行了什么”;state/event schema version 负责“今天还能不能正确读”。两者用途不同。

Resume 前做 Compatibility Check ​

恢复入口不要直接:

python
state = StateVCurrent(**json.loads(raw))
run(state)

而应该先经过:

text
load raw checkpoint
→ inspect schema/version + manifest
→ compatible? direct decode
→ migratable? upcast/migrate
→ incompatible? reject / fork / manual intervention
→ revalidate pending external actions
→ resume

特别是 pending approval/tool call:用户批准的是旧参数。即使状态结构可以迁移,也不能擅自把旧 approval 映射成一个语义更宽的新 Tool 调用。

Snapshot Migration 与 Event Upcasting ​

Snapshot / Checkpoint ​

可以把 v2 snapshot 明确迁移为 v3:补默认字段、重命名字段、拆分结构。Migration 应是 deterministic 且可测试的纯转换。

Event Log ​

历史 event 不建议原地改写。更常见的是读取时做 upcast:

text
TOOL_REQUESTED v1
→ upcaster
→ TOOL_REQUESTED v2 domain shape
→ reducer

如果新语义无法无损映射,就明确标记 unsupported,而不是猜。

部署兼容窗口 ​

只要系统允许 Run 跨小时/跨天存在,rolling deploy 就会出现“旧 Run + 新 Worker”组合。生产策略至少要选择一种:

  1. Backward-compatible window:新版本能读最近 N 个 state/event 版本;
  2. Version-pinned worker:旧 Run 继续路由给兼容 worker;
  3. Explicit migration:部署前迁移 paused state;
  4. Fail closed / fork:不兼容时拒绝直接 resume,创建人工确认的新分支。

选择取决于任务风险和系统复杂度,但不能假设所有 paused Run 都会在发布前结束。

Failure Modes ​

“JSON 能反序列化”就认为可恢复 ​

结构兼容不代表业务语义兼容,尤其是待执行 Tool、approval 和 idempotency key。

处理: resume compatibility 是显式 policy;高风险 pending action 版本变化时 fail closed 并重新审批。

直接修改历史 Event payload ​

审计、重放和旧 trace 会失去稳定含义。

处理: append-only 历史保持原样,通过 event version + upcaster 读取。

如何验证 ​

建立真实旧版本 fixtures:

Fixture新版本期望
v2 checkpoint 可无损迁移migrate 后状态等价
v1 event 可 upcastreducer 得到预期 state
Tool schema 已扩大权限resume 被拒绝并要求重新审批
完全未知 schema_versionfail closed,不默默填默认值

自测 ​

  1. 旧 checkpoint 缺少新版本必填字段。Resume 时是静默填默认值还是执行显式 migration?怎样判断安全?
  2. Schema migration 改变了状态语义但版本号没变,会让 replay/resume 出现什么隐蔽问题?

Sources ​

AI Engineering · Agent · Harness · Backend Systems