Skip to content

第 12 章:自动化与多 Agent 编排 ​

目标:区分“定时运行一个 Agent”和“协调多个 Agent 完成一个 DAG”,并理解 Orca 如何用事务、能力与消息传递控制副作用。

1. 两个系统解决不同问题 ​

系统AutomationOrchestration
触发时间、cron、RRULE、手动coordinator/CLI/API
主要对象automation + runrun + task + dispatch + message
Agent 数量通常一个/每次运行多 worker
Workspace新建或复用parent/child/federated
持久化主 StoreSQLite
关注点调度、precheck、历史DAG、通信、幂等、所有权

2. Automation 数据模型 ​

Automation 通常包含:

  • 名称、enabled;
  • trigger(预设、cron、RRULE);
  • timezone 与下次运行;
  • prompt 和 provider;
  • repo/new-worktree 或 existing workspace target;
  • setup policy;
  • fresh/reuse session;
  • created/updated metadata。

Run 记录 dispatch 时间、状态、workspace、terminal pane/PTY、output snapshot、错误和 precheck。

类型在 automations-types.ts。

3. 调度不是简单 setInterval ​

自动化需要处理:

  • app 长时间睡眠后补偿;
  • timezone/DST;
  • disabled / edited schedule;
  • 同一 automation 重叠运行;
  • repo/host/Agent 不可用;
  • headless serve 没有 renderer;
  • existing workspace session 已过期。

AutomationService 计算下一次 due,执行 precheck,再通过 runtime/worktree/terminal 现有能力启动,而不是自己复制一套 Git 和 PTY 逻辑。

4. 新 worktree 与复用 workspace ​

New per run ​

每次创建独立 worktree,隔离强、历史清楚,代价是磁盘和清理。

Existing workspace ​

直接在指定 worktree/folder 中启动。reuse-session 会尝试沿用上次 Agent session;若原 terminal 不在,回退 fresh session。

自动化创建的 workspace 会有 provenance,sidebar 可选择隐藏,避免定时任务淹没人工任务。

5. Headless dispatch ​

没有 renderer 时,runtime 自己维护 session tab snapshot,并为 automation 创建 workspace/terminal。输出通过 headless terminal model 截取有界 snapshot,run history 不依赖挂载 xterm。

这是 main-owned terminal state 的直接收益:自动化不需要假装有一个隐藏 UI。

6. Orchestration 的核心对象 ​

Run ​

全局 objective、coordinator handle 与 contract generation。

Task ​

spec、parent、dependencies、状态和结果,构成 DAG。

Dispatch ​

把 task 分配给具体 worker,记录 capability、pane、process incarnation、heartbeat 与失败次数。

Message ​

带 from/to、subject、body、type、priority、thread、sequence 与 delivery 状态。

7. Task DAG 的状态机 ​

一个 task 不能仅靠 worker 自报结果改变任意行。report 要匹配 run、task、dispatch、active generation 和 capability。

8. 为什么需要 mutation receipt ​

网络重试下,“创建 task”“dispatch worker”“发送消息”可能重复。Orchestration DB 保存:

  • caller fingerprint;
  • request id;
  • method;
  • payload hash;
  • effect/response receipt。

同 caller + request id + 同 payload 返回旧结果;同 id 不同 payload 拒绝。这把 at-least-once transport 提升为应用层幂等副作用。

9. Worker 启动 ​

Worker dispatch 会:

  1. 解析 placement:同 workspace、child worktree、folder 或 federated host;
  2. 创建/选择 workspace;
  3. 执行 setup gate;
  4. 创建 terminal 与 Agent session;
  5. 注入任务 spec、身份与 communication contract;
  6. 等待 ready/heartbeat;
  7. 将 pane/terminal/incarnation 绑定到 dispatch。

状态细分为 starting、ready、start_unknown、failed、succeeded、stopping、stop_unknown、stopped、abandoned。

start_unknown 很关键:超时不代表 worker 未启动,不能直接安全创建第二个。

10. 消息与 inbox ​

消息 type 包括 status、dispatch、worker_done、merge_ready、escalation、handoff、decision_gate、question、heartbeat。

worker 通过自己的 capability 读取 inbox/ack;coordinator 可以等待消息或 group address:

  • @all;
  • @idle;
  • Agent name group;
  • @worktree:<id>。

发送消息和直接往另一个 PTY 注入文字不同:消息可追踪、可 ack、可按 run 隔离,并能跨 federation relay。

11. Decision Gate 与 Question ​

Decision gate 是 coordinator 需要用户/策略选择时的持久对象;question 是 worker 向 coordinator 的交互。

它们都有 pending/resolved/timeout/closed 等显式状态,避免一条自然语言消息被多个并发 worker 各自解释成最终决定。

12. Circuit breaker 与 failure count ​

同一 task 不应无限失败重启。dispatch context 记录 failure_count 与 last_failure,达到策略边界后进入 circuit_broken。恢复需要明确 reset/新 dispatch,而不是后台自旋。

13. Federation:让 worker 跑在另一环境 ​

Federated dispatch 把 task 放到另一个 paired runtime:

数据库保存 peer fingerprint、protocol、remote epoch、remote worktree/terminal 与双向 imported sequence。断线后按 sequence 续传,不能把旧 peer 的消息导入新 runtime incarnation。

14. Legacy contract 与滚动升级 ​

编排系统仍保留 legacy run/principal/operation receipt 等兼容表。新旧 runtime 共存时通过 contract version 与 capability 决定路径。

升级策略遵循单调性:升级某一层不应让旧工作流突然不可用;但不能为了兼容在 side effect 不确定后降级并重复启动。

15. Agent 状态与编排上下文的连接 ​

worker pane 的 AgentStatusEntry.orchestration 包含 taskId、dispatchId、displayName、parent pane、coordinator handle 和 run id。renderer 因此可以把独立 PTY 显示成 coordinator 的子层级,而无需根据标题猜父子关系。

16. 源码导航 ​