跳转到内容

Scheduled Automations / Background Jobs

拆自 handbook/layers/future-capabilities.md。本章讲 MVP 不做 的定时任务 / 后台任务能力——但 MVP 必须把”任务”建模为 session,避免后期另起一套隐藏任务系统。也兼带提一下产品级 multi-agent 编排(同一根 session 模型下的扩展)。


1. 场景

场景现在没法做
”每天早上 9 点跑一遍依赖更新 check”local agent 进程不在线时无法触发
”每个 PR 创建后自动跑 code review skill”没有 event-driven 触发机制
”构建失败时 agent 自动尝试修复”没有外部 event → session trigger 通道
”每周生成项目健康报告”没有持久化的 schedule storage

为什么”等到 M10 再做”是可接受的:定时任务在没有 remote runtime([[remote-execution]])之前没有 production 部署位置;M9 之前 local-first agent 谈定时意义不大。

为什么必须在 MVP 阶段就在心里有这条线:如果 MVP 设计成”session 是用户驱动的”,到 M10 才发现要支持”系统驱动的 session”会撕裂 session 模型。

2. 核心原则:任务也是 session

不要: 要:
┌────────────────────┐ ┌────────────────────────────┐
│ Scheduler │ │ Scheduler │
│ ↓ │ │ ↓ trigger fire │
│ TaskRunner │ │ daemon API: │
│ (独立 runtime) │ │ session/new from schedule│
│ ↓ │ │ ↓ │
│ TaskState │ │ 普通 SessionEngine.runTurn │
│ TaskLog │ │ → 普通 event log │
│ → 与 session 完全 │ │ → 普通 PermissionEngine │
│ 无关 │ │ → 普通 replay / web view │
└────────────────────┘ └────────────────────────────┘
(坏:两套状态机、两套 audit) (好:一套抽象服务两类触发)

所有定时任务都是 session。trigger 不同(user message vs cron fired),但 session 行为不区分。

3. 触发模型

3 类 trigger,统一进 daemon 内部触发器:

Trigger例子落地位置
Schedulecron 表达式:“0 9 ** *“daemon 内置 scheduler,存储在 ~/.config/.../schedules.json
External eventwebhook(GitHub PR opened)、文件系统变化daemon 暴露 webhook endpoint 接收外部触发
Session reaction”上一个 turn turn.completed 后立即跑这个 skill”event log subscriber pattern

trigger 触发后:

trigger fires
emit `automation.triggered` event (含 sourceTriggerId)
daemon 调用 session/new + session/prompt
│ with messages: 由 trigger spec 模板化得到
正常 turn 走完
emit `automation.completed` event (含 sourceTriggerId, sessionId, outcome)

任意 web / mobile 客户端可 query automation.* event 看历史触发与结果。

4. 权限:自动化的特殊麻烦

定时任务的 ApprovalUI 麻烦:触发时用户可能不在线。

处理策略
预先批准 session policytrigger 注册时一并定义”这个 schedule 自动允许 read tools,不允许 destructive”
timeout policyturn 内遇到 ask 决策且无人 approve → 30 min timeout → 视为 deny → emit turn.completed(stopReason=error, errorCode=permission_timeout)
push 通知到 user远端 user 收到 mobile push;可在外面 approve([[remote-execution]] §3.4)
完全无人模式high-trust 项目可注册”全部 read tools auto-allow”的 schedule;但 destructive 永远 走 timeout deny

永远不能放宽的约束:destructive 决策任何 trigger 下都不能预先批准。timeout 触发后必须 deny + 通知 user。

5. 安全:自动化扩大攻击面

定时任务让攻击者多一个入口:

攻击面缓解
攻击者注入恶意 scheduleschedule 创建 / 修改要经过 user 审批;schedule 列表在 ApprovalUI 可见
触发频率过高烧 provider quota每个 schedule 配速率限制;超频 → emit automation.rate_limited
自动化 session 内 prompt injection(如 webhook payload 含恶意指令)trigger 数据按 untrusted 处理;与 MCP tool output 同等级
schedule 调用外部 webhook → 信息泄漏出站 host allowlist;与 plugin sandbox 共用
user 离线时 destructive 动作被批准destructive 永不被 schedule policy 预批;timeout deny

6. 重试与失败

状态处理
turn.completed(stopReason=error)schedule 重试策略:N 次 + 指数退避;超限后开 incident issue
permission_timeout不重试(user 没在;硬重试只会再 timeout);emit automation.skipped
provider quota 耗尽退避到下一个 quota 周期;emit automation.deferred
session crashdaemon level supervisor 重启 acp-server;session 用 event log replay 恢复

所有重试 / 跳过都进 event log,audit 可看完整时间线。

7. Product-Level Multi-Agent 编排

多 agent 协作是定时任务的高级延伸——一个 session 跑完后触发另一个 session(“agent A 跑完 PR review,自动让 agent B 跑 lint fix”)。

需要的能力:

能力状态
Session graph(一个 session 触发另一个)MVP event log + automation trigger 已经能支持
Task delegation eventM10+ 新增 task.delegated / task.completed_by_peer
Agent rolemanifest 声明 agent 擅长 / 不擅长什么;用于路由决策
Conflict resolution两个 agent 都想改同一文件 → 走 candidate workflow,user 最终拍板
Tool ownership不允许同时 N 个 agent 调用同一 destructive tool;用 lock event

MVP 不引入 multi-agent runtime——但 session model + event log + permission engine 都已经为它准备好了:

  • 多 agent 编排 = 多 session 嵌套调用
  • 跨 agent 通信 = event log 共享 / subscribe
  • 工具竞争 = PermissionEngine + lock event

到 M10 写 ADR 时只需要补 task.* event 类型,不需要重写 core。

8. 反模式

反模式原因
写一个独立的 BackgroundTaskManager service与 session 模型并列两套 state;audit / replay 分裂
自动化绕过 PermissionEngine任何工具调用都要经过 gate;自动化 = 预先批准的 policy,不是免审批
schedule 的 cron 字符串运行时变更(自我修改)schedule 修改也走 candidate / audit;不允许 agent 自己加新 schedule
把”agent 自我训练循环”做成 automationself-evolving 走 [[adr-0002]] §“Self-Modifying Prompts” 流程;不能用 schedule 偷偷 self-update

9. 实施路径

阶段工作
M0-M9(当前)保持 session 抽象 location/trigger 无关;event log subscriber pattern 落地(M9b ops)
M10-AUTOMATION ADR写 trigger 模型 / schedule storage / 失败重试 / 安全模型
M10-AUTOMATION实装 daemon 内置 scheduler + webhook receiver + ApprovalUI 集成
M10-MULTI-AGENT补 task.delegated 等 event 类型;编写 ADR;不强制
后续marketplace 集成的 automation 模板

10. 进一步阅读