Zum Inhalt springen

Heartbeat für Gateway Agents einrichten

Kennst du das Problem? Du baust einen Agenten, der eigentlich autonom arbeiten soll, aber du willst nicht ständig manuell nachschauen, ob er noch lebt oder Hilfe braucht. Gleichzeitig nervt es, wenn der Bot dich ohne echten Grund mit Nachrichten überflutet.

Heartbeat löst genau das. Es triggert regelmäßige Turns in der Haupt-Session, damit das Model wichtige Themen ansprechen kann, ohne dich zu zuspamen.

Heartbeat vs Cron? Schau dir Cron vs Heartbeat an, um zu entscheiden, welches Tool du wann nutzt.

Heartbeat führt periodische Agent-Turns in der Haupt-Session aus. So kann das Model alles hervorheben, was Aufmerksamkeit erfordert, ohne dich zu nerven.

Ein Heartbeat ist ein geplanter Turn in der Haupt-Session — er erstellt keine background task Records. Task-Records sind für losgelöste Arbeit gedacht (ACP-Runs, Sub-Agents, isolierte Cron-Jobs).

Troubleshooting: /automation/troubleshooting

  1. Lass Heartbeats aktiviert (Standard ist 30m, oder 1h für Anthropic OAuth/setup-token) oder leg dein eigenes Intervall fest.
  2. Erstelle eine kleine HEARTBEAT.md Checkliste im Agent-Workspace (optional, aber empfohlen).
  3. Entscheide, wohin Heartbeat-Nachrichten gesendet werden sollen (target: "none" ist Standard; setze target: "last", um den letzten Kontakt zu erreichen).
  4. Optional: Aktiviere die Zustellung von Heartbeat-Reasoning für mehr Transparenz.
  5. Optional: Nutze einen leichtgewichtigen Bootstrap-Context, falls Heartbeat-Runs nur HEARTBEAT.md benötigen.
  6. Optional: Aktiviere isolierte Sessions, um zu vermeiden, dass bei jedem Heartbeat der komplette Chat-Verlauf gesendet wird.
  7. Optional: Beschränke Heartbeats auf aktive Stunden (Lokalzeit).

Beispiel-Konfiguration:

{
agents: {
defaults: {
heartbeat: {
every: "30m",
target: "last", // explicit delivery to last contact (default is "none")
directPolicy: "allow", // default: allow direct/DM targets; set "block" to suppress
lightContext: true, // optional: only inject HEARTBEAT.md from bootstrap files
isolatedSession: true, // optional: fresh session each run (no conversation history)
// activeHours: { start: "08:00", end: "24:00" },
// includeReasoning: true, // optional: send separate `Reasoning:` message too
},
},
},
}
  • Intervall: 30m (oder 1h, wenn Anthropic OAuth/setup-token als Auth-Modus erkannt wird). Setze agents.defaults.heartbeat.every oder pro Agent agents.list[].heartbeat.every; nutze 0m zum Deaktivieren.
  • Prompt-Inhalt (konfigurierbar über 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.
  • Der Heartbeat-Prompt wird wortwörtlich als User-Message gesendet. Der System-Prompt enthält einen „Heartbeat“-Abschnitt und der Run wird intern markiert.
  • Aktive Stunden (heartbeat.activeHours) werden in der konfigurierten Zeitzone geprüft. Außerhalb des Fensters werden Heartbeats bis zum nächsten Zeitpunkt innerhalb des Fensters übersprungen.

Der Standard-Prompt ist absichtlich allgemein gehalten:

  • Hintergrundaufgaben: „Consider outstanding tasks“ stößt den Agenten an, Follow-ups zu prüfen (Inbox, Kalender, Erinnerungen, Warteschlangen) und Dringendes zu melden.
  • Check-in beim Menschen: „Checkup sometimes on your human during day time“ sorgt für gelegentliche, kurze „Brauchst du was?“-Nachrichten. Durch deine lokale Zeitzone wird Spam in der Nacht vermieden (siehe /concepts/timezone).

Heartbeat kann auf abgeschlossene background tasks reagieren, aber ein Heartbeat-Run selbst erzeugt keinen Task-Record.

Wenn du möchtest, dass ein Heartbeat etwas ganz Spezifisches tut (z. B. „Gmail PubSub Stats prüfen“ oder „Gateway-Status verifizieren“), setze agents.defaults.heartbeat.prompt (oder agents.list[].heartbeat.prompt) auf einen eigenen Text (wird wortwörtlich gesendet).

  • Wenn nichts deine Aufmerksamkeit erfordert, antwortet der Agent mit HEARTBEAT_OK.
  • Während Heartbeat-Runs behandelt OpenClaw HEARTBEAT_OK als Bestätigung (Ack), wenn es am Anfang oder Ende der Antwort steht. Das Token wird entfernt und die Antwort verworfen, wenn der restliche Inhalt ≤ ackMaxChars ist (Standard: 300).
  • Wenn HEARTBEAT_OK in der Mitte einer Antwort erscheint, wird es nicht speziell behandelt.
  • Für Alarme: Füge kein HEARTBEAT_OK hinzu; gib nur den Alarm-Text aus.

Außerhalb von Heartbeats werden zufällige HEARTBEAT_OK am Anfang oder Ende einer Nachricht entfernt und protokolliert; eine Nachricht, die nur aus HEARTBEAT_OK besteht, wird verworfen.

AI Setup Assistant

{
agents: {
defaults: {
heartbeat: {
every: "30m", // default: 30m (0m disables)
model: "anthropic/claude-opus-4-6",
includeReasoning: false, // default: false (deliver separate Reasoning: message when available)
lightContext: false, // default: false; true keeps only HEARTBEAT.md from workspace bootstrap files
isolatedSession: false, // default: false; true runs each heartbeat in a fresh session (no conversation history)
target: "last", // default: none | options: last | none | <channel id> (core or plugin, e.g. "bluebubbles")
to: "+15551234567", // optional channel-specific override
accountId: "ops-bot", // optional multi-account channel id
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, // max chars allowed after HEARTBEAT_OK
},
},
},
}
  • agents.defaults.heartbeat legt das globale Verhalten für Heartbeats fest.
  • agents.list[].heartbeat wird darüber gemergt. Wenn ein Agent einen heartbeat-Block hat, führen nur diese Agenten Heartbeats aus.
  • channels.defaults.heartbeat definiert Standardwerte für die Sichtbarkeit in allen Channels.
  • channels.<channel>.heartbeat überschreibt die Channel-Defaults.
  • channels.<channel>.accounts.<id>.heartbeat (bei Multi-Account-Channels) überschreibt die Einstellungen pro Account.

Sobald ein Eintrag in agents.list[] einen heartbeat-Block enthält, führen nur diese Agenten Heartbeats aus. Der Block pro Agent wird mit agents.defaults.heartbeat zusammengeführt. So kannst du gemeinsame Standards einmal definieren und pro Agent anpassen.

Beispiel: Zwei Agenten, aber nur der zweite Agent führt Heartbeats aus.

{
agents: {
defaults: {
heartbeat: {
every: "30m",
target: "last", // explicit delivery to last contact (default is "none")
},
},
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.",
},
},
],
},
}

Du kannst Heartbeats auf bestimmte Geschäftszeiten in einer Zeitzone einschränken:

{
agents: {
defaults: {
heartbeat: {
every: "30m",
target: "last", // explicit delivery to last contact (default is "none")
activeHours: {
start: "09:00",
end: "22:00",
timezone: "America/New_York", // optional; uses your userTimezone if set, otherwise host tz
},
},
},
},
}

Außerhalb dieses Fensters (vor 9:00 Uhr oder nach 22:00 Uhr Eastern Time) werden Heartbeats übersprungen. Der nächste geplante Tick innerhalb des Fensters läuft wieder normal.

Wenn deine Heartbeats rund um die Uhr laufen sollen, hast du zwei Möglichkeiten:

  • Lass activeHours komplett weg (keine Zeitbeschränkung; das ist der Standard).
  • Setze ein Fenster für den ganzen Tag: activeHours: { start: "00:00", end: "24:00" }.

Verwende nicht die gleiche Zeit für start und end (zum Beispiel 08:00 bis 08:00). Das wird als Fenster mit der Breite Null gewertet, wodurch Heartbeats immer übersprungen werden.

Nutze accountId, um einen spezifischen Account in Multi-Account-Channels wie Telegram anzusprechen:

