本章同样是从 s04 内核展开的独立样例,不包含 s11 的后台 Bash;它把问题从“已启动的工作如何完成”切换为“未来何时开始一个新轮次”。

Background Tasks 让已经启动的慢命令继续运行;Cron Scheduler 解决另一件事:在未来某个时间,把一条 prompt 重新交给 Agent。

schedule_cron(prompt, cron)

调度器到点生成待交付事件

等待 Agent 空闲

prompt 注入 messages

模型处理成功后确认交付

调度的是 Prompt

课程提供 schedule_cronlist_cronscancel_cron。任务记录包含 ID、cron 表达式、prompt、是否重复、是否持久化、待交付状态和最近触发时间。

这不是把 Shell 命令睡眠到未来执行。到点后模型仍根据当时上下文与权限处理 prompt,危险操作依然经过权限边界。

Cron 解析只是调度契约的一部分

教学实现支持五字段 cron,以及 **/N、单值、范围和列表。调度线程按本地时间每秒检查一次。

真实产品还要明确时区与夏令时、停机期间是否补跑、相同分钟如何去重,以及如何展示下一次运行。s12 使用本地时区,停机后不补跑,进程必须持续运行;真正全天候调度应交给系统级或云端服务。

先持久化,再进入交付队列

durable 任务到点时,运行时先写入 pending_deliverylast_fired,再放入内存队列。持久化失败则回滚,不假装已可靠排队。

文件写入采用临时文件加原子替换,降低半写风险。非 durable 任务只存在内存,进程退出后自然丢失。

至少一次交付意味着可能重复

Agent 空闲后,队列处理器把 prompt 注入消息并调用模型。若模型调用失败,就移除本次注入并重新排队;重启时,仍为 pending_delivery 的任务也会再次入队。

这是 at-least-once,而非 exactly-once。如果模型已收到 prompt,但进程在确认前崩溃,重启后可能重复交付。有副作用的自动化必须具备幂等键、状态检查或人工确认。

调度线程不能与前台抢状态

课程通过 Agent 锁等待当前轮次空闲,再处理定时 prompt。定时轮次不能弹出交互式确认,否则会与主 CLI 争抢输入。需要确认的操作应拒绝或留到前台交互。

建议覆盖的测试

  • 支持的 cron 语法正确触发;
  • 相同时间片不会重复排队;
  • durable 与非 durable 生命周期不同;
  • 写入失败不留下错误状态;
  • 模型失败后消息和队列恢复;
  • 重启恢复 pending_delivery
  • 取消后不继续触发;
  • 异步轮次不请求终端确认。

小结

Cron Scheduler 调度未来的 Agent 输入。可靠性来自持久化、空闲协调和失败重投,代价是至少一次语义与潜在重复。时区、停机补偿、幂等和权限是生产化必须补齐的边界。

参考资料