跳转至

心跳

Note

Heartbeat 是一项自动化。 关于选择系统拥有的监视器还是独立调度的任务, 请参阅 自动化。

Heartbeat 是一种系统拥有的自动化,它在主会话中运行周期性的智能体回合,让模型能够在不打扰你的情况下主动呈现任何需要关注的事项。

Heartbeat 是一个计划性的主会话回合。ACP 运行、子智能体和隔离的自动化任务使用各自的执行所有者。

在底层,heartbeat 节奏由 Automations 调度器负责:网关为每个启用了 heartbeat 的智能体维护一个系统拥有的自动化任务(在 openclaw cron list --all 中显示为 Heartbeat (agent-id))。Heartbeat 配置仍然是期望状态(desired-state)输入,而持久化的监视器调度表负责实际的触发 tick 以及运行器随后的冷却时间。网关在启动时和配置重载时写入配置更改。openclaw doctor --fix 可以在下一次网关启动之前物化缺失或过期的监视器行。请编辑 agents.*.heartbeat,而不是自动化任务。如果在配置更改被接受后保存监视器行失败,网关会保留已接受的配置并报告需要恢复。监视器重试使用当前已接受的配置。被拒绝的更改永远不会成为重试目标。

计划性的 heartbeat 需要 automations 系统。当 cron.enabled 为 false 或设置了 OPENCLAW_SKIP_CRON=1 时,网关会记录一条启动警告,并且不会运行计划性的 heartbeat。手动和事件驱动的 heartbeat 唤醒仍然可用。没有单独的 heartbeat 备用计时器。

设置 heartbeat.every: "0m" 仅禁用循环节奏。针对特定目标的事件驱动唤醒仍然可以运行一次智能体回合,例如后台 exec 完成时。它不会创建或重新启用循环调度。若要在不自动生成完成回合或其模型调用的情况下保留后台 exec,请设置 tools.exec.notifyOnExit: false;请查看 agents.entries.<id>.tools.exec.notifyOnExit 了解按智能体的覆盖配置。使用 process poll 收集结果。参见 后台 exec 通知。工具策略和沙箱机制控制智能体回合是否可以执行命令。

当循环节奏被禁用时,针对特定目标的事件唤醒仍保留相同的按智能体速率限制。这些限制是:事件回合之间至少间隔 30 秒,并且在 60 秒内启动五次后会触发洪泛保护。延迟的工作会在其保护期结束后恢复。配置重载会保留此记账信息,而不会将智能体纳入循环或广播式 heartbeat。

对话记录标记区分 [OpenClaw heartbeat poll] 与 exec 完成、cron 唤醒或会话事件。计划性轮询使用配置的 heartbeat 会话,该会话默认是智能体的主会话。针对特定目标的完成事件会返回拥有该工作的会话。事件标记保留其来源出处,而不会将内部指令复制到聊天历史中。静默确认对保持隐藏。

故障排查:自动化

快速入门(初学者)

1. 选择节奏

保持 heartbeat 启用(默认是 30m;当配置了 Anthropic OAuth/token 认证(包括 Claude CLI 复用)时为 1h),或设置你自己的节奏。

2. 添加监视器暂存区(可选)

使用 openclaw cron scratch <jobId> --set "..." 在 heartbeat 监视器的暂存区中存储一个简短的检查清单。

3. 决定 heartbeat 消息的发送位置

Heartbeat 警报默认发送到操作员的直接消息。将 commands.ownerAllowFrom 设置为一个数组,例如 ["telegram:123456789"],或使用具体的频道 allowFrom。仅包含通配符的允许列表无法识别所有者。

4. 可选调优

  • 如果 heartbeat 运行只需要监视器暂存区,请使用轻量级的引导上下文。
  • 启用隔离会话,避免每次 heartbeat 都发送完整的对话历史。
  • 将 heartbeat 限制在活跃时段(本地时间)内。

示例配置:

{
  commands: {
    ownerAllowFrom: ["telegram:123456789"],
  },
  agents: {
    defaults: {
      heartbeat: {
        every: "30m",
        target: "owner", // default: operator DM from ownerAllowFrom or channel allowFrom
        directPolicy: "allow", // default: allow direct/DM targets; set "block" to suppress
        lightContext: true, // optional: skip workspace bootstrap files for heartbeat runs
        isolatedSession: true, // optional: fresh session each run (no conversation history)
        // activeHours: { start: "08:00", end: "24:00" },
      },
    },
  },
}

