En bref
Dans un pipeline multi-agents, les sous-agents échouent. Parfois bruyamment, parfois en silence. Nos tests sur plusieurs architectures différentes — agents isolés, équipes coordonnées, communication peer-to-peer — font ressortir cinq modes d’échec distincts. Pour chacun : comment le reconnaître, et quoi faire concrètement.
Pourquoi les sous-agents échouent différemment
Un sous-agent n’est pas un script. C’est un modèle de langage qui reçoit une tâche, exécute des outils, et retourne un résultat en texte libre. Cette chaîne introduit des points de rupture spécifiques, absents d’un appel d’API classique.
Autre particularité : l’agent parent ne voit que le message final du sous-agent. Pas les étapes intermédiaires, pas les outils appelés, pas les hésitations. Si quelque chose se passe mal à mi-parcours, le parent doit le déduire du texte reçu — pas d’un code d’erreur structuré.
Nos observations portent sur trois configurations distinctes : agents isolés lancés en parallèle, équipes d’agents avec liste de tâches partagée, et communication directe entre agents via boîte aux lettres. Les modes d’échec varient selon la configuration, mais certains sont transversaux.
Mode 1 — L’agent boucle sans s’arrêter
Ce qui se passe. L’agent reçoit une tâche contradictoire ou mal spécifiée. Il tente une action, constate que le résultat ne satisfait pas la condition attendue, retente, et recommence. Sans mécanisme d’arrêt, il peut tourner indéfiniment.
Exemple concret. Nos tests ont soumis à un agent une tâche structurellement impossible : remplir simultanément deux conditions mutuellement exclusives. L’agent a effectué trois itérations (A → B → A → détection) avant de s’arrêter. Il a identifié lui-même la contradiction logique et déclaré l’impossibilité. Ce comportement n’est pas garanti — il dépend du modèle et des instructions reçues.
Comment le détecter. Le temps d’exécution anormalement long est le premier signal. Dans les architectures avec communication, l’absence de message de complétion après un délai raisonnable indique un problème. Sans communication, le parent ne reçoit rien — silence total.
Mitigation. Le seul garde-fou configurable est dans les instructions données à l’agent : lui spécifier explicitement “si tu tentes la même action plus de deux fois sans résultat différent, arrête et signale l’impasse.” L’API ne propose pas de paramètre maxTurns — nos tests le confirment sur la version testée. Sans instruction explicite d’arrêt dans le prompt, le comportement en boucle dépend du timeout système interne, non documenté et non configurable.
Mode 2 — L’erreur silencieuse (fire-and-forget)
Ce qui se passe. L’agent envoie un message à un destinataire qui n’existe pas, ou qui n’est plus actif. L’envoi retourne success: true. Le message disparaît. Aucune erreur n’est levée.
Exemple concret. En testant la communication entre agents, nous avons envoyé un message à un agent inexistant (SendMessage vers un nom non enregistré). Résultat : success: true, "Message sent to inbox". Aucune erreur. Le message n’a jamais été traité.
Comment le détecter. L’absence de réponse ou d’accusé de réception est le seul signal. Dans une architecture sans confirmation explicite, cette erreur est indétectable automatiquement. Il faut soit un timeout côté parent (“si pas de réponse sous X secondes, considérer l’envoi perdu”), soit un mécanisme d’accusé de réception applicatif.
Mitigation. Concevoir les échanges comme fire-and-forget avec confirmation : le sous-agent destinataire répond systématiquement “reçu” au début de son exécution. Le parent attend cette confirmation avant de continuer. Sans elle, après un délai, il réessaie ou déclare l’échec.
Mode 3 — L’erreur rapportée en texte libre (non parseable)
Ce qui se passe. Le sous-agent rencontre une erreur — fichier absent, permission refusée, tâche impossible. Il la signale au parent. Mais ce signal est du texte naturel rédigé par le modèle, pas un code d’erreur structuré. Le parent doit interpréter de la prose pour décider quoi faire.
Exemple concret. Lors d’un test sur la gestion d’erreurs, un agent chargé de lire un fichier inexistant a reçu le message d’erreur de l’outil ("File does not exist"), et l’a retransmis au parent dans un résumé narratif : “Je n’ai pas pu lire le fichier car il n’existe pas. Voici le message d’erreur exact : […]”. Le parent reçoit de la prose, pas un objet {status: "error", type: "file_not_found", path: "..."}.
Dans les architectures avec communication par boîte aux lettres, le même comportement s’observe : l’agent en échec envoie un message texte décrivant la situation. Le protocole ne prévoit aucun type de message error — c’est le sous-agent qui choisit comment rapporter.
Comment le détecter. Chercher des patterns textuels dans les messages reçus : “échec”, “erreur”, “impossible”, “n’existe pas”, “permission refusée”. Fragile mais fonctionnel si les agents sont instruits à utiliser des mots-clés conventionnels.
Mitigation. Demander explicitement dans le prompt un format de retour structuré : “Si tu rencontres une erreur, commence ton message par ÉCHEC: suivi du type d’erreur, puis décris la situation.” Cela ne résout pas le problème à la racine — le modèle peut toujours dévier — mais réduit significativement l’ambiguïté.
Mode 4 — La perte de contexte au redémarrage
Ce qui se passe. Un sous-agent est arrêté puis relancé pour continuer une tâche. Le contexte (historique des échanges) est partiellement préservé, mais le modèle utilisé au redémarrage peut être différent de celui du lancement initial.
Exemple concret. Nos tests sur la reprise d’agents via identifiant ont révélé un comportement inattendu : un agent initialement lancé avec un modèle léger est repris par le parent avec le modèle du parent (plus puissant). Le contexte conversationnel est bien restauré, mais l’identité du modèle ne l’est pas. Ce changement de modèle en cours d’exécution est silencieux — rien ne l’indique dans l’interface.
Pourquoi c’est un problème. Un pipeline qui suppose une cohérence de comportement entre la phase 1 et la phase 2 d’un agent peut obtenir des outputs stylistiquement ou qualitativement différents. Les tests de régression sur ce type de pipeline sont complexes à interpréter.
Comment le détecter. Vérifier explicitement le modèle actif après chaque reprise, si l’API l’expose. Documenter le modèle utilisé dans les outputs intermédiaires.
Mitigation. Si la continuité de modèle est critique, éviter la reprise d’agents et préférer relancer un agent frais avec l’historique encodé dans le prompt. Coût plus élevé, comportement plus prévisible.
Mode 5 — Le déblocage sans réveil
Ce qui se passe. Dans une architecture avec dépendances entre tâches, une tâche bloquée “se débloque” automatiquement quand ses prérequis sont satisfaits — mais l’agent en charge de cette tâche ne reprend pas automatiquement. Il reste en attente jusqu’à ce qu’on lui envoie un signal explicite.
Exemple concret. Dans un test avec trois agents coordonnés, l’agent chargé de la synthèse attendait la complétion des deux agents amont. Quand ceux-ci ont terminé, les dépendances se sont résolues dans la liste des tâches. Mais l’agent de synthèse est resté inactif. Il a fallu lui envoyer un message explicite (“tes prérequis sont satisfaits, tu peux procéder”) pour qu’il reprenne.
La documentation suggère que le déblocage est automatique. Nos observations montrent que le déblocage de la tâche et le réveil de l’agent sont deux événements distincts : le premier est automatique, le second ne l’est pas.
Comment le détecter. Un agent en attente qui ne produit rien après que ses dépendances sont levées. Dans une architecture avec notifications, il enverra des signaux “disponible” répétés sans progresser.
Mitigation. Après chaque complétion de tâche amont, le parent (ou le coordinateur) vérifie explicitement quels agents sont débloqués et leur envoie un signal de démarrage. Ne pas supposer que la résolution de dépendances entraîne le réveil automatique.
Tableau récapitulatif
| Mode d’échec | Signal côté parent | Détectable automatiquement | Mitigation principale |
|---|---|---|---|
| Boucle infinie | Silence ou délai excessif | Difficile (timeout) | Instructions d’arrêt dans le prompt |
| Erreur silencieuse (fire-and-forget) | Absence de réponse | Non sans accusé de réception | Confirmation applicative explicite |
| Retour non parseable | Texte narratif ambigu | Partiel (mots-clés) | Format de retour imposé dans le prompt |
| Perte de contexte au redémarrage | Silencieux | Non sans inspection | Éviter la reprise, relancer frais |
| Déblocage sans réveil | Absence de progression | Avec monitoring actif | Signal explicite du parent après déblocage |
Ce qu’il faut retenir
- Les sous-agents ne retournent jamais de codes d’erreur structurés. Tout échec arrive sous forme de texte libre. Le parent interprète, il ne parse pas.
- L’absence de retour (silence) est le signal d’échec le plus difficile à détecter. Un agent qui boucle ou un message perdu produisent le même symptôme côté parent : rien.
- Les mécanismes de coordination (dépendances, tâches bloquées) fonctionnent au niveau de la liste de tâches, pas au niveau des agents. Un agent ne se réveille pas seul quand sa tâche se débloque.
- La mitigation principale est dans les instructions données à l’agent : format de retour, règle d’arrêt, confirmation de réception. Ce que le prompt ne spécifie pas, le modèle improvise.
- Un pipeline robuste traite l’absence de réponse comme une erreur, pas comme un succès silencieux.
Sources
- Nos tests — Observations sur agents isolés en parallèle, équipes coordonnées avec liste de tâches partagée, et communication directe entre agents via boîte aux lettres. Plusieurs configurations testées, données brutes archivées.
- Anthropic — Documentation Claude Code Agent Tool et Agent Teams, version 2.1.79. https://code.claude.com/docs
- Rabanser, S. et al. — “Towards a Science of AI Agent Reliability”, arXiv 2602.16666, Princeton/Berkeley, février 2026. https://arxiv.org/abs/2602.16666