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

Graph 怎样被调度并持久化:Scheduler、State Machine 与 StateStore ​

前置:模型计划如何变成真实执行:ToolExecutor、Planner 与 GraphCompiler
核心问题:节点完成的一瞬间,Scheduler、State Machine、StateStore 各自更新什么,怎样保证 crash 后恢复到一致事实?

A/B READY 并行,C 等二者;A 已成功而 B crash,resume 保留 A result。批准按钮发 command,Runtime 验证后从 WAITING→RUNNING,而不是前端直接写 DB 状态。

Mental Model ​

最终架构把前面所有知识收敛为可替换 contract:Model、Context、Retriever、Tools、Planner、Runtime、State、Approval、Trace/Eval、MCP、Workspace、API。

Scheduler ​

Scheduler 只从 committed RunState/NodeState 推导 ready work,并通过 worker/ToolExecutor 发起 execution attempt。它不保存第二份“真实状态”。

claim、complete、fail、cancel 都通过 Runtime transition contract 提交;进程崩溃后可从 StateStore/CheckpointStore 重新计算 ready queue。

Run State Machine ​

State Machine 在最终 Harness 中表现为纯 transition/reducer + invariant validation:command/event 输入,得到新的 domain state 或明确拒绝。

🔍 源码对照:Observation 是 StateMachine 的输入事实之一 ​

完整源码与通用分析见 09-01 Run Lifecycle / State Machine。这里不重复代码;这里关注 State Machine:Observation 是 reducer / transition 的输入事实,而不是模型消息本身。

源码说明

Agent/conversation state、storage 与 subagent runtime 分开,是我们检验 Scheduler/StateStore boundary 的好材料:Scheduler 根据状态决定 ready work,但 authoritative state 不能藏在 scheduler coroutine/Promise 里;执行 owner 变化后仍必须通过 Store/version 看到同一事实。

工程边界

案例可能采用与 Shadow Harness 不同的持久化粒度;我们不复制 storage schema,只吸收 state ownership 与 execution ownership 解耦。

Shadow Harness 对照

  • Scheduler 是纯/近纯 decision layer:读取 state→选 ready nodes→提交 claim/transition。
  • StateStore 使用 optimistic version/lease 防止两个 worker 同时推进同一 node。

验证

两个 scheduler worker 同时读取 READY node,只允许一个 claim 成功;失败方必须重新读取 state,而不是继续执行旧 snapshot。

State Store ​

StateStore 是 materialized current state 的持久化 port,提供版本化 read/CAS/transaction;CheckpointStore 与 EventLog 分别承担恢复切片和历史记录。

Store adapter 可以换 Postgres/InMemory,但 Runtime 看见的 version/conflict semantics 必须一致。

一次 Node 完成时需要提交哪些事实 ​

test_auth 从 READY 进入 RUNNING,Executor 返回 exit code 0。Runtime 不应该只做:

python
node.status = "SUCCEEDED"

更完整的提交路径是:

text
Scheduler admits node
→ StateMachine: READY → RUNNING
→ persist attempt/execution identity
→ Executor runs
→ normalize result
→ StateMachine: RUNNING → SUCCEEDED
→ persist output/event/checkpoint
→ update downstream indegree
→ enqueue newly-ready nodes

StateStore 保存的是 Runtime truth,而 Scheduler 的 ready queue 可以是可重建的派生结构。这样进程 crash 后,不必相信内存队列仍然存在;从 durable node state + dependency graph 就能重新计算哪些节点应该 ready。

Failure Modes ​

Scheduler 与 StateStore 各自维护一套状态 ​

症状: 内存 scheduler 认为 node RUNNING,数据库仍是 PENDING,或反过来。

为什么危险: crash/resume 后无法确定哪套状态是真实事实。

处理: 状态迁移通过单一 Runtime reducer/transaction contract 提交;scheduler 从 committed state 推导 ready work。

如何验证 ​

Case断言
Scheduler 与 StateStore 各自维护一套状态在 claim/commit 之间注入 crash,恢复后 ready work 只由 committed StateStore 推导,不出现重复 RUNNING。

关联源码 ​

自测 ​

  1. Scheduler 选中 READY node 后进程 crash。StateStore 必须记录哪些 transition,恢复时才能知道这个 node 是否真的开始过?
  2. 为什么 Scheduler 的并发选择与 RunStateMachine 的合法状态转移是两套相邻但不同的职责?

Sources ​

AI Engineering · Agent · Harness · Backend Systems