1. OpenClaw Cron Jobs 工作机制详细报告
基于官方文档 + 多方资料综合整理 | 2026-02-28
1.1. 一、概述
OpenClaw 的 Cron 服务是内嵌于 Gateway 中的调度器,能够:
- 在指定时间触发 AI Agent 执行任务
- 支持一次性和周期性两种模式
- 将执行结果推送到聊天频道、Webhook 或仅记录日志
- 把 AI 助手从"被动响应工具"升级为主动执行者
核心架构位置:
用户配置 → Gateway 调度器 (Cron Service)
↓
┌───────────────┐
│ Main Session │ ← 注入主会话(共享上下文)
│ Isolated Job │ ← 独立会话(全新上下文)
└───────────────┘
↓
结果投递(Channel / Webhook / None)
1.2. 二、调度类型(Schedule Types)
1.2.1. at — 一次性定时执行
在指定时刻执行一次,执行完毕后自动删除(默认行为)。
| 参数 | 类型 | 说明 |
|---|---|---|
schedule.kind |
"at" |
声明为一次性任务 |
schedule.at |
ISO 8601 字符串 | 执行时间,无时区默认 UTC |
deleteAfterRun |
boolean | 成功后自动删除,默认 true |
示例:2 小时后提醒回电
openclaw cron add \
--name "Call back" \
--at "2h" \
--session main \
--system-event "Call the client" \
--wake now \
--delete-after-run
示例:指定精确时间
openclaw cron add \
--name "Meeting Reminder" \
--at "2026-02-01T16:00:00Z" \
--session main \
--system-event "Meeting starts now" \
--delete-after-run
注意: 一次性任务在任何终态(成功/失败/跳过)后都会被禁用,不会重试。
1.2.2. every — 固定间隔执行
按毫秒为单位定义固定周期,不关心精确时钟对齐。
| 参数 | 类型 | 说明 |
|---|---|---|
schedule.kind |
"every" |
声明为间隔任务 |
schedule.everyMs |
number | 间隔毫秒数 |
schedule.anchorMs |
number(可选) | 锚点时间戳,用于对齐起点 |
常用间隔换算:
| 时间 | 毫秒值 |
|---|---|
| 1 分钟 | 60,000 |
| 30 分钟 | 1,800,000 |
| 1 小时 | 3,600,000 |
| 6 小时 | 21,600,000 |
| 1 天 | 86,400,000 |
示例:每小时执行一次
openclaw cron add \
--name "Hourly Check" \
--every 3600000 \
--session isolated \
--message "Check for new emails and summarize"
警告: 常见错误是把
60000(1 分钟)误以为是 1 小时,导致费用爆炸。每 5 分钟调一次 LLM 约 $432/月。
1.2.3. cron — 标准 Cron 表达式
支持标准 5 字段(或含秒的 6 字段)Cron 语法,加可选 IANA 时区。
| 参数 | 类型 | 说明 |
|---|---|---|
schedule.kind |
"cron" |
声明为 Cron 表达式任务 |
schedule.expr |
string | 标准 Cron 表达式 |
schedule.tz |
string | IANA 时区标识符(如 America/Los_Angeles) |
schedule.staggerMs |
number | 抖动窗口(毫秒),0 表示精确执行 |
Cron 表达式格式(5 字段):
┌─────────── 分钟 (0-59)
│ ┌───────── 小时 (0-23)
│ │ ┌─────── 日期 (1-31)
│ │ │ ┌───── 月份 (1-12)
│ │ │ │ ┌─── 星期几 (0-7, 0和7都表示周日)
│ │ │ │ │
* * * * *
常用表达式示例:
| 表达式 | 含义 |
|---|---|
0 7 * * * |
每天早上 7:00 |
0 7 * * 1-5 |
工作日每天早上 7:00 |
0 9,17 * * * |
每天 9:00 和 17:00 |
*/30 * * * * |
每 30 分钟 |
0 0 1 * * |
每月 1 日午夜 |
0 0 * * 0 |
每周日午夜 |
示例:工作日每天早上 7 点推送晨报(洛杉矶时间)
openclaw cron add \
--name "Morning Brief" \
--cron "0 7 * * 1-5" \
--tz "America/Los_Angeles" \
--session isolated \
--message "Summarize weather, calendar events, and top emails" \
--announce \
--channel slack \
--to "channel:C1234567890"
1.3. 三、执行模式(Session Target)
1.3.1. Main Session — 主会话模式
将任务注入到主会话的心跳工作流中,共享完整的对话历史。
| 参数 | 值 | 说明 |
|---|---|---|
sessionTarget |
"main" |
使用主会话 |
payload.kind |
"systemEvent" |
必须使用系统事件载荷 |
wakeMode |
"now" | "next-heartbeat" |
唤醒时机 |
wakeMode 详解:
| 值 | 行为 | 适用场景 |
|---|---|---|
"now" |
立即触发心跳,等待完成(最多 2 分钟) | 时效性强的提醒 |
"next-heartbeat" |
非阻塞,等下一次心跳处理 | 后台低优先级任务 |
适用场景: 需要利用已有对话上下文的任务,如"继续上次讨论的项目检查"。
1.3.2. Isolated Session — 独立会话模式
在独立的 cron:<jobId> 会话中运行,每次执行都从零开始,不携带历史对话。
| 参数 | 值 | 说明 |
|---|---|---|
sessionTarget |
"isolated" |
使用独立会话 |
payload.kind |
"agentTurn" |
必须使用 Agent 轮次载荷 |
agentTurn 载荷参数:
| 参数 | 类型 | 说明 |
|---|---|---|
payload.message |
string(必填) | 发给 Agent 的提示词 |
payload.model |
string(可选) | 覆盖模型,如 "claude-opus-4-6" |
payload.thinking |
string(可选) | 思考深度:off/minimal/low/medium/high/xhigh |
payload.timeoutSeconds |
number(可选) | 执行超时秒数 |
allowUnsafeExternalContent |
boolean(可选) | 允许不安全外部内容(默认 false) |
适用场景: 定时报告生成、邮件摘要、代码备份等独立后台任务。
1.4. 四、投递配置(Delivery)
执行结果可以投递到多种目标。
1.4.1. 投递模式
| 模式 | 行为 |
|---|---|
"announce" |
通过子 Agent 通知流推送到聊天频道 |
"webhook" |
HTTP POST 到指定 URL(10 秒超时) |
"none" |
仅记录日志,不外发 |
1.4.2. 参数详解
| 参数 | 类型 | 说明 |
|---|---|---|
delivery.mode |
string | 投递模式 |
delivery.channel |
string | 频道类型(slack/discord/telegram/whatsapp 等) |
delivery.to |
string | 频道内具体目标 |
delivery.bestEffort |
boolean | true 时投递失败不影响任务状态 |
1.4.3. 各平台 delivery.to 格式
| 平台 | 格式 | 示例 |
|---|---|---|
| Slack | channel:<id> 或 user:<id> |
channel:C1234567890 |
| Discord | channel:<id> 或 user:<id> |
user:U9876543210 |
| Telegram | 聊天ID,话题用冒号分隔 | -1001234567890:topic:123 |
| 手机号 | +8613800138000 |
|
| 通用 | "last" |
发给上次 Agent 回复的目标 |
Webhook 示例:
openclaw cron add \
--name "Daily Report" \
--cron "0 18 * * 1-5" \
--session isolated \
--message "Generate daily summary report" \
--webhook "https://your-server.com/cron-results" \
--best-effort
1.5. 五、作业管理参数
1.5.1. 作业定义字段
| 字段 | 类型 | 说明 |
|---|---|---|
name |
string | 作业名称(人类可读标识) |
id |
string | 唯一 ID(自动生成) |
enabled |
boolean | 是否激活,默认 true |
description |
string | 描述/元数据 |
agentId |
string(可选) | 绑定特定 Agent,否则用默认 |
deleteAfterRun |
boolean | 成功后自动删除(at 类型默认 true) |
1.5.2. CLI 完整命令参考
# 列出所有作业
openclaw cron list
# 立即执行指定作业
openclaw cron run <jobId>
# 强制执行(跳过调度检查)
openclaw cron run <jobId> --force
# 查看执行历史
openclaw cron runs --id <jobId> --limit 50
# 禁用作业
openclaw cron edit <jobId> --enabled false
# 删除作业
openclaw cron rm <jobId>
# 查看 Cron 服务状态
openclaw cron status
1.6. 六、高级特性
1.6.1. 负载抖动(Stagger)
为避免大量作业在整点同时触发造成负载峰值,OpenClaw 使用基于作业 ID(SHA-256 哈希)的确定性抖动:
| 表达式类型 | 抖动行为 |
|---|---|
整点表达式(0 * * * *) |
自动加 0-5 分钟随机延迟 |
固定时间(0 7 * * *) |
精确执行,不加抖动 |
| 自定义 | 通过 --stagger 30s 或 schedule.staggerMs 设置 |
# 精确执行,禁用抖动
openclaw cron add --name "Exact Job" --cron "0 9 * * *" --exact
# 指定 2 分钟抖动窗口
openclaw cron add --name "Staggered Job" --cron "0 * * * *" --stagger 2m
1.6.2. 失败重试与指数退避
周期性作业连续失败时自动进入退避等待:
| 连续失败次数 | 下次重试等待 |
|---|---|
| 1 | 30 秒 |
| 2 | 1 分钟 |
| 3 | 5 分钟 |
| 4 | 15 分钟 |
| 5+ | 60 分钟 |
一次成功执行后,计数器自动重置为 0。一次性(
at)任务失败后不重试,直接禁用。
1.6.3. 模型与思考深度覆盖
独立会话任务支持按作业指定不同的模型和思考深度:
openclaw cron add \
--name "Deep Analysis" \
--cron "0 2 * * 0" \
--session isolated \
--message "Perform deep weekly code review" \
--model "claude-opus-4-6" \
--thinking high
1.6.4. 安全隔离
当作业消息来自外部钩子(如 hook:gmail:)时,OpenClaw 自动使用 buildSafeExternalPrompt 包裹内容,防止提示词注入攻击。如需信任外部内容,显式设置 allowUnsafeExternalContent: true。
1.7. 七、存储与持久化
1.7.1. 文件位置
| 文件 | 默认路径 |
|---|---|
| 作业定义 | ~/.openclaw/cron/jobs.json |
| 执行历史 | ~/.openclaw/cron/runs/<jobId>.jsonl |
1.7.2. 执行日志字段(CronRunLogEntry)
| 字段 | 说明 |
|---|---|
ts |
Unix 时间戳 |
jobId |
作业 ID |
status |
ok / error / skipped |
error |
错误信息 |
summary |
Agent 输出摘要 |
delivered |
是否成功投递 |
durationMs |
执行耗时(毫秒) |
model / provider |
使用的模型信息 |
usage |
Token 消耗数据 |
1.7.3. 日志保留配置
{
"cron": {
"runLog": {
"maxBytes": "2mb",
"keepLines": 2000
},
"sessionRetention": "24h"
}
}
1.8. 八、Gateway 全局配置
{
"cron": {
"enabled": true,
"store": "~/.openclaw/cron/jobs.json",
"maxConcurrentRuns": 1,
"webhookToken": "your-bearer-token",
"sessionRetention": "24h",
"runLog": {
"maxBytes": "2mb",
"keepLines": 2000
}
}
}
| 参数 | 说明 |
|---|---|
enabled |
全局开关 |
store |
作业存储文件路径 |
maxConcurrentRuns |
最大并发执行数(默认 1,串行) |
webhookToken |
Webhook 鉴权 Bearer Token |
sessionRetention |
独立会话保留时长(默认 24h) |
禁用 Cron 的方式:
# 环境变量(临时)
OPENCLAW_SKIP_CRON=1 openclaw gateway start
# 配置文件(持久)
# 设置 cron.enabled: false
1.9. 九、典型使用场景与最佳实践
1.9.1. 场景示例
| 场景 | 推荐类型 | 推荐模式 |
|---|---|---|
| 一次性会议提醒 | at |
main + systemEvent |
| 每日晨报推送 | cron |
isolated + announce |
| 每小时监控检查 | every |
isolated + webhook |
| 每周报告生成 | cron |
isolated + none(写文件) |
| 代码定期备份 | every |
isolated(shell-only,免费) |
1.9.2. 最佳实践
- 优先使用 Isolated 模式:避免污染主会话,适合绝大多数后台任务
- 明确具体的 Prompt:
"summarize top 5 GitHub issues from last 24h"比"check things"有效得多 - 计算成本:
成本/次 × 每天次数 × 30天部署前必算 - 显式设置时区:VPS 通常是 UTC,一定要用
--tz避免时间错位 - 启用
--best-effort:投递失败不应影响核心任务状态 - Shell-only 任务走脚本:git 备份、文件清理不需要调用 LLM,成本为零
1.9.3. 故障排查清单
# 1. 检查 Cron 是否启用
openclaw cron status
# 2. 查看作业列表和下次执行时间
openclaw cron list
# 3. 查看执行历史和错误信息
openclaw cron runs --id <jobId> --limit 20
# 4. 立即触发测试
openclaw cron run <jobId> --force
# 5. 检查时区设置
# 确保 --tz 与你实际所在时区匹配
1.10. 十、技术架构内部机制
- 计时器循环:最大延迟钳制为 60 秒,即使任务计划在几年后,每 60 秒也会检查一次
- 并发锁:使用异步互斥锁串行化写操作,读操作非阻塞
- 原子写入:通过临时文件重命名保证
jobs.json写入的原子性 - 启动追赶:Gateway 重启后自动执行期间遗漏的任务
- 通知重试:子 Agent 结果通知失败时,最多重试 3 次;超过 5 分钟的过期通知强制丢弃
评论