Votre subagent part dans la mauvaise direction ? Vous pouvez désormais le recadrer en plein vol


Lundi après-midi, vous faites lancer par Hermes trois subagents pour paralléliser un refactor : un pour le frontend, un pour le backend, un pour les tests. Une demi-heure plus tard, vous jetez un œil à l’avancement et vous réalisez que celui du backend fonce dans la mauvaise direction — il écrit toujours contre l’ancienne API alors que la nouvelle a modifié chaque signature. Avant, votre seule option était de tuer tout le lot, de ré-expliquer les exigences et de repartir de zéro ; si vous n’aviez pas de chance, les deux subagents qui s’en sortaient bien se retrouvaient pris dans la déflagration. Plus maintenant. Depuis le 13 août, delegate_task embarque une console de contrôle en temps réel — vous pouvez lister les subagents en cours d’exécution, recadrer celui qui a dévié, ou stopper celui qui est irrécupérable, sans interrompre le reste de l’équipe.

La console du chef d’orchestre : trois actions de contrôle

D’abord, une petite précision : un subagent est un « clone » distinct que Hermes envoie travailler en toute indépendance, avec son propre contexte de conversation isolé et sa propre session terminal. Auparavant, delegate_task n’avait qu’un seul verbe — spawn : lancer une tâche, attendre le résumé. La PR #85232 ajoute trois actions de contrôle directement dans le même outil, sans introduire le moindre nouvel outil. Le modèle appelle toujours delegate_task ; il reçoit simplement trois nouveaux paramètres : action, subagent_id et message.

Action Paramètres Effet
action='list' aucun Liste les subagents encore en cours d’exécution lancés par cette conversation
action='steer' subagent_id + message Met une correction de cap en file dans un subagent en cours d’exécution sans l’arrêter
action='stop' subagent_id Interrompt un subagent en avance ; son résultat partiel revient quand même normalement
omise ou action='spawn' goal/tasks, etc. Le mode de lancement d’origine — comportement inchangé

Les trois actions de contrôle s’exécutent de manière synchrone — elles ne passent jamais par la file de distribution en arrière-plan et renvoient immédiatement, si bien que vous obtenez une réponse instantanée du type « voici ce qui tourne » directement dans la conversation.

Comment l’utiliser : l’exercice complet découvrir → recadrer → stopper

Imaginons que vous venez de lancer trois subagents et que vous voulez voir où ils en sont :

{
  "tool": "delegate_task",
  "action": "list"
}

Chaque entrée de la liste retournée contient subagent_id, parent_id, depth, goal, model, started_at et accepting_steer — le champ goal permet de repérer d’un coup d’œil celui qui « écrit toujours contre l’ancienne API ».

Une fois le fautif repéré, injectez une correction :

{
  "tool": "delegate_task",
  "action": "steer",
  "subagent_id": "sa-7f3k9",
  "message": "Heads up: the backend API signature changed. Use the new /v2/users endpoint — the field is userId, not id."
}

steer fonctionne en mettant le texte en file dans l’entrée en attente du subagent cible, où il est délivré à la prochaine tool boundary de l’enfant — il n’arrache pas le subagent à ce qu’il est en train de faire ; la correction atterrit à un point sûr. Et si le subagent se termine avant d’avoir jamais consommé le steer, l’instruction ne s’évapore pas dans le vide : elle remonte sous la forme d’un champ missed_steer dans l’entrée de complétion de ce subagent, pour que vous sachiez que la correction de cap n’est jamais arrivée.

Si ce subagent est vraiment irrécupérable, mettez-y fin :

{
  "tool": "delegate_task",
  "action": "stop",
  "subagent_id": "sa-7f3k9"
}

stop s’appuie sur la mécanique d’interruption : le subagent s’arrête à sa prochaine frontière d’itération, et tout résultat partiel qu’il a produit revient sous la forme d’un message de complétion normal — aucun travail gaspillé, aucun état orphelin. Vous pouvez récupérer la sortie partielle et lancer un subagent tout neuf pour finir le reste.

Limites et sécurité : vous ne contrôlez que votre propre arbre

La console de contrôle s’accompagne de quelques limites volontairement conçues — apprenez-les et vous n’aurez pas de surprises :

  • Chaîne de propriété : une conversation ne peut contrôler que les subagents qu’elle a elle-même lancés. Hermes fait respecter cette règle via une chaîne de weakrefs _delegate_parent_ref avec vérifications d’identité — vous ne pouvez pas steer les enfants d’une autre conversation depuis la vôtre. C’est la même garantie qui empêche plusieurs sessions Hermes de se marcher dessus.
  • Les actions de contrôle ne consomment pas le budget de spawn : il existe un plafond par tour sur le nombre de subagents que vous pouvez lancer, mais list/steer/stop en sont exemptés — par conception. Or, c’est justement quand le plafond est atteint que « stopper d’urgence celui qui part en vrille » compte le plus, donc stop reste utilisable.
  • Les subagents ne peuvent pas lancer de subagents par défaut : un enfant avec role='leaf' ne reçoit jamais l’outil delegate_task ; seul un role='orchestrator' explicite conserve la panoplie d’outils de distribution (bornée par delegation.max_spawn_depth). Le contrôle réside toujours du côté de la conversation de premier niveau.
  • Délai de livraison du steer : steer est une « injection en file », pas une « interruption instantanée ». Si le subagent est coincé dans un appel d’outil très long, la correction n’atterrit qu’à la prochaine tool boundary — parfait dans la plupart des cas, mais pour les situations de type « il faut s’arrêter tout de suite », stop est le bon outil.

Quand l’orchestration en direct porte ses fruits

Le vrai gain, c’est de faire passer votre « inspection humaine » de l’après-coup au moment où ça se passe :

  • Correction de cap précoce sur les longues tâches : quand on réécrit des dizaines de milliers de lignes, découvrir au bout de dix minutes qu’on part dans la mauvaise direction coûte cher. Un list + steer en plein milieu peut faire gagner des heures.
  • Traitement chirurgical dans les lots parallèles : sur trois subagents, un seul a dévié — steer ou stop uniquement sur celui-là pendant que les deux autres continuent de tourner, au lieu de relancer tout le lot.
  • En complément des flux kanban/review : si vous gérez les tâches de subagents sur un board (voir notre guide du cycle de vie kanban review), la console de contrôle comble le vide du « comment intervenir en pleine tâche » que le board seul ne pouvait pas résoudre.

Nous avons déjà parlé de delegate_taskle merge-reconciler, arbitre neutre de fusion de code illustrait le schéma « on lance et on attend les résultats ». Cette surface de contrôle fait passer delegate_task du fire-and-forget au pilotage en cours d’exécution. Les subagents sont au cœur des workflows multi-agents de Hermes depuis la v0.20.0 (voir les notes de version de la v0.20.0 Herald), et ils ont enfin un volant pour les diriger en direct.

Une phrase à retenir : list pour voir, steer pour parler, stop pour freiner — les trois sans interrompre les subagents qui font bien leur travail. La prochaine fois qu’un subagent dévie, pas besoin de retourner la table et de tout recommencer.