Agent-Schleife (OpenClaw)

Eine agentische Schleife ist der vollstaendige “echte” Durchlauf eines Agenten: Eingabe -> Kontextaufbau -> Modellinferenz -> Tool-Ausfuehrung -> gestreamte Antworten -> Persistenz. Das ist der massgebliche Pfad, der eine Nachricht in Aktionen und eine finale Antwort verwandelt und dabei den Sitzungszustand konsistent haelt.

In OpenClaw ist eine Schleife ein einzelner, serialisierter Durchlauf pro Sitzung, der Lebenszyklus- und Stream-Events ausgibt, waehrend das Modell denkt, Tools aufruft und Output streamt. Dieses Dokument erklaert, wie diese Schleife von Anfang bis Ende verdrahtet ist.

Einstiegspunkte

  • Gateway-RPC: agent und agent.wait.
  • CLI: agent-Befehl.

Funktionsweise (Ueberblick)

  1. Der agent-RPC validiert Parameter, loest die Sitzung auf (sessionKey/sessionId), persistiert Sitzungsmetadaten und gibt sofort { runId, acceptedAt } zurueck.
  2. agentCommand fuehrt den Agenten aus:
    • loest Modell- und Thinking/Verbose-Defaults auf
    • laedt den Skills-Snapshot
    • ruft runEmbeddedPiAgent auf (pi-agent-core-Runtime)
    • gibt lifecycle end/error aus, falls die eingebettete Schleife keins ausgibt
  3. runEmbeddedPiAgent:
    • serialisiert Durchlaeufe ueber pro-Sitzung- und globale Queues
    • loest Modell- und Auth-Profil auf und baut die pi-Session
    • abonniert pi-Events und streamt Assistant/Tool-Deltas
    • erzwingt ein Timeout -> bricht den Durchlauf bei Ueberschreitung ab
    • gibt Payloads und Usage-Metadaten zurueck
  4. subscribeEmbeddedPiSession verbindet pi-agent-core-Events mit dem OpenClaw-agent-Stream:
    • Tool-Events => stream: "tool"
    • Assistant-Deltas => stream: "assistant"
    • Lebenszyklus-Events => stream: "lifecycle" (phase: "start" | "end" | "error")
  5. agent.wait nutzt waitForAgentJob:
    • wartet auf lifecycle end/error fuer die runId
    • gibt { status: ok|error|timeout, startedAt, endedAt, error? } zurueck

Queueing und Nebenlaeufigkeit

  • Durchlaeufe werden pro Sitzungsschluessel (Session-Lane) und optional ueber eine globale Lane serialisiert.
  • Das verhindert Tool/Session-Races und haelt die Sitzungshistorie konsistent.
  • Messaging-Kanaele koennen Queue-Modi waehlen (collect/steer/followup), die dieses Lane-System speisen. Siehe Command Queue.

Sitzungs- und Workspace-Vorbereitung

  • Der Workspace wird aufgeloest und erstellt; Sandbox-Durchlaeufe koennen auf einen Sandbox-Workspace-Root umgeleitet werden.
  • Skills werden geladen (oder aus einem Snapshot wiederverwendet) und in Umgebung und Prompt injiziert.
  • Bootstrap-/Kontextdateien werden aufgeloest und in den System-Prompt-Report injiziert.
  • Eine Schreib-Sperre fuer die Sitzung wird erworben; der SessionManager wird vor dem Streaming geoeffnet und vorbereitet.

Prompt-Aufbau und System-Prompt

  • Der System-Prompt wird aus OpenClaws Basis-Prompt, Skills-Prompt, Bootstrap-Kontext und pro-Durchlauf-Overrides zusammengebaut.
  • Modellspezifische Limits und Compaction-Reserve-Tokens werden durchgesetzt.
  • Siehe System-Prompt fuer das, was das Modell sieht.

Hook-Punkte (Abfangmoeglichkeiten)

OpenClaw hat zwei Hook-Systeme:

  • Interne Hooks (Gateway-Hooks): eventgesteuerte Skripte fuer Befehle und Lebenszyklus-Events.
  • Plugin-Hooks: Erweiterungspunkte innerhalb des Agent/Tool-Lebenszyklus und der Gateway-Pipeline.

Interne Hooks (Gateway-Hooks)

  • agent:bootstrap: laeuft waehrend des Aufbaus der Bootstrap-Dateien, bevor der System-Prompt finalisiert wird. Hiermit kannst du Bootstrap-Kontextdateien hinzufuegen oder entfernen.
  • Befehls-Hooks: /new, /reset, /stop und andere Befehls-Events (siehe Hooks-Dokumentation).

Siehe Hooks fuer Einrichtung und Beispiele.

