Heartbeat 和 cron job 在 OpenClaw 里很容易混在一起。它们都能定时做事,都能让 agent 主动运行,并且都和主会话有关系。但它们的实现思路完全不同。
核心区别在于三条不同的执行路径:
Heartbeat负责定时唤醒主会话,Cron(main)负责定时往主会话里塞一条 system event,- 而
Cron(isolated)负责定时开一个独立的 agent run。
Heartbeat
Heartbeat 本质上是一个固定间隔的巡检机制。默认每隔一段时间,OpenClaw 会在主会话里发起一次 agent turn,看有没有什么事情值得处理。这次 turn 会带着一个很短的 prompt,要求 agent 优先读取 HEARTBEAT.md 并严格执行,如果没有需要处理的事情就回复 HEARTBEAT_OK。
这个固定间隔不是 agent 自己决定的,而是 OpenClaw 配置层决定的。默认情况下,Heartbeat 一般每 30 分钟运行一次;在某些 Anthropic OAuth / setup-token 模式下,默认会变成 1 小时一次。也就是说,Heartbeat 不是一种“agent 想起来就跑”的机制,而是 OpenClaw 自己维护的一条定时循环。
因此,Heartbeat 更像是一个周期性的主会话检查点。它的核心特点不是准时,而是带有上下文。它运行在 main session 里,能看到最近的对话和行动历史。这非常适合处理需要结合上下文判断的任务,比如检查最近有没有重要邮件、确认未来两小时的日历事件、监控后台任务状态,或者在长时间未交互时决定是否做轻量提醒。这些事情不要求精确到某一分钟,但必须依赖主会话的上下文。
Cron Job
Cron job 是另一套调度机制。它不是周期性巡检,而是显式定义的调度任务。你需要给它一个 schedule,OpenClaw 会把它存起来,计算下一次运行时间并按时执行。
Cron 的优势是精确和显式。你可以设定具体的执行时间(比如每周一上午 9 点,或是 20 分钟后),还可以为这条任务单独指定 session、model 和 delivery 方式。这决定了 cron 更像传统意义上的调度系统。
最容易混淆的地方是,OpenClaw 里的 cron job 有两种截然不同的执行路径:Cron(main) 和 Cron(isolated)。
Cron(main)
Cron(main) 并不是自己开一个独立 agent run。到点后,它会先把一条 system event 注入 main session,再让主会话处理这件事。很多时候,这个处理动作会和 heartbeat 配合。
所以 Cron(main) 的重点不是隔离执行,而是把一件定时发生的事情放进主会话上下文。它适合处理诸如 2 小时后提醒回电话、每 4 小时检查项目状态、或者明天上午把某件事丢回 main session 让 agent 决定处理方式等带有强时间属性的关联任务。
Cron(isolated)
Cron(isolated) 才是更接近传统任务调度器的那种 cron。它会在独立 session 里跑,不污染主会话历史,也不依赖 main session 的上下文。同时你可以给它单独指定模型、思考深度和投递方式。
这适合处理独立的后台工作单元。比如每天早上 7 点生成 morning briefing,每周一跑深度分析,或者每周日自动做一次 review 并发送 summary。当你希望一个任务独立运作且不把主会话弄得太吵时,就应该使用 Cron(isolated)。
Heartbeat 和 Cron(main) 的区别到底在哪
两者最后都会回到 main session 并且都可能留下新内容,但它们的根本区别在于触发语义:一个是 periodic awareness loop(周期性感知),一个是 precise trigger(精确触发)。
Heartbeat 是一次真正的 main session agent turn。它醒来后会根据上下文判断有没有值得处理的事。如果产出了结果(如总结、提醒),就会写入主会话;如果没必要做事,就返回 HEARTBEAT_OK,系统会尽量把影响降到最低。它是 session-centric 的,目的是为了让主会话持续保持低频的后台感知能力。
Cron(main) 则是要在某个明确的时间点,把一件具体的事(system event)注入 main session,交由主会话后续处理。它不问“现在该不该做”,而是直接派发“现在做这件事”。它是 task-centric 的,适合“明天上午 9 点把这个 review 任务送回主会话”这种带有明确时间语义的调度。
所以,Cron(main) 在很多具体任务上确实可以模拟 Heartbeat。如果只是想每隔 30 分钟做一件非常明确的事,完全可以用 Cron(main) 来实现。
但它不能完全替代 Heartbeat。因为 Heartbeat 解决的不是“如何精确调度一件事”,而是“如何让 main session 周期性地保持 awareness”。前者是 task-centric,后者是 session-centric。这也是 Heartbeat 仍然值得作为独立机制存在的原因。
一个具体例子:定期总结过去一天的 main session
假设目标是“定期总结反思过去一天的主会话内容”。用 Heartbeat 或 Cron(main) 都能做,两者也都能利用上下文并最终把总结结果写回主会话。
但触发逻辑截然不同:如果用 Heartbeat,语义是“每隔一段时间检查一下,现在是否值得做一次总结”,如果 agent 觉得没必要,完全可以什么都不做;如果用 Cron(main),语义则是“现在立刻投递一条明确的总结任务”。
前者是周期性的后台判断,后者是精确触发的任务投递。
核心区别与选型
| 机制 | 运行位置 | 是否共享主会话历史 | 时间精度 | 适合什么 |
|---|---|---|---|---|
| Heartbeat | main session | 是 | 低到中 | 周期性 awareness、批量检查、上下文判断 |
| Cron(main) | main session | 是 | 高 | 定时把事件送进主会话 |
| Cron(isolated) | isolated session | 否 | 高 | 独立任务、精确定时、不同模型和投递策略 |
决定用哪个机制,关键在于回答两个问题:这件事需不需要主会话上下文?这件事需不需要精确时间?
如果需要上下文但不需要特别准时,使用 Heartbeat。如果需要准时且希望事情回到主会话里处理,选择 Cron(main)。如果既需要准时又希望和主会话隔离,选择 Cron(isolated)。
Heartbeat 是基于 Cron 实现的吗
不是。
Heartbeat 和 cron job 是两套独立机制,不是“Heartbeat 只是系统偷偷帮你建的一条 cron”。
Heartbeat 本身有自己的定时循环。Cron 也有自己的 job store、schedule 和 next-run 计算逻辑。它们在产品层面会互相配合,但不是一套东西换个名字。
References: