36 KiB
doc_id, title, language, source_language, counterpart, implementation_status, document_status, translation_status, last_verified, owners
| doc_id | title | language | source_language | counterpart | implementation_status | document_status | translation_status | last_verified | owners | |
|---|---|---|---|---|---|---|---|---|---|---|
| architecture.agent-graph-stream-scheduling | 第七章:Graph 是调度,不是第二套 Runtime——主 Agent 监督下的流式 Agent Work | zh-CN | zh-CN | ./agent-graph-stream-scheduling-draft.md | current | draft | synced | 2026-08-23 |
|
第七章:Graph 是调度,不是第二套 Runtime——主 Agent 监督下的流式 Agent Work
本章回答一个问题:Maka 如何把相互依赖、运行中动态展开的 Agent work 组织成图,同时不再发明一套 Agent runtime?Maka 把每个 child Session 视为 operator 容器,把每次 Session-inline AgentRun 视为 activation,把每个已提交 RuntimeEvent 视为 reference-only stream record。SQLite control plane 保存 topology、schedule intent、admission 和 supervisor wake;已有的 Session 与 Runtime ledger 继续拥有运行事实。主 Agent 始终在图旁担任 supervisor:它观察和修改 schedule,但正常 record delivery 不等待它批准。Graph 是建立在 Runtime 事实之上的持久调度,不是第二个运行宇宙。
本章直接建立在第一章之上。Runtime Event Log 仍然是“Agent 实际做了什么”的语义 authority。Graph 只是增加了一组 identity 和 projection,用来回答另外几类问题:哪个 child Session 是一个 operator、哪些已提交 record 会流向另一个 operator、supervisor 请求了哪些 work、哪个 intent 被精确 admission 一次,以及何时应该唤醒 root Agent 检查一个稳定 checkpoint。
本文面向修改 Graph contract、child Session、调度、恢复或 Desktop 接线的工程师,描述截至 2026-08-23 已验证的实现。它不描述任意有环 workflow、分布式执行、图级资源优化,也不把当前实现说成可视化 workflow authoring system。
从运行中才逐渐显形的工作开始
假设用户让 Maka review 一个跨层改动:
- 一个 specialist 检查 Runtime invariant;
- 另一个 specialist 检查 storage 与 recovery;
- 两者提交的 findings 暴露出还需要一次 Desktop 检查;
- 主 Agent 再让一个 synthesis specialist 对比选中的 findings;
- 主 Agent 读取权威 child output,并选择最终 result records。
这不只是一个 batch。后续 work 依赖前面产生的事实,而且有用的 topology 在一开始并不完全已知。但这也不是替换 Agent loop 的理由:每个 specialist 仍然需要普通的 model/tool loop、permission、history、context compaction、usage accounting、stop、recovery 和 inspection。
因此真正有用的抽象是:
child Session → operator 容器
Session-inline AgentRun → operator activation
已提交 RuntimeEvent → immutable stream record
record 沿 edge 可见 → route
确定性的 input state → readiness intent
持久 admission row → exactly-once execution identity
supervisor schedule update → control-plane decision
Graph layer 只协调这些既有对象,不复制它们。
先说结论
当前设计建立在六条边界上:
- Runtime 继续拥有执行 authority。 Graph 不引入 GraphRun event ledger,也不复制 model/tool loop。
- 持久 child Session 是 operator 边界。 后续 activation 复用它的 runtime snapshot、history、lifecycle、usage 和产品 identity。
- 只有已提交 RuntimeEvent 才能成为 Graph record。 partial chunk 和进程内 callback 永远不是持久 dataflow fact。
- Readiness 是确定性 projection,admission 是 SQLite decision。 重算 runnable intent 不会把同一工作执行两次。
- 主 Agent 在 data path 旁监督。 observation callback、Desktop invalidation 和 supervisor turn 可以失败或重试,但不能阻塞 record projection。
- Schedule closure 与 runtime quiescence 是两回事。 “此刻没有 runnable work”不等于“supervisor 已完成 Graph”。
这些边界让 Graph 直接复用 Maka 已经解决的困难部分:Session 创建与生命周期、AgentRun identity、RuntimeEvent 持久化、permission、context compaction、child-output inspection、usage 和 tool activity、Desktop conversation component,以及重启恢复。
Identity 模型
Graph 有意保留多种 identity,而不把它们压扁成一个泛化的“node status”。
| Identity | 含义 | 持久 authority |
|---|---|---|
| Root Session | 用户面对的会话,其主 Agent 监督 Graph | Session store |
| Graph | 由一个 root Session 派生的调度 namespace | SQLite Graph control plane |
| Work | 一条 supervisor instruction 与 input frontier | Schedule update log |
| Operator | 到一个 child Session 的稳定 Graph binding | Operator provision |
| Child Session | 一个 operator 可复用的执行与产品容器 | Session store 与 metadata control plane |
| Activation | 该 operator 的一次 Session-inline execution | AgentRun |
| Turn / Run | Child Session 内精确的输入与执行 identity | Session 与 AgentRun ledger |
| RuntimeEvent | canonical semantic execution fact | Runtime Event Log |
| Record | 引用一个已提交 RuntimeEvent 的有界 Graph projection | 可重建 projection |
| Route | Record 沿一条 direct edge 对下游可见 | 可重建 trace projection |
| Readiness intent | 由 route 和 policy 确定性派生的候选 | 可重建 readiness projection |
| Claim | 把一个 intent 持久 admission 到精确 Session、Turn、Run | SQLite Graph control plane |
| Supervisor wake | 请求运行一次 root-Agent checkpoint turn | SQLite Graph control plane |
最重要的层级是:
root Session
└── graph
├── schedule revisions
├── operator
│ └── child Session
│ ├── activation / AgentRun
│ │ └── committed RuntimeEvents → graph records
│ └── later activation / AgentRun
├── operator
│ └── child Session
└── admission claims and supervisor wakes
Operator 不是 AgentRun。稳定的 operator-to-Session binding 才让 follow-up 自然成立:Session 保持不变,每次 activation 获得新的 Turn 与 Run identity。
同一套 Runtime 上的两个 plane
最容易理解当前实现的方法,是把它看成 data plane 旁边的一层 control plane。
flowchart LR
U["User"] --> M["Root Session<br/>Main Agent supervisor"]
subgraph CP["SQLite Graph control plane"]
S["Schedule revisions<br/>add / stop / replace / finish"]
T["Monotonic topology<br/>operator provisions"]
C["Intent claims<br/>admission state"]
W["Supervisor wakes<br/>delivery attempts"]
RM["Bounded client projection"]
end
subgraph DP["Existing Session / Runtime data plane"]
O1["Operator A<br/>Child Session"]
O2["Operator B<br/>Child Session"]
A1["AgentRun activation"]
A2["AgentRun activation"]
L1["Runtime Event Log"]
L2["Runtime Event Log"]
end
M -->|"view / update tools"| S
S --> T
T --> O1
T --> O2
C --> A1
C --> A2
O1 --> A1 --> L1
O2 --> A2 --> L2
L1 -. "reference-only records and routes" .-> RM
L2 -. "reference-only records and routes" .-> RM
RM --> W
W -->|"new root turn"| M
Control plane 与 data plane 之间的箭头都是 typed boundary:
- provision 把 child Session relation 与 operator metadata 原子创建;
- claim 在执行前,把确定性 intent 绑定到预分配的 Turn 与 Run identity;
- Runtime 通过普通的 Session-inline child path 执行;
- observation 把 immutable RuntimeEvent fold 回 Graph record 与 client projection;
- durable wake 在有价值的 checkpoint 后启动一次普通 root Session turn。
任何 Graph callback 都不会成为 model output、tool result 或 terminal state 的 owner。
为什么 child Session 是 operator 容器
较早的 child-agent 设计可以把执行直接放在 parent Session 下,只用一个 child AgentRun 区分它。这足够支撑短暂的 foreground call,却不是长寿命 Graph work 的良好 operator 边界。
Linked child Session 可以自然复用:
- Session 创建、停止、归档与恢复;
- 冻结的 subagent runtime snapshot,包括 profile、system prompt、tool surface 和 permission ceiling;
- 后续 follow-up 所需的多次 Session-inline AgentRun;
- RuntimeEvent 与 message 持久化;
- context 构造与 compaction;
- usage、tool activity 与 artifact accounting;
- Desktop 与 TUI 的会话检查组件;
- 基于精确 child Session 和 current Run 的
agent_output; - 未来通过同一 Runtime host 实现的多 client 观察。
Child 会持久保存回到 root 的 lineage:
parentSessionId
spawnedBy.parentRunId
spawnedBy.parentTurnId
spawnedBy.toolCallId
graph.graphId
graph.workId
graph.operatorId
Parent 不需要维护可变 child ID 数组。反向查询与 Graph topology 是 read-model concern。Cross-Session provenance 也不会塞进 AgentRun.parentRunId,所以 child Session 内的 Runs 仍然保留普通 Session-inline history semantics。
从 RuntimeEvent 到 stream record
Projection,而不是复制
readCommittedAgentGraphProjection() 读取每个 operator binding 的 immutable RuntimeEvents,产生有界的 AgentGraphRecord。Record 携带 identity、order、facet、supervisor signal,以及到 source Session、Run、RuntimeEvent 的引用;它不复制完整 message、tool arguments 或 tool result payload。
这层分离带来几个结果:
- Graph 可以用小而稳定的值做 route 与 schedule;
- 权威 child output 仍留在 Runtime ledger;
- access control 与 archive 继续附着在原始 resource 上;
- read model 不会悄悄变成竞争性的 event store。
主 Agent 需要读取某个 candidate record 背后的真实答案时,使用 operator 的
childSessionId、currentRunId 和 view=result 调用 agent_output。这个投影只返回
最终已提交的模型文本、对应的 Graph result/terminal record ID,以及有界的 artifact
引用。原始 Runtime events 仍可用于显式诊断,但不再属于 supervisor 的正常数据路径。
Commit 是 stream boundary
只有 non-partial、immutable RuntimeEvent 才进入 Graph projection。Provider chunk 与已 yield 的 SessionEvent 可以更新 best-effort client view,但不是 Graph fact。Terminal history 只由 authoritative RuntimeEvent fold 写入,因为 stop race 仍可能在 Runtime durability barrier 把已 yield 的 completion 改写为 aborted terminal fact。
规则是:
只有当 Runtime 已提交 Graph 所引用的 semantic event,该事实才能进入 Graph。
Record facet 与 signal
Record 暴露有界 facet,例如 message、thinking、error、tool call、tool dispatch、tool result、artifact update、permission request、permission decision、user-question request、transfer、usage、completed、failed、aborted、cancelled 和 generic runtime fact。
同一 record 还可以带 attention 或 terminal 等 supervisor-facing signal。它们是同一 record identity 上的 meta-stream,不是第二份事实。Supervisor signal 不能改变下游 operator 收到什么。
稳定 replay 顺序
Record 使用确定性的 total order:
- event time;
- Run creation time;
- operator identity;
- Run identity;
- committed event ordinal;
- RuntimeEvent identity;
- record identity。
每个 activation 还链接前一个 record。Replay 验证每个 activation 只有一次 terminal transition,并拒绝终止后的 record。因此重启后可以从 Runtime ledger 重建 projection,而不把 callback arrival order 当成 authority。
Topology 与 routing
Existing operator binding 组成的 DAG
Trace topology 包含 operator 与 directed edge。校验会拒绝缺失 operator、self-loop、重复 endpoint 和 cycle,再派生确定性 topological order。
对每个已提交 source record,trace projection 都会在每条 direct outgoing edge 上创建 reference-only route。Edge 只拥有 visibility,不拥有 readiness policy。下游 adapter 决定一条 visible route、一个 settled activation frontier,还是 supervisor 显式选择,足以启动 work。
动态 topology 只做 monotonic add
当前产品路径支持单调增加:
agent_idwork provision 一个新 child Session 与新 operator;operator_idwork 在已有 operator 上创建后续 activation;- input record 的 producer 决定新 operator 的入边;
- provision、child Session、initial Turn 和 initial Run identity 都被确定性预分配;
- retry 要么观察到已有 provision,要么只创建一次。
首版不支持任意删边、删点、rewire 或 cycle。Supervisor 可以 stop 或 supersede work,但历史 topology 与事实保持可解释。
Readiness 不是 admission
可复用 Runtime primitive 定义了两种 policy projection。
map
map 对 operator 可见的每条 routed record 产生一个确定性 intent。没有 input route 时,operator 报告 input_route wait。
all_settled
all_settled 为每个 direct upstream operator 指定一个 immutable activation。它等待 activation 出现并结束,然后在 sealed inputs 上产生一个 intent。
显式 activation frontier 很关键。如果同一个 child Session 后来执行 follow-up activation,新 Run 不能悄悄改变已声明 join 的含义。
两种 policy 都只产生确定性 intent ID 与 readiness-context fingerprint,不启动 Runtime work。Supervisor 可以观察相同的 waiting/runnable projection,但 readiness 派生过程不需要它批准。
当前 Desktop host profile 默认不安装自动 map 或 all_settled policy。主 Agent 通过 add_work 与已提交 input_ids 显式推进动态图。Policy primitives 可以被其它 host adapter 使用,而不需要修改 execution runtime。
Supervisor schedule
Graph Mode 只给 root Agent 一组紧凑 control surface:
view_agent_graph读取持久 schedule state、runtime state、readiness、wait 与有界 recent activity;update_agent_graph追加一条 idempotent schedule decision,包含add_work、stop、finish或允许的组合;agent_output读取选定 child Session Run 的权威输出。
Child Session 永远不会获得 Graph supervisor tools。
Revision-linearized intent
每条 schedule update 记录:
- source root Session、Run、Turn 和 tool call;
- stable update identity 与 fingerprint;
- 零到多个 work addition;
- 零到多个 stop decision;
- 可选 finish decision;
- 严格递增的 Graph revision 与 commit time。
SQLite 拥有 revision order。同 source 与内容的 tool retry 是幂等的;冲突 identity reuse 会失败,而不是产生含糊 control history。
Work 与 input frontier
一个 work item 只会指向 catalog agent_id 或已有 operator_id 之一,并携带 instruction、已提交 input record IDs,以及可选的被替换 work 或 activation。
Input IDs 不是复制出来的 prompt,而是 durable frontier。默认 scheduled prompt 只携带有界 record reference——record、operator、activation、facet 与 RuntimeEvent source——不会复制 upstream payload。Host 可以提供其它 prompt renderer。真正需要 semantic source content 的 work,必须把内容写入 instruction,或使用显式授权的 Runtime retrieval path;edge 本身不授予 cross-Session payload access。
Stop、replace 与 finish
Stop 可以指向 work 或 activation。尚未 admission 的 work 变成 cancelled;正在执行的 child Session 通过普通 Runtime stop path 停止;已终止执行继续作为历史事实存在。
replaces 显式表达 supersession,而不是修改旧 work row。
finish 选择已提交 Graph record IDs,并关闭 fresh admission。它不能与新 work 同时提交。已经 claim 的 work 仍然可恢复,因为 closure decision 不能把一个已经持久 admission、拥有精确 Run identity 的执行遗弃。
先 claim,再执行
Readiness 与 schedule reconciliation 可以重复计算很多次。Exactly-once execution identity 来自 claim protocol:
- 计算确定性 intent 与 readiness-context fingerprint;
- render 并 fingerprint execution prompt;
- 预分配 target operator、child Session、Turn 与 Run identity;
- 在 expected schedule revision 上 conditional claim;
- conditional 把 admission 从
claimed推进到executing; - 调用已有 Session-inline child execution primitive;
- 一旦 Run 存在,就以 AgentRun 与 RuntimeEvent ledger 为 authority。
如果 Run 创建后进程重试,runClaimedAgentGraphIntent() 会检查或恢复那个精确 Run,不会再次调用 provider。Claim 只是 admission authority,不与 Runtime terminal fact 竞争。
Child Session 会串行化自己的 claimed Graph activation。不同 operator 可以并发,同一 Session 的两个 activation 仍遵守普通 per-Session order。
Reconciliation:推进到 quiescent,再请 supervisor 判断
Host coordinator 为每个 root Graph 维护一个进程内 single-flight driver。持久 row,而不是这个内存 driver,仍然是 restart authority。
一次 reconciliation 会:
- 读取 schedule revision、provision、claim、AgentRun 与已提交 RuntimeEvent;
- 重建 monotonic topology 与当前 observation;
- 应用 stop 与 supersession decision;
- 为尚无 operator 的 catalog-agent work 做 provision;
- 解析 scheduled work 与已配置 readiness intent;
- 拒绝或 defer 未提交 input;
- 在当前 revision 上 claim 并 begin eligible activation;
- 通过 child Session 并发 dispatch 不同 operator;
- fold 新 RuntimeEvent,并重复直到 quiescent、cancelled、stale、failed 或达到 activation bound。
stateDiagram-v2
[*] --> Observe
Observe --> ApplyControl
ApplyControl --> Provision
Provision --> Resolve
Resolve --> Claim: eligible intent
Resolve --> Quiescent: no eligible intent
Claim --> Execute
Execute --> Observe: RuntimeEvent committed
Quiescent --> WakeSupervisor: useful dispatch or failure
WakeSupervisor --> Observe: supervisor adds work
WakeSupervisor --> Closed: supervisor finishes
Closed --> [*]
Quiescence 只描述当前事实与 policy:此刻没有更多 activation eligible。它不表示用户任务完成。只有持久 finish update 才会关闭 fresh Graph admission。
Structural reconciliation 也不拥有 resource permit 或 global fairness。Shared child-run capacity、provider backpressure 与 cross-Graph priority 属于 dispatcher 外围的 host admission layer。
主 Agent 始终在图旁
主 Agent 既不是每条 record 必经的 node,也不是 child execution 内部 callback。它是 external supervisor,承担三类职责:
- **Observe:**检查紧凑 schedule、topology、operator state、wait、failure 与 candidate result record。
- **Control:**添加 dependent work、follow up 已有 operator、stop/replace 失去价值的 work,并关闭 schedule。
- **Synthesize:**读取权威 child output、选择已提交 result record,并回答用户。
这个位置同时保留自治与响应性。Operator 可以按照持久 control decision 推进,root Agent 仍然是普通 conversation participant。用户可以通过 host 观察或停止 Graph,而不把 supervisor 变成 data-delivery bottleneck。
Observer callback 只用于 presentation,并且 fire-and-forget。损坏的 Desktop listener 或 supervisor observation hook 不能让 operator activation 失败。
持久 supervisor wake
一个有用 checkpoint 即使没有新的用户消息,也必须最终把主 Agent 带回来。因此 host 会在 SQLite 中持久保存 supervisor wake。
Wake 状态流转为:
pending → running → delivered
↘ waiting_permission
↘ retryable_failed → running
每次 delivery attempt 都预分配 root Turn identity,并以 agent_graph origin 启动一次普通 root Session turn。Prompt 要求主 Agent inspect Graph,在需要时读取 child output,然后继续 schedule 或 finish。
“Prompt 已持久化”不等于“wake 已 delivered”。只有 host 观察到 root AgentRun completed,delivery 才完成。Permission suspension 会被显式 parked。重启后,wake coordinator 会对比 stored attempt 与 AgentRun fact,把被中断 attempt 标记为 retryable,只恢复安全的 delivery。
Context overflow 与普通 transient failure 分开处理。Host 会记录 overflow diagnostic, 最多执行一次 aggressive compaction,并在可用时报告压缩前后 token 估算与 dropped event 数量。若第二次仍 overflow,会立即返回有界的 durable partial result;不会带着完全相同的 超长 context 再做第三次重试。
Session activity registry 会把这个 host-created turn 与其它 root Session activity 串行化。多个 client 可以观察同一个持久 Session 与 Graph state,但不会成为 scheduler owner。
Persistence 与 authority
Graph 把 SQLite 用作 workspace/session metadata control plane,而不是 transcript 或 Runtime ledger 的替代品。
| 数据 | Authority | 原因 |
|---|---|---|
| Child Session 配置与 parent relation | Session storage 加 metadata transaction | 产品 identity 与冻结 runtime snapshot |
| Agent execution lifecycle | AgentRun ledger | 精确 Turn/Run state 与 terminal semantics |
| Message、tool、permission、usage、terminal fact | Runtime Event Log | Canonical interaction facts |
| Schedule revision | SQLite | 有序、幂等的 supervisor control decision |
| Operator provision 与 topology relation | SQLite | 原子的 child Session/operator identity |
| Intent claim 与 admission state | SQLite | Revision-linearized exactly-once admission |
| Supervisor wake 与 attempt | SQLite | 可恢复的 root-turn delivery |
| Graph record、route、readiness、replay timeline | 确定性 projection | 建立在持久事实上的可重建 view |
| Desktop snapshot 与 terminal activity page | SQLite materialized read side | 有界、高效的 client read |
权威 schedule、provision、claim 或 wake 操作发生 SQLite failure 时应直接报错。Coordinator 不会扫描 JSONL 来替代 Graph control plane。
Materialized Desktop projection 不同:它是 derived state。Incremental projection commit 可以失败,而不影响 Runtime 或 schedule authority。Coordinator 会把 projection 标记为 dirty,在 reconciliation 边界做 best-effort rebuild,并在 client read 前再次 repair;成功 rebuild 后才清除 dirty state。
三个 status plane 不能压扁
Client 可能同时观察到:
work.status = requested
claim.admissionState = executing
operator.currentActivation.status = completed
这不是矛盾。
- Work status 记录 supervisor intent,以及它是否被 stopped 或 superseded。
- Claim admission 记录某个确定性 intent 是否已 admission 或 cancelled。
- Activation status 记录 Runtime 实际发生了什么。
把三者压成一个 generic node state 会抹掉因果。Bounded client read model 可以派生 presentation status,但仍保留 work、claim、control decision 与 Run reference 供检查。
重建一条 replayable Graph timeline
Graph 还可以跨 control plane 与 data plane 重建一条统一的 reference-only timeline。getTimeline() 会 join:
- 一份 transactionally consistent SQLite snapshot,其中包含 schedule update、operator provision、current admission,以及 supervisor wake 与 attempt;
- 创建 schedule decision 或执行 wake turn 的 root Session AgentRuns;
- 每个 provisioned operator 的 committed child RuntimeEvent projection。
可分页 event stream 覆盖 supervisor-turn start/termination、schedule commit/finish、operator provision、intent claim、activation start、committed record、activation terminal、wake claim、wake attempt 和 wake settlement。Response 会在 page-level currentState 中单独返回 current admission 与 wake state;这些 mutable snapshot 不是携带 cursor 的 historical event。
Timeline event 有意不暴露 schedule instruction、finish reason、child message content 或 tool payload,只保留回答以下问题所需的 ID、facet、source RuntimeEvent reference 与 Run coordinate:
- 哪个 supervisor turn 创建了这项 work?
- 哪个 operator 和 child Session 接收了它?
- 哪个精确 activation 产生了 candidate record?
- Graph 是否在 final schedule decision 前唤醒了 supervisor?
重建顺序先按 event time,再按稳定 event-kind rank 与 type-specific identity tie-break 排序。公开的 sequence 是 deterministic reconstruction order,不表示 SQLite 与 Runtime ledger 共享一个物理 commit sequence。同一毫秒内的 Runtime record 保留 committed ledger order。
每页默认 100 个 event,上限 256。Opaque cursor 绑定 Graph、event identity 与 event time;页面同时报告 total event、前置 omission 与后置 omission。
Coverage 会被显式报告,而不是靠读者猜测。对于本次读取的 immutable ledger,Runtime record 是 complete 的;但当前 SQLite schema 只保留最新 admission state 与最新 wake state,不保留每个被覆盖的 transition。Reconciliation-loop iteration 也没有作为历史 event 持久化。Timeline 会报告全部三项限制:
admission_transition_history_not_persisted
supervisor_wake_transition_history_not_persisted
reconcile_history_not_persisted
因此 timeline 可以 replay、可以用于诊断,却不会冒充新的 authority。每个 event 都能指回真正拥有 underlying fact 的 store。
Client 访问与 Desktop 产品接线
Runtime Host 通过有界的 agent.graph.query 与 agent.graph.operator.query operation 暴露持久化 Graph projection。Client 通过 agent.graph.stop 显式控制 Graph;关闭连接或 Session subscription 永远不会停止 Graph。需要一致 live view 的 client,应先为 root Session 建立 subscription,再执行首次 query。此后,subscription.agent_graph_changed 与 Session update 共用该 subscription 的有序 sequence,并通知 client 重新查询 projection。它只是 invalidation hint,不是 replay log,也不是第二套 source of truth。Query result 通过 omitted data 与 continuation cursor 表达边界,而不会无限增长。
Desktop 组合了当前 host-managed Graph profile:
- Graph 可以是 Session orchestration mode,也可以是 one-turn override;
/graph on、/graph off与/graph <task>暴露这些选择;- 只有 root Session 获得
view_agent_graph、update_agent_graph与agent_output; - Electron main 拥有 coordinator、wake coordinator、SQLite store、Runtime adapter 与 startup recovery;
- renderer IPC 只暴露 bounded snapshot、operator inspection、stop 与 invalidation hint;
- Agent Graph panel 展示 aggregate state、visible operator、wait、selected result,并可打开 child Session;
- Stop Graph 会 abort reconciliation,并通过 Runtime 停止已知 child Session;
- Startup 先 repair interrupted Runtime state,再恢复 wake 与 Graph schedule。
Renderer invalidation 遵循同一契约。重新连接的 client 会重新查询持久化 projection,不把进程内 notification replay 成事实。
当前 panel 是 operational view,不是 node-and-edge authoring canvas。主 Agent 仍通过 typed schedule update 编写 topology。
End-to-end sequence
sequenceDiagram
participant U as User
participant M as Main Agent
participant SQL as SQLite control plane
participant G as Graph coordinator
participant CS as Child Session operator
participant R as AgentRun / RuntimeEvent log
participant D as Desktop read model
U->>M: Graph-mode task
M->>SQL: update_agent_graph(add_work)
SQL-->>G: durable schedule revision
G->>SQL: provision operator + child Session relation
G->>SQL: claim intent with Turn/Run IDs
G->>CS: run claimed activation
CS->>R: ordinary model/tool execution
R-->>G: committed RuntimeEvents
G->>D: materialize records and operator state
G->>SQL: claim supervisor wake at checkpoint
SQL-->>M: host starts root supervisor Turn
M->>G: view_agent_graph
M->>R: agent_output(child Session, Run)
M->>SQL: add dependent work or finish(result record IDs)
SQL-->>D: closed schedule and selected results
M-->>U: synthesized answer
注意 child result 不经过 supervisor callback 传输。Runtime 先提交它,Graph 再 projection 出一个引用;主 Agent 随后决定是否以及何时读取权威 payload。
Failure 与 recovery invariant
当前实现保护这些 invariant:
- schedule update append-only、按 revision 排序,并按 source identity 幂等;
- operator provision 单调且 retry-safe;
- provisioned operator 永远解析到同一个 linked child Session;
- 一个 intent 最多对应一个 claim 与精确 Turn/Run identity;
- 已存在的 claimed Run 会被观察或恢复,不会盲目再次执行;
- record 只引用已提交 non-partial RuntimeEvent;
- callback 与 renderer failure 不能改变 Graph execution;
- closure 阻止 fresh admission,但不遗弃 existing claim;
- Graph stop 保留 durable schedule fact 与 historical Runtime fact;
- startup recovery 从 SQLite control row 与 Runtime ledger 派生工作,而不是依赖内存 registry;
- supervisor wake 只有在 root AgentRun completed 后才算 delivered;
- derived client projection 失败后可以 rebuild,而不改变 authority。
- replay timeline 不暴露 child 或 schedule payload,并显式报告不完整的 transition coverage。
这些 invariant 比任何单个 UI 或 prompt 的形状都重要。新的 host adapter 必须保留它们。
当前限制与 non-goal
当前 Graph 不能被误解为通用 distributed stream processor。
- Topology 是只做 monotonic add 的 directed acyclic graph;任意 deletion、rewire 与 cycle 尚未实现。
- Desktop 默认通过 supervisor schedule update 显式推进 dependent work,不会暗中推断自动 policy-driven topology。
map与all_settled是 structural readiness primitive,不是完整 window、watermark、keyed state 或 backpressure system。- Structural scheduler 不拥有 global resource permit、fairness、provider rate limit 或 distributed lease。
- Quiescence 不是 graph completion;
finish是显式 supervisor decision。 - Read model 有界且 reference-only;完整 child content 必须走权威 Runtime read path。
- Desktop panel 是 inspection 与 stop surface,不是 visual graph editor。
- Coordinator 已暴露 paginated replay timeline,但 Desktop IPC 与当前 Agent Graph panel 尚未把它渲染成交互式 chronological visualization。
- Admission 与 wake row 目前只向 timeline reconstruction 暴露 latest state,reconcile-loop history 也没有持久化。
这些都是有意保留的边界。它们让 Graph 有用,同时不把 workflow semantic、resource management 或 product presentation 塞进 Agent runtime。
Graph、Swarm、agent_spawn 与 Rive
四种机制解决不同的协调问题。
| 需求 | 机制 | Ownership model |
|---|---|---|
| 有限独立 fan-out,随后一次 synthesis | Swarm 模式 | 主 Agent 把独立 item 排进同一张 Graph,并异步监督 |
| 一次 linked specialist execution 或 follow-up | agent_spawn / child Session |
Parent Agent 显式拥有 delegation |
| 从 root conversation 监督动态依赖 Agent work | Agent Graph | Child Session 与 Runtime record 之上的 SQLite schedule/control plane |
| 显式 workflow step、任意 resume policy 或分布式 workflow authority | Rive | Workflow runtime 拥有 workflow state |
Graph 位于 foreground fan-out 与独立 workflow runtime 之间:足够动态、持久,可以协调 dependent Agent work;同时 Session Runtime 仍是唯一 execution universe。
代码阅读地图
建议按以下顺序阅读:
packages/core/src/orchestration.ts与graph-command.ts:Session 与 one-turn Graph mode。packages/runtime/src/graph-mode.ts:main-Agent supervisor contract。packages/core/src/agent-graph-schedule.ts:work、stop、finish、revision 与 store protocol。packages/core/src/agent-graph-topology.ts:monotonic operator provision。packages/runtime/src/stream-graph-projection.ts:RuntimeEvent-to-record projection 与 replay。packages/runtime/src/stream-graph-trace.ts:topology validation 与 reference-only route。packages/runtime/src/stream-graph-readiness.ts:map与 sealedall_settledreadiness。packages/core/src/agent-graph-control.ts与packages/runtime/src/stream-graph-admission.ts:durable intent claim。packages/runtime/src/stream-graph-dispatch.ts:structural drive-to-quiescence loop。packages/runtime/src/stream-graph-schedule-reconcile.ts:schedule、dynamic provision、stop、claim 与 dispatch convergence。packages/runtime/src/session-manager.ts:child Session provision 与 claimed activation execution。packages/runtime/src/stream-graph-coordinator.ts:host-owned single-flight lifecycle、client projection repair 与 root-only timeline access。packages/runtime/src/agent-graph-timeline.ts:reference-only control/data-plane reconstruction、stable order、coverage 与 pagination。packages/runtime/src/agent-graph-supervisor-wake.ts:回到 root Agent 的持久路径。packages/storage/src/sqlite-session-metadata-schema.ts与sqlite-session-metadata-store.ts:Graph control-plane transaction 与 timeline metadata snapshot。apps/desktop/src/main/main.ts、runtime-host-session-domains-ipc-main.ts与apps/desktop/src/renderer/agent-graph-panel.tsx:产品组合与 bounded UI。Graph 变更事件走通用 session-domains 桥接的agentGraphChanged,没有 Graph 专属的主进程 IPC 模块。
最相关的 contract tests 位于:
packages/runtime/src/__tests__/stream-graph-*.test.tspackages/runtime/src/__tests__/agent-graph-timeline.test.tspackages/runtime/src/__tests__/agent-graph-supervisor-wake.test.tspackages/runtime/src/__tests__/session-manager.test.tspackages/storage/src/__tests__/sqlite-session-metadata-store.test.tspackages/storage/src/__tests__/agent-graph-timeline-metadata.test.ts
总结
Maka Graph 从一个流处理视角出发:
subagent work 表现得像 operator
Agent message 表现得像 stream record
dependency 表现得像 route 与 input frontier
coordination 表现得像 graph 上的 scheduling
实现把这个观察具体化,却没有改写 Agent runtime。Child Session 提供稳定 operator container;AgentRun 提供 activation;RuntimeEvent 提供 immutable fact;确定性 projection 提供 record、route 与 readiness;SQLite 提供 revision-linearized schedule、topology、admission、client materialization 与 supervisor wake;Desktop 提供 host 与 operational view。
主 Agent 是这个设计最有辨识度的部分。它始终在图旁:对用户保持可用,可以检查任意 operator,可以添加或停止 work,并负责选择和综合最终 record。Data path 无需等待模型批准即可推进,而 judgment 留在用户能够看见和影响的 conversation 中。
这就是该架构的承诺:复用一套可信 Runtime,增加一层持久 Graph control plane,让监督 Agent 足够靠近 schedule、能够理解和修改它,同时不成为它的 bottleneck。