对于已配置的 Telegram 机器人,请使用 JSON 数组设置所有者,即使只有一个条目也是如此。将 123456789 替换为你的 Telegram 用户 ID,并包含你想保留的任何现有所有者:

openclaw config set commands.ownerAllowFrom '["telegram:123456789"]'

若要显式选择收件人,请分别设置频道和收件人:

openclaw config set agents.defaults.heartbeat.to '"123456789"'
openclaw config set agents.defaults.heartbeat.target telegram

保留数字聊天 ID 周围的内层双引号,以便 to 存储为字符串。heartbeat.target 接受 owner、last、none 或频道 ID(如 telegram);telegram:123456789 应放在 commands.ownerAllowFrom 中,而不是 target。

默认值

  • 间隔:30m。当解析出的认证模式为 OAuth/token(包括 Claude CLI 复用)时,应用 Anthropic 提供程序默认值会将此值提升为 1h,但仅在 heartbeat.every 未设置时才如此。请设置 agents.defaults.heartbeat.every 或按智能体设置 agents.entries.*.heartbeat.every。使用 0m 禁用循环节奏。
  • 投递目标:owner。OpenClaw 使用 commands.ownerAllowFrom 中第一个具体的条目,然后是频道的 allowFrom,并且绝不会将这条路由发送到群组。如果没有可解析的所有者私聊(DM),后台轮询会以 reason=no-route 跳过。设置 target: "last" 以跟随最近的对话(包括群组),或设置 target: "none" 以仅进行内部运行。
  • 提示正文(可通过 agents.defaults.heartbeat.prompt 配置):Follow the heartbeat monitor scratch context when provided. Recurring tasks are automations; create or change their schedules with the automations tool, not heartbeat scratch. Do not infer or repeat old tasks from prior chats. If nothing needs attention, reply NO_REPLY.
  • 超时:未设置的 heartbeat 回合在设置了 agents.defaults.timeoutSeconds 时使用该值。否则,它们使用 heartbeat 节奏,上限为 600 秒。若需要更长的 heartbeat 工作时间,请设置 agents.defaults.heartbeat.timeoutSeconds 或按智能体设置 agents.entries.*.heartbeat.timeoutSeconds。在后台命令完成后恢复工作的回合,或处理后台任务审查、受阻任务事件以及恢复的重启工作的回合,使用普通的智能体超时(默认 48 小时);heartbeat 节奏和超时设置不会缩短这些延续工作。事件必须包含在回合中;隔离的监视器不会继承其基础会话中待处理工作的预算。
  • heartbeat 提示会作为计划性用户消息逐字发送。Heartbeat 运行使用与普通智能体回合相同的系统提示。没有针对 heartbeat 的系统提示专用部分。
  • 当使用 0m 禁用循环 heartbeat 时,自动化任务会保留但处于禁用状态。Doctor 在创建或更新此任务时会报告监视器已禁用,而不是将其保留的间隔显示为活跃节奏。其监视器暂存区会保留,供你重新启用节奏时使用。针对特定目标的事件驱动唤醒仍然可用。
  • 当 automations 被完全禁用时,即使 heartbeat 节奏仍然启用,计划性的 heartbeat 也不会运行。
  • 活跃时段(heartbeat.activeHours)在配置的时区中检查。在窗口之外,heartbeat 会被跳过,直到窗口内的下一个 tick。
  • 当主队列或自动化工作处于活跃或排队状态、同一智能体的任何回复或嵌入运行处于活跃状态,以及已解析的目标会话存在活跃或排队的工作时,计划性的 heartbeat 会延迟。尚未开始准备的、无事件的普通监视器轮询会被记录为已跳过,并等待其下一个持久化的节奏 tick,而不是在忙碌工作后面保持一个运行中的自动化一直开启。携带排队事件或计划任务的唤醒,以及已在执行后获得接纳或保留的工作,仍然会重试。即时唤醒和手动唤醒会绕过宽泛的同智能体活跃运行检查,但仍然遵守主队列、自动化和目标会话的忙碌保护。同级智能体不会相互暂停。
  • 针对特定目标的后台命令完成会等待其自身会话变为空闲,包括最终投递恢复,但不会等待无关的会话或自动化。与计划性 heartbeat 工作合并的完成事件会保留计划性工作的忙碌保护。

