ハートビート(Gateway)
Heartbeat と Cron のどちらを使うべきですか? 使い分けの指針については Automation & Tasks を参照してください。Heartbeat は、定期的なエージェントターン をメインセッションで実行し、 必要な注意事項をモデルが表に出せるようにしつつ、過剰な通知を防ぎます。 Heartbeat は、スケジュールされたメインセッションのターンです — background task レコードは作成しません。 タスクレコードは、切り離された作業(ACP 実行、subagent、分離された cron ジョブ)用です。 トラブルシューティング: Scheduled Tasks
クイックスタート(初心者向け)
- Heartbeat を有効のままにする(デフォルトは
30m、Anthropic OAuth/token auth の場合は1h。Claude CLI reuse を含む)か、独自の頻度を設定します。 - エージェントワークスペースに小さな
HEARTBEAT.mdチェックリストまたはtasks:ブロックを作成します(任意ですが推奨)。 - Heartbeat メッセージの送信先を決めます(デフォルトは
target: "none"です。最後の連絡先に送るにはtarget: "last"を設定します)。 - 任意で、透明性のために heartbeat reasoning 配信を有効にします。
- 任意で、heartbeat 実行で
HEARTBEAT.mdだけが必要な場合は軽量な bootstrap コンテキストを使用します。 - 任意で、heartbeat ごとに会話履歴全体を送らないように分離セッションを有効にします。
- 任意で、heartbeat をアクティブ時間帯(ローカル時刻)に制限します。
デフォルト
- 間隔:
30m(または、Anthropic OAuth/token auth が検出された auth mode の場合は1h。Claude CLI reuse を含む)。agents.defaults.heartbeat.everyまたはエージェントごとの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 が有効かつ 実行が内部的にフラグ付けされている場合にのみ「Heartbeat」セクションが含まれます。
- Heartbeat を
0mで無効にすると、通常実行でも bootstrap コンテキストからHEARTBEAT.mdが除外されるため、モデルは heartbeat 専用の指示を見ません。 - アクティブ時間帯(
heartbeat.activeHours)は、設定されたタイムゾーンで判定されます。 時間帯外では、heartbeat は次に時間帯内に入る tick までスキップされます。
heartbeat プロンプトの目的
デフォルトのプロンプトは、意図的に広い内容になっています:- バックグラウンドタスク: 「未処理タスクを検討する」は、エージェントに フォローアップ(受信箱、カレンダー、リマインダー、キュー済み作業)を確認させ、 緊急なものを表に出すよう促します。
- 人へのチェックイン: 「日中にときどき人間の様子を確認する」は、 軽い「何か必要ですか?」メッセージを時々送るよう促しますが、 設定されたローカルタイムゾーンを使うことで夜間の通知過多を避けます(/concepts/timezone を参照)。
agents.defaults.heartbeat.prompt(または
agents.list[].heartbeat.prompt)にカスタム本文(そのまま送信される)を設定してください。
レスポンス契約
- 注意が必要なことが何もなければ、
HEARTBEAT_OKで返信します。 - heartbeat 実行中、OpenClaw は返信の先頭または末尾に
HEARTBEAT_OKが現れた場合、 それを ack として扱います。このトークンは削除され、残りの内容がackMaxChars以下(デフォルト: 300)であれば、その返信は破棄されます。 HEARTBEAT_OKが返信の途中に現れた場合は、 特別扱いされません。- アラートの場合は、
HEARTBEAT_OKを含めないでください。アラート文だけを返します。
HEARTBEAT_OK は削除されて
ログに記録されます。メッセージが HEARTBEAT_OK だけの場合は破棄されます。
設定
スコープと優先順位
agents.defaults.heartbeatはグローバルな heartbeat 動作を設定します。agents.list[].heartbeatはその上にマージされます。いずれかのエージェントにheartbeatブロックがある場合、heartbeat を実行するのはそれらのエージェントだけです。channels.defaults.heartbeatは全チャネルの可視性デフォルトを設定します。channels.<channel>.heartbeatはチャネルデフォルトを上書きします。channels.<channel>.accounts.<id>.heartbeat(マルチアカウントチャネル)はチャネルごとの設定を上書きします。
エージェントごとの heartbeat
いずれかのagents.list[] エントリに heartbeat ブロックが含まれている場合、heartbeat を実行するのはそれらのエージェントだけです。エージェントごとのブロックは
agents.defaults.heartbeat の上にマージされます
(共有デフォルトを一度設定し、エージェントごとに上書きできます)。
例: 2つのエージェントがあり、heartbeat を実行するのは2番目のエージェントだけです。
アクティブ時間帯の例
特定のタイムゾーンの業務時間に heartbeat を制限します:24時間365日の設定
heartbeat を終日実行したい場合は、次のいずれかのパターンを使用します:activeHoursを完全に省略する(時間帯制限なし。これがデフォルト動作です)。- 終日ウィンドウを設定する:
activeHours: { start: "00:00", end: "24:00" }。
start と end の時刻(たとえば 08:00 から 08:00)は設定しないでください。
これは幅ゼロのウィンドウとして扱われるため、heartbeat は常にスキップされます。
マルチアカウントの例
Telegram のようなマルチアカウントチャネルで特定のアカウントを対象にするにはaccountId を使います:
フィールドメモ
every: heartbeat 間隔(duration string。デフォルト単位 = 分)。model: heartbeat 実行用の任意のモデル上書き(provider/model)。includeReasoning: 有効な場合、利用可能なときに別のReasoning:メッセージも配信します(/reasoning onと同じ形式)。lightContext: true の場合、heartbeat 実行では軽量な bootstrap コンテキストを使い、ワークスペース bootstrap ファイルからHEARTBEAT.mdのみを保持します。isolatedSession: true の場合、各 heartbeat は以前の会話履歴を持たない新しいセッションで実行されます。cron のsessionTarget: "isolated"と同じ分離パターンを使用します。heartbeat ごとのトークンコストを大幅に削減します。最大限節約するにはlightContext: trueと組み合わせてください。配信ルーティングは引き続きメインセッションのコンテキストを使います。session: heartbeat 実行用の任意のセッションキー。main(デフォルト): エージェントのメインセッション。- 明示的なセッションキー(
openclaw sessions --jsonまたは sessions CLI からコピー)。 - セッションキー形式: Sessions および Groups を参照してください。
target:last: 最後に使用された外部チャネルに配信します。- 明示的なチャネル: 任意の設定済みチャネルまたは plugin id。たとえば
discord、matrix、telegram、whatsapp。 none(デフォルト): heartbeat は実行しますが、外部には配信しません。
directPolicy: 直接/DM 配信の動作を制御します:allow(デフォルト): 直接/DM への heartbeat 配信を許可します。block: 直接/DM 配信を抑制します(reason=dm-blocked)。
to: 任意の受信者上書き(チャネル固有 id。たとえば WhatsApp の E.164 や Telegram の chat id)。Telegram の topic/thread には<chatId>:topic:<messageThreadId>を使用します。accountId: マルチアカウントチャネル用の任意のアカウント id。target: "last"の場合、そのアカウント id は、最後に解決されたチャネルがアカウントをサポートしていれば適用され、そうでなければ無視されます。アカウント id が解決されたチャネルの設定済みアカウントに一致しない場合、配信はスキップされます。prompt: デフォルトのプロンプト本文を上書きします(マージされません)。ackMaxChars:HEARTBEAT_OKの後に許容される最大文字数。suppressToolErrorWarnings: true の場合、heartbeat 実行中のツールエラー警告ペイロードを抑制します。activeHours: heartbeat 実行を時間帯に制限します。start(HH:MM、含む。日の始まりには00:00を使用)、end(HH:MM、含まない。日末には24:00が使用可能)、および任意のtimezoneを持つオブジェクトです。- 省略または
"user":agents.defaults.userTimezoneが設定されていればそれを使い、そうでなければホストシステムのタイムゾーンにフォールバックします。 "local": 常にホストシステムのタイムゾーンを使います。- 任意の IANA 識別子(例:
America/New_York): 直接使用されます。無効な場合は、上記の"user"動作にフォールバックします。 - アクティブウィンドウとして扱うには
startとendは等しくしてはいけません。等しい値は幅ゼロ(常に時間帯外)として扱われます。 - アクティブ時間帯の外では、heartbeat は次に時間帯内に入る tick までスキップされます。
- 省略または
配信動作
- Heartbeat はデフォルトでエージェントのメインセッション(
agent:<id>:<mainKey>)で実行され、session.scope = "global"の場合はglobalで実行されます。特定のチャネルセッション(Discord/WhatsApp など)に上書きするにはsessionを設定します。 sessionは実行コンテキストにのみ影響します。配信はtargetとtoによって制御されます。- 特定のチャネル/受信者に配信するには、
target+toを設定します。target: "last"の場合、配信にはそのセッションの最後の外部チャネルが使われます。 - Heartbeat 配信は、デフォルトで直接/DM 宛先を許可します。heartbeat ターン自体は実行したまま直接宛先への送信を抑制するには、
directPolicy: "block"を設定します。 - メインキューがビジーな場合、heartbeat はスキップされ、後で再試行されます。
targetが外部宛先に解決されない場合でも、実行自体は行われますが、 外向きメッセージは送信されません。showOk、showAlerts、useIndicatorがすべて無効の場合、実行は事前にreason=alerts-disabledとしてスキップされます。- アラート配信のみが無効な場合、OpenClaw は引き続き heartbeat を実行し、期限付きタスクのタイムスタンプを更新し、セッションのアイドルタイムスタンプを復元し、外向きのアラートペイロードを抑制できます。
- Heartbeat 専用の返信はセッションをアクティブ状態に保ちません。
updatedAtは復元されるため、アイドル期限切れは通常どおり動作します。 - 切り離された background tasks はシステムイベントをキューに入れ、メインセッションが何かにすばやく気づくべきときに heartbeat を起こすことができます。この wake によって heartbeat 実行が background task になるわけではありません。
可視性の制御
デフォルトでは、HEARTBEAT_OK の確認応答は抑制され、アラート内容は
配信されます。これはチャネルごと、またはアカウントごとに調整できます:
各フラグの意味
showOk: モデルが OK のみの返信を返したときにHEARTBEAT_OK確認応答を送信します。showAlerts: モデルが非 OK の返信を返したときにアラート内容を送信します。useIndicator: UI のステータス表示向けに indicator イベントを発行します。
チャネルごととアカウントごとの例
よくあるパターン
| 目的 | 設定 |
|---|---|
| デフォルト動作(OK は無言、アラートは有効) | (設定不要) |
| 完全に無音(メッセージなし、indicator なし) | channels.defaults.heartbeat: { showOk: false, showAlerts: false, useIndicator: false } |
| indicator のみ(メッセージなし) | channels.defaults.heartbeat: { showOk: false, showAlerts: false, useIndicator: true } |
| 1つのチャネルでのみ OK を表示 | channels.telegram.heartbeat: { showOk: true } |
HEARTBEAT.md(任意)
ワークスペースにHEARTBEAT.md ファイルがある場合、デフォルトプロンプトは
エージェントにそれを読むよう指示します。これは「heartbeat チェックリスト」と考えてください: 小さく、安定していて、
30分ごとに含めても安全なものです。
通常実行では、HEARTBEAT.md は
デフォルトエージェントで heartbeat ガイダンスが有効な場合にのみ注入されます。
頻度を 0m にして heartbeat cadence を無効にするか、
includeSystemPromptSection: false を設定すると、通常の bootstrap
コンテキストから除外されます。
HEARTBEAT.md が存在していても、実質的に空(空行と
# Heading のような Markdown 見出しだけ)の場合、OpenClaw は API 呼び出しを節約するため heartbeat 実行をスキップします。
このスキップは reason=empty-heartbeat-file として報告されます。
ファイルが存在しない場合でも、heartbeat は実行され、モデルが何をするかを判断します。
プロンプト膨張を避けるため、小さく保ってください(短いチェックリストまたはリマインダー)。
HEARTBEAT.md の例:
tasks: ブロック
HEARTBEAT.md は、heartbeat 自体の中で間隔ベースの
チェックを行うための小さな構造化 tasks: ブロックもサポートしています。
例:
- OpenClaw は
tasks:ブロックを解析し、各タスクをそれぞれのintervalに対して確認します。 - その tick で期限が来ているタスクだけが heartbeat プロンプトに含まれます。
- 期限が来ているタスクがない場合、無駄なモデル呼び出しを避けるため、heartbeat は完全にスキップされます(
reason=no-tasks-due)。 HEARTBEAT.md内のタスク以外の内容は保持され、期限到来タスクリストの後に追加コンテキストとして付加されます。- タスクの最終実行タイムスタンプはセッション状態(
heartbeatTaskState)に保存されるため、通常の再起動後も間隔が維持されます。 - タスクのタイムスタンプが進むのは、heartbeat 実行が通常の返信パスを完了した後だけです。
empty-heartbeat-file/no-tasks-dueでスキップされた実行は、タスク完了として記録されません。
エージェントは HEARTBEAT.md を更新できますか?
はい — そうするように指示すれば可能です。HEARTBEAT.md はエージェントワークスペース内の通常のファイルなので、
通常のチャットで、たとえば次のようにエージェントに指示できます:
- 「毎日のカレンダーチェックを追加するように
HEARTBEAT.mdを更新して」 - 「
HEARTBEAT.mdを、もっと短くして受信箱のフォローアップに集中する内容に書き直して」
HEARTBEAT.md
を更新すること」のような明示的な一文を含めることもできます。
安全上の注意: HEARTBEAT.md にシークレット(API キー、電話番号、秘密トークン)を入れないでください —
これはプロンプトコンテキストの一部になります。
手動 wake(オンデマンド)
システムイベントをキューに入れ、すぐに heartbeat をトリガーするには次を実行します:heartbeat が設定されている場合、
手動 wake はそれらの各エージェント heartbeat を即座に実行します。
次の予定 tick を待つには --mode next-heartbeat を使用します。
reasoning 配信(任意)
デフォルトでは、heartbeat は最終的な「回答」ペイロードのみを配信します。 透明性が必要な場合は、次を有効にします:agents.defaults.heartbeat.includeReasoning: true
Reasoning: で始まる別メッセージも配信します
(/reasoning on と同じ形式)。これは、エージェントが複数のセッション/codex を管理していて、
なぜあなたに通知すると判断したのかを見たい場合に便利です —
ただし、望まない内部詳細まで漏れる可能性もあります。グループチャットでは通常、無効のままにしておくことをおすすめします。
コスト意識
Heartbeat は完全なエージェントターンを実行します。間隔を短くするほどトークン消費は増えます。コストを下げるには:- 完全な会話履歴を送らないように
isolatedSession: trueを使用する(実行あたりおよそ 100K トークンから 2-5K に削減)。 - bootstrap ファイルを
HEARTBEAT.mdのみに制限するためlightContext: trueを使用する。 - より安価な
modelを設定する(例:ollama/llama3.2:1b)。 HEARTBEAT.mdを小さく保つ。- 内部状態更新だけが必要なら
target: "none"を使用する。
関連
- Automation & Tasks — すべての自動化メカニズムの概要
- Background Tasks — 切り離された作業がどのように追跡されるか
- Timezone — タイムゾーンが heartbeat スケジューリングにどう影響するか
- Troubleshooting — 自動化の問題をデバッグする方法