{
agents: {
list: [
{
id: "ops",
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: Heartbeat-Intervall (Duration-String; Standardeinheit sind Minuten).
  • model: Optionales Model-Override für Heartbeat-Runs (provider/model).
  • includeReasoning: Wenn aktiviert, wird auch die separate Reasoning: Nachricht gesendet, falls verfügbar (entspricht /reasoning on).
  • lightContext: Bei true nutzen Heartbeat-Runs einen leichtgewichtigen Bootstrap-Kontext und behalten nur die HEARTBEAT.md aus den Workspace-Dateien.
  • isolatedSession: Bei true läuft jeder Heartbeat in einer frischen Session ohne vorherigen Verlauf. Das nutzt das gleiche Isolationsmuster wie Cron mit sessionTarget: "isolated" und senkt die Token-Kosten pro Heartbeat massiv. Kombiniere das mit lightContext: true für maximale Ersparnis. Das Routing der Zustellung nutzt weiterhin den Kontext der Main Session.
  • session: Optionaler Session-Key für Heartbeat-Runs.
    • main (Standard): Main Session des Agents.
    • Expliziter Session-Key (kopiere diesen aus openclaw sessions --json oder dem sessions CLI).
    • Formate für Session-Keys findest du unter Sessions und Groups.
  • target:
    • last: Zustellung an den zuletzt genutzten externen Channel.
    • Expliziter Channel: Jede konfigurierte Channel- oder Plugin-ID, zum Beispiel discord, matrix, telegram oder whatsapp.
    • none (Standard): Führt den Heartbeat aus, schickt aber keine Nachricht nach außen.
  • directPolicy: Steuert das Verhalten bei DMs:
    • allow (Standard): Erlaubt die Zustellung per DM.
    • block: Unterdrückt die Zustellung an DMs (reason=dm-blocked).
  • to: Optionaler Empfänger-Override (Channel-spezifische ID, z. B. E.164 für WhatsApp oder eine Telegram Chat-ID). Für Telegram-Topics nutzt du <chatId>:topic:<messageThreadId>.
  • accountId: Optionale Account-ID für Multi-Account-Channels. Bei target: "last" wird die ID auf den ermittelten Channel angewendet, sofern dieser Accounts unterstützt. Passt die ID nicht zu einem konfigurierten Account, wird die Zustellung übersprungen.
  • prompt: Überschreibt den Standard-Prompt (wird nicht zusammengeführt).
  • ackMaxChars: Maximale Zeichenanzahl, die nach HEARTBEAT_OK vor der Zustellung erlaubt ist.
  • suppressToolErrorWarnings: Bei true werden Warnungen zu Tool-Fehlern während der Heartbeat-Runs unterdrückt.
  • activeHours: Schränkt Heartbeats auf ein Zeitfenster ein. Objekt mit start (HH:MM, inklusiv; 00:00 für Tagesbeginn), end (HH:MM, exklusiv; 24:00 für Tagesende) und optionaler timezone.
    • Weggelassen oder "user": Nutzt dein agents.defaults.userTimezone oder die Host-Zeitzone.
    • "local": Nutzt immer die Zeitzone des Host-Systems.
    • Jeder IANA-Identifier (z. B. America/New_York): Wird direkt verwendet; bei Ungültigkeit greift das "user"-Verhalten.
    • start und end dürfen nicht identisch sein; solche Werte werden als Fenster mit der Breite Null behandelt.
    • Außerhalb des Fensters werden Heartbeats bis zum nächsten Tick innerhalb des Fensters übersprungen.
  • Heartbeats laufen standardmäßig in der Main Session des Agents (agent:<id>:<mainKey>) oder global, wenn session.scope = "global" gesetzt ist. Mit session kannst du dies auf eine spezifische Channel-Session (Discord, WhatsApp etc.) überschreiben.
  • session beeinflusst nur den Kontext des Runs; die eigentliche Zustellung wird über target und to gesteuert.
  • Um an einen bestimmten Channel oder Empfänger zu senden, setze target + to. Bei target: "last" wird der letzte externe Channel dieser Session genutzt.
  • Zustellungen per DM sind standardmäßig erlaubt. Setze directPolicy: "block", um DMs zu unterdrücken, während der Heartbeat-Turn trotzdem ausgeführt wird.
  • Wenn die Main Queue belegt ist, wird der Heartbeat übersprungen und später erneut versucht.
  • Falls target kein externes Ziel findet, wird der Run trotzdem ausgeführt, aber es geht keine Nachricht raus.
  • Antworten, die nur aus einem Heartbeat bestehen, halten die Session nicht aktiv. Der Zeitstempel updatedAt wird zurückgesetzt, damit das Idle-Timeout normal funktioniert.
  • Abgetrennte background tasks können ein System-Event einreihen und den Heartbeat wecken, wenn die Main Session etwas schnell bemerken soll. Dieses Wecken führt nicht dazu, dass der Heartbeat selbst einen Background-Task ausführt.

Standardmäßig werden HEARTBEAT_OK Bestätigungen unterdrückt, während Alert-Inhalte zugestellt werden. Du kannst das pro Channel oder pro Account anpassen:

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

Rangfolge: per-account → per-channel → channel defaults → built-in defaults.

  • showOk: sendet eine HEARTBEAT_OK Bestätigung, wenn das Model eine reine OK-Antwort zurückgibt.
  • showAlerts: sendet den Alert-Inhalt, wenn das Model eine Antwort zurückgibt, die kein OK ist.
  • useIndicator: sendet Indicator-Events für UI-Statusanzeigen.

Wenn alle drei auf false stehen, überspringt OpenClaw den Heartbeat-Run komplett (kein API-Aufruf).

channels:
defaults:
heartbeat:
showOk: false
showAlerts: true
useIndicator: true
slack:
heartbeat:
showOk: true # all Slack accounts
accounts:
ops:
heartbeat:
showAlerts: false # suppress alerts for the ops account only
telegram:
heartbeat:
showOk: true
ZielKonfiguration
Standardverhalten (stumme OKs, Alerts an)(keine Konfiguration nötig)
Komplett stumm (keine Nachrichten, kein Indicator)channels.defaults.heartbeat: { showOk: false, showAlerts: false, useIndicator: false }
Nur Indicator (keine Nachrichten)channels.defaults.heartbeat: { showOk: false, showAlerts: false, useIndicator: true }
OKs nur in einem Channelchannels.telegram.heartbeat: { showOk: true }

Wenn eine HEARTBEAT.md Datei im Workspace existiert, weist der Standard-Prompt den Agenten an, diese zu lesen. Betrachte sie als deine „Heartbeat-Checkliste“: klein, stabil und sicher genug, um sie alle 30 Minuten mitzuschicken.

Falls die HEARTBEAT.md zwar existiert, aber praktisch leer ist (nur Leerzeilen oder Markdown-Header wie # Heading), überspringt OpenClaw den Heartbeat-Run, um API-Aufrufe zu sparen. Wenn die Datei ganz fehlt, läuft der Heartbeat trotzdem und das Model entscheidet selbst, was zu tun ist.

Halte die Datei winzig (kurze Checkliste oder Erinnerungen), um Prompt-Bloat zu vermeiden.

Beispiel für eine 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.

Ja – wenn du ihn darum bittest.

Die HEARTBEAT.md ist eine ganz normale Datei im Workspace des Agenten. Du kannst ihm also in einem normalen Chat Anweisungen geben wie:

  • „Aktualisiere die HEARTBEAT.md und füge einen täglichen Kalender-Check hinzu.“
  • „Schreibe die HEARTBEAT.md um, damit sie kürzer ist und sich auf Inbox-Follow-ups konzentriert.“

Wenn du möchtest, dass das proaktiv passiert, kannst du auch eine explizite Zeile in deinen Heartbeat-Prompt einbauen: „Wenn die Checkliste veraltet ist, aktualisiere die HEARTBEAT.md mit einer besseren Version.“

Sicherheitshinweis: Packe keine Secrets (API-Keys, Telefonnummern, private Token) in die HEARTBEAT.md – sie wird Teil des Prompt-Kontexts.

Du kannst ein System-Event in die Warteschlange stellen und einen sofortigen Heartbeat auslösen mit:

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

Wenn mehrere Agents einen heartbeat konfiguriert haben, führt ein manueller Wake jeden dieser Agent-Heartbeats sofort aus.

Nutze --mode next-heartbeat, um auf den nächsten geplanten Tick zu warten.

Standardmäßig liefern Heartbeats nur die finale „Answer“-Payload.

Wenn du Transparenz willst, aktiviere:

  • agents.defaults.heartbeat.includeReasoning: true

Wenn diese Option aktiviert ist, senden Heartbeats auch eine separate Nachricht mit dem Präfix Reasoning: (gleiches Format wie /reasoning on). Das ist nützlich, wenn der Agent mehrere Sessions oder Codexes verwaltet und du sehen willst, warum er sich bei dir meldet. Es kann aber auch mehr interne Details preisgeben, als du möchtest. Ich empfehle dir, die Funktion in Gruppen-Chats eher deaktiviert zu lassen.

Heartbeats führen vollständige Agent-Turns aus. Kürzere Intervalle verbrauchen mehr Tokens. Um deine Kosten niedrig zu halten, empfehle ich dir diese Ansätze:

  • Nutze isolatedSession: true, um das Senden des gesamten Konversationsverlaufs zu vermeiden (das reduziert den Verbrauch von ca. 100K auf etwa 2-5K Tokens pro Durchlauf).
  • Nutze lightContext: true, um Bootstrap-Dateien auf die HEARTBEAT.md zu beschränken.
  • Setze ein günstigeres model ein (zum Beispiel ollama/llama3.2:1b).
  • Halte die HEARTBEAT.md so klein wie möglich.
  • Nutze target: "none", wenn du lediglich interne Status-Updates benötigst.
OpenClaw

OpenClaw Expert

Noch festgefahren?

Wenn diese Seite nicht hilft, frage OpenClaw Expert nach Schritt-fuer-Schritt-Loesungen.