心跳 prompt 的作用

默认 prompt 被刻意保持狭窄:在提供时遵循 heartbeat monitor scratch context,将重复性工作保留在自动化任务中,并在没有需要关注的事项时回复 NO_REPLY。它会明确告知代理不要从先前聊天中推断或重复旧任务,因此默认安装会保持安静,而不是反复讨论过时的对话上下文。

主动的心跳行为需选择启用:

  • 重复性检查:为收件箱检查、日历扫描或排队中的后续事项创建 自动化。每个任务按各自计划执行其配置的负载。默认心跳不会从先前聊天中推断重复性工作。
  • 人工检查:如果你希望偶尔收到一条轻量级的“有什么需要吗?”消息,请创建一个计划任务,并限制其计划,以避免在你已配置的本地时区中夜间提醒(参见 时区)。

心跳可以响应来自后台执行的完成事件。

如果你希望心跳执行非常具体的操作(例如“检查 Gmail PubSub 统计”或“验证网关健康状态”),请将 agents.defaults.heartbeat.prompt(或 agents.entries.*.heartbeat.prompt)设置为自定义正文(按原样发送)。

响应约定

  • 如果没有需要关注的事项,请回复 NO_REPLY。
  • 心跳运行也可以改为调用 heartbeat_respond,并传入 notify: false 以不产生可见更新,或传入 notify: true 以及 notificationText 以发出告警。若存在结构化工具响应,则优先于文本回退。
  • 带有 notify: false 的有意义 heartbeat_respond 结果仍保持静默,但会被记住为该会话中下一用户轮次的有界内部上下文。已生成但投递被阻止或未确认的 notify: true 告警也会被记录,包括其告警文本和投递原因。这是该会话的最新结果,而不是告警历史或精确投递重放队列。no_change 确认和已确认的可见通知不会以这种方式存储。
  • 现有自定义 prompt 仍可能返回旧版 HEARTBEAT_OK 确认。OpenClaw 会在回复的开头或结尾接受它,并在剩余内容不超过 300 个字符时丢弃该回复。抑制预算是固定的。
  • 位于回复中间的旧版 HEARTBEAT_OK 不会被特殊处理。
  • 对于告警,只返回告警文本。不要包含静默确认。
  • 投递会选择最后一个可外发的非推理负载。独立的推理或思考负载仍保持内部状态。仅包含推理的结果不会产生告警。
  • 在心跳轮次期间,工具错误警告仍保持启用。
  • openclaw system heartbeat last --json 会将已确认的、通过消息工具发送给心跳接收方的发送报告为 sent,而不会再次发送确认。
  • 如果心跳启动了后台工作但未发送更新,其状态事件会报告 skipped,原因为 background-work。请检查任务是否完成。这不是“一切正常”的确认。

在心跳之外,消息开头/结尾出现的多余 HEARTBEAT_OK 会被移除并记录日志。如果消息仅包含 HEARTBEAT_OK,则会被丢弃。

配置

{
  agents: {
    defaults: {
      heartbeat: {
        every: "30m", // default: 30m (0m disables)
        model: "anthropic/claude-opus-4-6",
        lightContext: false, // default: false; true skips workspace bootstrap files for heartbeat runs
        isolatedSession: false, // default: false; true runs each heartbeat in a fresh session (no conversation history)
        target: "owner", // default | options: last | none | <channel id>
        accountId: "ops-bot", // optional multi-account channel id
        prompt: "Follow the heartbeat monitor scratch context when provided. Recurring tasks are automations; create or change their schedules with the automations tool, not heartbeat scratch. Do not infer or repeat old tasks from prior chats. If nothing needs attention, reply NO_REPLY.",
      },
    },
  },
}

作用范围与优先级

  • agents.defaults.heartbeat 设置全局心跳行为。
  • agents.entries.*.heartbeat 会叠加合并。如果任何代理具有 heartbeat 块,则仅这些代理会运行心跳。
  • 环境归属通过 agents.defaults.heartbeat.agentId、agents.defaults.systemAgent.agentId、旧版默认所有者,然后唯一代理来解析。当没有按代理或默认心跳块适用,且该链使多代理名册无所有者时,心跳保持禁用,并发出验证和 Gateway 警告。
  • channels.defaults.heartbeatVisibility 为所有渠道设置可见性默认值。
  • channels.<channel>.heartbeatVisibility 覆盖渠道默认值。
  • channels.<channel>.accounts.<id>.heartbeatVisibility(多账户渠道)覆盖按渠道的设置。

