惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Hacker News: Ask HN
Hacker News: Ask HN
H
Help Net Security
Microsoft Azure Blog
Microsoft Azure Blog
B
Blog RSS Feed
Jina AI
Jina AI
Stack Overflow Blog
Stack Overflow Blog
量子位
博客园_首页
Vercel News
Vercel News
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Forbes - Security
Forbes - Security
IT之家
IT之家
N
News and Events Feed by Topic
S
Security Affairs
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Webroot Blog
Webroot Blog
Recorded Future
Recorded Future
L
LangChain Blog
Y
Y Combinator Blog
AI
AI
MyScale Blog
MyScale Blog
大猫的无限游戏
大猫的无限游戏
小众软件
小众软件
Know Your Adversary
Know Your Adversary
AWS News Blog
AWS News Blog
Help Net Security
Help Net Security
Cyberwarzone
Cyberwarzone
L
Lohrmann on Cybersecurity
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Google Online Security Blog
Google Online Security Blog
V2EX - 技术
V2EX - 技术
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
PCI Perspectives
PCI Perspectives
I
Intezer
T
Tenable Blog
G
Google Developers Blog
Application and Cybersecurity Blog
Application and Cybersecurity Blog
T
Troy Hunt's Blog
L
LINUX DO - 最新话题
云风的 BLOG
云风的 BLOG
C
CXSECURITY Database RSS Feed - CXSecurity.com
有赞技术团队
有赞技术团队
O
OpenAI News
P
Proofpoint News Feed
TaoSecurity Blog
TaoSecurity Blog
C
Check Point Blog
Last Week in AI
Last Week in AI
S
Schneier on Security
Simon Willison's Weblog
Simon Willison's Weblog
Blog — PlanetScale
Blog — PlanetScale

博客园 - 念槐聚

使用axel替代wget,实现Linux环境下载加速 大模型购买综合对比 Excel中生成可编辑数据的甘特图 Claude 优秀插件 Pi Agent和Claude Code 为zed工具配置claudecode+自定义模型 pi agent 和claudecode、codex、Trae、Qwen、Qoder等对比 ESXi物理服务器RAID卡及磁盘等处理操作点滴记录 vscode和Qwen code、Trae、workbuddy等对比,优劣推荐 主流 Kubernetes 管理工具特性对比 博文阅读密码验证 - 博客园 博文阅读密码验证 - 博客园 博文阅读密码验证 - 博客园 博文阅读密码验证 - 博客园 博文阅读密码验证 - 博客园 博文阅读密码验证 - 博客园 raspberrypi+openclaw笔记 Python+Stable Video Diffusion (SVD) 实现本地离线视频生成 开发模式对比 OpenClaw模型对比选择2 OpenClaw模型对比选择1 ollama ERR_CONNECTION_REFUSED coding plan对比,deepseek、字节、阿里、智谱、kimi 等coding plan 对比 openclaw问题修复 auth.profiles.ollama:default.mode: Invalid input
OPENCLAW问题:TERMINATE SOCKET: Ping Pong does not transfer heartbeat within heartbeat intervall
念槐聚 · 2026-03-04 · via 博客园 - 念槐聚

openclaw遇到问题:

OPENCLAW  TERMINATE SOCKET: Ping Pong does not transfer heartbeat within heartbeat intervall

image

找了一下,看起来很多人也都遇到了这个问题,尝试修改配置与解决,记录如下:

修改点:

# 需要更新到最新版本(包含 PR fix: keep reconnecting after runtime reconnect cycle failure #96 的修复)
# 可选配置优化(针对网络不稳定的环境):
{
  "channels": {
    "dingtalk": {
      "maxConnectionAttempts": 20,
      "initialReconnectDelay": 1000,
      "maxReconnectDelay": 60000,
      "reconnectJitter": 0.3
    }
  }
}

# 已知限制:8 秒心跳间隔是 dingtalk-stream SDK 硬编码的,无法在插件层面修改。如果网络延迟持续超过 8 秒,断连仍会发生,但新版本保证了自动恢复。

