Yoda
参考Agent 设计指南自动化编排

定时任务 / Routines

CC 用「会话内 cron + 桌面任务 + 云端 Routines」三层覆盖从轮询到无人值守;Codex 把调度放进桌面 App 的 Automations,CLI 侧只给 codex exec 让你自己接 cron

定时任务 / Routines

结论

Claude Code 把"定时执行"做成了三层产品矩阵:(1) 会话内 /loop + CronCreate/CronList/CronDelete 工具(本地、要求会话开着、最小 1 分钟间隔、7 天自动过期);(2) Desktop 本地 scheduled tasks(本地、不要求会话开着);(3) 云端 Routines(Anthropic 托管基础设施,schedule/API/GitHub 三种触发器,最小 1 小时间隔,CLI 入口是 /schedule)[一手文档]。Codex 走的是另一条路:调度器不在 CLI 里——codex-rs 源码中没有任何 cron/scheduler 模块[一手源码],官方方案是 Codex 桌面 App 的 Automations(本地执行、支持 thread automation 心跳式唤醒和 standalone automation、worktree 隔离),CLI 侧只提供 codex exec 非交互模式让用户自己接系统 cron / CI[一手文档]。对 harness 来说:CC 的会话内 cron 可以被程序化复用(durable 任务落盘 .claude/scheduled_tasks.json),Codex 则必须由 harness 自己实现调度层。

研究问题

  • CC 的三种调度方式(/loop、Desktop、Routines)各自的执行位置、持久性、安全边界是什么?
  • 调度的底层工具(CronCreate 等)如何实现?任务存哪里?
  • Codex 有没有等价物?CLI 里有没有调度器?
  • 失败重试、预算与安全边界各家怎么处理?

各 Agent 设计与实现

Claude Code

层 1:会话内调度(/loop + Cron 工具)[一手文档][一手源码]

/loop 是 bundled skill,把 prompt 转成 cron 表达式后交给底层三件套工具:CronCreate / CronList / CronDelete(docs/scheduled-tasks.md:157-165)。关键机制:

  • 任务是会话作用域的:调度器每秒检查到期任务,以低优先级入队,"fires between your turns"——不会打断进行中的回合(docs/scheduled-tasks.md:169)。
  • 抖动(jitter):为避免全体用户同一墙钟时刻打 API,按 task ID 派生确定性偏移——recurring 任务最多延后 30 分钟(或半个间隔),整点/半点的 one-shot 最多提前 90 秒(docs/scheduled-tasks.md:175-180)。
  • 7 天强制过期:recurring 任务创建 7 天后最后触发一次然后自删,"This bounds how long a forgotten loop can run"(docs/scheduled-tasks.md:184)。
  • 上限 50 个任务/会话——源码 CronCreateTool.ts:25const MAX_JOBS = 50[一手源码]。
  • durable 开关:CronCreate 的输入 schema 里有 durable 字段,"true = persist to .claude/scheduled_tasks.json and survive restarts. false (default) = in-memory only"(src_2026-03-31/tools/ScheduleCronTool/CronCreateTool.ts:39-41);存储路径定义在 utils/cronTasks.ts:74const CRON_FILE_REL = join('.claude', 'scheduled_tasks.json')[一手源码]。文档只描述了 resume 恢复未过期任务,durable 落盘细节是源码层信息(重建源码滞后线上约 2 个月,行为可能已演化)。
  • prompt 工程细节有趣:CronCreate 的 prompt 明确教模型避开整点——"the user will not notice, and the fleet will"(ScheduleCronTool/prompt.ts:110)——把防止 API 峰值的运维诉求写进了工具提示词[一手源码]。
  • 自适应间隔:/loop 不带间隔时由 Claude 每轮自选 1 分钟到 1 小时的延迟,并可改用 Monitor 工具流式监听代替轮询(docs/scheduled-tasks.md:63-71)。
  • 杀开关:CLAUDE_CODE_DISABLE_CRON=1 整体禁用(docs/scheduled-tasks.md:205)。

层 2:Desktop 本地 scheduled tasks[一手文档]

