
1. 从“手动跑脚本”到“定时自动跑”OpenClaw CLI 的调度场景如果你已经在用 OpenClaw 的 CLI 处理日常事务比如每天拉一次数据、定时巡检日志、周期性生成一份摘要那你大概率经历过这样的阶段一开始靠手动敲命令后来写个 shell 脚本再后来发现脚本本身也需要被“按时叫醒”。这时候 Cron 就登场了。OpenClaw 的 Cron 不是操作系统里那个crontab而是 Gateway 内部的一套调度系统。它把“什么时候跑”和“跑什么”拆成两个独立的概念任务持久化存储在~/.openclaw/cron/目录下重启 Gateway 不会丢计划。你可以把它理解成一个内置在 OpenClaw 里的“闹钟管理器”闹钟响了之后它可以选择在主会话里丢一个系统事件也可以开一个隔离会话专门跑一轮 agent跑完还能把结果发到 Slack、Telegram 或者一个 Webhook 地址。这篇文章聚焦 OpenClaw CLI 场景下的定时自动化从 Cron 表达式怎么写、调度怎么配到日志巡检、数据同步这类常见任务怎么落地给出可以直接复制的crontab配置骨架和 OpenClaw 命令组合。最后会附一条手动触发加日志核对的验证动作帮你确认调度是不是真的按预期生效了。适合已经装好 OpenClaw、想把手动流程变成自动流程的读者。2. 前置准备TaoToken 与 OpenClaw 的接入配置在开始写调度之前先把模型接入这一层理顺。OpenClaw 的隔离任务isolated在运行时需要调用模型如果你用的是 TaoToken 提供的 API需要先拿到 API Key 并配置好 base URL。TaoToken 的官网入口是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 地址是 https://taotoken.net/api 。注意 API 地址后面不加 UTM 参数直接用于配置。拿到 Key 之后在 OpenClaw 的配置里把 provider 指向 TaoToken。具体操作是进入控制台创建 API Key控制台入口https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite创建完 Key 后在 API Keys 页面可以查看和管理API Keys 管理https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite配置写入 OpenClaw 的配置文件后可以用一条最简单的命令验证模型是否通openclaw system event --mode now --text ping如果这条命令能正常触发一次心跳并返回结果说明模型接入层没问题。接下来才是 Cron 调度的事。如果你还没配好可以先看接入文档接入文档https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite3. 可复制配置Cron 表达式与 OpenClaw 命令组合3.1 Cron 表达式基础与 OpenClaw 的错开机制OpenClaw 的 Cron 表达式使用 croner 解析支持 5 字段分 时 日 月 周或 6 字段秒 分 时 日 月 周。如果省略时区默认使用 Gateway 主机的本地时区。这一点很容易踩坑你以为写的是 UTC结果跑的是本地时间。# 每天 7:00 运行本地时区 0 7 * * * # 每 2 小时运行一次 0 */2 * * * # 每分钟运行一次6 字段带秒 0 * * * * *OpenClaw 对周期性的整点表达式比如0 * * * *、0 */2 * * *会自动应用一个确定性的错开窗口每个任务最多错开 5 分钟。这是为了减少多个 Gateway 在整点时的负载峰值。固定小时的表达式比如0 7 * * *保持精确不会错开。如果你想显式控制错开窗口可以用--stagger参数openclaw cron add \ --name Minute watcher \ --cron 0 * * * * * \ --tz UTC \ --stagger 30s \ --session isolated \ --message Run minute watcher checks. \ --announce如果希望严格按计划运行、不要任何错开用--exact强制设置staggerMs 0。3.2 日志巡检任务的配置骨架假设你要每小时巡检一次应用日志发现 ERROR 关键字就生成摘要并推送到 Slack。这是一个典型的隔离任务因为巡检过程不需要污染主会话的上下文。openclaw cron add \ --name Log patrol \ --cron 0 * * * * \ --tz Asia/Shanghai \ --session isolated \ --message 读取 /var/log/app/error.log 最近 200 行统计 ERROR 和 WARN 的数量如果有 ERROR 则列出前 5 条并给出可能的原因分析。 \ --announce \ --channel slack \ --to channel:C1234567890 \ --light-context这里有几个关键参数值得说明。--session isolated表示在专用的cron:会话中运行每次运行都是新的会话 id不会延续之前的对话。--light-context使用精简引导上下文适合不需要工作区引导文件注入的巡检任务能减少不必要的 token 消耗。--announce表示把结果传递到指定频道。3.3 数据同步任务的配置骨架数据同步通常需要保持上下文比如每天同步时要知道上次同步到哪个位置。这时候用自定义持久化会话更合适openclaw cron add \ --name Data sync \ --cron 0 2 * * * \ --tz Asia/Shanghai \ --session session:data-sync-monitor \ --message 检查上游数据源的最新时间戳与本地 /data/last_sync.txt 对比如果有新数据则执行同步脚本 /opt/scripts/sync.sh并更新 last_sync.txt。 \ --announce \ --channel telegram \ --to -1001234567890:topic:123session:data-sync-monitor是一个持久化的命名会话多次运行之间会保持上下文。这意味着 agent 能记住上次同步的状态适合每日站会、项目监控这类需要“接着上次说”的工作流。3.4 一次性提醒与手动触发除了周期性任务OpenClaw 也支持一次性任务。比如创建一个 20 分钟后触发的提醒openclaw cron add \ --name Calendar check \ --at 20m \ --session main \ --system-event Next heartbeat: check calendar. \ --wake now--at接受 ISO 8601 时间戳或人类可读的持续时间如20m。如果省略时区ISO 时间戳会被视为 UTC。一次性任务默认在成功执行后自动删除设置--delete-after-run可以显式声明这个行为。手动触发一个已存在的任务openclaw cron run job-idcron.run现在只在手动运行被排队后确认而不是在任务完成后。成功的排队响应类似{ ok: true, enqueued: true, runId }。要检查最终完成情况用openclaw cron runs --id job-id --limit 504. 验证请求手动触发加日志核对配置完调度之后不要干等下一个整点。最稳妥的验证方式是手动触发一次然后核对运行日志。第一步列出所有任务找到刚创建的 job-idopenclaw cron list第二步手动强制运行openclaw cron run job-id第三步查看运行历史openclaw cron runs --id job-id --limit 10运行历史存储在~/.openclaw/cron/runs/job-id.jsonl是 JSONL 格式按大小和行数自动修剪。默认maxBytes是 2MBkeepLines是 2000 行。如果你在运行历史里看到了完成条目并且--announce的目标频道收到了消息说明调度链路是通的。第四步检查任务存储文件cat ~/.openclaw/cron/jobs.json | python3 -m json.tool这个文件由 Gateway 管理手动编辑只在 Gateway 停止时是安全的。更推荐用openclaw cron edit或 cron 工具调用 API 来修改。如果你用的是隔离任务还可以检查运行会话的保留情况。隔离运行会创建会话条目...:cron:jobId:run:runId和转录文件由cron.sessionRetention修剪默认 24 小时。5. 本篇常见错排查5.1 “任务创建了但什么都没跑”先检查 cron 是否启用。配置里cron.enabled默认为 true但环境变量OPENCLAW_SKIP_CRON1会完全禁用 cron。另外确认 Gateway 是否持续运行因为 cron 在 Gateway 进程内部运行Gateway 停了调度自然就停了。对于 cron 调度重点确认时区。--tz参数和主机时区是否匹配如果省略时区cron 表达式使用 Gateway 主机的本地时区而schedule.at的 ISO 时间戳省略时区时被视为 UTC。这两个默认行为不一致很容易搞混。5.2 周期性任务失败后持续延迟OpenClaw 对周期性任务在连续错误后应用指数退避30 秒、1 分钟、5 分钟、15 分钟然后重试间隔变为 60 分钟。退避会在下一次成功运行后自动重置。如果你看到任务“越来越晚”先去看运行历史里的错误类型。瞬时错误速率限制 429、提供者过载、网络错误、5xx 服务器错误会触发重试。永久错误认证失败、配置验证错误会立即禁用任务。一次性任务schedule.kind: at对瞬时错误最多重试 3 次采用指数退避30 秒 → 1 分钟 → 5 分钟。5.3 Telegram 传递到错误的地方Telegram 的论坛主题需要用:topic:形式编码到to字段中--to -1001234567890:topic:123如果你在日志或存储的“最后路由”目标中看到telegram:...前缀这是正常的cron 传递接受它们并且仍然能正确解析主题 ID。但为了确定性路由建议始终使用显式的:topic:标记。5.4 运行日志增长过快高频率的 cron 设置会产生大量的运行会话和运行日志。如果你发现~/.openclaw/cron/runs/目录增长很快可以调整配置{ cron: { sessionRetention: 12h, runLog: { maxBytes: 3mb, keepLines: 1500 } } }把嘈杂的后台任务移到隔离模式并设置合适的传递规则避免不必要的通信。定期用openclaw cron runs检查增长情况在日志变得过大之前调整保留策略。5.5 模型覆盖导致上下文切换隔离任务可以覆盖模型和思考级别openclaw cron add \ --name Deep analysis \ --cron 0 6 * * 1 \ --session isolated \ --message Weekly deep analysis. \ --model opus \ --thinking high但注意你也可以在主会话任务上设置 model这会更改共享的主会话模型。建议只在隔离任务上使用模型覆盖避免意外的上下文切换。解析优先级是任务有效负载覆盖 钩子特定默认值 Agent 配置默认值。6. 把调度接进你的日常工作流Cron 调度的价值不在于“能定时跑”而在于把那些重复的、需要按节奏执行的 CLI 工作流固化下来。日志巡检、数据同步、每日摘要、项目监控这些任务一旦配好你就不需要再记“今天有没有跑”。如果你还在手动敲命令的阶段建议先从一条最简单的周期性隔离任务开始用--announce把结果推到一个你常看的频道。跑通之后再逐步加上--light-context、模型覆盖、自定义会话这些进阶配置。对于需要长期运行编码任务或 Agent 工作流的场景可以了解 Coding PlanCoding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite如果你更想先在对话里验证模型效果可以直接用模型对话入口模型对话https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_contentmodel-chatutm_campaignrewrite调度配好之后记得定期用openclaw cron runs --id job-id看一眼运行历史。我自己的习惯是每周扫一次确认没有任务因为认证失败被静默禁用。这个动作花不了两分钟但能避免“以为在跑其实早就停了”的尴尬。