为什么 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 的心跳机制非常灵活,但也因此带来了一些配置复杂性。通过这次排查,我深入理解了:
- HEARTBEAT_OK 的语义:表示"无需通知",而非"执行成功"
- Prompt 的重要性:需要覆盖所有可能的场景,避免遗漏
当然,你完全可以给OpenClaw描述现象让他给你解决,但是知道一些原理总归是有好处的。
希望这篇文章能帮助你快速定位和解决类似问题。如果你有其他问题或经验,欢迎交流讨论!