按代理的心跳

如果任何 agents.entries.* 条目包含 heartbeat 块,则仅这些代理会运行心跳。按代理的块会叠加合并到 agents.defaults.heartbeat 之上(因此你可以一次性设置共享默认值,并按代理覆盖)。

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

{
  agents: {
    defaults: {
      heartbeat: {
        every: "30m",
        target: "owner", // default: operator DM
      },
    },
    entries: {
      main: { default: true },
      ops: {
        heartbeat: {
          every: "1h",
          target: "whatsapp",
          to: "+15551234567",
          timeoutSeconds: 45,
          prompt: "Follow the heartbeat monitor scratch context when provided. Recurring tasks are automations; create or change their schedules with the automations tool, not heartbeat scratch. Do not infer or repeat old tasks from prior chats. If nothing needs attention, reply NO_REPLY.",
        },
      },
    },
  },
}

活跃时段示例

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

{
  agents: {
    defaults: {
      heartbeat: {
        every: "30m",
        target: "owner", // default: operator DM
        activeHours: {
          start: "09:00",
          end: "22:00",
          timezone: "America/New_York", // optional; uses your userTimezone if set, otherwise host tz
        },
      },
    },
  },
}

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

24/7 设置

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

  • 完全省略 activeHours(不设时间窗口限制,这是默认行为)。
  • 设置全天窗口:activeHours: { start: "00:00", end: "24:00" }。

Warning

不要将 start 和 end 设置为同一时间(例如 08:00 到 08:00)。这会被视为零宽度窗口,因此心跳将始终被跳过。

多账户示例

使用 accountId 在类似 Telegram 的多账户频道上指定特定账户:

{
  agents: {
    entries: {
      ops: {
        default: true,
        heartbeat: {
          every: "1h",
          target: "telegram",
          to: "12345678:topic:42", // optional: route to a specific topic/thread
          accountId: "ops-bot",
        },
      },
    },
  },
  channels: {
    telegram: {
      accounts: {
        "ops-bot": { botToken: "YOUR_TELEGRAM_BOT_TOKEN" },
      },
    },
  },
}

字段说明

every string(路径)
心跳间隔(持续时间字符串,默认单位分钟)。
model string(路径)
心跳运行的可选模型覆盖(provider/model)。
lightContext boolean(路径)默认值:false
为 true 时,心跳运行使用轻量级引导上下文,并跳过工作区引导文件。无论哪种方式,Monitor scratch 仍会由心跳运行器注入。
isolatedSession boolean(路径)默认值:false
为 true 时,每次心跳都在全新会话中运行,不包含任何先前的对话历史。使用与 sessionTarget: "isolated" 的自动化任务相同的隔离模式。可大幅降低每次心跳的 token 成本。与 lightContext: true 结合使用可获得最大节省。投递路由和对话上下文仍遵循所选会话,包括其频道、账户和话题。如果该会话之后迁移,后台命令的完成会保留其原始事件路由。它不会借用新房间的描述或激活策略。
session string(路径)

心跳运行的可选会话键。

  • main(默认):代理主会话。
  • 显式会话键(从 openclaw sessions --json 或 sessions CLI 复制)。
  • 会话键格式:参见 Sessions 和 Groups。
target string(路径)
  • owner(默认):投递到从 commands.ownerAllowFrom 解析出的第一个可用操作者 DM,其次为频道 allowFrom。此路由永远不会解析为群组或频道。
  • last:显式跟随最近使用的外部会话,包括群组和频道。
  • 显式频道:任何已配置的频道或插件 ID,例如 discord、matrix、telegram 或 whatsapp。
  • none:仅为了内部状态运行心跳。不要对外投递。

对于显式的 Telegram 接收者,请使用 target: "telegram" 和 to: "123456789"。 target 字段不接受诸如 "telegram:123456789" 的频道与接收者组合值。

