一个定时任务好管,五个就乱了
不少人把 Claude Code 放在一台常开的 Mac mini 上之后,第一件事就是加定时任务:早上做一次代码巡检,中午整理依赖更新,晚上跑一轮 SEO 页面检查,再加一个每周的文档同步。单个任务跑得都不错,可任务一多,常见的麻烦就来了:
- 规则写了好几份:每个任务的提示词里各抄一遍「别动 .env」「改完要跑测试」,改一条规则要改五处,迟早漏一处。
- 任务互相撞车:两个任务同一时间在同一个仓库里改文件,或者上一轮还没跑完下一轮又启动了。
- 失败重跑重复干活:任务跑到第三步失败,重跑时又从第一步开始,同一个提交被做两遍,同一条通知发两次。
- 出了问题查不到:只知道「昨晚好像没跑成」,不知道卡在哪个任务、哪一步。
解决思路其实很朴素:一本共享规则本 + 每个任务一本手册 + 一个统一的调度入口 + 每一步都留状态记录。下面按步骤在新加坡的 Mac mini 上搭一遍。
准备清单
- 一台常开、不休眠的 Mac mini,已装好 Claude Code 并完成登录(Claude 账号由你自己开通,用你自己的账号)。
- 能用 SSH 或 UU 远程连接登录这台机器。
- 一个放任务的目录,例如
~/agents,以及任务要处理的 git 仓库。
步骤一:把共享规则写成一本「规则本」
在 ~/agents/RULES.md 里只写所有任务都要遵守的规则,例如:
- 只在指定仓库和指定分支里改动,不碰其他目录。
- 不读取
.env、密钥文件和凭据目录。 - 每次改动后先跑测试,测试不过就停下并写明原因,不要硬提交。
- 输出结果统一写到
~/agents/state/下,不往终端以外的地方乱发消息。
每个仓库根目录的 CLAUDE.md 里加一句「执行定时任务时先读 ~/agents/RULES.md」,再配合 .claude/settings.json 里的 allow / deny 规则把读写范围卡住。这样规则只维护一份,改一处全部任务生效。
步骤二:每个任务一本手册(playbook)
在 ~/agents/playbooks/ 下给每个任务建一个文件,比如 code-review.md、deps-update.md、seo-check.md。每本手册只写这个任务自己的内容:
- 目标:这次要完成什么,做到什么程度算完成。
- 步骤:拆成编号清楚的几步,每一步能单独验证。
- 完成标记:每做完一步,在状态文件里记下步骤编号和时间。
- 停止条件:遇到什么情况必须停下等人看,比如要改动超过一定数量的文件、测试连续失败。
手册写得越具体,Claude Code 在无人值守时越少「自由发挥」。规则本管底线,手册管流程,两者不要混写。
步骤三:一个统一的调度脚本
不要给每个任务各写一个 launchd 配置去直接调 Claude。更好管的做法是写一个 ~/agents/run.sh,所有定时任务都调用它,只传任务名,例如 run.sh seo-check。这个脚本做四件事:
- 加锁:macOS 默认没有 flock,可以用
mkdir ~/agents/locks/任务名当锁,目录已存在就说明上一轮还在跑,直接退出;任务结束时删掉锁目录。如果多个任务改同一个仓库,就按仓库加锁,而不是按任务。 - 读状态:读取
~/agents/state/任务名.json,看今天已经完成到第几步。 - 调用 Claude Code:用无交互模式
claude -p把「先读规则本,再读这本手册,从第 N 步继续」交给它,并用--max-turns限制单次轮数,避免卡在循环里。 - 写日志:标准输出和错误输出按日期写进
~/agents/logs/,方便第二天回看。
launchd 那边每个任务只保留一个很短的配置,用 StartCalendarInterval 指定时间,程序统一指向 run.sh。具体的 plist 写法和权限规则,可以参考本站之前那篇讲无人值守权限的文章。
步骤四:让重跑「从断点继续」而不是从头再来
防止重复干活,关键是每一步都要可判断是否已完成:
- 提交前先检查 git 日志里有没有当天同名的提交,有就跳过。
- 发通知前先看状态文件里有没有「已通知」标记。
- 生成文件前先看目标文件是否已经存在且内容是今天的。
把这些检查直接写进手册的每一步里,Claude Code 重跑时就会先核对再动手。失败的那一轮只需要从记录的步骤编号继续,前面做过的不会再做一遍。
步骤五:错开时间,给机器留余量
同一台机器上的任务不要都挤在整点。比如巡检放在 8:10,依赖更新放在 12:40,页面检查放在 21:20,周任务放在周日下午。错开之后,每个任务都能独占 CPU 和内存,也更容易从日志里分清是谁出的问题。再加一个每天收尾的小任务,只读 state/ 和 logs/,汇总成一份当天的运行简报,有失败才提醒你。
上线前自检
- 手动执行
run.sh 任务名两次,第二次应当被锁挡住或直接跳过已完成的步骤。 - 故意让某一步失败,确认重跑时从这一步继续。
- 检查 deny 规则:让任务试着读
.env,应当被拒绝。 - 合上本地电脑过一夜,第二天看日志和简报是否完整。
为什么放在一台新加坡的整机上
这套编排依赖两件事:机器要一直开着,环境要一直稳定。放在自己笔记本上,合盖、断网、系统更新都会打断任务;放在多人共用的环境里,资源和网络都不受你控制。Zumac.Ai 提供的是新加坡家庭宽带 的 Mac mini M6,整机独享、一人一台物理机,适合把 Claude Code 和这些定时任务长期挂着,作为一个稳定合规的使用环境。你用 SSH 或 UU 远程连接随时进去看日志、改手册,任务照常按时跑。实际连接体验取决于你本地的网络线路。
小结
定时任务多了以后,比提示词写得好不好更重要的,是结构清不清楚:规则本只维护一份,手册一个任务一本,所有任务走同一个入口并且加锁,每一步都留下完成标记。把这套结构放在一台常开的新加坡 Mac mini 上,Claude Code 就能每天按部就班地干活,出了问题你也能很快找到卡在哪一步。