Plugin-Hooks (Agent- und Gateway-Lebenszyklus)

Diese laufen innerhalb der Agent-Schleife oder Gateway-Pipeline:

  • before_model_resolve: laeuft vor der Sitzung (ohne messages), um Provider/Modell deterministisch vor der Modellaufloesung zu ueberschreiben.
  • before_prompt_build: laeuft nach dem Laden der Sitzung (mit messages), um prependContext, systemPrompt, prependSystemContext oder appendSystemContext vor der Prompt-Uebermittlung zu injizieren. Verwende prependContext fuer dynamischen Text pro Turn und die System-Context-Felder fuer stabile Anweisungen, die im System-Prompt-Bereich stehen sollen.
  • before_agent_start: Legacy-Kompatibilitaets-Hook, der in beiden Phasen laufen kann; bevorzuge die expliziten Hooks oben.
  • agent_end: inspiziert die finale Nachrichtenliste und Durchlauf-Metadaten nach Abschluss.
  • before_compaction / after_compaction: beobachtet oder annotiert Compaction-Zyklen.
  • before_tool_call / after_tool_call: faengt Tool-Parameter/Ergebnisse ab.
  • tool_result_persist: transformiert Tool-Ergebnisse synchron, bevor sie ins Sitzungstranskript geschrieben werden.
  • message_received / message_sending / message_sent: Hooks fuer ein- und ausgehende Nachrichten.
  • session_start / session_end: Sitzungs-Lebenszyklus-Grenzen.
  • gateway_start / gateway_stop: Gateway-Lebenszyklus-Events.

Siehe Plugins fuer die Hook-API und Registrierungsdetails.

Streaming und Teilantworten

  • Assistant-Deltas werden von pi-agent-core gestreamt und als assistant-Events ausgegeben.
  • Block-Streaming kann Teilantworten entweder bei text_end oder message_end ausgeben.
  • Reasoning-Streaming kann als separater Stream oder als Block-Antworten ausgegeben werden.
  • Siehe Streaming fuer Chunking und Block-Reply-Verhalten.

Tool-Ausfuehrung und Messaging-Tools

  • Tool-Start/Update/End-Events werden ueber den tool-Stream ausgegeben.
  • Tool-Ergebnisse werden hinsichtlich Groesse und Bild-Payloads bereinigt, bevor sie geloggt/ausgegeben werden.
  • Messaging-Tool-Sends werden getrackt, um doppelte Assistant-Bestaetigungen zu unterdruecken.

Antwort-Formung und -Unterdrueckung

  • Finale Payloads werden zusammengestellt aus:
    • Assistant-Text (und optionalem Reasoning)
    • Inline-Tool-Zusammenfassungen (wenn verbose + erlaubt)
    • Assistant-Fehlertext, wenn das Modell fehlschlaegt
  • NO_REPLY wird als stilles Token behandelt und aus ausgehenden Payloads herausgefiltert.
  • Messaging-Tool-Duplikate werden aus der finalen Payload-Liste entfernt.
  • Wenn keine darstellbaren Payloads uebrig bleiben und ein Tool fehlgeschlagen ist, wird eine Fallback-Tool-Fehlerantwort ausgegeben (es sei denn, ein Messaging-Tool hat bereits eine sichtbare Antwort gesendet).

Compaction und Retries

  • Auto-Compaction gibt compaction-Stream-Events aus und kann einen Retry ausloesen.
  • Bei einem Retry werden In-Memory-Puffer und Tool-Zusammenfassungen zurueckgesetzt, um doppelten Output zu vermeiden.
  • Siehe Compaction fuer die Compaction-Pipeline.

Event-Streams (aktuell)

  • lifecycle: wird von subscribeEmbeddedPiSession ausgegeben (und als Fallback von agentCommand)
  • assistant: gestreamte Deltas von pi-agent-core
  • tool: gestreamte Tool-Events von pi-agent-core

Chat-Kanal-Handling

  • Assistant-Deltas werden in Chat-delta-Nachrichten gepuffert.
  • Ein Chat-final wird bei lifecycle end/error ausgegeben.

Timeouts

  • agent.wait Standard: 30s (nur das Warten). Der Parameter timeoutMs ueberschreibt das.
  • Agent-Runtime: agents.defaults.timeoutSeconds Standard 600s; wird im runEmbeddedPiAgent-Abort-Timer durchgesetzt.

Wo Durchlaeufe vorzeitig enden koennen

  • Agent-Timeout (Abbruch)
  • AbortSignal (Abbrechen)
  • Gateway-Trennung oder RPC-Timeout
  • agent.wait-Timeout (nur das Warten, stoppt den Agenten nicht)