目录

OpenClaw Heartbeat 配置避坑指南:duration 字段不支持 'day' 单位

一个 365d 引发的排查之旅,揭示 OpenClaw 配置参数的隐藏陷阱

OpenClaw Heartbeat 配置避坑指南:duration 字段不支持 ‘day’ 单位

背景

在使用 OpenClaw 的过程中,有时候我们想要减少不必要的 API 调用开销,把 agent 的心跳(heartbeat)间隔设置得非常长——比如一年一次。这样既保持心跳功能可用,又不会频繁消耗 token。然而,配置之后实际效果可能和预期大相径庭。

现象

openclaw.jsonagents.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”

这句话有两种理解方式:

  1. 如果只写一个纯数字(如 "365"),会被当作 365 分钟处理
  2. 带了后缀的情况:解析器只支持 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️⃣ 配置参数的示例就是全部支持范围

很多开源项目的文档示例往往就是全部支持的范围。如果在示例中只看到 mh,就不要假设 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 heartbeat

4️⃣ 了解回退机制

每个配置字段在解析失败时回退到什么值,也应该在配置前了解清楚。有时候"不报错"不代表"正常工作"。

延伸思考

类似的"单位陷阱"在各类系统中层出不穷:

  • Kubernetes 的 CPU/Memory 资源限制中,M 是兆字节(Mi)还是百万(M)?
  • Nginxclient_max_body_size 中,M 单位是否跟随系统 locale?
  • Redis 配置文件中,time 单位是秒还是毫秒?
  • Docker Composemem_limit 是否支持 GB 缩写?

配置文件的单位解析往往是最容易被忽视的细节,但也是最容易引发线上问题的源头。

所有的聪明最终都通向两个词:简单谦虚。不确定的时候,永远假设自己不理解,去查文档,去验证。这比任何高级技巧都管用。

一句话总结:OpenClaw heartbeat 的 every 字段只支持 m(分钟)和 h(小时),不支持 d(天)。想禁用心跳请用 "0m",想长时间间隔请用小时单位。


–全文完–

感谢阅读
若你有故事想讲、有困惑想聊、或是想找个人说说心里话,甚至只是吐槽发泄一下情绪,都欢迎来找我聊聊:   《内容已折叠,点击展开》

希望我写的每一个字,成为我自己和某个人活下去、拼下去的力量。                     《内容已折叠,点击展开》

“技术终归是工具,而我们一次次认真把问题理顺,守住的其实不只是页面样式和代码输出,还有那一点不愿被混乱打败的心气,是每一个深夜仍愿点灯前行的人。”

转载请注明来自https://oklife.me。

文尾配图水墨画图片