Sub-Agents
Sub-Agents sind Hintergrund-Agent-Runs, die aus einem bestehenden Agent-Run gespawnt werden. Sie laufen in ihrer eigenen Session (agent:<agentId>:subagent:<uuid>) und melden nach Abschluss ihr Ergebnis an den anfragenden Chat-Kanal zurück.
Slash-Befehl
Verwende /subagents, um Sub-Agent-Runs für die aktuelle Session zu inspizieren oder zu steuern:
/subagents list/subagents kill <id|#|all>/subagents log <id|#> [limit] [tools]/subagents info <id|#>/subagents send <id|#> <message>/subagents steer <id|#> <message>/subagents spawn <agentId> <task> [--model <model>] [--thinking <level>]
Thread-Bindungs-Steuerung:
Diese Befehle funktionieren auf Kanälen, die persistente Thread-Bindungen unterstützen. Siehe Thread-unterstützende Kanäle unten.
/focus <subagent-label|session-key|session-id|session-label>/unfocus/agents/session idle <duration|off>/session max-age <duration|off>
/subagents info zeigt Run-Metadaten (Status, Zeitstempel, Session-ID, Transkript-Pfad, Cleanup).
Spawn-Verhalten
/subagents spawn startet einen Hintergrund-Sub-Agent als Benutzerbefehl, nicht als internes Relay, und sendet ein einziges finales Abschluss-Update zurück an den anfragenden Chat, wenn der Run beendet ist.
- Der Spawn-Befehl ist nicht-blockierend; er gibt sofort eine Run-ID zurück.
- Bei Abschluss meldet der Sub-Agent eine Zusammenfassungs-/Ergebnisnachricht an den anfragenden Chat-Kanal.
- Für manuelle Spawns ist die Zustellung resilient:
- OpenClaw versucht zuerst direkte
agent-Zustellung mit einem stabilen Idempotency-Key. - Bei Fehlschlag der direkten Zustellung wird auf Queue-Routing zurückgefallen.
- Wenn Queue-Routing noch nicht verfügbar ist, wird das Announce mit kurzem exponentiellem Backoff wiederholt, bevor es aufgegeben wird.
- OpenClaw versucht zuerst direkte
- Der Completion-Handoff an die anfragende Session ist runtime-generierter interner Kontext (nicht benutzergeschriebener Text) und enthält:
Result(assistant-Antworttext oder letztestoolResult, wenn die Assistant-Antwort leer ist)Status(completed successfully/failed/timed out/unknown)- kompakte Runtime-/Token-Stats
- eine Zustellungsanweisung, die dem anfragenden Agent sagt, in normaler Assistenten-Stimme umzuschreiben (nicht rohe interne Metadaten weiterleiten)
--modelund--thinkingüberschreiben Defaults für diesen spezifischen Run.- Verwende
info/log, um Details und Ausgabe nach Abschluss zu inspizieren. /subagents spawnist One-Shot-Modus (mode: "run"). Für persistente Thread-gebundene Sessions verwendesessions_spawnmitthread: trueundmode: "session".- Für ACP-Harness-Sessions (Codex, Claude Code, Gemini CLI) verwende
sessions_spawnmitruntime: "acp"und siehe ACP Agents.
Hauptziele:
- “Recherche / lange Aufgabe / langsames Tool”-Arbeit parallelisieren, ohne den Haupt-Run zu blockieren.
- Sub-Agents standardmäßig isoliert halten (Session-Trennung + optionales Sandboxing).
- Die Tool-Oberfläche schwer missbrauchbar halten: Sub-Agents bekommen standardmäßig keine Session-Tools.
- Konfigurierbare Verschachtelungstiefe für Orchestrator-Muster unterstützen.
Kostenhinweis: Jeder Sub-Agent hat seinen eigenen Kontext und Token-Verbrauch. Für schwere oder repetitive
Aufgaben setze ein günstigeres Modell für Sub-Agents und behalte deinen Haupt-Agent auf einem hochwertigeren Modell.
Das kannst du über agents.defaults.subagents.model oder pro-Agent-Overrides konfigurieren.
Tool
Verwende sessions_spawn:
- Startet einen Sub-Agent-Run (
deliver: false, globale Lane:subagent) - Führt dann einen Announce-Schritt aus und postet die Announce-Antwort in den anfragenden Chat-Kanal
- Standard-Modell: erbt vom Aufrufer, es sei denn, du setzt
agents.defaults.subagents.model(oder pro Agentagents.list[].subagents.model); ein explizitessessions_spawn.modelgewinnt trotzdem. - Standard-Thinking: erbt vom Aufrufer, es sei denn, du setzt
agents.defaults.subagents.thinking(oder pro Agentagents.list[].subagents.thinking); ein explizitessessions_spawn.thinkinggewinnt trotzdem. - Standard-Run-Timeout: Wenn
sessions_spawn.runTimeoutSecondsweggelassen wird, verwendet OpenClawagents.defaults.subagents.runTimeoutSecondsfalls gesetzt; ansonsten fällt es auf0(kein Timeout) zurück.
Tool-Parameter:
task(erforderlich)label?(optional)agentId?(optional; unter einer anderen Agent-ID spawnen, wenn erlaubt)model?(optional; überschreibt das Sub-Agent-Modell; ungültige Werte werden übersprungen und der Sub-Agent läuft mit dem Standardmodell mit einer Warnung im Tool-Ergebnis)thinking?(optional; überschreibt das Thinking-Level für den Sub-Agent-Run)runTimeoutSeconds?(Standard istagents.defaults.subagents.runTimeoutSecondsfalls gesetzt, sonst0; wenn gesetzt, wird der Sub-Agent-Run nach N Sekunden abgebrochen)thread?(Standardfalse; wenntrue, wird eine Kanal-Thread-Bindung für diese Sub-Agent-Session angefordert)mode?(run|session)- Standard ist
run - wenn
thread: trueundmodeweggelassen, wird Standardsession mode: "session"erfordertthread: true
- Standard ist
cleanup?(delete|keep, Standardkeep)sandbox?(inherit|require, Standardinherit;requirelehnt Spawn ab, es sei denn, die Kind-Runtime ist gesandboxt)sessions_spawnakzeptiert keine Kanal-Zustellungsparameter (target,channel,to,threadId,replyTo,transport). Für die Zustellung verwendemessage/sessions_sendaus dem gespawnten Run.
Thread-gebundene Sessions
Wenn Thread-Bindungen für einen Kanal aktiviert sind, kann ein Sub-Agent an einen Thread gebunden bleiben, sodass Folgenachrichten von Benutzern in diesem Thread weiterhin an dieselbe Sub-Agent-Session geroutet werden.
Thread-unterstützende Kanäle
- Discord (aktuell der einzige unterstützte Kanal): unterstützt persistente thread-gebundene Subagent-Sessions (
sessions_spawnmitthread: true), manuelle Thread-Steuerung (/focus,/unfocus,/agents,/session idle,/session max-age) und Adapter-Keyschannels.discord.threadBindings.enabled,channels.discord.threadBindings.idleHours,channels.discord.threadBindings.maxAgeHoursundchannels.discord.threadBindings.spawnSubagentSessions.
Schneller Ablauf:
- Spawne mit
sessions_spawnundthread: true(und optionalmode: "session"). - OpenClaw erstellt oder bindet einen Thread an dieses Session-Ziel im aktiven Kanal.
- Antworten und Folgenachrichten in diesem Thread werden an die gebundene Session geroutet.
- Verwende
/session idle, um Inaktivitäts-Auto-Unfocus zu inspizieren/aktualisieren, und/session max-agefür das harte Limit. - Verwende
/unfocuszum manuellen Trennen.
Manuelle Steuerung:
/focus <target>bindet den aktuellen Thread (oder erstellt einen) an ein Sub-Agent/Session-Ziel./unfocusentfernt die Bindung für den aktuell gebundenen Thread./agentslistet aktive Runs und Bindungsstatus auf (thread:<id>oderunbound)./session idleund/session max-agefunktionieren nur für fokussierte gebundene Threads.
Config-Schalter:
- Globaler Standard:
session.threadBindings.enabled,session.threadBindings.idleHours,session.threadBindings.maxAgeHours - Kanal-Override und Spawn-Auto-Bind-Keys sind adapter-spezifisch. Siehe Thread-unterstützende Kanäle oben.
Siehe Konfigurationsreferenz und Slash-Befehle für aktuelle Adapter-Details.
Allowlist:
agents.list[].subagents.allowAgents: Liste von Agent-IDs, die überagentIdangesprochen werden können (["*"]für beliebige). Standard: nur der anfragende Agent.- Sandbox-Vererbungsschutz: Wenn die anfragende Session gesandboxt ist, lehnt
sessions_spawnZiele ab, die ungesandboxt laufen würden.
Entdeckung:
- Verwende
agents_list, um zu sehen, welche Agent-IDs aktuell fürsessions_spawnerlaubt sind.
Auto-Archivierung:
- Sub-Agent-Sessions werden automatisch nach
agents.defaults.subagents.archiveAfterMinutesarchiviert (Standard: 60). - Die Archivierung verwendet
sessions.deleteund benennt das Transkript in*.deleted.<timestamp>um (gleicher Ordner). cleanup: "delete"archiviert sofort nach dem Announce (behält das Transkript aber per Umbenennung).- Auto-Archivierung ist Best-Effort; ausstehende Timer gehen verloren, wenn das Gateway neu startet.
runTimeoutSecondsarchiviert nicht automatisch; es stoppt nur den Run. Die Session bleibt bis zur Auto-Archivierung.- Auto-Archivierung gilt gleichermaßen für Tiefe-1 und Tiefe-2 Sessions.
Verschachtelte Sub-Agents
Standardmäßig können Sub-Agents keine eigenen Sub-Agents spawnen (maxSpawnDepth: 1). Du kannst eine Verschachtelungsebene aktivieren, indem du maxSpawnDepth: 2 setzt, was das Orchestrator-Muster erlaubt: Main → Orchestrator-Sub-Agent → Worker-Sub-Sub-Agents.
Wie aktivieren
{
agents: {
defaults: {
subagents: {
maxSpawnDepth: 2, // Sub-Agents dürfen Kinder spawnen (Standard: 1)
maxChildrenPerAgent: 5, // max. aktive Kinder pro Agent-Session (Standard: 5)
maxConcurrent: 8, // globale Concurrency-Lane-Cap (Standard: 8)
runTimeoutSeconds: 900, // Standard-Timeout für sessions_spawn wenn weggelassen (0 = kein Timeout)
},
},
},
}
Tiefenebenen
| Tiefe | Session-Key-Form | Rolle | Kann spawnen? |
|---|---|---|---|
| 0 | agent:<id>:main | Haupt-Agent | Immer |
| 1 | agent:<id>:subagent:<uuid> | Sub-Agent (Orchestrator bei Tiefe 2 erlaubt) | Nur wenn maxSpawnDepth >= 2 |
| 2 | agent:<id>:subagent:<uuid>:subagent:<uuid> | Sub-Sub-Agent (Leaf Worker) | Nie |
Announce-Kette
Ergebnisse fließen die Kette hinauf zurück:
- Tiefe-2 Worker beendet → meldet an seinen Parent (Tiefe-1 Orchestrator)
- Tiefe-1 Orchestrator empfängt das Announce, synthetisiert Ergebnisse, beendet → meldet an Main
- Haupt-Agent empfängt das Announce und liefert an den Benutzer
Jede Ebene sieht nur Announces von ihren direkten Kindern.
Tool-Policy nach Tiefe
- Rolle und Steuerungsbereich werden beim Spawnen in die Session-Metadaten geschrieben. Das verhindert, dass flache oder wiederhergestellte Session-Keys versehentlich Orchestrator-Privilegien zurückerhalten.
- Tiefe 1 (Orchestrator, wenn
maxSpawnDepth >= 2): Bekommtsessions_spawn,subagents,sessions_list,sessions_history, damit er seine Kinder verwalten kann. Andere Session-/System-Tools bleiben gesperrt. - Tiefe 1 (Leaf, wenn
maxSpawnDepth == 1): Keine Session-Tools (aktuelles Standardverhalten). - Tiefe 2 (Leaf Worker): Keine Session-Tools —
sessions_spawnist auf Tiefe 2 immer gesperrt. Kann keine weiteren Kinder spawnen.
Pro-Agent-Spawn-Limit
Jede Agent-Session (auf jeder Tiefe) kann maximal maxChildrenPerAgent (Standard: 5) aktive Kinder gleichzeitig haben. Das verhindert unkontrolliertes Fan-Out von einem einzelnen Orchestrator.
Kaskaden-Stopp
Das Stoppen eines Tiefe-1 Orchestrators stoppt automatisch alle seine Tiefe-2 Kinder:
/stopim Haupt-Chat stoppt alle Tiefe-1 Agents und kaskadiert zu ihren Tiefe-2 Kindern./subagents kill <id>stoppt einen bestimmten Sub-Agent und kaskadiert zu seinen Kindern./subagents kill allstoppt alle Sub-Agents des Anfragenden und kaskadiert.
Authentifizierung
Sub-Agent-Auth wird nach Agent-ID aufgelöst, nicht nach Session-Typ:
- Der Sub-Agent-Session-Key ist
agent:<agentId>:subagent:<uuid>. - Der Auth-Store wird aus dem
agentDirdieses Agents geladen. - Die Auth-Profile des Haupt-Agents werden als Fallback eingemischt; Agent-Profile überschreiben Haupt-Profile bei Konflikten.
Hinweis: Der Merge ist additiv, so dass Haupt-Profile immer als Fallbacks verfügbar sind. Vollständig isolierte Auth pro Agent wird noch nicht unterstützt.
Announce
Sub-Agents melden sich über einen Announce-Schritt zurück:
- Der Announce-Schritt läuft innerhalb der Sub-Agent-Session (nicht der anfragenden Session).
- Wenn der Sub-Agent genau
ANNOUNCE_SKIPantwortet, wird nichts gepostet. - Ansonsten hängt die Zustellung von der Tiefe des Anfragenden ab:
- Top-Level-anfragende Sessions verwenden einen Folge-
agent-Call mit externer Zustellung (deliver=true) - verschachtelte anfragende Subagent-Sessions erhalten eine interne Folge-Injektion (
deliver=false), damit der Orchestrator Kind-Ergebnisse in-Session synthetisieren kann - wenn eine verschachtelte anfragende Subagent-Session nicht mehr existiert, fällt OpenClaw auf den Anfragenden dieser Session zurück, wenn verfügbar
- Top-Level-anfragende Sessions verwenden einen Folge-
- Kind-Completion-Aggregation ist auf den aktuellen Anfragenden-Run beschränkt, wenn verschachtelte Completion-Findings erstellt werden, um zu verhindern, dass veraltete Prior-Run-Kind-Outputs in das aktuelle Announce einfließen.
- Announce-Antworten bewahren Thread-/Topic-Routing, wenn auf Kanal-Adaptern verfügbar.
- Announce-Kontext wird zu einem stabilen internen Event-Block normalisiert:
- Quelle (
subagentodercron) - Kind-Session-Key/ID
- Announce-Typ + Task-Label
- Statuszeile, abgeleitet vom Runtime-Ergebnis (
success,error,timeoutoderunknown) - Ergebnisinhalt vom Announce-Schritt (oder
(no output)wenn fehlend) - eine Follow-Up-Anweisung, die beschreibt, wann zu antworten vs. still zu bleiben
- Quelle (
Statuswird nicht aus der Modellausgabe abgeleitet; er kommt von Runtime-Ergebnissignalen.
Announce-Payloads enthalten eine Stats-Zeile am Ende (auch wenn gewrappt):
- Runtime (z.B.
runtime 5m12s) - Token-Verbrauch (Input/Output/Gesamt)
- Geschätzte Kosten, wenn Modellpreise konfiguriert sind (
models.providers.*.models[].cost) sessionKey,sessionIdund Transkript-Pfad (damit der Haupt-Agent History übersessions_historyabrufen oder die Datei auf der Festplatte inspizieren kann)- Interne Metadaten sind nur für die Orchestrierung gedacht; benutzerseitige Antworten sollten in normaler Assistenten-Stimme umgeschrieben werden.
Tool-Policy (Sub-Agent-Tools)
Standardmäßig bekommen Sub-Agents alle Tools außer Session-Tools und System-Tools:
sessions_listsessions_historysessions_sendsessions_spawn
Wenn maxSpawnDepth >= 2, erhalten Tiefe-1-Orchestrator-Sub-Agents zusätzlich sessions_spawn, subagents, sessions_list und sessions_history, damit sie ihre Kinder verwalten können.
Override über Config:
{
agents: {
defaults: {
subagents: {
maxConcurrent: 1,
},
},
},
tools: {
subagents: {
tools: {
// deny gewinnt
deny: ["gateway", "cron"],
// wenn allow gesetzt ist, wird es allow-only (deny gewinnt trotzdem)
// allow: ["read", "exec", "process"]
},
},
},
}
Nebenläufigkeit
Sub-Agents verwenden eine dedizierte In-Process-Queue-Lane:
- Lane-Name:
subagent - Nebenläufigkeit:
agents.defaults.subagents.maxConcurrent(Standard8)
Stoppen
- Das Senden von
/stopim anfragenden Chat bricht die anfragende Session ab und stoppt alle aktiven Sub-Agent-Runs, die daraus gespawnt wurden, mit Kaskadierung zu verschachtelten Kindern. /subagents kill <id>stoppt einen bestimmten Sub-Agent und kaskadiert zu seinen Kindern.
Einschränkungen
- Sub-Agent-Announce ist Best-Effort. Wenn das Gateway neu startet, geht ausstehende “Announce-Back”-Arbeit verloren.
- Sub-Agents teilen sich weiterhin die gleichen Gateway-Prozess-Ressourcen; behandle
maxConcurrentals Sicherheitsventil. sessions_spawnist immer nicht-blockierend: es gibt sofort{ status: "accepted", runId, childSessionKey }zurück.- Sub-Agent-Kontext injiziert nur
AGENTS.md+TOOLS.md(keinSOUL.md,IDENTITY.md,USER.md,HEARTBEAT.mdoderBOOTSTRAP.md). - Maximale Verschachtelungstiefe ist 5 (
maxSpawnDepth-Bereich: 1—5). Tiefe 2 wird für die meisten Anwendungsfälle empfohlen. maxChildrenPerAgentbegrenzt aktive Kinder pro Session (Standard: 5, Bereich: 1—20).