定时任务(Gateway网关调度器)
定时任务还是心跳? 请参阅定时任务与心跳对比了解何时使用哪种方式。Cron 是 Gateway 的内置调度器。 它会持久化作业,在合适的时间唤醒代理,并且可选地将输出回传到聊天中。 如果你想要 “每天早上运行” 或 “20 分钟后提醒智能体”,定时任务就是对应的机制。 故障排查:/automation/troubleshooting
TL;DR
- 定时任务运行在 Gateway网关内部(而非模型内部)。
- 任务持久化存储在
~/.openclaw/cron/下,因此重启不会丢失计划。 - 两种执行方式:
- 主会话:入队一个系统事件,然后在下一次心跳时运行。
- 隔离式:在
cron:<jobId>中运行专用智能体轮次,可投递摘要(默认 announce)或不投递。
- 唤醒是一等功能:任务可以请求”立即唤醒”或”下次心跳时”。
快速开始(可操作)
创建一个一次性提醒,验证其存在,然后立即运行:工具调用等价形式(Gateway网关定时任务工具)
有关规范的 JSON 结构和示例,请参阅工具调用的 JSON 模式。定时任务的存储位置
定时任务默认持久化存储在 Gateway网关主机的~/.openclaw/cron/jobs.json 中。Gateway网关将文件加载到内存中,并在更改时写回,因此仅在 Gateway网关停止时手动编辑才是安全的。请优先使用 openclaw cron add/edit 或定时任务工具调用 API 进行更改。
Gateway 会将该文件加载到内存中,并在发生更改时写回,因此只有在 Gateway 停止时手动编辑才是安全的。 5. 更改时优先使用 openclaw cron add/edit 或 cron
工具调用 API。
新手友好概述
将定时任务理解为:何时运行 + 做什么。-
选择调度计划
- 一次性提醒 →
schedule.kind = "at"(CLI:--at) - 重复任务 →
schedule.kind = "every"或schedule.kind = "cron" - 如果你的 ISO 时间戳省略了时区,将被视为 UTC。
- 一次性提醒 →
-
选择运行位置
sessionTarget: "main"→ 在下一次心跳时使用主会话上下文运行。sessionTarget: "isolated"→ 在cron:<jobId>中运行专用智能体轮次。
-
选择负载
- 主会话 →
payload.kind = "systemEvent" - 隔离会话 →
payload.kind = "agentTurn"
- 主会话 →
schedule.kind = "at")默认会在成功运行后删除。设置
deleteAfterRun: false 可保留它(成功后会禁用)。 19. 设置
deleteAfterRun: false 以保留它们(成功后将被禁用)。
概念
21. 作业
定时任务是一条存储记录,包含:- 一个调度计划(何时运行),
- 一个负载(做什么),
- 可选的投递(输出发送到哪里)。
-
- 可选的 代理绑定(
agentId):在特定代理下运行作业;如果 缺失或未知,Gateway 将回退到默认代理。
- 可选的 代理绑定(
- 作业通过稳定的
jobId标识(由 CLI/Gateway API 使用)。 - 在代理工具调用中,
jobId是规范字段;为兼容性也接受旧的id。 - 一次性作业默认在成功后自动删除;设置
deleteAfterRun: false可保留它们。
调度计划
定时任务支持三种调度类型:at:一次性时间戳(ISO 8601 字符串)。every:固定间隔(毫秒)。cron:5 字段 cron 表达式,可选 IANA 时区。
croner。如果省略时区,将使用 Gateway网关主机的本地时区。 36. 如果省略时区,则使用 Gateway 主机的
本地时区。
主会话与隔离式执行
主会话任务(系统事件)
- 主作业会入队一个系统事件,并可选择唤醒心跳运行器。
- 它们必须使用
payload.kind = "systemEvent"。
wakeMode: "now":事件触发立即心跳运行。wakeMode: "next-heartbeat"(默认):事件等待下一次计划心跳。
- 当你需要正常的心跳提示 + 主会话上下文时,这是最佳选择。
- 参见 Heartbeat。
隔离任务(专用定时会话)
隔离任务在会话cron:<jobId> 中运行专用智能体轮次。
关键行为:
- 提示以
[cron:<jobId> <任务名称>]为前缀,便于追踪。 - 每次运行都会启动一个全新的会话 ID(不继承之前的对话)。
- 任务通过稳定的
jobId标识(用于 CLI/Gateway网关 API)。 在智能体工具调用中,jobId是规范字段;旧版id仍可兼容使用。 一次性任务默认会在成功运行后自动删除;设置deleteAfterRun: false可保留它。 -
announce:将摘要投递到目标频道,并在主会话中发布一条简要摘要。
-
none:仅内部使用(不投递,也不发布主会话摘要)。
-
wakeMode控制主会话摘要何时发布:
-
now:立即心跳。
-
next-heartbeat:等待下一个计划的心跳。
- 当你需要正常的心跳提示 + 主会话上下文时,这是最佳选择。参见心跳。
负载结构(运行内容)
支持两种负载类型:systemEvent:仅限主会话,通过心跳提示路由。agentTurn:仅限隔离会话,运行专用智能体轮次。
agentTurn 字段:
message:必填文本提示。model/thinking:可选覆盖(见下文)。timeoutSeconds:可选超时覆盖。
delivery.mode:none|announce。
delivery.mode可选announce(投递摘要)或none(内部运行)。- 当启用 announce 投递时,该轮次会抑制消息工具发送;请使用
delivery.channel/delivery.to来指定目标。 - Telegram 通过
message_thread_id支持论坛主题。对于定时任务投递,你可以将主题/帖子编码到to字段中: -
- 公告投递会抑制该运行中的消息工具发送;请使用
delivery.channel/delivery.to将消息定向到聊天。
- 公告投递会抑制该运行中的消息工具发送;请使用
- 当
delivery.mode = "none"时,不会向主会话发布摘要。 23. 如果隔离作业省略了delivery,OpenClaw 默认使用announce。
delivery,隔离任务会默认以“announce”方式投递摘要。
25. 当 delivery.mode = "announce" 时,cron 会通过出站频道适配器直接投递。
- 不会启动主代理来编写或转发消息。
- 行为细节:
-
- 仅心跳响应(没有实际内容的
HEARTBEAT_OK)不会被投递。
- 仅心跳响应(没有实际内容的
-
- 如果隔离运行已通过消息工具向同一目标发送过消息,为避免重复,将跳过投递。
-
- 缺失或无效的投递目标会使作业失败,除非
delivery.bestEffort = true。
- 缺失或无效的投递目标会使作业失败,除非
delivery.bestEffort:投递失败时避免任务失败-
- 主会话摘要遵循
wakeMode:now会触发立即心跳,next-heartbeat则等待下一个计划的心跳。
- 主会话摘要遵循
- 主会话任务入队一个系统事件,并可选择唤醒心跳运行器。它们必须使用
payload.kind = "systemEvent"。
模型和思维覆盖
隔离任务(agentTurn)可以覆盖模型和思维级别:
model:提供商/模型字符串(例如anthropic/claude-sonnet-4-20250514)或别名(例如opus)thinking:思维级别(off、minimal、low、medium、high、xhigh;仅限 GPT-5.2 + Codex 模型)
model,但这会更改共享的主会话模型。我们建议仅对隔离任务使用模型覆盖,以避免意外的上下文切换。 40. 解析优先级:
优先级解析顺序:
- 任务负载覆盖(最高优先级)
- 钩子特定默认值(例如
hooks.gmail.model) -
- 投递(频道 + 目标)
投递(渠道 + 目标)
隔离任务可以通过顶层delivery 配置投递输出:
delivery.mode:announce(投递摘要)或nonedelivery.channel:whatsapp/telegram/discord/slack/mattermost(插件)/signal/imessage/lastdelivery.to:渠道特定的接收目标
- 如果省略
delivery.channel或delivery.to,cron 可以回退到主会话的 “最后路由”(代理最后一次回复的位置)。
delivery.channel 或 delivery.to,定时任务会回退到主会话的“最后路由”(智能体最后回复的位置)。
目标格式提醒:
- Slack/Discord/Mattermost(插件)目标应使用明确前缀(例如
channel:<id>、user:<id>)以避免歧义。 - Telegram 主题应使用
:topic:格式(见下文)。
Telegram 投递目标(主题/论坛帖子)
- Telegram 通过
message_thread_id支持论坛主题。 6. 对于 cron 投递,你可以将主题/线程编码到to字段中:
-1001234567890(仅聊天 ID)-1001234567890:topic:123(推荐:明确的主题标记)-1001234567890:123(简写:数字后缀)
telegram:... / telegram:group:... 也可接受:
telegram:group:-1001234567890:topic:123
工具调用的 JSON 模式
- 直接调用 Gateway
cron.*工具时(代理工具调用或 RPC)请使用以下结构。 直接调用 Gateway网关cron.*工具(智能体工具调用或 RPC)时使用这些结构。CLI 标志接受人类可读的时间格式如20m,但工具调用应使用 ISO 8601 字符串作为schedule.at,并使用毫秒作为schedule.everyMs。
cron.add 参数
一次性主会话任务(系统事件):schedule.kind:at(at)、every(everyMs)或cron(expr,可选tz)。schedule.at接受 ISO 8601(可省略时区;省略时按 UTC 处理)。everyMs为毫秒数。sessionTarget必须为"main"或"isolated",且必须与payload.kind匹配。- 可选字段:
agentId、description、enabled、deleteAfterRun、delivery。 wakeMode省略时默认为"next-heartbeat"。
cron.update 参数
jobId是规范字段;id可兼容使用。- 在补丁中使用
agentId: null可清除智能体绑定。
cron.run 和 cron.remove 参数
存储与历史
- 任务存储:
~/.openclaw/cron/jobs.json(Gateway网关管理的 JSON)。 - 运行历史:
~/.openclaw/cron/runs/<jobId>.jsonl(JSONL,自动清理)。 - 覆盖存储路径:配置中的
cron.store。
配置
cron.enabled: false(配置)OPENCLAW_SKIP_CRON=1(环境变量)
CLI 快速开始
一次性提醒(UTC ISO,成功后自动删除):--due to only run when due):
Gateway网关 API 接口
cron.list、cron.status、cron.add、cron.update、cron.removecron.run(强制或到期)、cron.runs如需不创建任务直接发送系统事件,请使用openclaw system event。
故障排除
”没有任何任务运行”
- 检查定时任务是否已启用:
cron.enabled和OPENCLAW_SKIP_CRON。 - 检查 Gateway网关是否持续运行(定时任务运行在 Gateway网关进程内部)。
- 对于
cron调度:确认时区(--tz)与主机时区的关系。
A recurring job keeps delaying after failures
- OpenClaw applies exponential retry backoff for recurring jobs after consecutive errors: 30s, 1m, 5m, 15m, then 60m between retries.
- Backoff resets automatically after the next successful run.
- One-shot (
at) jobs disable after a terminal run (ok,error, orskipped) and do not retry.
Telegram 投递到了错误的位置
- 对于论坛主题,使用
-100…:topic:<id>以确保明确无歧义。 - 如果你在日志或存储的”最后路由”目标中看到
telegram:...前缀,这是正常的;定时任务投递接受这些前缀并仍能正确解析主题 ID。