Skip to content

Heartbeat(Gateway)

Heartbeat vs Cron? 何时用哪个,见 Cron vs Heartbeat

Heartbeat 会在 main session 中运行 周期性的 agent turns,让模型在不刷屏的前提下,把需要关注的事情浮出来。

快速开始(新手)

  1. 保持 heartbeats 启用(默认 30m;当检测到 Anthropic OAuth/setup-token 时为 1h),或设置你自己的频率。
  2. 在 agent workspace 创建一个很小的 HEARTBEAT.md 清单(可选但推荐)。
  3. 决定 heartbeat 消息发送到哪里(默认 target: "last")。
  4. 可选:启用 heartbeat reasoning 投递以提高透明度。
  5. 可选:把 heartbeats 限制在活跃时段(本地时间)。

示例配置:

json5
{
  agents: {
    defaults: {
      heartbeat: {
        every: "30m",
        target: "last",
        // activeHours: { start: "08:00", end: "24:00" },
        // includeReasoning: true, // optional: 也发送一条单独的 `Reasoning:` 消息
      },
    },
  },
}

默认值

  • 间隔:30m(当检测到 Anthropic OAuth/setup-token 作为鉴权模式时为 1h)。设置 agents.defaults.heartbeat.every 或 per-agent agents.list[].heartbeat.every;用 0m 禁用。
  • Prompt 内容(可通过 agents.defaults.heartbeat.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.
  • heartbeat prompt 会作为 user message 原样发送。system prompt 会包含一个 “Heartbeat” 章节,且该 run 会在内部打标。
  • 活跃时段(heartbeat.activeHours)按配置的时区检查;在窗口之外会跳过,直到下一次 tick 落在窗口内。

heartbeat prompt 的用途

默认 prompt 有意保持“宽泛”:

  • 后台任务:让 agent 回顾待办(收件箱、日历、提醒、排队工作),并把紧急事项浮出来。
  • 对人的轻量 check-in:白天偶尔发一条“你需要什么吗?”的轻提示;同时通过本地时区避免夜间刷屏(见 /concepts/timezone)。

如果你希望 heartbeat 做得更具体(例如“检查 Gmail PubSub 统计”或“验证 gateway health”),请把 agents.defaults.heartbeat.prompt(或 agents.list[].heartbeat.prompt)设置为自定义内容(会原样发送)。

响应约定(Response contract)

  • 如果没有需要关注的事项,回复 HEARTBEAT_OK
  • 在 heartbeat run 中,如果回复的 开头或结尾 出现 HEARTBEAT_OK,OpenClaw 会把它当作 ack:该 token 会被剥离;并且如果剩余内容 ackMaxChars(默认 300),整条回复会被丢弃。
  • 如果 HEARTBEAT_OK 出现在回复 中间,则不会被特殊处理。
  • 对于告警内容,不要 包含 HEARTBEAT_OK;只返回告警文本。

在非 heartbeat 场景下,如果消息开头/结尾出现游离的 HEARTBEAT_OK,它会被剥离并记录;如果消息仅为 HEARTBEAT_OK,则会被丢弃。

配置

json5
{
  agents: {
    defaults: {
      heartbeat: {
        every: "30m", // default: 30m(0m 禁用)
        model: "anthropic/claude-opus-4-5",
        includeReasoning: false, // default: false(可用时投递单独的 Reasoning: 消息)
        target: "last", // last | none | <channel id>(core 或 plugin,例如 "bluebubbles")
        to: "+15551234567", // 可选:按 channel 的收件人覆盖
        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 设置全局 heartbeat 行为。
  • agents.list[].heartbeat 在其之上合并;如果任意 agent 存在 heartbeat block,则 只有这些 agents 会运行 heartbeats。
  • channels.defaults.heartbeat 设置所有 channels 的可见性默认值。
  • channels.<channel>.heartbeat 覆盖 channel 默认值。
  • channels.<channel>.accounts.<id>.heartbeat(多账号 channel)覆盖单个账号。

Per-agent heartbeats

如果任意 agents.list[] 条目包含 heartbeat block,则 只有这些 agents 会运行 heartbeats。per-agent block 会合并到 agents.defaults.heartbeat 之上(你可以设置共享默认值,然后按 agent 覆盖)。

示例:两个 agents,只有第二个 agent 运行 heartbeats。

json5
{
  agents: {
    defaults: {
      heartbeat: {
        every: "30m",
        target: "last",
      },
    },
    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.",
        },
      },
    ],
  },
}

字段备注

  • every:heartbeat 间隔(duration string;默认单位为分钟)。
  • model:可选,heartbeat runs 的模型覆盖(provider/model)。
  • includeReasoning:启用后,当可用时也投递单独的 Reasoning: 消息(与 /reasoning on 同形)。
  • session:可选,heartbeat runs 的 session key。
    • main(默认):agent 的 main session。
    • 显式 session key(可从 openclaw sessions --jsonsessions CLI 复制)。
    • session key 格式见 SessionsGroups
  • target
    • last(默认):投递到该 session 最近使用的外部 channel。
    • 显式 channel:whatsapp / telegram / discord / googlechat / slack / msteams / signal / imessage
    • none:运行 heartbeat 但 不对外投递
  • to:可选,收件人覆盖(channel-specific id,例如 WhatsApp 的 E.164 或 Telegram chat id)。
  • prompt:覆盖默认 prompt body(不会合并)。
  • ackMaxChars:在投递前,HEARTBEAT_OK 后允许的最大字符数。

投递行为

  • 默认情况下 heartbeats 在 agent 的 main session 中运行(agent:<id>:<mainKey>),当 session.scope = "global" 时为 global。 设置 session 可覆盖为某个特定 channel session(Discord/WhatsApp/etc.)。
  • session 只影响运行上下文;投递由 targetto 控制。
  • 要投递到特定 channel/收件人,请设置 target + to。使用 target: "last" 时,会投递到该 session 最近的外部 channel。
  • 如果 main queue 正忙,本次 heartbeat 会被跳过,稍后重试。
  • 如果 target 解析不到外部目的地,本次 run 仍会执行,但不会发送出站消息。
  • 仅 heartbeat 的回复 不会 让 session 保持活跃;updatedAt 会被恢复,因此 idle expiry 行为保持正常。

可见性控制

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

yaml
channels:
  defaults:
    heartbeat:
      showOk: false # 隐藏 HEARTBEAT_OK(默认)
      showAlerts: true # 显示告警消息(默认)
      useIndicator: true # 发出 indicator events(默认)
  telegram:
    heartbeat:
      showOk: true # 在 Telegram 上显示 OK ack
  whatsapp:
    accounts:
      work:
        heartbeat:
          showAlerts: false # 对该账号抑制告警投递

优先级:per-account → per-channel → channel defaults → 内置默认值。

每个 flag 的含义

  • showOk:当模型返回仅 OK 的回复时,发送 HEARTBEAT_OK ack。
  • showAlerts:当模型返回非 OK 回复时,发送告警内容。
  • useIndicator:为 UI 状态面发出 indicator events。

如果 三者都为 false,OpenClaw 会完全跳过 heartbeat run(不调用模型)。

Per-channel vs per-account 示例

yaml
channels:
  defaults:
    heartbeat:
      showOk: false
      showAlerts: true
      useIndicator: true
  slack:
    heartbeat:
      showOk: true # 所有 Slack accounts
    accounts:
      ops:
        heartbeat:
          showAlerts: false # 仅对 ops account 抑制告警
  telegram:
    heartbeat:
      showOk: true

常见模式

GoalConfig
Default behavior (silent OKs, alerts on)(no config needed)
Fully silent (no messages, no indicator)channels.defaults.heartbeat: { showOk: false, showAlerts: false, useIndicator: false }
Indicator-only (no messages)channels.defaults.heartbeat: { showOk: false, showAlerts: false, useIndicator: true }
OKs in one channel onlychannels.telegram.heartbeat: { showOk: true }

HEARTBEAT.md(可选)

如果 workspace 中存在 HEARTBEAT.md 文件,默认 prompt 会让 agent 去读取它。你可以把它当作“heartbeat 清单”:小、稳定、且每 30 分钟包含一次也很安全。

如果 HEARTBEAT.md 存在但实际上是空的(只有空行与类似 # Heading 的 markdown 标题),OpenClaw 会跳过 heartbeat run 以节省 API 调用。 如果文件不存在,heartbeat 仍会运行,由模型决定做什么。

保持它很小(短清单或提醒),避免 prompt 膨胀。

示例 HEARTBEAT.md

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 workspace 里的普通文件,因此你可以在正常聊天中说:

  • “Update HEARTBEAT.md to add a daily calendar check.”
  • “Rewrite HEARTBEAT.md so it’s shorter and focused on inbox follow-ups.”

如果你希望它主动发生,也可以在 heartbeat prompt 里加一句明确指令,例如: “如果清单已经过时,就更新 HEARTBEAT.md 为更好的版本。”

安全提示:不要把 secrets(API keys、手机号、私密 token)写进 HEARTBEAT.md —— 它会成为 prompt 上下文的一部分。

手动唤醒(按需)

你可以入队一个 system event 并触发一次立即 heartbeat:

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

如果多个 agents 配置了 heartbeat,手动唤醒会立即运行这些 agents 的 heartbeat。

使用 --mode next-heartbeat 会等待下一次计划的 tick。

Reasoning 投递(可选)

默认情况下,heartbeats 只投递最终“答案”负载。

如果你希望更透明,可以启用:

  • agents.defaults.heartbeat.includeReasoning: true

启用后,heartbeats 在可用时还会投递一条单独的消息,前缀为 Reasoning:(与 /reasoning on 同形)。这在 agent 管理多个 sessions/codexes、你想知道它为什么决定 ping 你时很有用——但也可能泄露比你希望更多的内部细节。在群聊中建议保持关闭。

成本意识

Heartbeats 会运行完整的 agent turns。间隔越短越耗 tokens。请保持 HEARTBEAT.md 小,并在你只需要内部状态更新时考虑使用更便宜的 modeltarget: "none"