定时任务(Gateway 调度器)
Cron 还是 Heartbeat? 参考 Cron vs Heartbeat 了解何时使用哪一种。Cron 是 Gateway 内置的调度器。它会持久化作业,在合适时间唤醒代理,并可选地把输出发送回聊天。 如果你想要 “每天早上运行一次” 或 “20 分钟后提醒我”,cron 就是机制。
TL;DR
- Cron 在 Gateway 内部运行(不在模型内部)。
- 作业保存在
~/.openclaw/cron/,重启不会丢失计划。 - 两种执行风格:
- 主会话:排队一个系统事件,在下一次心跳中运行。
- 隔离:在
cron:<jobId>中运行独立的代理轮次,可选发送输出。
- 唤醒是第一等能力:作业可以请求“现在唤醒”或“下次心跳”。
新手友好概览
把 cron 作业理解为:什么时候运行 + 做什么。-
选择调度方式
- 单次提醒 →
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"
- 主会话 →
deleteAfterRun: true 会在单次作业成功后从存储中移除。
概念
作业
一个 cron 作业是一个持久化记录,包含:- schedule(何时运行)、
- payload(做什么)、
- 可选的 delivery(输出要发送到哪里)。
- 可选 agent 绑定(
agentId):用指定 agent 运行;缺失或未知时,Gateway 会回退到默认 agent。
jobId 标识(CLI/Gateway API 使用)。
在 agent 工具调用中,jobId 为规范字段;旧字段 id 为兼容而保留。
单次作业成功后可通过 deleteAfterRun: true 自动删除。
调度方式
Cron 支持三种调度类型:at:单次时间戳(epoch 毫秒)。Gateway 接受 ISO 8601 并转成 UTC。every:固定间隔(毫秒)。cron:5 字段 cron 表达式,可选 IANA 时区。
croner。如未指定时区,使用 Gateway 主机的本地时区。
主会话 vs 隔离执行
主会话作业(系统事件)
主会话作业会排队一个系统事件,并可选唤醒心跳运行器。 必须使用payload.kind = "systemEvent"。
wakeMode: "next-heartbeat"(默认):事件等待下一次计划心跳。wakeMode: "now":触发一次立即心跳运行。
隔离作业(专用 cron 会话)
隔离作业会在会话cron:<jobId> 中运行一次独立代理轮次。
关键行为:
- 提示词会加上
[cron:<jobId> <job name>]前缀,便于追踪。 - 每次运行都会使用 全新的会话 id(不继承旧对话)。
- 会将摘要发布到主会话(前缀
Cron,可配置)。 wakeMode: "now"会在发布摘要后立即触发心跳。- 若
payload.deliver: true,输出会投递到频道;否则保持内部。
载荷结构(运行什么)
支持两类载荷:systemEvent:仅主会话,通过心跳提示词路由。agentTurn:仅隔离会话,运行独立代理轮次。
agentTurn 字段:
message:必需的文本提示词。model/thinking:可选覆盖(见下)。timeoutSeconds:可选超时覆盖。deliver:true时把输出发送到频道目标。channel:last或具体频道。to:频道的具体目标(手机号/聊天/频道 id)。bestEffortDeliver:投递失败也不让作业失败。
session=isolated):
postToMainPrefix(CLI:--post-prefix):发布到主会话的系统事件前缀。postToMainMode:summary(默认)或full。postToMainMaxChars:postToMainMode=full时的最大字符数(默认 8000)。
模型与 thinking 覆盖
隔离作业(agentTurn)可以覆盖模型与 thinking 级别:
model:Provider/model 字符串(如anthropic/claude-sonnet-4-20250514)或别名(如opus)thinking:thinking 级别(off、minimal、low、medium、high、xhigh;仅 GPT-5.2 + Codex 模型)
model,但这会改变共享的主会话模型。
我们建议只在隔离作业中做模型覆盖,以避免意外的上下文切换。
优先级顺序:
- 作业载荷覆盖(最高)
- Hook 特定默认值(例如
hooks.gmail.model) - Agent 配置默认值
投递(频道 + 目标)
隔离作业可以把输出投递到频道。作业载荷可指定:channel:whatsapp/telegram/discord/slack/mattermost(插件)/signal/imessage/lastto:频道的具体接收目标
channel 或 to 缺失,cron 可以回退到主会话的“last route”(代理上一次回复的地方)。
投递说明:
- 只要设置了
to,即便省略deliver,cron 也会自动投递最终输出。 - 想要不显式设置
to也投递到 last route,请使用deliver: true。 - 用
deliver: false可以即使存在to也不投递,让输出保持内部。
- Slack/Discord/Mattermost(插件)目标应使用显式前缀(例如
channel:<id>、user:<id>),避免歧义。 - Telegram 话题应使用
:topic:形式(见下)。
Telegram 投递目标(话题 / 论坛线程)
Telegram 通过message_thread_id 支持论坛话题。对于 cron 投递,可将话题/线程编码进 to 字段:
-1001234567890(仅 chat id)-1001234567890:topic:123(推荐:显式话题标记)-1001234567890:123(简写:数字后缀)
telegram:group:-1001234567890:topic:123
存储与历史
- 作业存储:
~/.openclaw/cron/jobs.json(Gateway 管理的 JSON)。 - 运行历史:
~/.openclaw/cron/runs/<jobId>.jsonl(JSONL,自动清理)。 - 覆盖存储路径:配置中的
cron.store。
配置
cron.enabled: false(config)OPENCLAW_SKIP_CRON=1(env)