OpenClaw Heartbeat 配置避坑指南:duration 字段不支持 'day' 单位
一个 365d 引发的排查之旅,揭示 OpenClaw 配置参数的隐藏陷阱

OpenClaw Heartbeat 配置避坑指南:duration 字段不支持 ‘day’ 单位
背景
在使用 OpenClaw 的过程中,有时候我们想要减少不必要的 API 调用开销,把 agent 的心跳(heartbeat)间隔设置得非常长——比如一年一次。这样既保持心跳功能可用,又不会频繁消耗 token。然而,配置之后实际效果可能和预期大相径庭。
现象
在 openclaw.json 的 agents.defaults.heartbeat 中,我们设置了:
"heartbeat": {
"every": "365d",
"target": "none",
"timeoutSeconds": 120,
"lightContext": true,
"isolatedSession": true
}期望是:心跳一年只跑一次,几乎等同于禁用。
但观察 session 日志后发现,heartbeat polls 仍然在频繁触发,远非一年一次。这到底是怎么回事?
排查过程
第 1 步:确认配置已生效
首先通过 gateway config.get 确认配置确实写入了 agents.defaults.heartbeat:
openclaw gateway config.get agents.defaults.heartbeat返回的输出确实包含了 "every": "365d"。配置写入了,问题不在写入层。
第 2 步:查阅官方文档
翻阅 OpenClaw 官方文档 gateway/heartbeat.md,找到 every 字段的描述:
Heartbeat interval — duration string; default unit = minutes.
文档示例中出现的取值:
"30m"— 30 分钟(默认值)"1h"— 1 小时"0m"— 禁用心跳
发现关键点:没有任何示例使用 “d”(天)单位。
第 3 步:分析根因
这里的核心线索是文档中的这句话:“default unit = minutes”。
这句话有两种理解方式:
- 如果只写一个纯数字(如
"365"),会被当作 365 分钟处理 - 带了后缀的情况:解析器只支持
m(分钟)和h(小时)
当 "365d" 被传入时,可能发生了以下两种情况之一:
| 可能性 | 机制 | 实际效果 |
|---|---|---|
| 可能性 A | 解析器忽略不认识的后缀 d,只读数字 365,默认单位分钟 | 365 分钟 ≈ 6 小时一次 |
| 可能性 B | 整体解析失败,回退到 heartbeat 默认值 | 30 分钟一次 |
无论哪种情况,结果都是心跳仍在频繁触发——与"一年一次"的期望相去甚远。
解决方案
针对这个问题,有三种可行的修复方案:
方案 A:禁用(推荐)
"heartbeat": {
"every": "0m",
"target": "none"
}使用 "0m" 明确禁用心跳机制。既然已经设置了 "target": "none"(心跳结果不通知任何人),直接禁用是最干净的方案。
方案 B:使用小时单位
"heartbeat": {
"every": "8760h",
"target": "none"
}365 天 × 24 小时 = 8760 小时。既然 h(小时)是文档示例中明确支持的单位,用小时来表示长间隔是安全的方案。
方案 C:保持默认
"heartbeat": {
"every": "30m",
"target": "none"
}如果不需要特殊的长间隔控制,保持默认值 30 分钟。配合 "target": "none",心跳虽然运行但不会产生通知打扰。
经验总结
这次排查虽然是个小问题,但折射出几个通用经验:
1️⃣ 配置参数的示例就是全部支持范围
很多开源项目的文档示例往往就是全部支持的范围。如果在示例中只看到 m 和 h,就不要假设 d 也受支持。这不是文档疏漏,而是设计使然。
2️⃣ 不假设单位支持
即使 h(小时)、d(天)在人类语言中都是常见时间单位,但底层解析器未必支持所有单位。不同的项目使用的 duration 解析库不同:
- 有些使用 Golang 的
time.ParseDuration(只支持 ns/us/ms/s/m/h) - 有些使用自定义解析器(可能支持 d/w/y)
- OpenClaw 的 heartbeat 解析器目前只确认支持 m 和 h
3️⃣ 验证配置效果
配置完毕后,通过以下方式验证实际效果:
# 查看 gateway 日志中 heartbeat 的触发频率
openclaw gateway logs | grep heartbeat
# 查看 session 列表确认 heartbeat session 的创建时间间隔
openclaw sessions list --agent oc-engineer | grep heartbeat4️⃣ 了解回退机制
每个配置字段在解析失败时回退到什么值,也应该在配置前了解清楚。有时候"不报错"不代表"正常工作"。
延伸思考
类似的"单位陷阱"在各类系统中层出不穷:
- Kubernetes 的 CPU/Memory 资源限制中,M 是兆字节(Mi)还是百万(M)?
- Nginx 的
client_max_body_size中,M 单位是否跟随系统 locale? - Redis 配置文件中,time 单位是秒还是毫秒?
- Docker Compose 的
mem_limit是否支持 GB 缩写?
配置文件的单位解析往往是最容易被忽视的细节,但也是最容易引发线上问题的源头。
所有的聪明最终都通向两个词:简单和谦虚。不确定的时候,永远假设自己不理解,去查文档,去验证。这比任何高级技巧都管用。
一句话总结:OpenClaw heartbeat 的
every字段只支持m(分钟)和h(小时),不支持d(天)。想禁用心跳请用"0m",想长时间间隔请用小时单位。
–全文完–

梦行志