directPolicy "allow" | "block"(路径)默认值:allow
控制直接/DM 投递行为。allow:允许直接/DM 心跳投递。block:抑制直接/DM 投递(reason=dm-blocked)。
to string(路径)
显式频道目标的接收者(例如 WhatsApp 的 E.164 号码或 Telegram 聊天 ID)。owner 或未设置 target 时会忽略 to。对于 Telegram 话题/主题线程,请使用 <chatId>:topic:<messageThreadId>。
accountId string(路径)
多账户频道的可选账户 ID。当 target: "last" 时,如果解析出的最后频道支持账户,则该账户 ID 会应用到该频道;否则将被忽略。如果账户 ID 与已解析频道所配置的账户不匹配,则跳过投递。
prompt string(路径)
覆盖默认提示词主体(不合并)。
timeoutSeconds number(路径)默认值:global timeout or min(every, 600)
允许心跳代理回合在被中止前运行的最大秒数。保持未设置时,如果设置了 agents.defaults.timeoutSeconds 则使用该值,否则使用心跳节奏(上限 600 秒)。 Exec 完成、后台任务以及恢复后的重启续跑改用普通代理超时,包括将 agents.defaults.timeoutSeconds 显式设置为 0 表示无超时。
activeHours object(路径)

将心跳运行限制在一个时间窗口内。对象包含 start(HH:MM,含起始时间,00:00 表示当天开始)、end(HH:MM,不含结束时间,允许 24:00 表示当天结束),以及可选的 timezone。

  • 省略或设为 "user":如果设置了 agents.defaults.userTimezone 则使用该值,否则回退到主机系统时区。
  • "local":始终使用主机系统时区。
  • 任何 IANA 标识符(例如 America/New_York):直接使用。如果无效,则回退到上述 "user" 行为。
  • 有效窗口的 start 和 end 不能相等。相等值会被视为零宽度(始终位于窗口之外)。
  • 在有效窗口之外,心跳会被跳过,直到窗口内的下一个触发到来。

Note

心跳配置是严格的:只接受上面列出的字段。确认抑制、推理可见性、系统提示词指导、忙碌延迟和工具错误警告行为是固定的运行时策略,而不是心跳配置字段。

投递行为

会话与目标路由
  • 默认情况下,心跳在代理的主会话中运行(agent:<id>:main),当 session.scope = "global" 时则在 global 中运行。设置 session 可覆盖为特定的频道会话(Discord/WhatsApp 等)。
  • session 只影响运行上下文。投递由 target 和 to 控制。
  • 默认的 owner 目标会选择一个显式配置的所有者身份。仅当会话的最后一条路由是直接与该所有者的私聊时,它才会复用完全相同的账户/线程。
  • 如果唤醒事件带有频道和接收者,它会在所有者发现之前使用该指定来源。此事件目标可以是群组,因为它是显式指定的,而非推断出来的。
  • 要投递到特定频道/接收者,请设置频道 target 并加上 to。target: "last" 是显式选择最近使用的外部会话(包括群组)的方式。
  • 默认情况下,心跳投递允许直接/DM 目标。设置 directPolicy: "block" 可抑制向直接目标的发送,同时仍执行心跳回合。
  • 当主队列或自动化任务忙碌、同一代理的任何回复或嵌入式运行处于活动状态,或解析出的目标会话有活动或排队中的工作时,计划心跳会被跳过。尚未开始准备的、没有事件的普通监控轮询会等待下一个持久化节奏触发。排队中的事件、计划任务以及执行后已受理或保留的工作会保留其重试。立即唤醒和手动唤醒仅绕过针对同一代理活动运行的宽泛预检。
  • 如果 owner 没有具体的、支持 DM 的所有者或已配置频道,轮询会在代理运行之前以 reason=no-route 跳过。当会话没有外部路由时,显式 last 也会跳过。
  • 由隐式 owner 默认目标投递的第一条提醒会解释定期检查以及如何选择 target: "none"。后续提醒会省略该行。
可见性与跳过行为
  • 如果心跳回合在模型能够回复之前失败,只要 OpenClaw 本身拒绝了运行,失败通知就会指明原因。一个例子是会话运行时仍在另一个 runner 中忙碌。原始提供商或运行时错误仍隐藏在详细失败详情设置(/verbose on 或 /verbose full)之后,与普通聊天相同。
  • 如果 showOk、showAlerts 和 useIndicator 全部禁用,则运行会提前跳过,原因为 reason=alerts-disabled。
  • 如果仅禁用告警投递,OpenClaw 仍可以运行心跳、更新到期任务时间戳、恢复会话空闲时间戳,并抑制向外的告警负载。
  • 如果渠道就绪检查阻止了告警,OpenClaw 会记录未投递。它会在 1 分钟宽限期后重试心跳,而不消耗其频率槽位。该重试会再次运行心跳。它不会重放之前完全相同的告警。一旦发送进入持久投递队列,该队列负责传输重试。
  • 如果解析出的心跳目标支持正在输入状态,OpenClaw 会在心跳运行期间显示正在输入状态。它使用心跳本应发送聊天输出的同一目标,并可通过 typingMode: "never" 禁用。
