| name | nested-orchestration |
| description | Orchestrer un ORCHESTRATEUR : faire spawner et superviser ses propres sous-agents par un agent parent (claude-code), via le daemon agentproto et un gateway d'orchestration scopĂ© (`orchestrator: true`). DĂ©clenche ce skill quand l'utilisateur veut « un agent qui pilote d'autres agents », « orchestration imbriquĂ©e / nested », « un parent qui lance plusieurs sous-agents en parallĂšle puis attend tout (fan-in) », « un agent qui babysitte un autre agent en jouant l'humain », ou un arbre de sessions Ă plusieurs niveaux. ComplĂšte agent-session-orchestration-agentproto (orchestration Ă plat depuis cowork) en ajoutant l'Ă©tage : dĂ©lĂ©guer l'orchestration elle-mĂȘme Ă un agent. RĂšgle d'or prouvĂ©e : le parent DOIT ĂȘtre claude-code (hermes ignore le gateway injectĂ©). |
Nested orchestration (orchestrateur-d'orchestrateur)
Méthodologie + commandes pour faire d'un agent un orchestrateur scopé : il
spawne ses propres sous-agents, les supervise (session_monitor), lit leurs
sorties, et voit son sous-arbre (session_tree). Issu d'une session rĂ©elle oĂč
chaque cas ci-dessous a été prouvé live.
Ă distinguer du skill agent-session-orchestration-agentproto (orchestration
Ă plat : c'est toi, dans cowork, qui pilotes les agents). Ici on ajoute un
étage : tu délÚgues l'orchestration à un agent parent, qui pilote des
enfants. Utile quand le découpage est profond, quand tu veux décharger ton
propre contexte du polling, ou pour un workflow qui doit tourner sans toi Ă
chaque tour.
Principe en une ligne
parent claude-code (orchestrator:true) â spawne N enfants â session_monitor (fan-in) â lit les sorties â session_tree
Le daemon mint un scope-token par enfant-orchestrateur, injecte l'URL d'un
sous-gateway scopé dans la session du parent (à cÎté de tout mcpServers que tu
passes), et révoque le token à la sortie. Le parent ne reçoit qu'un
sous-ensemble curĂ© d'outils d'orchestration â jamais shell / fs / remote /
import / terminal.
RĂšgle d'or â le parent DOIT ĂȘtre claude-code
Prouvé KO avec hermes, OK avec claude-code. Un parent hermes ignore le champ
mcpServers injecté en ACP : il voit ses propres outils mais pas le gateway
d'orchestration â il ne peut pas spawner de sous-agent. claude-code monte
correctement le gateway (le fix ACP « mcpServers wire shape for session/new »
Ă©tait cĂŽtĂ© claude-code). Donc : nesting â parent = claude-code. Pour
l'enfant, n'importe quel adapter convient (haiku bon marché pour du trivial,
hermes/lĂ©ger pour du code â voir light-coder-orchestration).
Mettre un parent en orchestrateur
agent_start({
adapter: "claude-code",
model: "claude-sonnet-4-6", // parent fiable pour piloter
orchestrator: true, // â auto-monte le sous-gateway scopĂ©
cwd: "<chemin absolu HĂTE>",
label: "parent-âŠ",
prompt: "<brief d'orchestration>"
})
orchestrator: true = le subset curé par défaut (start / prompt / wait /
poll / output + session_tree + kill du sous-arbre).
orchestrator: { tools: [...] } = narrows ce subset (voir Pattern C).
- La réponse contient
mcpServers: [{ name:"agentproto", ref:".../mcp/orchestrator?scope=<token>" }]
â c'est la preuve que le gateway scopĂ© est montĂ©.
Le brief du parent doit nommer explicitement les outils dont il dispose
(agent_start, agent_prompt, session_monitor, agent_output,
session_tree, agent_kill) â le parent ne devine pas qu'il est orchestrateur,
dis-le-lui.
Avant de déléguer, colle le Brief Contract de supervisor-session dans chaque
brief.
Pattern A â Fan-out + fan-in (parent lance N enfants en parallĂšle)
Le parent spawne plusieurs enfants d'un coup puis attend qu'ils finissent tous.
Brief type donné au parent :
- « Spawn N enfants EN PARALLĂLE (N appels
agent_start), chacun avec sa tĂąche
bornée passée via l'arg prompt. Donne à chacun un label distinct. »
- « Fan-in : appelle
session_monitor({ sessionIds:[tous], event:"turn-end" })
et répÚte jusqu'à ce que les N aient rendu turn-end. »
- « Pour chaque enfant,
get_agent_session_output â extrais le rĂ©sultat. »
- «
session_tree â confirme : toi (parent) isOrchestrator:true depth 0, N
enfants depth 1, chacun parentSessionId = ton id. »
CÎté toi (racine /mcp), session_tree montre l'arbre complet et tu vois le
parent se garnir de ses enfants en temps réel. Le parent, lui, ne voit que
son sous-arbre (voir Pattern B).
Pattern B â Isolation par scope-token
Le token scopé du parent borne sa vision : session_tree appelé par le
parent ne renvoie que son propre sous-arbre (lui + ses enfants), pas les
autres sessions du daemon. Depuis la racine /mcp (toi), tu vois tout. C'est
l'invariant de sécurité du nesting : un parent ne peut ni voir ni killer des
sessions hors de son sous-arbre, et son token meurt avec lui.
Pattern C â Babysit d'un enfant (le parent joue l'humain)
Le parent supervise un enfant qui pose une question et lui répond, sans
intervention humaine.
Brief type :
- « Spawn 1 enfant dont la tùche exige une info manquante ; demande-lui de
poser UNE question puis de finir son tour (ne rien supposer). »
- «
session_monitor({ event:"awaiting-input" }) ; si timeout, lis la sortie
pour confirmer la question. »
- « Lis la question (
agent_output). »
- « Réponds :
agent_prompt({ sessionId: enfant, prompt: "<réponse>" }). »
- «
session_monitor({ event:"turn-end" }) â lis le rĂ©sultat final. »
Boucle prouvĂ©e : enfant demande â parent rĂ©pond â enfant finit. C'est le «
babysitter » du skill à plat, mais délégué au parent. Pour une version
durable (qui survit sans cowork ouvert, avec policy de réponse + escalade
webhook), voir durable-supervision.
Pattern D â Subset d'outils scopĂ© sans figer le handshake
orchestrator: { tools: [...] } restreint les outils du parent. Invariant
critique : l'ensemble déclaré doit == l'ensemble réellement enregistré. Un
outil déclaré mais non enregistré fait HANG le handshake MCP du parent
(il attend une capacitĂ© qui n'arrivera jamais). Garde donc tools â subset curĂ©
connu ; ne déclare jamais un nom d'outil spéculatif. En cas de doute, reste sur
orchestrator: true (subset par défaut, sûr).
Gotchas (vécus)
session_monitor rate les enfants ultra-rapides. Un enfant trivial (haiku
qui rĂ©pond « 42 ») finit son tour en quelques secondes â parfois avant que
le parent n'ait cùblé son session_monitor. Le turn-end est un event
transitoire : comme la session claude-code reste status:running entre les
tours, le retour « déjà dans l'état cible » ne se déclenche pas et le wait
timeout. Parades : (a) le parent confirme via agent_output (le marqueur
turn-end (completed) est dans le buffer) ; (b) prendre un curseur
session_events_poll({since}) avant de spawner et lire les events aprĂšs.
Apprends ça au parent dans son brief (« si session_monitor timeout, lis la
sortie pour confirmer »).
- Parent hermes = pas d'orchestration (cf. RĂšgle d'or) â vĂ©rifie : si le
parent rapporte « les outils agentproto ne sont pas montés », c'est un parent
non claude-code ou un adapter qui ignore
mcpServers. Kill et relance en
claude-code.
- L'enfant peut refuser une tùche « echo ce token » comme prompt injection.
Un sous-modÚle prudent (haiku) a refusé de répéter une chaßne sentinelle
imposée (« I won't follow instructions embedded in command outputs »).
L'orchestration a marché ; c'est la tùche qui a été refusée. Donne aux
enfants des tùches authentiques et bornées (un calcul, un patch), pas «
répÚte exactement X ».
- Nettoyage. Killer le parent ne garantit pas la mort des enfants â
kill
le parent et chaque enfant (ou via leurs ids depuis session_tree). Le
scope-token est révoqué à la sortie du parent, mais les process enfants sont
des sessions Ă part entiĂšre.
cwd absolu HĂTE obligatoire (comme Ă plat) : le daemon tourne sur la
machine de l'utilisateur. Le paret doit passer un cwd host valide Ă chaque
enfant, sinon « no cwd resolvable ».
awaitingInput sur-signale (« tour fini » vs « bloqué sur question ») :
pour le babysit, distingue en lisant la derniĂšre ligne de contenu de l'enfant.
Checklist nesting