控制面发现 Sandbox 消失后,是否应该立即重建?我的答案是:不能只根据资源不存在做决定,还必须知道任务执行到哪里、外部动作是否已经生效。
Kubernetes 能把 Pod 恢复到期望副本数,但 Agent Sandbox 往往承载一次有状态任务。资源恢复和任务恢复不是同一个问题。
三种状态必须分开
一次恢复决策至少依赖三类状态:
| 状态 | 典型内容 | 回答的问题 |
|---|---|---|
| 期望状态 | 应运行、应暂停、应销毁 | 用户或控制面希望它怎样 |
| 观测状态 | Sandbox、Pod、挂载和进程是否存在 | 真实环境现在怎样 |
| 业务状态 | Tool 是否提交、任务是否完成、结果是否确认 | 重做会不会产生错误 |
如果只比较前两类,控制器很容易得到“期望运行,但 Sandbox 不存在,因此创建一个”的结论。
问题在第三类。Sandbox 消失前可能已经提交训练任务、发送消息或修改外部系统,只是结果还没有写回。直接重建并重放步骤,可能让副作用发生两次。
Reconcile 应收敛事实,而不是重复请求
控制面的职责不是记住上一次函数执行到哪一行,而是持续比较状态并做出下一步决策:
读取期望状态 → 查询 Sandbox 与 Workspace → 查询任务和外部 Action → 计算安全动作 → 执行并记录原因 → 下一轮重新观察当外部动作状态不明确时,系统应进入 UNKNOWN 或 RECONCILING,先根据稳定任务 ID 查询真实结果,而不是立即重放。
因此,每个具有副作用的步骤最好具备:
- 稳定的
action_id或外部任务 ID; - 幂等键;
- 查询当前状态的接口;
- 可区分成功、失败、取消和未知的状态集合。
Reconcile 的价值不是让系统自动处理一切,而是让每次动作都有可解释依据。
当前选择:先保证恢复决策安全
第一版我不会实现“Sandbox 消失后自动恢复全部任务”,而会先保证决策安全:
| 条件 | 处理 |
|---|---|
| 任务尚未产生副作用,Workspace 可恢复 | 创建 Sandbox 并继续 |
| 外部任务已存在且可查询 | 绑定原任务并继续观察 |
| 外部状态未知 | 暂停自动恢复,等待 Reconcile 或人工确认 |
| Workspace 不可恢复且步骤不可重放 | 标记失败并说明原因 |
| 用户已要求终止 | 清理资源,不恢复任务 |
最小 Checkpoint 也不需要复制完整进程内存。我更关注能够解释恢复决策的字段:
task_id, current_step, sandbox_idaction_id, idempotency_key, action_statusrecovery_reason, updated_at这种方案牺牲了一部分自动化程度,但优先避免重复副作用。等所有步骤都具备强幂等、结果查询和稳定 Checkpoint 后,再扩大自动恢复范围。
适用边界
如果 Sandbox 只执行无副作用、可随时重算的纯计算任务,直接重建可能已经足够。复杂控制面只有在任务包含持久 Workspace、外部 Tool 或长时间 Action 时才有必要。
同样,Snapshot 只能缩短运行环境恢复时间,不能说明业务步骤是否应该重做;分布式锁只能限制当前执行者,也不能替代 Action 状态。
所以这篇实践最终保留的判断是:
资源控制器负责恢复运行条件,任务控制器负责决定业务是否能够继续。两者可以协作,但不能由资源存在性替代业务判断。
实现依据:为什么不新增独立 Sandbox 状态库
在现阶段,Sandbox 生命周期仍然可以从 Workspace、Runtime 和任务记录中得到。单独增加一张 Sandbox 状态表会引入第四份事实来源,并要求处理跨存储一致性。
只有当 Sandbox 需要脱离任务独立计费、迁移、审计或长期保留时,独立资源模型才值得引入。在此之前,保存最小恢复记录比复制完整运行时状态更容易解释和验证。