会话生命周期与审计
  • 仅心跳回复不会保持会话存活。心跳元数据可能会更新会话行,但空闲过期使用来自最后一条真实用户/渠道消息的 lastInteractionAt,每日过期使用 sessionStartedAt。
  • 控制 UI 和 WebChat 历史会隐藏心跳提示和仅 OK 确认。底层会话记录仍可能包含这些回合,用于审计/重放。
  • 当主会话需要快速注意到某些事情时,后台执行可以入队一个系统事件并唤醒心跳。

可见性控制

默认情况下,静默的心跳确认会被抑制,而告警内容会被投递。你可以按渠道或按账户调整此设置:

{
  channels: {
    defaults: {
      heartbeatVisibility: {
        showOk: false, // Hide HEARTBEAT_OK (default)
        showAlerts: true, // Show alert messages (default)
        useIndicator: true, // Emit indicator events (default)
      },
    },
    telegram: {
      heartbeatVisibility: {
        showOk: true, // Show OK acknowledgments on Telegram
      },
    },
    whatsapp: {
      accounts: {
        work: {
          heartbeatVisibility: {
            showAlerts: false, // Suppress alert delivery for this account
          },
        },
      },
    },
  },
}

优先级:按账户 → 按渠道 → 渠道默认值 → 内置默认值。

各标志的作用

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

如果三者均为 false,OpenClaw 将完全跳过心跳运行(不调用模型)。

按渠道与按账户示例

{
  channels: {
    defaults: {
      heartbeatVisibility: {
        showOk: false,
        showAlerts: true,
        useIndicator: true,
      },
    },
    slack: {
      heartbeatVisibility: {
        showOk: true, // all Slack accounts
      },
      accounts: {
        ops: {
          heartbeatVisibility: {
            showAlerts: false, // suppress alerts for the ops account only
          },
        },
      },
    },
    telegram: {
      heartbeatVisibility: {
        showOk: true,
      },
    },
  },
}

常见模式

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

监控草稿(可选)

每个心跳自动化任务都拥有一个私有的监控草稿,存储在共享状态数据库中。可以把它看作你的“心跳清单”:小巧、稳定,并且适合每 30 分钟检查一次。当草稿存在时,其内容会被追加到心跳提示中。

使用自动化 CLI 管理它(任务 id 来自 openclaw cron list --all):

openclaw cron scratch <jobId>                 # print the current scratch
openclaw cron scratch <jobId> --set "..."     # replace it with exact text
openclaw cron scratch <jobId> --file notes.md # replace it from a file (- for stdin)
openclaw cron scratch <jobId> --unset         # remove it

写入受比较并交换保护:传入 --expected-revision <n> 可在并发编辑时失败,而不是覆盖。草稿上限为 256 KiB,并且不会出现在 cron list/cron runs 输出中。

代理也可以更新自己的草稿:在心跳回合中,heartbeat_respond 接受一个可选的 scratch 字符串,它会完全替换监控器未来心跳使用的草稿。

Note

从 HEARTBEAT.md 或仅配置的心跳频率迁移? 运行 openclaw doctor --fix。Doctor 会先从 agents.*.heartbeat 创建或更新系统拥有的监控行。然后它将每个代理工作区中的 HEARTBEAT.md 导入监控草稿。它会将任何有效的旧版 tasks: 条目转换为自动化任务。它会将原始文件归档到状态目录(backups/heartbeat-migration/)下,并删除该文件。运行时的心跳指令仅来自数据库草稿。运行时永远不会读取 HEARTBEAT.md。

如果工作区和状态目录位于不同的文件系统上,Doctor 会将原始文件保留在其原位置旁边的私有 HEARTBEAT.md.doctor-archived.* 目录中。状态目录中的备份仍保持为不可变快照。通过已打开的文件描述符进行的后续写入仍可在工作区归档中恢复。

