乐于分享
好东西不私藏

闹钟、账本和保安:OpenClaw 后台三兄弟

闹钟、账本和保安:OpenClaw 后台三兄弟
用过 OpenClaw 的人,大概率被三个词绕晕过:Cron、Task、Heartbeat。看着都是"后台自己跑",查文档又全是英文黑话,什么 scheduler、ledger、patrol——翻译成人话,其实就是你家里的三样东西。

一张图先定方向

面对这么多机制,先别急着背概念,问自己一个问题:你要什么?
五个机制各管一摊:Cron 管准点,Heartbeat 管巡逻,Task 管留痕,Task Flow 管编排,Hooks 管响应。今天重点讲前三个——后台三兄弟。

闹钟(Cron):到点就叫,叫完就睡

Cron 是调度器,只回答一个问题:什么时候干?
它长在 Gateway 进程内部,不靠模型自觉,靠时间表达式说话:
30 8,20 * * *   每天 08:30 / 20:30
0 21 * * 1-5    工作日 21:00
三种玩法:cron 表达式跑周期任务、every 跑毫秒级间隔、at 跑一次性提醒——at 用完即焚,触发完自动删,像极了闹钟按掉就清净。
它还有个让人安心的脾气:任务定义、运行状态、历史记录全存在共享 SQLite 里,Gateway 重启也不丢。你可以理解成闹钟内置了电池,断电了照样到点响。
但闹钟就是闹钟。它只管到点叫你,至于你起没起、起没起得来——它不关心。那是账本的事。

记账本(Task):干了什么,一笔不落

Task 是台账,记录所有脱离主会话跑的活儿:isolated cron、子代理、ACP 调用、CLI 后台操作……每次执行,账本上就多一行。
每一笔账都有严格的生死流程:
queued → running → terminal
├─ succeeded
├─ failed
├─ timed_out
├─ cancelled
└─ lost
排队、开跑、终局——终局五个下场:成功、失败、超时、取消、走丢,写得明明白白。terminal 的记录留 7 天,走丢的只留 24 小时,然后自动清理。账本嘛,太旧的收据该扔就扔。
关键一点:Task 只记录,不调度。它决定不了"何时跑",只负责"跑了没、跑成什么样"。排查故障、审计行为,它是第一数据源。

巡夜保安(Heartbeat):拎手电筒转一圈

Heartbeat 是主会话里的周期巡检,默认每 30 分钟一次。保安大哥拎着手电筒在屋里转一圈:有没有新邮件?日历上有没有快到期的安排?有没有该提醒你的事?
它跟 Cron 最大的区别:不产生 Task 记录。保安巡逻不写台账——或者说,巡逻本身不该进账本。
它还有几个小脾气:不刷新会话新鲜度、忙的时候自动往后躲(skipWhenBusy)、清单驱动(HEARTBEAT.md 里有啥查啥,空文件直接跳过)、还能配 lightContext 只带清单轻装上阵。

一张表看清三兄弟

维度
Cron
Task
Heartbeat
角色
调度器
台账
巡检器
回答
何时跑
跑得如何
有无异常需上报
触发方式
时间表达式/间隔/一次性
由执行产生
周期轮询(默认30m)
会话
主会话/isolated/持久会话
记录(跨会话)
主会话(可 isolated)
产生 Task 记录
✅ 每次执行产生
本身就是记录
❌ 不产生
持久化
SQLite(定义+历史)
SQLite(7天)
无独立存储(走会话)
典型场景
每日报告、定时提醒
审计、故障排查
收件箱/日历/通知巡检
管理命令
openclaw cron *openclaw tasks *
配置 agents.defaults.heartbeat

进程、通信与供应商差异

表看完了,再往深挖一层——后台任务到底在哪个"房间"里跑,跑完怎么把话捎给你。
主副进程与会话隔离。OpenClaw 里 Gateway 是主进程,cron 任务默认跑在 isolated 独立会话里:上下文跟主会话彻底隔离,不带你的对话历史。主会话(main)像你家客厅,聊天都在这里,有完整记忆;isolated 会话像临时客房,客人进门不带走客厅记忆,干完活就走,干净利落。
消息怎么回来?主会话里你直接对话,一来一回。isolated 不行——它跑完,靠 delivery 机制把结果送回来:announce 投递到指定频道,或者 webhook 回调,channel / to / threadId 都能配。相当于客房的人干完活不当面汇报,而是写了张纸条从门缝塞出来,投递到你指定的信箱。
为什么不同供应商报错长得不一样?
这就好玩了。火山引擎是配额制,超限直接甩你一脸429 rate_limit + 明确的错误信息——显式失败,一眼定位,属于大声喊"我不行了"的类型。DeepSeek 呢?某些请求 HTTP 200 连接都建好了,流式响应却只有 keep-alive,永远不吐数据——静默挂起,伪装成"慢",最后客户端超时。这是闷声装死的类型。
两种失败模式完全不同:一个喊得响,一个死得静。所以在多供应商 fallback 链里,某家的"挂起"永远比"报错"难排查——报错是证据,挂起是疑案。

到底怎么选?点菜表

你的需求
该用谁
每天早上 9 点准点发日报
Cron
"2 小时后提醒我"
Cron
at,用完即焚)
每周跑一次深度分析
Cron
(可换独立模型)
每 30 分钟查一遍收件箱
Heartbeat
盯日历上快到期的安排
Heartbeat
查"刚才那个任务为啥失败"
Task,翻账本
审计这几天后台都跑了啥
Task
openclaw tasks audit
多步研究后汇总成文
Task Flow
会话重置时跑个脚本
Hooks

聚焦:Cron vs Heartbeat

有人总在这俩之间犹豫——都是周期性的,区别到底在哪?五个维度一次说清:
维度
Cron
Heartbeat
时机
精确(到分/到秒)
大约(默认 30 分钟)
会话上下文
全新(isolated)或共享
完整主会话上下文
Task 记录
每次必产生
永不产生
结果投递
频道 / webhook / 静默
主会话内联
适合
报告、提醒、后台活
收件箱、日历、通知巡检
一句话:要准点、要隔离 → Cron;要上下文、时机灵活 → Heartbeat。

附注:版本差异

OpenClaw7.1之后,官方文档把 Cron 改叫Automations(自动任务),旧文档和命令行里还是 cron。看到两个词别懵,是同一个东西——就像同一个老同事,换了张新工牌。

问答:台账会无限扩充吗?

问:Task 台账会越记越多、最后撑爆吗?
答:不会,有自动整理机制。

终态记录

(succeeded / failed / timed_out / cancelled):保留 7 天,到期自动修剪
lost(走丢)记录:只保留24 小时,更快清掉
所以台账是个滚动窗口——永远只留最近 7 天的账,相当于账房先生每周自动撕旧收据。几千条记录在 SQLite 里也就几 MB,完全不用担心。
想主动检查的话,openclaw tasks audit 能揪出卡在 running 的僵尸任务;定期清理会话则用 openclaw sessions cleanup。一账一清,各司其职。

口诀送你:

Cron 定闹钟,Task 记台账,Heartbeat 是巡逻。要定时 → Cron;要留痕 → Task;要巡检 → Heartbeat。

三个机制各管一摊,谁也替不了谁。下次再看到后台任务不对劲,先想一句:该看计划(cron list)、台账(tasks list),还是巡逻记录(heartbeat)?想清楚这一句,排查的路就顺了一半。