Desktop App 的 Routines 页可建 Local 任务:本地执行、最小间隔 1 分钟、可按任务配置 permission mode、可选 worktree 隔离("Enable the worktree toggle ... isolated Git worktree",docs/desktop-scheduled-tasks.md)。机器必须开机且 App 在运行。

层 3:云端 Routines(research preview)[一手文档]

Routine = 保存的配置(prompt + repos + connectors),跑在 Anthropic 托管云上,"keep working when your laptop is closed"(docs/routines.md:13)。三种触发器可组合(docs/routines.md:15-21):

触发器机制
Scheduled预设频率或 one-off 时间戳;自定义 cron 经 /schedule update 设置,最小间隔 1 小时,更频繁的表达式被拒绝(routines.md:135)
API每 routine 一个 /fire HTTP 端点 + 独立 bearer token,beta 头 experimental-cc-routine-2026-04-01(routines.md:188-194)
GitHubClaude GitHub App webhook,支持 pull_request / release 两类事件 + 字段过滤器(routines.md:250-258)

安全与预算边界:routine 全程无权限提示("no permission-mode picker and no approval prompts during a run",routines.md:53);默认只能 push claude/ 前缀分支(routines.md:315);网络默认 Trusted 白名单;每账户有 daily run cap,one-off 不计入(routines.md:359-365)。失败语义上文档专门警告:run 列表的绿色状态只表示"started and exited without an infrastructure error. It does not mean the task in your prompt succeeded"(routines.md:297)——没有自动重试机制的描述,失败处理靠人读 transcript[一手文档][推断]。

Codex CLI

CLI 内没有调度器[一手源码]。在 codex-rs @ b89ce9a 全仓搜索 cron/schedule/automation,没有任何调度模块;codex cloud 子命令只有 Exec/Status/List/Apply/Diff 五个动作(cloud-tasks/src/cli.rs:15-27),是按需提交云任务,不带定时触发。

官方的定时能力在 Codex 桌面 App 的 Automations(developers.openai.com/codex/app/automations,访问于 2026-06-11)[一手文档]:

  • 本地执行:“the machine running the local Codex app must be powered on, Codex must be running”。这是和 CC Routines 最大的区别——CC Routines 是云端的,Codex Automations 是本地的(对应 CC 的 Desktop scheduled tasks 层)。
  • 两种形态:standalone automation(每次独立新 run,结果进 Triage 收件箱,可跨多个项目复用)和 thread automation(“heartbeat-style recurring wake-up calls attached to the current thread”,支持分钟级间隔,保留线程上下文)——后者相当于 CC 的 /loop 但持久化在 App 里。
  • 隔离:Git 仓库可选在本地 checkout 或独立 worktree 上跑;自定义 cadence 用 cron 语法。
  • 安全模型:复用沙箱设置(read-only / workspace-write / full access),“Automations use approval_policy = "never" when your organization policy allows it”,企业可用 requirements.toml 禁止。
  • 可组合 skills:automation prompt 里用 $skill-name 显式触发技能。

CLI 侧的官方姿势是 codex exec + 外部调度(developers.openai.com/codex/noninteractive,访问于 2026-06-11)[一手文档]:“Run as part of a pipeline (CI, pre-merge checks, scheduled jobs)”;默认 read-only 沙箱,自动化场景建议显式 --sandbox workspace-write,并提供 --ignore-user-config / --ignore-rules 做受控环境。

差异矩阵

维度Claude CodeCodex
会话内轮询/loop + CronCreate/List/Delete,1 分钟粒度,自适应间隔thread automation(桌面 App),分钟级间隔;CLI 无
本地无人值守Desktop scheduled tasksApp standalone automations
云端无人值守Routines(Anthropic 托管,关机也跑)本地源码与已抓取文档中未见云端定时;codex cloud 仅按需提交 [推断]
事件触发API trigger + GitHub webhook + ChannelsGitHub @codex 提及(按需,非定时)
最小间隔本地 1 分钟 / 云端 1 小时App 分钟级;codex exec 随外部 cron 任意
任务持久化会话内默认内存,durable 落 .claude/scheduled_tasks.json;7 天过期App 内部存储(格式未公开)
防峰值设计确定性 jitter(task ID 派生)未见等价机制
失败处理无自动重试;绿色状态≠任务成功,靠人读 transcript无发现则自动归档,有发现进 Triage 收件箱
无人值守权限Routines 全自动无审批;本地任务按配置approval_policy="never"(组织策略允许时),沙箱兜底
程序化入口/schedule CLI、/fire HTTP APIcodex exec(stdout 只输出最终消息,适合管道)