OpenClaw Ping Pong 心跳超时问题

此问题发生在 OpenClaw 的 Ping/Pong 心跳机制未能在预期时间间隔内收到 pong 响应时,导致 WebSocket 连接终止。这在长时间空闲或网络不稳定的情况下会发生。

示例:

TERMINATE SOCKET: Ping Pong does not transfer heartbeat within heartbeat intervall
ERROR: WebSocket was closed before the connection was established

根本原因通常与 dingtalk-stream SDK 硬编码的 8 秒心跳间隔有关。如果在此时间内未收到 pong 响应,SDK 将关闭连接。空闲期间的 NAT 超时或路由器重置等网络变化都可能触发此问题。

诊断步骤

首先检查心跳是否已启用并正常运行:

openclaw system heartbeat last
openclaw config get agents.defaults.heartbeat
openclaw channels status --probe

如果看到跳过原因如 quiet-hours(安静时段)、requests-in-flight(请求进行中)或 empty-heartbeat-file(心跳文件为空),请相应调整配置。

解决方案

PR #96 引入了一个关键修复,改进了重连逻辑。在此补丁之前,重连失败可能导致系统卡在 FAILED 状态,直到手动重启。更新后确保即使多次失败也能持续重试直至恢复。强烈建议更新到最新版本

您还可以针对不稳定网络优化重连设置:

{
  "channels": {
    "dingtalk": {
      "maxConnectionAttempts": 20,
      "initialReconnectDelay": 1000,
      "maxReconnectDelay": 60000,
      "reconnectJitter": 0.3
    }
  }
}

虽然无法在插件层面更改 8 秒的心跳间隔,但这些设置可确保断开连接后自动恢复。

总结

  • 更新到包含 PR #96 的版本
  • 验证心跳配置
  • 调整重连参数以在网络波动时保持稳定

附录

补充部分参考命令:
Automation Troubleshooting

自动化故障排查

本页面用于解决调度器和投递相关问题(cron + heartbeat)。

命令阶梯

openclaw status
openclaw gateway status
openclaw logs --follow
openclaw doctor
openclaw channels status --probe

然后运行自动化检查:

openclaw cron status
openclaw cron list
openclaw system heartbeat last

Cron 未触发

openclaw cron status
openclaw cron list
openclaw cron runs --id <jobId> --limit 20
openclaw logs --follow

正常输出示例:

  • cron status 显示已启用(enabled)且有未来的 nextWakeAtMs
  • 任务已启用,且具有有效的调度/时区设置
  • cron runs 显示 ok 或明确的跳过原因

常见特征:

特征 含义
cron: scheduler disabled; jobs will not run automatically 配置/环境中禁用了 cron
cron: timer tick failed 调度器 tick 崩溃;检查周围的堆栈/日志上下文
reason: not-due(在 run 输出中) 未使用 --force 调用手动运行,且任务尚未到期

Cron 已触发但未投递

openclaw cron runs --id <jobId> --limit 20
openclaw cron list
openclaw channels status --probe
openclaw logs --follow

正常输出示例:

  • 运行状态为 ok
  • 隔离任务设置了投递模式/目标
  • 通道探测报告目标通道已连接

常见特征:

特征 含义
运行成功但投递模式为 none 不期望外部消息
投递目标缺失/无效(channel/to) 运行可能在内部成功,但跳过 outbound
通道认证错误(unauthorized, missing_scope, Forbidden) 通道凭据/权限阻止了投递

心跳被抑制或跳过

openclaw system heartbeat last
openclaw logs --follow
openclaw config get agents.defaults.heartbeat
openclaw channels status --probe

正常输出示例:

  • 心跳已启用,且间隔非零
  • 上次心跳结果为 ran(或跳过原因可理解)

常见特征:

特征 含义
heartbeat skipped with reason=quiet-hours 超出 activeHours 时间范围
requests-in-flight 主通道繁忙;心跳被推迟
empty-heartbeat-file 间隔心跳被跳过,因为 HEARTBEAT.md 无可操作内容,且无标记的 cron 事件在队列中
alerts-disabled 可见性设置抑制了 outbound 心跳消息

时区和 activeHours 注意事项

openclaw config get agents.defaults.heartbeat.activeHours
openclaw config get agents.defaults.heartbeat.activeHours.timezone
openclaw config get agents.defaults.userTimezone || echo "agents.defaults.userTimezone not set"
openclaw cron list
openclaw logs --follow

快速规则:

  • 配置路径未找到agents.defaults.userTimezone 表示该键未设置;心跳回退到主机时区(或如果设置了则使用 activeHours.timezone
  • 未指定 --tz 的 Cron:使用网关主机时区
  • 心跳 activeHours:使用配置的时区解析(user、local 或显式 IANA 时区)
  • 无时区信息的 ISO 时间戳:对于 cron 调度被视为 UTC

常见特征:

  • 主机时区更改后,任务在错误的 wall-clock 时间运行
  • 由于 activeHours.timezone 设置错误,白天期间心跳总是被跳过

相关文档:

  • /automation/cron-jobs
  • /gateway/heartbeat
  • /automation/cron-vs-heartbeat
  • /concepts/timezone

心跳配置与操作

配置与运维

心跳(Heartbeat)

心跳 vs Cron? 请参阅 Cron vs Heartbeat 了解何时使用哪种机制。

心跳在主会话中定期运行 Agent 轮次,使模型能够在不打扰你的情况下提示任何需要注意的事项。

故障排查: /automation/troubleshooting


快速入门(初学者)

  • 保持心跳启用(默认为 30 分钟,Anthropic OAuth/设置令牌模式下为 1 小时),或设置你自己的频率。
  • 在 Agent 工作区创建一个简短的 HEARTBEAT.md 检查清单(可选但推荐)。
  • 决定心跳消息应发送到哪里(target: "none" 为默认值;设置 target: "last" 路由到最后联系人)。
  • 可选:启用心跳推理投递以增强透明度。
  • 可选:将心跳限制在活跃时段(本地时间)。

配置示例:

{
  "agents": {
    "defaults": {
      "heartbeat": {
        "every": "30m",
        "target": "last",        // 显式投递到最后联系人(默认为 "none")
        "directPolicy": "allow", // 默认:允许直接/私信目标;设为 "block" 以抑制
        // "activeHours": { "start": "08:00", "end": "24:00" },
        // "includeReasoning": true, // 可选:同时发送单独的 `Reasoning:` 消息
      }
    }
  }
}

默认值

配置项 说明
间隔 30 分钟(检测到 Anthropic OAuth/设置令牌认证模式时为 1 小时)。设置 agents.defaults.heartbeat.every 或每个 Agent 的 agents.list[].heartbeat.every;使用 0m 禁用。
提示主体 可通过 agents.defaults.heartbeat.prompt 配置:如果存在则读取 HEARTBEAT.md(工作区上下文)。严格遵循。不要从之前的对话中推断或重复旧任务。如果无需关注,回复 HEARTBEAT_OK。
活跃时段 心跳提示作为用户消息原样发送。系统提示包含"Heartbeat"部分,且运行被内部标记。heartbeat.activeHours 在配置的时区中检查。窗口期外,心跳跳过直到下一个窗口内的 tick。

心跳提示的用途

默认提示故意设计得较为宽泛:

  • 后台任务: "Consider outstanding tasks" 提示 Agent 检查后续事项(收件箱、日历、提醒、排队工作)并提示任何紧急事项。
  • 人工检查: "Checkup sometimes on your human during day time" 提示偶尔发送轻量的"有什么需要吗?"消息,但通过使用你配置的本地时区避免夜间打扰(参见 /concepts/timezone)。

如果你希望心跳执行非常具体的操作(例如"检查 Gmail PubSub 统计"或"验证网关健康"),设置 agents.defaults.heartbeat.prompt(或 agents.list[].heartbeat.prompt)为自定义主体(原样发送)。


响应约定

  • 如果无需关注,回复 HEARTBEAT_OK
  • 心跳运行期间,当 HEARTBEAT_OK 出现在回复开头或结尾时,OpenClaw 将其视为确认。该标记被剥离,如果剩余内容 ≤ ackMaxChars(默认:300),则丢弃回复。
  • 如果 HEARTBEAT_OK 出现在回复中间,则不特殊处理。
  • 对于告警,不要包含 HEARTBEAT_OK;仅返回告警文本。
  • 心跳之外,消息开头/结尾的零散 HEARTBEAT_OK 被剥离并记录;仅包含 HEARTBEAT_OK 的消息被丢弃。

配置

{
  "agents": {
    "defaults": {
      "heartbeat": {
        "every": "30m",                    // 默认:30 分钟(0m 禁用)
        "model": "anthropic/claude-opus-4-6",
        "includeReasoning": false,         // 默认:false(可用时投递单独的 Reasoning: 消息)
        "target": "last",                  // 默认:none | 选项:last | none | <频道 id>(核心或插件,如 "bluebubbles")
        "to": "+15551234567",              // 可选的频道特定覆盖
        "accountId": "ops-bot",            // 可选的多账号频道 id
        "prompt": "Read HEARTBEAT.md if it exists (workspace context). Follow it strictly. Do not infer or repeat old tasks from prior chats. If nothing needs attention, reply HEARTBEAT_OK.",
        "ackMaxChars": 300                 // HEARTBEAT_OK 后允许的最大字符数
      }
    }
  }
}

作用域与优先级

  • agents.defaults.heartbeat 设置全局心跳行为。
  • agents.list[].heartbeat 在其上合并;如果任何 Agent 有心跳块,则仅这些 Agent 运行心跳。
  • channels.defaults.heartbeat 设置所有频道的可见性默认值。
  • channels.<channel>.heartbeat 覆盖频道默认值。
  • channels.<channel>.accounts.<id>.heartbeat(多账号频道)覆盖每频道设置。

每个 Agent 的心跳

如果任何 agents.list[] 条目包含心跳块,则仅这些 Agent 运行心跳。每个 Agent 的块在 agents.defaults.heartbeat 上合并(因此你可以一次性设置共享默认值,并按 Agent 覆盖)。

示例: 两个 Agent,仅第二个 Agent 运行心跳。

{
  "agents": {
    "defaults": {
      "heartbeat": {
        "every": "30m",
        "target": "last"  // 显式投递到最后联系人(默认为 "none")
      }
    },
    "list": [
      { "id": "main", "default": true },
      {
        "id": "ops",
        "heartbeat": {
          "every": "1h",
          "target": "whatsapp",
          "to": "+15551234567",
          "prompt": "Read HEARTBEAT.md if it exists (workspace context). Follow it strictly. Do not infer or repeat old tasks from prior chats. If nothing needs attention, reply HEARTBEAT_OK."
        }
      }
    ]
  }
}

活跃时段示例

将心跳限制在特定时区的营业时间内:

{
  "agents": {
    "defaults": {
      "heartbeat": {
        "every": "30m",
        "target": "last",  // 显式投递到最后联系人(默认为 "none")
        "activeHours": {
          "start": "09:00",
          "end": "22:00",
          "timezone": "America/New_York"  // 可选;如果设置了 userTimezone 则使用,否则使用主机时区
        }
      }
    }
  }
}

此窗口期外(东部时间上午 9 点前或晚上 10 点后),心跳跳过。窗口期内的下一个计划 tick 将正常运行。


24/7 设置

如果你希望心跳全天运行,使用以下模式之一:

  • 完全省略 activeHours(无时间窗口限制;这是默认行为)。
  • 设置全天窗口:activeHours: { start: "00:00", end: "24:00" }
  • 不要将开始和结束时间设为相同(例如 08:00 到 08:00)。这被视为零宽度窗口,因此心跳总是被跳过。

多账号示例

使用 accountId 定位多账号频道(如 Telegram)上的特定账号:

{
  "agents": {
    "list": [
      {
        "id": "ops",
        "heartbeat": {
          "every": "1h",
          "target": "telegram",
          "to": "12345678:topic:42",  // 可选:路由到特定话题/线程
          "accountId": "ops-bot"
        }
      }
    ]
  },
  "channels": {
    "telegram": {
      "accounts": {
        "ops-bot": { "botToken": "YOUR_TELEGRAM_BOT_TOKEN" }
      }
    }
  }
}

字段说明

字段 说明
every 心跳间隔(持续时间字符串;默认单位 = 分钟)。
model 心跳运行的可选模型覆盖(provider/model)。
includeReasoning 启用时,同时投递单独的 Reasoning: 消息(可用时,与 /reasoning on 相同格式)。
session 心跳运行的可选会话密钥。
- main(默认):Agent 主会话。
- 显式会话密钥(从 openclaw sessions --json 或 sessions CLI 复制)。
会话密钥格式:参见 Sessions and Groups
target - last:投递到最后使用的外部频道。
- 显式频道:whatsapp / telegram / discord / googlechat / slack / msteams / signal / imessage
- none(默认):运行心跳但不外部投递。
directPolicy 控制直接/私信投递行为:
- allow(默认):允许直接/私信心跳投递。
- block:抑制直接/私信投递(reason=dm-blocked)。
to 可选的收件人覆盖(频道特定 id,例如 WhatsApp 的 E.164 或 Telegram 聊天 id)。对于 Telegram 话题/线程,使用 <chatId>:topic:<messageThreadId>
accountId 多账号频道的可选账号 id。当 target: "last" 时,账号 id 应用于解析后的最后频道(如果支持账号);否则被忽略。如果账号 id 与解析频道的配置账号不匹配,投递跳过。
prompt 覆盖默认提示主体(不合并)。
ackMaxChars HEARTBEAT_OK 后投递前允许的最大字符数。
suppressToolErrorWarnings 为 true 时,抑制心跳运行期间的工具错误警告负载。
activeHours 将心跳运行限制在时间窗口内。对象包含 start(HH:MM,包含;使用 00:00 表示一天开始)、end(HH:MM 不包含;24:00 允许表示一天结束)和可选 timezone
- 省略或 "user":如果设置了 agents.defaults.userTimezone 则使用,否则回退到主机系统时区。
- "local":始终使用主机系统时区。
- 任何 IANA 标识符(如 America/New_York):直接使用;如果无效,回退到上述 "user" 行为。
- startend 对于活跃窗口不能相等;相等值被视为零宽度(始终在窗口外)。
- 活跃窗口外,心跳跳过直到窗口内的下一个 tick。

投递行为

  • 心跳默认在 Agent 的主会话中运行(agent:<id>:<mainKey>),或当 session.scope = "global" 时为全局。设置 session 以覆盖到特定频道会话(Discord/WhatsApp 等)。
  • session 仅影响运行上下文;投递由 targetto 控制。
  • 要投递到特定频道/收件人,设置 target + to。使用 target: "last" 时,投递使用该会话的最后外部频道。
  • 心跳投递默认允许直接/私信目标。设置 directPolicy: "block" 以在仍运行心跳轮次的同时抑制直接目标发送。
  • 如果主队列繁忙,心跳跳过并稍后重试。
  • 如果 target 解析为无外部目标,运行仍发生但不发送出站消息。
  • 仅心跳的回复不会保持会话存活;last updatedAt 被恢复,因此空闲过期行为正常。

可见性控制

默认情况下,HEARTBEAT_OK 确认被抑制,而告警内容被投递。你可以按频道或按账号调整:

channels:
  defaults:
    heartbeat:
      showOk: false      # 隐藏 HEARTBEAT_OK(默认)
      showAlerts: true   # 显示告警消息(默认)
      useIndicator: true # 发送指示器事件(默认)
  telegram:
    heartbeat:
      showOk: true       # 在 Telegram 上显示 OK 确认
  whatsapp:
    accounts:
      work:
        heartbeat:
          showAlerts: false  # 抑制此账号的告警投递

优先级: 每账号 → 每频道 → 频道默认值 → 内置默认值。


每个标志的作用

标志 作用
showOk 当模型返回仅 OK 的回复时,发送 HEARTBEAT_OK 确认。
showAlerts 当模型返回非 OK 回复时,发送告警内容。
useIndicator 为 UI 状态界面发送指示器事件。

如果三个都为 false,OpenClaw 完全跳过心跳运行(无模型调用)。


每频道 vs 每账号示例

channels:
  defaults:
    heartbeat:
      showOk: false
      showAlerts: true
      useIndicator: true
  slack:
    heartbeat:
      showOk: true           # 所有 Slack 账号
    accounts:
      ops:
        heartbeat:
          showAlerts: false  # 仅抑制 ops 账号的告警
  telegram:
    heartbeat:
      showOk: true

常见模式

目标 配置
默认行为(静默 OK,告警开启) (无需配置)
完全静默(无消息,无指示器) channels.defaults.heartbeat: { showOk: false, showAlerts: false, useIndicator: false }
仅指示器(无消息) channels.defaults.heartbeat: { showOk: false, showAlerts: false, useIndicator: true }
仅在单个频道显示 OK channels.telegram.heartbeat: { showOk: true }

HEARTBEAT.md(可选)

如果工作区中存在 HEARTBEAT.md 文件,默认提示告诉 Agent 读取它。将其视为你的"心跳检查清单":小巧、稳定,且每 30 分钟包含一次是安全的。

  • 如果 HEARTBEAT.md 存在但实际为空(仅空白行和 markdown 标题如 # Heading),OpenClaw 跳过心跳运行以节省 API 调用。如果文件缺失,心跳仍运行,模型决定做什么。
  • 保持小巧(简短检查清单或提醒)以避免提示膨胀。

HEARTBEAT.md 示例:

# Heartbeat checklist

- Quick scan: anything urgent in inboxes?
- If it's daytime, do a lightweight check-in if nothing else is pending.
- If a task is blocked, write down _what is missing_ and ask Peter next time.

Agent 可以更新 HEARTBEAT.md 吗?

可以——如果你要求它这样做。

HEARTBEAT.md 只是 Agent 工作区中的一个普通文件,因此你可以在正常聊天中告诉 Agent:

"Update HEARTBEAT.md to add a daily calendar check."
"Rewrite HEARTBEAT.md so it's shorter and focused on inbox follow-ups."

如果你希望这主动发生,还可以在心跳提示中包含显式行,如:"If the checklist becomes stale, update HEARTBEAT.md with a better one."

安全提示: 不要将机密(API 密钥、电话号码、私有令牌)放入 HEARTBEAT.md —— 它会成为提示上下文的一部分。


手动唤醒(按需)

你可以排队系统事件并立即触发心跳:

openclaw system event --text "Check for urgent follow-ups" --mode now

如果多个 Agent 配置了心跳,手动唤醒会立即运行每个 Agent 的心跳。

使用 --mode next-heartbeat 等待下一个计划 tick。


推理投递(可选)

默认情况下,心跳仅投递最终的"答案"负载。

如果你想要透明度,启用:

"agents.defaults.heartbeat.includeReasoning": true

启用时,心跳还将投递前缀为 Reasoning: 的单独消息(与 /reasoning on 相同格式)。这在 Agent 管理多个会话/法典且你想了解它为何决定 ping 你时很有用——但也可能泄露比你想要的更多内部细节。建议在群聊中保持关闭。


成本意识

心跳运行完整的 Agent 轮次。更短的间隔消耗更多 token。保持 HEARTBEAT.md 小巧,并考虑如果你只想要内部状态更新,使用更便宜的模型或 target: "none"


tbd...