心跳 (Heartbeat, Gateway)
心跳 vs 定时任务? 参见 定时任务 vs 心跳 了解何时使用哪种方式。
心跳在主会话中运行周期性的 agent 轮次,以便模型可以在不打扰你的情况下提醒需要注意的事项。
快速入门 (新手向)
- 保持心跳启用(默认 30m,或 Anthropic OAuth/setup-token 为 1h)或设置你自己的频率。
- 在 agent 工作区创建一个小的 HEARTBEAT.md 检查清单(可选但推荐)。
- 决定心跳消息应该发送到哪里(target: "last" 是默认值)。
- 可选:启用心跳推理传递以提高透明度。
- 可选:限制心跳在活跃时段(本地时间)。
配置示例:
{
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 禁用。
- 提示内容(可通过 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"部分,并在内部标记该运行。
- 活跃时段(heartbeat.activeHours)在配置的时区检查。在窗口外,心跳将被跳过直到下一个在窗口内的时刻。
心跳提示的用途
默认提示有意设计得很宽泛:
- 后台任务:"考虑未完成的任务"提示 agent 检查后续事项(收件箱、日历、提醒、排队工作)并提醒紧急事项。
- 人类问候:"白天偶尔问候你的主人"提示偶尔发送轻量级的"需要什么吗?"消息,但通过使用配置的本地时区避免夜间打扰(参见 /concepts/timezone)。
如果你希望心跳执行非常具体的任务(例如"检查 Gmail Pub/Sub 统计"或"验证 gateway 健康状况"),设置 agents.defaults.heartbeat.prompt(或 agents.list[].heartbeat.prompt)为自定义内容(逐字发送)。
响应约定
- 如果没有需要注意的事项,回复 HEARTBEAT_OK。
- 在心跳运行期间,OpenClaw 将 HEARTBEAT_OK 视为确认,当它出现在回复的开头或结尾时。该标记会被剥离,如果剩余内容**≤ ackMaxChars**(默认:300),回复将被丢弃。
- 如果 HEARTBEAT_OK 出现在回复的中间,则不会特殊处理。
- 对于警报,不要包含 HEARTBEAT_OK;只返回警报文本。
在心跳之外,消息开头/结尾的 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", // 可选的渠道特定覆盖
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 有 heartbeat 块,只有那些 agent 运行心跳。
- channels.defaults.heartbeat 设置所有渠道的可见性默认值。
- channels.<channel>.heartbeat 覆盖渠道默认值。
- channels.<channel>.accounts.<id>.heartbeat(多账户渠道)覆盖每个渠道的设置。
每个 agent 的心跳
如果任何 agents.list[] 条目包含 heartbeat 块,只有那些 agent 运行心跳。每个 agent 块合并在 agents.defaults.heartbeat 之上(因此你可以设置一次共享默认值并按 agent 覆盖)。
示例:两个 agent,只有第二个 agent 运行心跳。
{
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:心跳间隔(持续时间字符串;默认单位 = 分钟)。
- model:心跳运行的可选模型覆盖(provider/model)。
- includeReasoning:启用时,当可用时也传递单独的 Reasoning: 消息(与 /reasoning on 相同形式)。
- session:心跳运行的可选会话键 (session key)。
- main(默认):agent 主会话。
- 显式会话键(从 openclaw sessions --json 或 sessions CLI 复制)。
- 会话键格式:参见 Sessions 和 Groups。
- target:
- last(默认):传递到最后使用的外部渠道。
- 显式渠道:whatsapp / telegram / discord / googlechat / slack / msteams / signal / imessage。
- none:运行心跳但不向外部传递。
- to:可选的接收者覆盖(渠道特定 ID,例如 WhatsApp 的 E.164 或 Telegram 的聊天 ID)。
- prompt:覆盖默认提示内容(不合并)。
- ackMaxChars:HEARTBEAT_OK 后允许的最大字符数。
传递行为
- 心跳默认在 agent 的主会话中运行(agent:<id>:<mainKey>),或当 session.scope = "global" 时为 global。设置 session 以覆盖到特定渠道会话(Discord/WhatsApp 等)。
- session 仅影响运行上下文;传递由 target 和 to 控制。
- 要传递到特定渠道/接收者,设置 target + to。使用 target: "last",传递使用该会话的最后外部渠道。
- 如果主队列繁忙,心跳将被跳过并稍后重试。
- 如果 target 解析为无外部目标,运行仍然发生但不发送出站消息。
- 仅心跳的回复不会保持会话活跃;最后的 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 如下内容:
- "更新 HEARTBEAT.md 添加每日日历检查。"
- "重写 HEARTBEAT.md,使其更短并专注于收件箱后续。"
如果你希望这主动发生,你也可以在心跳提示中包含明确的行,如:"如果检查清单变得过时,请用更好的内容更新 HEARTBEAT.md。"
安全提示:不要将机密(API 密钥、电话号码、私人令牌)放入 HEARTBEAT.md — 它会成为提示上下文的一部分。
手动唤醒(按需)
你可以排队一个系统事件并触发立即心跳:
openclaw system event --text "Check for urgent follow-ups" --mode now
如果多个 agent 配置了 heartbeat,手动唤醒会立即运行每个这些 agent 的心跳。
使用 --mode next-heartbeat 等待下一个计划时刻。
推理传递(可选)
默认情况下,心跳只传递最终的"答案"负载。
如果你想要透明度,启用:
- agents.defaults.heartbeat.includeReasoning: true
启用后,心跳还将传递一个单独的前缀为 Reasoning: 的消息(与 /reasoning on 相同形式)。这在 agent 管理多个会话/代码库时可能很有用,你想看到它为什么决定 ping 你 — 但它也可能泄露比你想要的更多内部细节。最好在群组聊天中保持关闭。
成本意识
心跳运行完整的 agent 轮次。更短的间隔消耗更多令牌。保持 HEARTBEAT.md 小巧,并考虑更便宜的 model 或 target: "none",如果你只想要内部状态更新。