当 scratch 存在但实际为空时,OpenClaw 会跳过 heartbeat 运行以节省 API 调用。实际为空表示仅包含空行、Markdown 或 HTML 注释、类似 # Heading 的 Markdown 标题、围栏标记,或空的检查清单存根。该跳过会报告为 reason=empty-heartbeat-file。没有到期任务的计划间隔监视器会在因繁忙执行队列而延迟之前解决此跳过。如果不存在 scratch,heartbeat 仍会运行,并由模型决定要执行的操作。

保持其极小(简短的检查清单或提醒),以避免 prompt 膨胀。

示例 scratch:

# 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.

使用自动化安排重复检查

Monitor scratch 是 prompt 上下文,而不是调度器。将每个重复检查创建为一个自动化任务,使其拥有自己的节奏、启用/禁用状态和运行历史。当检查应使用正常对话上下文时,自动化任务仍可以指向主会话。

旧版 scratch 可能包含结构化的 tasks: 块。升级后运行一次 openclaw doctor --fix:Doctor 会将每个有效条目转换为独立调度的自动化任务。它会保留每个条目的间隔和之前的上次运行时间。它会移除已弃用的块,并保留周围的 scratch 文本。运行时 heartbeat 轮次不会将 tasks: 文本解析为调度。

Doctor 创建的 heartbeat 任务作业会保留 heartbeat 的活跃时段、冷却、洪泛和繁忙保护。同时到期的作业可以合并为一个 heartbeat 轮次。活跃时段之外的触发会被跳过,并在其下一个计划触发时间重试。

代理可以更新其 scratch 吗

是的。在 heartbeat 轮次期间,代理可以向 heartbeat_respond 传递一个 scratch 值,以完全替换未来 heartbeat 的 monitor scratch。你也可以在普通聊天中要求它运行 openclaw cron scratch <jobId> --set ...,或者使用相同命令自行编辑 scratch。请使用自动化来管理重复调度,而不是将调度器语法写入 scratch。

Warning

请勿将机密信息(API 密钥、电话号码、私有 Token)放入 monitor scratch——它会成为 prompt 上下文的一部分。

手动唤醒(按需)

使用 openclaw system event 将系统事件加入队列,并可选地触发立即 heartbeat:

openclaw system event --text "Check for urgent follow-ups" --mode now
标志 描述
--text <text> 系统事件文本(必填)。
--mode <mode> now 立即运行 heartbeat;next-heartbeat(默认)等待下一个计划触发。
--session-key <sessionKey> 为事件指定特定会话;默认为代理的主会话。
--json 输出 JSON。

如果未提供 --session-key,且多个代理配置了 heartbeat,则 --mode now 会立即运行这些代理的每个 heartbeat。

即使另一个代理成功或被静默跳过,广播完成报告也会报告某个代理失败。繁忙重试和受保护延迟会保持其现有重试行为。

同一 CLI 组中的相关 heartbeat 控制:

openclaw system heartbeat last     # show the last heartbeat event
openclaw system heartbeat enable   # enable heartbeats
openclaw system heartbeat disable  # disable heartbeats

成本意识

Heartbeat 会运行完整的代理轮次。更短的间隔会消耗更多 Token。为降低成本:

  • 使用 isolatedSession: true 以避免发送完整对话历史(每次运行从约 100K Token 降至约 2-5K)。
  • 使用 lightContext: true 以在 heartbeat 运行时跳过工作区引导文件。
  • 设置更便宜的 model(例如 ollama/llama3.2:1b)。
  • 保持 monitor scratch 较小。
  • 如果只想更新内部状态,请显式设置 target: "none"。

heartbeat 后的上下文溢出

Heartbeat 在运行完成后会保留共享会话现有的运行时模型。因此,将某个会话切换到更小本地模型的 heartbeat 可能会让该模型保留到下一个主会话轮次。一个具有 32k 窗口的 Ollama 模型就是一个例子。下一个轮次可能会报告上下文溢出。如果会话的最后运行时模型也与配置的 heartbeat.model 匹配,OpenClaw 的恢复消息会指出 heartbeat 模型泄漏是可能的原因。该消息还会建议修复方法。

为避免此问题,请使用 isolatedSession: true 在新会话中运行 heartbeat。你可以将其与 lightContext: true 组合,以获得最小的 prompt。否则,请选择一个上下文窗口足够容纳共享会话的 heartbeat 模型。

本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 cl/openclaw