Heartbeat (Gateway)

Heartbeat 还是 Cron? 查看 Cron vs Heartbeat 了解如何选择。

Heartbeat 会在主 Session 中定期运行 Agent 轮次,让模型可以主动提醒需要注意的事项,而不会频繁打扰你。

快速开始(新手)

  1. 保持 Heartbeat 启用(默认是 30m,如果使用 Anthropic OAuth/setup-token 则是 1h),或设置你自己的频率。
  2. 在 Agent Workspace 中创建一个小巧的 HEARTBEAT.md 清单(可选但推荐)。
  3. 决定 Heartbeat 消息发送到哪里(target: "last" 是默认值)。
  4. 可选:启用 Heartbeat 推理过程传递,提高透明度。
  5. 可选:限制 Heartbeat 仅在活跃时段运行(本地时间)。

配置示例:

{
  agents: {
    defaults: {
      heartbeat: {
        every: "30m",
        target: "last",
        // activeHours: { start: "08:00", end: "24:00" },
        // includeReasoning: true, // 可选:同时发送单独的 `Reasoning:` 消息
      },
    },
  },
}

默认设置

  • 间隔:30m(如果检测到使用 Anthropic OAuth/setup-token 认证模式则是 1h)。通过 agents.defaults.heartbeat.every 或单个 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 会原样作为用户消息发送。系统 Prompt 包含一个 “Heartbeat” 部分,运行时会在内部标记。
  • 活跃时段(heartbeat.activeHours)会在配置的时区中检查。在时间窗口之外,Heartbeat 会被跳过,直到下一个在窗口内的时刻。

Heartbeat Prompt 的用途

默认 Prompt 故意设计得比较宽泛:

  • 后台任务:“考虑未完成的任务”会提示 Agent 检查待办事项(收件箱、日历、提醒、排队的工作),并提醒任何紧急事项。
  • 人工检查:“在白天偶尔检查你的人类”会提示偶尔发送轻量级的”有什么需要帮忙的吗?”消息,但通过使用你配置的本地时区来避免夜间打扰(参见 /concepts/timezone)。

如果你想让 Heartbeat 做非常具体的事情(例如”检查 Gmail PubSub 统计”或”验证 Gateway 健康状态”),可以设置 agents.defaults.heartbeat.prompt(或 agents.list[].heartbeat.prompt)为自定义内容(原样发送)。

响应约定

  • 如果没有需要注意的事项,回复 HEARTBEAT_OK
  • 在 Heartbeat 运行期间,OpenClaw 会将出现在回复开头或结尾HEARTBEAT_OK 视为确认。该标记会被移除,如果剩余内容 ackMaxChars(默认:300),回复会被丢弃。
  • 如果 HEARTBEAT_OK 出现在回复的中间,则不会特殊处理。
  • 对于警报,不要包含 HEARTBEAT_OK;只返回警报文本。

在 Heartbeat 之外,消息开头/结尾的零散 HEARTBEAT_OK 会被移除并记录;仅包含 HEARTBEAT_OK 的消息会被丢弃。

配置

