为什么 OpenClaw 的 Heartbeat 不生效?一次完整的排查与解决

8 阅读4分钟

为什么 OpenClaw 的 Heartbeat 不生效?一次完整的排查与解决

本文记录了在配置 OpenClaw 心跳任务时遇到的各类问题及其解决方案,希望能帮助遇到类似问题的开发者快速定位并解决。

背景

OpenClaw 是一个强大的 AI 助手框架,支持定时任务(cron)和心跳机制。心跳任务可以定期执行检查、发送通知等操作。然而,在实际配置过程中,我发现心跳任务虽然执行了,但消息始终无法正常送达。

问题现象

配置心跳任务后,通过 openclaw cron list 和openclaw cron runs --id xxx查看执行记录: Tips:id通过list命令获取

{
  "status": "ok",
  "delivered": false,
  "deliveryStatus": "not-delivered",
  "summary": "HEARTBEAT_OK"
}

任务执行成功,但消息没有投递。这让我非常困惑。

排查过程

问题一:HEARTBEAT_OK 的陷阱

现象:任务执行成功,但返回 HEARTBEAT_OK 后消息不投递

原因HEARTBEAT_OK 是 OpenClaw 的特殊标记,表示"心跳正常,无需通知用户"。当返回这个标记时,系统会跳过消息投递。

解决方案:使用openclaw cron runs --id xxx检查任务返回内容,核对是不是 HEARTBEAT_OK

 错误:HEARTBEAT_OK
 正确:🔔 心跳测试消息 - 时间: 2026-03-27 16:20

问题二:任务清单被自动勾选

现象:HEARTBEAT.md 中的任务被心跳任务自动勾选为 [x],导致下次检查时认为没有待执行任务

原因:心跳任务执行时会读取 HEARTBEAT.md,某些模型会自动将任务标记为完成

解决方案:在任务描述中添加明确指示:

- [ ] 测试心跳任务 - 每次心跳发送测试消息
  - ⚠️ 注意:不要勾选此任务,保持未完成状态

问题三:Prompt 不完整

现象:心跳任务只处理部分任务,其他任务被忽略

原因:cron 任务的 prompt 只描述了特定任务的处理逻辑,没有覆盖所有场景。

Tips:cron prompt 路径为:.openclaw/cron/.jobs.json

错误示例

如果当前时间在 7:55-8:05 之间,执行天气报告...
(没有说明其他时间该怎么处理)

正确做法:在 prompt 中明确所有任务的处理逻辑:

【重要】任务处理逻辑:

1. 「测试心跳任务」:
   - 每次心跳都执行
   - 输出格式:🔔 心跳测试消息
   - 不要回复 HEARTBEAT_OK

2. 「每日天气报告」:
   - 仅在 7:55-8:05 执行
   - 调用 API 获取数据并输出
   - 不要回复 HEARTBEAT_OK

注意:不要因为某个任务条件不满足就直接返回 HEARTBEAT_OK

完整配置示例

1. HEARTBEAT.md(任务清单)

# HEARTBEAT.md - 定时任务检查

## 任务清单
- [ ] 每日天气报告 - 每天早上8点发送天气报告
  - ⚠️ 注意:不要勾选此任务
  - 触发条件:当前时间在 7:55-8:05 之间
- [ ] 测试心跳任务 - 每次心跳发送测试消息
  - ⚠️ 注意:不要勾选此任务

## 检查流程
1. 读取任务清单
2. 检查待执行任务
3. 执行并输出结果

2. cron/jobs.json(任务配置)

{
  "version": 1,
  "jobs": [
    {
      "id": "heartbeat-check-001",
      "name": "heartbeat-check",
      "schedule": {
        "kind": "cron",
        "expr": "*/15 * * * *",
        "tz": "Asia/Shanghai"
      },
      "sessionTarget": "isolated",
      "payload": {
        "kind": "agentTurn",
        "message": "Read HEARTBEAT.md...",
      },
      "delivery": {
        "mode": "announce",
        "channel": "feishu",
        "to": "user:ou_xxx"
      }
    }
  ]
}

经验总结

1. 理解 HEARTBEAT_OK 的语义

HEARTBEAT_OK 不是"执行成功",而是"无需通知用户"。如果你希望用户收到消息,绝对不要返回 HEARTBEAT_OK

2. Prompt 要覆盖所有场景

不要只写"如果有任务就执行",要明确"每个任务在什么条件下执行"以及"如果都不满足该怎么处理"。

3. 使用独立的模板文件

对于复杂任务(如天气报告),建议将模板放在独立文件中(如 templates/weather-report.md),保持 HEARTBEAT.md 的可读性。

4. 任务状态管理

HEARTBEAT.md 中的任务清单状态([ ] vs [x])会影响心跳任务的判断,务必添加"不要勾选"的提示。

调试技巧

1. 查看执行记录

openclaw cron runs --id <job-id> --limit 5

2. 手动触发测试

openclaw cron run <job-id>

3. 查看实时日志

tail -f /tmp/openclaw/openclaw-$(date +%Y-%m-%d).log

结语

OpenClaw 的心跳机制非常灵活,但也因此带来了一些配置复杂性。通过这次排查,我深入理解了:

  1. HEARTBEAT_OK 的语义:表示"无需通知",而非"执行成功"
  2. Prompt 的重要性:需要覆盖所有可能的场景,避免遗漏

当然,你完全可以给OpenClaw描述现象让他给你解决,但是知道一些原理总归是有好处的。

希望这篇文章能帮助你快速定位和解决类似问题。如果你有其他问题或经验,欢迎交流讨论!