最小复现

# CC:会话内 5 分钟轮询(需 v2.1.72+)
claude
> /loop 5m check if the deployment finished
# 预期输出:确认 cron 表达式(*/5 * * * *)、cadence 和 8 位 job ID

# CC:创建云端 routine(需 claude.ai 订阅登录,API key 模式下 /schedule 被隐藏)
> /schedule daily PR review at 9am

# Codex:用系统 cron 接 codex exec(CLI 侧唯一姿势)
crontab -e
# 0 9 * * 1-5 cd /path/to/repo && codex exec --sandbox workspace-write "review yesterday's commits" >> ~/codex-cron.log 2>&1

(以上 CC 命令行为依据官方文档描述,本机未实测云端 routine 创建流程。)

Harness 接入建议(Yoda 实践)

Yoda(Electron,编排 26 个 provider 的本地 PTY 会话)做调度层时的取舍:

  1. 不要依赖 runtime 内置调度器做跨 runtime 统一。CC 的会话内 cron 绑定会话生命周期(7 天过期、会话关闭即停),Codex CLI 干脆没有——harness 自己持有调度器(如 node-cron + SQLite 任务表),到点用各 runtime 的 headless 入口(claude -p / codex exec)拉起新会话,行为才可预测、可观测。
  2. 借鉴 CC 的 jitter 设计:多任务/多项目并发时按任务 ID 派生确定性偏移,避免整点齐发打满 rate limit。
  3. borrow Codex 的 Triage 收件箱模型:定时任务大多数 run 是"无事发生",UI 上应该自动归档静默 run、只把有 finding 的 run 推到收件箱,否则用户会关掉所有自动化。
  4. 无人值守 run 必须降权:参照两家共识——CC Routines 限制 claude/ 分支 + 网络白名单,Codex 用沙箱模式兜底。Yoda 的对应物是 worktree 隔离(已有 per-conversation worktree 基建)+ 限制自动 run 的 auto-approve 范围。
  5. 云端层不要自建:CC Routines / Codex cloud 是账号绑定的托管服务,harness 做到"展示 + 跳转"即可(CC 有 /schedule list 可解析)。

失效条件

  • Routines 处于 research preview,/fire API 在 experimental-cc-routine-2026-04-01 beta 头后,请求/响应形状和限额随版本变化(docs/routines.md:209)
  • CronCreate 的 durable 字段来自 2026-03-31 重建源码,gated by isDurableCronEnabled(),线上可能未全量或已改名
  • CC 的 7 天过期 / 50 任务上限 / jitter 参数均为当前实现常量,版本升级需回归
  • Codex 若在 CLI 或云端补上原生调度(如 codex automations 子命令),本章 Codex 侧结论过期
  • Bedrock/Vertex/Foundry 上 /loop 行为不同(无自适应间隔、不读 loop.md),多云部署需单独验证

参考资料

  • CC 文档(社区镜像,约 3 小时同步一次):claude-code-docs/docs/scheduled-tasks.mddocs/routines.mddocs/desktop-scheduled-tasks.md
  • CC 重建源码(2026-03-31):src_2026-03-31/tools/ScheduleCronTool/{CronCreateTool.ts,prompt.ts}src_2026-03-31/utils/cronTasks.ts
  • Codex 源码(b89ce9a,2026-06-06):codex-rs/cloud-tasks/src/cli.rs
  • Codex Automations:https://developers.openai.com/codex/app/automations (访问于 2026-06-11)
  • Codex 非交互模式:https://developers.openai.com/codex/noninteractive (访问于 2026-06-11)

On this page