{
  agents: {
    defaults: {
      heartbeat: {
        every: "30m", // 默认:30m(0m 禁用)
        model: "anthropic/claude-opus-4-5",
        includeReasoning: false, // 默认:false(在可用时传递单独的 Reasoning: 消息)
        target: "last", // last | none | <channel id>(核心或插件,例如 "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 块,只有这些 Agent 会运行 Heartbeat。
  • channels.defaults.heartbeat 为所有 Channel 设置可见性默认值。
  • channels.<channel>.heartbeat 覆盖 Channel 默认值。
  • channels.<channel>.accounts.<id>.heartbeat(多账户 Channel)覆盖单个 Channel 设置。

单个 Agent 的 Heartbeat

如果任何 agents.list[] 条目包含 heartbeat 块,只有这些 Agent 会运行 Heartbeat。单个 Agent 的块会在 agents.defaults.heartbeat 之上合并(所以你可以设置一次共享默认值,然后按 Agent 覆盖)。

示例:两个 Agent,只有第二个 Agent 运行 Heartbeat。

{
  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 间隔(时长字符串;默认单位 = 分钟)。
  • model:Heartbeat 运行的可选模型覆盖(provider/model)。
  • includeReasoning:启用时,在可用时也传递单独的 Reasoning: 消息(与 /reasoning on 形式相同)。
  • session:Heartbeat 运行的可选 Session 键。
    • main(默认):Agent 主 Session。
    • 显式 Session 键(从 openclaw sessions --jsonsessions CLI 复制)。
    • Session 键格式:参见 SessionsGroups
  • target:
    • last(默认):传递到最后使用的外部 Channel。
    • 显式 Channel:whatsapp / telegram / discord / googlechat / slack / msteams / signal / imessage
    • none:运行 Heartbeat 但不向外部传递
  • to:可选的接收者覆盖(Channel 特定 ID,例如 WhatsApp 的 E.164 或 Telegram 聊天 ID)。
  • prompt:覆盖默认 Prompt 内容(不合并)。
  • ackMaxChars:HEARTBEAT_OK 后传递前允许的最大字符数。

传递行为

  • Heartbeat 默认在 Agent 的主 Session 中运行(agent:<id>:<mainKey>),或当 session.scope = "global" 时在 global 中运行。设置 session 可覆盖到特定 Channel Session(Discord/WhatsApp 等)。
  • session 只影响运行上下文;传递由 targetto 控制。
  • 要传递到特定 Channel/接收者,设置 target + to。使用 target: "last" 时,传递使用该 Session 的最后一个外部 Channel。
  • 如果主队列繁忙,Heartbeat 会被跳过并稍后重试。
  • 如果 target 解析为没有外部目标,运行仍会发生但不会发送出站消息。
  • 仅 Heartbeat 的回复不会保持 Session 活跃;最后的 updatedAt 会被恢复,因此空闲过期行为正常。

可见性控制

默认情况下,HEARTBEAT_OK 确认会被抑制,而警报内容会被传递。你可以按 Channel 或按账户调整:

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

优先级:单个账户 → 单个 Channel → Channel 默认值 → 内置默认值。

各标志的作用

  • showOk:当模型返回仅 OK 的回复时,发送 HEARTBEAT_OK 确认。
  • showAlerts:当模型返回非 OK 回复时,发送警报内容。
  • useIndicator:为 UI 状态界面发出指示器事件。

如果三个都是 false,OpenClaw 会完全跳过 Heartbeat 运行(不调用模型)。

单个 Channel 与单个账户示例

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 }
仅在一个 Channel 中显示 OKchannels.telegram.heartbeat: { showOk: true }

HEARTBEAT.md(可选)

如果 Workspace 中存在 HEARTBEAT.md 文件,默认 Prompt 会告诉 Agent 读取它。把它想象成你的”Heartbeat 清单”:小巧、稳定,每 30 分钟包含一次也很安全。

如果 HEARTBEAT.md 存在但实际上是空的(只有空行和 Markdown 标题如 # Heading),OpenClaw 会跳过 Heartbeat 运行以节省 API 调用。如果文件缺失,Heartbeat 仍会运行,模型会决定做什么。

保持它小巧(简短的清单或提醒)以避免 Prompt 膨胀。

HEARTBEAT.md 示例:

# Heartbeat 清单

- 快速扫描:收件箱中有紧急事项吗?
- 如果是白天,在没有其他待办事项时做一次轻量级检查。
- 如果任务被阻塞,写下_缺少什么_,下次问 Peter。

Agent 可以更新 HEARTBEAT.md 吗?

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

HEARTBEAT.md 只是 Agent Workspace 中的一个普通文件,所以你可以在正常聊天中告诉 Agent 类似这样的话:

  • “更新 HEARTBEAT.md,添加每日日历检查。”
  • “重写 HEARTBEAT.md,让它更短,专注于收件箱跟进。”

如果你想让这主动发生,也可以在 Heartbeat Prompt 中包含明确的一行,比如:“如果清单变得过时,用更好的内容更新 HEARTBEAT.md。”

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

手动唤醒(按需)

你可以排队一个系统事件并立即触发 Heartbeat:

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

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

使用 --mode next-heartbeat 等待下一个计划的时刻。

推理过程传递(可选)

默认情况下,Heartbeat 只传递最终的”答案”负载。

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

  • agents.defaults.heartbeat.includeReasoning: true

启用时,Heartbeat 还会传递一个前缀为 Reasoning: 的单独消息(与 /reasoning on 形式相同)。当 Agent 管理多个 Session/Codex 时,这很有用,你可以看到它为什么决定提醒你——但它也可能泄露比你想要的更多内部细节。在群聊中最好保持关闭。

成本意识

Heartbeat 运行完整的 Agent 轮次。更短的间隔会消耗更多 Token。保持 HEARTBEAT.md 小巧,如果你只想要内部状态更新,考虑使用更便宜的 modeltarget: "none"