
进阶 · 定时任务
OpenClaw 定时任务怎么建:每天 9 点发日报、20 分钟后提醒,到点不执行怎么查
建定时任务用 openclaw automations create(add 是同一条命令),时间写在第一个位置,要龙虾做的事写在第二个位置:
openclaw automations create "0 9 * * *" "汇总昨晚到现在的更新,用中文写。" --name "Overnight updates"
OpenClaw 文档现在把定时任务叫 automations。这条是每天 9 点跑一次,9 点按 Gateway 所在机器的时区算。从命令行建的这类任务默认在独立会话里执行,执行完的最后一段回复默认往聊天频道发。这条没写去向,调度器会退回到会话历史里的路由,或机器上唯一接着的那个频道;建任务时命令的输出里带一段投递路由预览,写明解析到了哪条路由,还是会放弃发送。要稳妥就加 --channel 和 --to 写明发到哪个群;机器上接了多个频道的,--channel 必须写。不想发出来,加 --no-deliver。
openclaw cron 还能用。命令行参考写的是两个拼法指向同一组命令,每个子命令两边都认,旧脚本里的 openclaw cron list 不用改;配置文件里相关的键也还叫 cron.*。2026.9.7 移除的 Tasks 是另一样东西,调度器还在,已经建好的定时任务怎么确认,见下文「升到 2026.9.7 后 Tasks 不见了」一节。
「20 分钟后提醒我」这种一次性提醒怎么建
一次性任务用 --at,写法同官方管理页的 One-shot reminder 示例。这里的 add 换成 create 也一样;时间可以像开头那样放在第一个位置,也可以像这条用 --at 给:
openclaw automations add \
--name "Calendar check" \
--at "20m" \
--session main \
--system-event "提醒:去看一眼日历。" \
--wake now
--at "20m":从现在起 20 分钟后。这里也可以写 ISO 8601 时间戳,例如文档 Quick start 里的2027-02-01T16:00:00Z。--session main:在这个 agent 的主会话里执行。主会话提醒用的是这个会话自己的投递上下文,不能另指定发到哪个频道;要发到指定频道,用独立会话的任务。--system-event:往主会话里排进一条系统事件,这一步本身不调用模型。要让龙虾动脑子处理一件事,用的是--message,那是一次有模型参与的 agent 回合;文档把它列为独立会话、当前会话和自定义会话任务的提示词参数;下一节的日报示例把同样的提示词放在第二个位置参数里给。--wake now:事件排进去以后立即唤醒心跳来处理;另一个取值是--wake next-heartbeat,等下一次心跳再处理。
要定在某个具体时刻,留意时区:不带时区的时间戳按 UTC 算。想按北京时间写,就不带偏移量,再加一个 --tz:
openclaw automations add \
--name "Reminder" \
--at "2027-02-01T09:00:00" \
--tz "Asia/Shanghai" \
--session main \
--system-event "提醒:把周报发出去。" \
--wake now
一次性任务成功跑完会自动删除,想留着就加 --keep-after-run。
每天早上 9 点发日报的周期任务,命令和每个参数怎么写
每天北京时间 9 点把汇总发到一个 Telegram 群,命令是这样(结构同官方的 Morning brief 示例):
openclaw automations create "0 9 * * *" \
"汇总昨晚到现在的更新,写成一份日报。用中文回答,网址、代码和产品名保持原样。" \
--name "Morning brief" \
--tz "Asia/Shanghai" \
--session isolated \
--announce \
--channel telegram \
--to "-1001234567890"
- 第一个位置参数是日程。可以填 cron 表达式、
every 1h这样的间隔、20m这样的相对时长,或一个 ISO 时间戳。 - 第二个位置参数是给 agent 的提示词,官方另一些示例用
--message来给。定时任务不会根据频道或之前的消息推断回复语言,要中文就写进提示词里。 --tz:cron 表达式按哪个 IANA 时区算。--session isolated:每个任务用自己专属的cron:<jobId>会话,报告和后台杂务适合用这一种。可选值还有main、current、session:<id>。--announce --channel telegram --to "-1001234567890":把最后的回复发到这个 Telegram 群。--to换成你自己的群或频道 ID。
没写 --agent 时,命令会给一条警告,然后落到默认的 main agent。机器上配了多个 agent 的,建的时候加 --agent ops 这样的参数指定归属;多 agent 的配置见《一台龙虾跑多个 agent:工作和私人分开怎么配》。
日报、分类、状态检查这类例行任务,官方的建议是按任务难度选模型,用轻一档的,每次更省更快,写法是加 --model。指定的模型不在允许范围内,那一次运行会直接报校验错误,不会悄悄换回默认模型。
不想敲命令也有两条路。在聊天里,owner 可以用 /loop [interval] <prompt> 建一个绑定当前对话的周期任务,/loop status 查看,/loop stop [name] 删除。另一条是直接让龙虾做:同一件事你让它做过几次,它会提议改成定时,复述时间和内容让你确认;确认后它建好任务并立刻试跑一次,试跑失败就把任务删掉并告诉你。
时间怎么写:--at、--every、--cron 的区别和时区
日程文档里按时间触发的类型有三种:
| 类型 | 参数 | 什么时候触发 |
|---|---|---|
| at | --at | 只跑一次。ISO 8601 时间戳,或 20m 这样的相对时长 |
| every | --every | 固定间隔,如 10m、1h、1d |
| cron | --cron | 5 段或 6 段 cron 表达式,可配 --tz |
时区有三条规则。cron 表达式不带 --tz,用 Gateway 主机的时区;--at 的时间戳不带时区,按 UTC;--tz 不能和 --every 一起用。龙虾装在一台时区是 UTC 的云服务器上、又没写 --tz 的,0 9 * * * 会在北京时间 17 点跑。
分钟是 0、小时是通配符的表达式(如 0 * * * *)会被自动错开最多 5 分钟,要准点加 --exact。
cron 表达式里「日」和「星期」两段都不是通配符时,两者是「或」的关系:
# 本意:15 号且正好是周一的 9 点
# 实际:每月 15 号的 9 点,加上每个周一的 9 点
0 9 15 * 1
这样写一个月会触发五六次。要两个条件同时满足,有两个办法:用解析库 croner 的 + 修饰符写成 0 9 15 * +1;或者日程只按其中一段排,另一个条件放进提示词或命令里判断。
日报会发到哪个频道,不想发出来怎么设
去向有三种模式,各对应一个参数:
| 模式 | 参数 | 效果 |
|---|---|---|
| announce | --announce | agent 自己没发消息时,由调度器把最后的回复发到目标频道 |
| webhook | --webhook <url> | 把这次运行的结果 POST 到一个 URL |
| none | --no-deliver | 调度器不代发 |
独立会话的任务默认就是 announce。目标的写法跟着频道走:Telegram 直接写群 ID,如 --to "-1001234567890";Slack、Discord、Mattermost 要带前缀,写成 channel:<id> 或 user:<id>。--webhook 不能和 --announce、--channel、--to 这些聊天参数混用。频道本身还没接好的,先看《用龙虾自动回 Telegram/微信消息(配置教程)》。
--no-deliver 关掉的只是调度器的代发。有可用的聊天路由时,agent 仍然可以在运行中用 message 工具自己发消息。
还有一种做法适合「有事才说」的任务:在提示词里约定,没有可报的内容时只回复 NO_REPLY。纯文本的回复只含这个标记、或以它结尾的,整条都不会发出去。反过来,该送到的日报末尾不要带它。
建好以后改去向不用重建:
openclaw automations edit <job-id> --announce --channel slack --to "channel:C1234567890"
openclaw automations edit <job-id> --no-deliver
任务连续失败,调度器会发提醒。有 announce 目标的任务,默认在连续失败 2 次后往那个目标发一条失败提醒,冷却时间 1 小时;同一个原因的反复失败算作一起,不会一遍遍提醒。
建了哪些定时任务、昨晚那次跑没跑,用哪条命令查
openclaw automations list
openclaw automations list --all
openclaw automations show <job-id>
openclaw automations get <job-id>
openclaw automations runs <job-id> --limit 50
list 默认只列启用中的任务,各个 agent 的都在里面;加 --all 才带上已停用的。任务 ID 从这里拿。
show 给人看:一个任务的详情,连同解析出来的投递路由,也就是它实际会发到哪。它还接受任务名,名字完全一致即可,不分大小写;重名时它会报有歧义并列出各任务的完整 ID,这时改用 ID。get 给脚本用,直接输出存下来的任务 JSON。
runs 是运行历史,昨晚那次跑没跑看这里。每条记录有两个状态要分开读:status 是任务本身执行得怎样,取值 ok、error、skipped;completionStatus 是连同送达在内整件事有没有完成,取值 succeeded、failed、unknown。执行成功但要求的送达失败,记成 status: "ok" 加 completionStatus: "failed"。
只想看出问题的那几次,用筛选:
openclaw automations runs <job-id> --status error
openclaw automations runs <job-id> --delivery-status not-delivered
openclaw automations runs --all --status error --limit 20
最后一条不带任务 ID,查的是所有任务合在一起的历史。运行历史保留 7 天,每个任务另有只留最新 2000 条的上限。
定时任务到点不执行,按这个顺序查
排障页给了一组从外到内的命令:
openclaw status
openclaw gateway status
openclaw automations status
openclaw automations list
openclaw automations runs <job-id> --limit 20
openclaw system heartbeat last
openclaw logs --follow
openclaw doctor
这组命令跑完,按下面几项逐个排除。
Gateway 在不在跑、调度有没有被关
定时任务在 Gateway 进程里执行,不在模型里。Gateway 没在运行,到点就不会触发;openclaw automations 这组命令本身也要连上运行中的 Gateway 才有结果。
配置里的 cron.enabled: false,或者 Gateway 启动环境里的 OPENCLAW_SKIP_CRON=1,任何一个都会停掉自动运行。两个都清掉,再重启 Gateway。
默认情况下,Gateway 离线期间错过的周期任务会在启动后补上;不过启动时不会立刻执行逾期的 agent 任务,而是重新排期,避免一开机就调用模型。把 cron.skipMissedJobs 设成 true 的,错过的那几次直接跳过,推到下一个未来的时间点。
任务是不是被停用、时区对不对
openclaw automations list 里找不到它,换 openclaw automations list --all。按时间触发的周期任务连续执行失败 10 次会被自动停用,日程反复算不出来的,出错 3 次也会。把会话归档,同样会停用绑在那个会话上的任务,恢复会话不会把它们重新打开。处理完原因后执行:
openclaw automations enable <job-id>
任务没被停用,再对照上面「时间怎么写」那一节的三条规则,用 show 看它记下的日程和下一次运行时间是不是你想的那个钟点。
运行历史里记了什么
runs 里有记录、状态是 skipped 或 error,说明到点触发了,只是没跑成。记录里带着摘要和错误信息。记成 skipped 的一种情况是任务指向本机或内网的模型服务(Ollama、vLLM、LM Studio 这类):调度器会先探一下端点,连不上就把这次记为 skipped,等后面的日程再试。连续 error 之后,周期任务按 30 秒、1 分钟、5 分钟、15 分钟、60 分钟的间隔退避,下一次成功后恢复原来的节奏。手动用 openclaw automations run <job-id> --due 检查时输出 reason: not-due,意思只是任务还没到点。
跑了但消息没收到
这不算「没执行」。先用 show 看投递模式是不是 none。不是 none 的,用 openclaw automations runs <job-id> --delivery-status not-delivered 找出那几次,再对照:回复是不是以 NO_REPLY 结尾;--channel 和 --to 有没有缺或写错,缺了或无效时发送会被跳过;频道报 unauthorized 或 Forbidden 的,发送是被凭证拦下的;接了多个频道却没指定 --channel。
都对不上,再开着 openclaw logs --follow 等下一次触发,或者执行 openclaw doctor。
升到 2026.9.7 后 Tasks 不见了,原来的定时任务还在吗
2026.9.7 的发布说明有一节「Tasks and TaskFlow removal」:Tasks 和 TaskFlow 的面板、命令、API 都移除了。调度器不在其中,这一节还把 Cron 历史列为替代去处之一;Automation 总览页列的移除范围是共享的 Tasks 台账、TaskFlow 编排 API 和 TaskFlow Webhooks 插件。
升级后执行 openclaw automations list --all,看原来的定时任务是否都在;有没有跑,看 openclaw automations runs,也就是发布说明说的 Cron 历史。原先放在 Tasks 里的其它工作,发布说明给的去处是 subagent 控制、ACP 会话、后台进程和 Lobster 流水线;TaskFlow Webhooks 没有对应的 HTTP 替代。已有的 Task 和 Flow 记录会保留,部分 Codex 分派要手动迁移。手动替换安装后,启动前先执行 openclaw doctor --fix。这一版其它要改的设置见《OpenClaw 2026.9.7 更新内容、升级后要改的设置和两个已知故障》。
升级后提醒不来了,还有三种更早的改动可能对得上:
- Heartbeat scratch 里的
tasks:块。v2026.8.1 之前它可以当日程用,现在运行时不再解析。从更早的版本升上来,执行openclaw doctor --fix,每一条会被转成一个普通的、可编辑的主会话定时任务,原来的间隔和上次运行时间都保留。 - 从对话里自动记下的跟进事项。这个实验功能在 v2026.8.1 移除了,龙虾不再从聊天里提取待办并通过心跳提醒。要提醒,就明确建一个定时任务。
- 旧的文件存储。机器上还留着
jobs.json、<name>-state.json或runs/*.jsonl的,命令行参考给的路线是先装 2026.9.7 并执行openclaw doctor --fix,之后再升到最新版;2026.9.7 的发布说明对早于 2026 年 6 月的安装写的是先经 2026.9.5。拿不准走哪条,在当前版本上执行openclaw doctor:它会保留这些文件,并报出需要先经过的中间版本。
常见问题
- openclaw cron 和 openclaw automations 是两套东西吗?
- 不是。OpenClaw 命令行参考写的是这组命令注册为 openclaw cron,openclaw automations 是它的别名,每个子命令两种拼法都能用;Automations 文档页则以 openclaw automations 为主来写。两边操作的是同一批任务,openclaw cron list 和 openclaw automations list 列出的内容相同。
- 定时任务建好以后想改时间或提示词,要删掉重建吗?
- 不用,用 openclaw automations edit。日程参数(--at、--every、--cron 等)在 edit 上同样可用,会替换原来的日程;提示词用 --message 改,模型用 --model 改,去向用 --announce、--channel、--to 或 --no-deliver 改。暂时不想让它跑,用 openclaw automations disable,之后用 enable 恢复。
- 每小时整点的任务为什么晚了几分钟才跑?
- 这是有意的错峰。分钟为 0、小时为通配符的周期表达式会被自动错开,最多 5 分钟,用来减少整点的负载尖峰。要求准点就给任务加 --exact;想自己指定错开的范围,用 --stagger 加一个时长,例如 30s。这两个参数只对 cron 类型的日程有效。
- 一次性提醒执行完,在列表里找不到了,正常吗?
- 用 --at 建的一次性任务成功完成后会自动删除,想保留就在建的时候加 --keep-after-run。另一种情况是要求送达却没送到或结果不明,这时任务会以停用状态留下,默认的列表不显示停用的任务,要用 openclaw automations list --all 才看得到。
- 不想等到明天 9 点,能现在就试跑一次吗?
- 执行 openclaw automations run 加任务 ID 就行,默认是强制运行,不管到没到点;命令在这次运行排进队列后就返回,并给出一个 runId。要等它跑完再返回,加 --wait。结果用 openclaw automations runs 加任务 ID 和 --run-id 查看。手动跑一次不改变任务原来的周期。