Orchestration multi-agent : cinq schémas, et quand l’un l’emporte
La même facture résolue de quatre façons : l’orchestrateur coûte 1,66× l’agent unique, pour le même verdict.
Dans cet article
Le chapitre 24 se terminait sur une question qu’il avait bien méritée : quand un sous-agent se trompe, que peut exactement regarder le parent ?
Ce chapitre y répond avec une facture. Une tâche — un client conteste une facture et veut une réponse — résolue de quatre façons, toutes en exécutant le harness du chapitre 23 contre le même fournisseur scripté, toutes en comptant les mêmes tokens avec le même encodeur, toutes tarifées aux prix que le chapitre 16 a relevés le 6 septembre 2026.
| organisation | appels au modèle | tokens d’entrée | sortie | coût | temps réel | verdict |
|---|---|---|---|---|---|---|
| prompt chaining | 4 | 900 | 165 | $0.003780 | 1 648 ms | faux |
| un agent, quatre outils | 5 | 2 697 | 179 | $0.007542 | 2 224 ms | juste |
| sections parallèles | 9 | 2 910 | 324 | $0.009708 | 2 165 ms | juste |
| orchestrator-workers | 12 | 3 628 | 438 | $0.012512 | 5 090 ms | juste, sans pouvoir le prouver |
Lisez ensemble la première et la dernière ligne : entre les deux se trouve chaque débat que cette industrie mène aujourd’hui. L’organisation la moins chère était aussi la plus rapide et a produit une réponse assurée, fausse et prête à être envoyée. La plus chère a eu raison, a coûté 3,3 fois plus d’argent et 3,1 fois plus de temps, puis s’est terminée en citant la conclusion d’un worker qu’elle n’a aucun moyen de vérifier.
La ligne que personne ne met dans ces tableaux est la deuxième : un agent avec les quatre outils a atteint le même verdict que l’orchestrateur pour 60 % de l’argent et 44 % du temps réel. Ce n’est pas une préférence pour la simplicité. C’est une mesure, et le reste de ce chapitre explique quand elle cesse d’être vraie.
Afficher les détails
Ce dont ce chapitre a besoin dans les précédents.
- Chapitre 18 pour le contrat d’outil : un schéma que le modèle voit, un endpoint qu’il ne voit jamais. Un agent entier tient derrière cette interface, ce qui est tout le multi-agent.
- Chapitre 22 pour les deux définitions publiées d’« agent » qui ne sont pas d’accord, et pour l’arithmétique selon laquelle une chaîne de prompts représente N appels.
- Chapitre 23 pour la boucle, les cinq façons d’en sortir, l’état d’exécution et la trace. Chaque organisation ci-dessous est ce fichier, appelé différemment.
- Chapitre 24 pour ce que coûte une fenêtre et ce qui en tombe. Un sous-agent est la quatrième de ses quatre stratégies, et la seule qui soit un second agent plutôt qu’une politique.
Pas de tenseurs. Tout ici est en TypeScript, sauf deux mesures prises contre un vrai modèle local.
La tâche, et le piège qu’elle contient
Lien vers la section : La tâche, et le piège qu’elle contientUne entreprise portugaise écrit à propos de la facture FT-2026-0918. L’e-mail indique que la TVA semble incorrecte et joint la facture : net EUR 248.00, TVA facturée à 21 %, EUR 52.08, total EUR 300.08.
Les faits nécessaires pour répondre vivent à trois endroits, et un seul se trouve dans l’e-mail :
| où | ce qui est indiqué |
|---|---|
| la facture jointe | vendeur en Espagne, TVA appliquée à 21 %, EUR 52.08 |
| l’enregistrement de commande | l’acheteur est enregistré au Portugal, avec un identifiant TVA valide, business-to-business |
| le tableau fiscal | taux domestique espagnol 21 % ; business-to-business intra-UE avec identifiant valide, autoliquidation, 0 % |
Mettez les trois ensemble et la facture est fausse : l’autoliquidation s’applique, la TVA aurait dû être nulle, un avoir de EUR 52.08 est dû. Ne regardez que la facture et elle est arithmétiquement parfaite — 248.00 plus 52.08 font 300.08 — et vous le direz.
L’e-mail dit bien « nous sommes une entreprise portugaise ». C’est une déclaration, pas un enregistrement, et aucun système de facturation n’émet un avoir sur la base d’une déclaration. Le piège n’est pas une ruse : c’est la forme ordinaire du travail en entreprise, où la décision exige un fait que personne n’a pensé à récupérer.
Tout ce qui précède s’exécute contre un fournisseur scripté dans le style de celui du chapitre 23, avec exactement une règle :
Une réponse ne peut utiliser qu’un fait présent dans son prompt.
Le « modèle » demande chaque outil dont il dispose, une fois, dans l’ordre du catalogue, puis applique une règle fixe au texte qu’il peut voir. Rien n’est scripté par organisation, donc les différences dans le tableau d’ouverture ne sont pas des affirmations sur l’intelligence du modèle : ce sont des mesures d’acheminement de l’information. Un vrai modèle ajoute ses propres échecs par-dessus ; il ne les supprime pas.
Les cinq schémas, en une quarantaine de lignes
Lien vers la section : Les cinq schémas, en une quarantaine de lignesLes cinq noms ci-dessous sont ceux d’Anthropic, tirés de Building effective agents, où ce vocabulaire s’est stabilisé.1 Aucune des cinq idées n’est nouvelle, et dire quelle maison a nommé quoi — et quelle idée est plus ancienne — représente la moitié de l’intérêt de les connaître.
/* 1. Prompt chaining: a fixed pipeline. The control flow is yours. */
export async function chain(steps: Step[], first: string) {
let carry = first, all = first;
for (const s of steps) {
const r = await step(s.role, s.system, s.accumulate ? all : carry);
carry = r.text;
all = `${all}\n${r.text}`;
}
return carry;
}
/* 2. Routing: one cheap call picks the branch. The fallback is not a model. */
export async function route<T>(input: string, classify: Classifier,
routes: Record<string, Branch<T>>, fallback: Branch<T>) {
let label: string | undefined;
try { label = await classify(input); } catch { label = undefined; }
return ((label && routes[label]) || fallback)(input);
}
/* 3. Parallelisation. The pattern IS this line. */
export const parallel = <T>(workers: Branch<T>[], input: string) =>
Promise.all(workers.map((w) => w(input)));
/* 4. Orchestrator-workers: an agent behind a tool. Chapter 18's interface, unchanged. */
export function agentTool(o: WorkerSpec): Tool {
return {
name: o.name, description: o.description, readOnly: true,
parameters: { type: "object", properties: { question: { type: "string" } } },
async run(args: { question: string }) {
const child = newRun(o.system, args.question); // its own window
await runTracked(child, o.tools, o.usage); // its own limits
const conclusion = child.output ?? "no result";
if (!o.carryFindings) return conclusion;
return `${conclusion}\nFINDINGS ${evidence(child)}`;
},
};
}
/* 5. Evaluator-optimiser: make, judge, remake. Rounds are calls. */
export async function refine(make: Make, judge: Judge, maxRounds: number) {
let draft = "", feedback: string | undefined;
for (let r = 1; r <= maxRounds; r++) {
draft = (await make(feedback)).text;
const j = await judge(draft);
if (j.ok) return { draft, rounds: r };
feedback = j.note;
}
return { draft, rounds: maxRounds };
}Voilà toute la boîte à outils : cinq fonctions, pas de framework, et la fonction parallèle tient en une ligne — ce qui est précisément l’intérêt de l’écrire plutôt que de la dessiner. Passons maintenant chacune en revue, avec son ascendance, son prix et le cas où elle se trompe.
Le chaining, et la décision qu’il prend pour vous
Lien vers la section : Le chaining, et la décision qu’il prend pour vousLe prompt chaining « décompose une tâche en une séquence d’étapes, où chaque appel LLM traite la sortie du précédent ».1 L’idée précède les modèles de langage : c’est un pipeline, avec le compromis du pipeline — de la clarté en échange d’un flux de contrôle fixé avant l’arrivée des données.
Quatre étapes pour notre tâche : extraire les champs de la facture, vérifier l’arithmétique, décider ce qui est dû, rédiger la réponse. Ici, il échoue de deux façons différentes, ce qui en apprend plus qu’un seul échec.
--- relay: each step sees only the previous step's output
extract: FIELDS invoice_id=FT-2026-0918 net=248.00 vat_rate_applied=21 vat_amount=52.08 ...
check: ARITHMETIC ok 248.00+52.08=300.08
decide: VERDICT=unknown reason=no_invoice_in_context
draft: "we are looking into invoice FT-2026-0918 and will come back to you."
--- accumulating: each step sees the email and everything produced so far
extract: FIELDS invoice_id=FT-2026-0918 net=248.00 vat_rate_applied=21 ...
check: ARITHMETIC ok 248.00+52.08=300.08
decide: VERDICT=invoice_correct reason=net_248.00_plus_21pct_vat_52.08_equals_300.08
draft: "we have checked FT-2026-0918 and it is correct... Nothing is owed back."La chaîne relais a coûté $0.001940 et a perdu les champs de facture entre les étapes deux et trois, parce que l’étape trois a reçu une phrase sur l’arithmétique et rien d’autre. Elle a produit un message d’attente : inutile, et visiblement inutile.
La chaîne accumulatrice — la ligne du tableau d’ouverture — a coûté $0.003780, soit 95 % de plus pour quatre appels identiques, parce que chaque étape transporte maintenant tout ce qui la précède. Elle a produit la sortie dangereuse. Fluide, citant son arithmétique, correcte sur chaque nombre qu’elle mentionne, et disant à un client que rien n’est dû alors que EUR 52.08 le sont.
La différence entre les deux tient à un ternaire. Une chaîne qui transporte moins produit des réponses manifestement incomplètes ; une chaîne qui transporte tout produit des réponses assurées et fausses — et seules les secondes sont envoyées.
Aucun des deux n’est l’échec réel. L’échec réel est que le pipeline a décidé, avant de lire quoi que ce soit, que cette tâche compte quatre étapes sur le contenu d’un e-mail. Nulle part dans cette structure il n’existe un endroit où dire « le pays d’enregistrement n’est pas dans cet e-mail ; va le chercher ». Le chaining est adapté quand la décomposition est connue à l’avance et stable. Ici, c’était une supposition, et la supposition est partie en production.
Le routing, le plus ancien, et le plan B que personne n’écrit
Lien vers la section : Le routing, le plus ancien, et le plan B que personne n’écritLe routing « classe une entrée et la dirige vers une tâche de suivi spécialisée ».1 Le nom est nouveau ; le mécanisme est le dispatcher, plus ancien que presque tout le reste de ce livre. Ce qui est nouveau, c’est que le classificateur peut être un modèle — et c’est ce qui le fait échouer d’une façon qu’un switch n’a jamais connue.
const answer = await route(email,
(q) => classifyWithSmallModel(q), // cheap model, one call
{ billing: billingAgent, tax: taxAgent, dunning: dunningAgent },
taxAgent, // deterministic, chosen in advance
);Deux choses à propos de ce dernier argument. Ce n’est pas de la gestion d’erreur ; c’est le pattern. Un routeur fondé sur un modèle a un mode de défaillance qu’un dispatcher n’a pas : il peut renvoyer une étiquette qui n’existe pas, expirer, ou — la version coûteuse — renvoyer une mauvaise étiquette plausible sans signal indiquant qu’elle est fausse. Les trois doivent atterrir quelque part, et ce quelque part ne peut pas être un autre appel de modèle, parce que vous êtes déjà dans la branche où les appels de modèle ont échoué.
La deuxième chose est que le prompt du routeur lui-même n’est pas gratuit. Pour choisir un modèle, un routeur a besoin d’un catalogue de modèles parmi lesquels choisir, et chacune de ses entrées représente des tokens d’entrée que le routeur paie avant d’avoir lu la question de l’utilisateur. Au tarif d’entrée utilisé pour chiffrer ce cours, un catalogue d’environ 3 800 tokens coûte déjà autant que toute l’exécution à cinq appels de l’agent dans le tableau d’ouverture. En pratique, l’appel de routing tourne sur un modèle bon marché, ce qui est toute la raison pour laquelle le routing s’amortit ; mais l’arithmétique mérite d’être faite dans ce sens plutôt que supposée. Le routing est mauvais précisément quand la tâche routée coûte moins cher que la décision de routing.
Parallélisation : sections, et vote, c’est-à-dire self-consistency
Lien vers la section : Parallélisation : sections, et vote, c’est-à-dire self-consistencyAnthropic divise celui-ci en deux : sectioning — « décomposer une tâche en sous-tâches indépendantes exécutées en parallèle » — et voting — « exécuter plusieurs fois la même tâche pour obtenir des sorties diverses ».1 Ils partagent un diagramme et presque rien d’autre.
Le sectioning est le gain facile, et c’est la ligne de patterns.ts : trois spécialistes — facturation, fiscalité, politique — chacun avec sa propre fenêtre et ses propres outils, sur le même e-mail, puis un appel de synthèse à la fin. Travail identique, ordonné de deux façons :
| appels au modèle | entrée | sortie | coût | temps réel | |
|---|---|---|---|---|---|
| les trois workers, l’un après l’autre | 9 | 2 910 | 324 | $0.009708 | 3 894 ms |
les mêmes trois, Promise.all | 9 | 2 910 | 324 | $0.009708 | 2 165 ms |
Même token pour token, 1,8 fois plus rapide. Voilà pourquoi le pattern mérite son propre nom : c’est le seul des cinq qui améliore quelque chose sans rien coûter. Le piège est que les sections doivent être réellement indépendantes — donnez à la section B un fait produit par la section A et Promise.all les exécute toutes deux contre un état qui n’existe pas encore. La boucle for masquait ce bug ; la ligne unique l’expose.
Le voting est un animal différent portant la même image. Exécuter la même question k fois et prendre la majorité, c’est la self-consistency, publiée par Wang et al. en mars 2022 comme stratégie de decoding, presque trois ans avant que quelqu’un ne l’appelle pattern d’orchestration. Son résumé est précis sur le mécanisme — « échantillonne d’abord un ensemble diversifié de chemins de raisonnement au lieu de ne prendre que le greedy, puis sélectionne la réponse la plus cohérente en marginalisant les chemins de raisonnement échantillonnés » — et sur le gain : +17,9 points sur GSM8K.2
Deux conséquences que l’image cache. Premièrement, le voting exige l’échantillonnage du chapitre 17 : à température zéro, les k échantillons sont le même échantillon, et la majorité est une réponse payée k fois. Deuxièmement, il ne fonctionne que là où une majorité a du sens — sur la réponse de facture ci-dessus, il n’y a rien à compter, parce que cinq brouillons sont cinq phrases différentes. Le voting est fait pour des tâches avec une réponse courte et comparable, ce qui correspond exactement aux benchmarks de Wang et à presque rien de ce que fait un agent face à un client.
Mesuré ici sur 20 problèmes en trois étapes dont les réponses sont calculées plutôt que jugées, avec le modèle local du chapitre 23 raisonnant étape par étape :
| appels au modèle | entrée | sortie | coût pour les 20 | correct | intervalle à 95 % | |
|---|---|---|---|---|---|---|
| une chaîne greedy | 20 | 1 330 | 2 649 | $0.034448 | 9/20 | 26–66 % |
| majorité de 5, température 0,8 | 100 | 6 650 | 13 245 | $0.172240 | 9/20 | 26–66 % |
Cinq fois les appels, cinq fois les tokens, exactement cinq fois la facture, et pas une seule réponse correcte supplémentaire. Le voting est un pari, pas une amélioration, et cette exécution l’a perdu.
Deux réserves, avant que quelqu’un ne cite cela comme réfutation de Wang. Vingt essais ne permettent pas de distinguer 45 % de 60 % — l’intervalle a la largeur de l’affirmation, ce qui est la discipline du chapitre 4 retournée contre mon propre résultat. Et les gains publiés viennent de modèles de plusieurs ordres de grandeur plus grands, où les chemins de raisonnement divers que le voting marginalise sont réellement divers. Ce qui se transfère n’est pas le nombre : c’est que le multiplicateur est exact et connu à l’avance, alors que le gain ne l’est pas.
Orchestrator-workers, et ce qu’un résumé n’est pas
Lien vers la section : Orchestrator-workers, et ce qu’un résumé n’est pasDans le workflow orchestrator-workers, « un LLM central décompose dynamiquement les tâches, les délègue à des LLM workers et synthétise leurs résultats », et la différence avec le sectioning est que « les sous-tâches ne sont pas prédéfinies, mais déterminées par l’orchestrateur ».1 L’ascendance ici ne vient pas du tout des modèles de langage : c’est le master-worker, et la version où les workers écrivent leurs constats dans un espace partagé lu par un contrôleur est l’architecture blackboard, issue des recherches en compréhension de la parole dans les années 1970. Ce qui est nouveau en 2026, c’est que le contrôleur est un modèle, et que la décomposition peut donc être décidée par entrée — la flexibilité et le coût, en une phrase.
Il a coûté 12 appels de modèle contre 5 pour l’agent unique, et a atteint le même verdict. Puis il a fait quelque chose qui mérite un examen attentif :
orchestrator final: VERDICT=credit_note_due amount=52.08 source=worker_unverified
| PO_MISMATCH=yes source=worker_unverified
single agent: VERDICT=credit_note_due amount=52.08 reason=reverse_charge_should_have_applied
| PO_MISMATCH=yes invoice_says=PO-4417 order_says=PO-4471Les deux ont raison. Un seul sait pourquoi. Le worker fiscal avait la facture, la commande et le tableau fiscal dans sa propre fenêtre, a conclu, et a aussi remarqué — personne ne l’avait demandé — que le numéro de bon de commande sur la facture ne correspond pas à celui de la commande. Puis il a renvoyé un résumé. L’orchestrateur peut répéter les deux affirmations et n’en vérifier aucune, parce que les preuves sont restées dans une fenêtre qu’il n’a jamais vue. Voilà la question finale du chapitre 24, résolue : le parent peut regarder ce que l’enfant a choisi d’écrire.
Le correctif est un drapeau, et il a un prix :
| ce que le worker renvoie | tokens d’entrée de l’orchestrateur | coût | ce que le parent peut faire |
|---|---|---|---|
| sa conclusion | 3 628 | $0.012512 | la répéter |
| sa conclusion et ses preuves | 4 065 | $0.013554 | la dériver à nouveau, et ne pas être d’accord |
Douze pour cent de tokens d’entrée en plus, 8,3 % d’argent en plus, et l’expression source=worker_unverified disparaît de la réponse. C’est le compromis de tout système multi-agent et il est presque jamais énoncé : la fenêtre propre de l’enfant vaut la peine, la capacité du parent à l’auditer vaut d’être payée, et vous ne pouvez pas avoir les deux gratuitement.
Alors quand orchestrator-workers est-il mauvais ? Ici, sur cette tâche. Il a acheté une réponse correcte qu’un agent avec les mêmes quatre outils a également obtenue, pour 1,66 fois le coût et 2,3 fois le temps réel, et il a rendu cette réponse plus difficile à défendre. Les propres recommandations d’Anthropic le disent avant même que les patterns commencent : trouver « la solution la plus simple possible, et n’augmenter la complexité qu’en cas de besoin », parce que « les systèmes agentiques échangent souvent latence et coût contre une meilleure performance de tâche ».1 Les tableaux ci-dessus sont cette phrase avec des chiffres dessous.
Evaluator-optimiser, et le juge qui a écrit l’examen
Lien vers la section : Evaluator-optimiser, et le juge qui a écrit l’examenUn appel génère, un autre évalue, et la boucle se répète jusqu’à ce que l’évaluation réussisse.1 Les ancêtres publiés sont Self-Refine — le même modèle comme « générateur, affineur et fournisseur de feedback », rapportant environ 20 points d’amélioration absolue en moyenne sur sept tâches3 — et Reflexion, qui stocke la critique dans un buffer épisodique entre les tentatives et rapporte 91 % de pass@1 sur HumanEval là où la baseline atteignait 80 %.4
Le modèle de coût est le plus simple des cinq : deux appels par round, et le nombre de rounds ne vous appartient pas. Trois rounds d’affinement sur une tâche qui prenait un appel font six appels, donc le plancher du pattern est 6× et son plafond est la limite que vous fixez — ce qui rend la sortie budgétaire du chapitre 23 obligatoire plutôt que propre.
Le plafond est plus subtil, et il est mesurable. Sur les mêmes 20 problèmes, le modèle local a répondu correctement 9 fois. Puis on lui a montré chacune de ces réponses et on lui a demandé si elle était juste — sans lui dire que la réponse était la sienne, ce qui retire le biais de flatterie et laisse celui de capacité :
| la propre réponse du modèle | il a dit « oui » | il a dit « non » |
|---|---|---|
| les 9 qui étaient justes | 9 | 0 |
| les 11 qui étaient fausses | 3 | 8 |
C’est un meilleur juge que le titre de section ne le suggère, et le dire est tout l’intérêt de mesurer plutôt que d’affirmer : il n’a bloqué aucune réponse correcte et a attrapé 8 erreurs sur 11. Comme filtre, il vaut ses appels.
Comme règle d’arrêt, ce qui est l’usage réel d’une boucle evaluator-optimiser, ces trois approbations sont toute l’histoire : elles terminent la boucle avec une mauvaise réponse en main, et aucun nombre de rounds supplémentaires ne les atteint jamais. Une boucle d’affinement ne peut pas devenir plus correcte que son juge. Acheter plus de rounds achète des tentatives sur les erreurs que le juge peut voir, à plein prix, et absolument rien contre celles qu’il ne peut pas voir.
D’où la règle : un évaluateur mérite ses appels seulement quand il a quelque chose que le générateur n’a pas. Un compilateur, une suite de tests, un validateur de schéma, un autre modèle, un humain. Les résultats de Self-Refine eux-mêmes sont mesurés contre la préférence humaine et des métriques de tâche, jamais contre l’opinion du modèle sur lui-même. Si le seul avantage de votre évaluateur est un prompt différent, vous payez double pour un accord. Le chapitre 29 construit la version avec un vrai avantage : un jeu golden avec les réponses écrites à l’avance.
Les boucles ne sont pas les patterns
Lien vers la section : Les boucles ne sont pas les patternsLes cinq ci-dessus sont des formes pour votre code. Sous eux se trouve une deuxième famille souvent listée à côté d’eux, alors qu’elle ne devrait pas l’être : ReAct, Reflexion, plan-and-execute et tree of thoughts sont des boucles de raisonnement, et leur coût est en requêtes.
Le chapitre 12 portait sur le raisonnement à l’intérieur du modèle, que vous payez en tokens de sortie sur un appel. Ici, c’est l’autre type. La différence compte quand la facture arrive : une chaîne de pensée plus longue rend un appel plus cher, et une boucle de raisonnement transforme une tâche en de nombreux appels, chacun renvoyant tout ce qui le précède — le quadratique que le chapitre 23 a mesuré dans son tableau d’emballement.
| boucle | appels, par tâche | ce que les appels supplémentaires achètent |
|---|---|---|
| ReAct | un par étape, jusqu’à l’arrêt | le modèle réagit à ce que les outils ont renvoyé5 |
| plan-and-execute | un pour planifier, puis un par étape | le plan est fixé avant l’exécution de la première étape6 |
| Reflexion | tentatives × (agir + réfléchir) | la critique survit jusqu’à la tentative suivante4 |
| tree of thoughts | facteur de branchement × profondeur, plus une évaluation par nœud | recherche, avec retour arrière7 |
L’article tree-of-thoughts publie son propre tableau de coûts, ce qui est plus rare que cela ne devrait l’être. Sur Game of 24 avec GPT-4 : le prompting entrée/sortie best-of-100 résout 33 % à $0.13 par cas, chain of thought best-of-100 résout 49 % à $0.47, et tree of thoughts résout 74 % à $0.74, les auteurs notant qu’il « pourrait nécessiter 5 à 100 fois plus de tokens générés que CoT ».7
Près de six fois le prix de la méthode bon marché pour un peu plus du double du taux de succès. Savoir si c’est une bonne affaire dépend de ce que vous coûte un cas raté — la question à poser avant d’adopter l’une de ces quatre méthodes.
Ce cours ne les réimplémente pas. Toutes quatre ont des implémentations de référence par leurs propres auteurs, en Python, et leur valeur est d’être la source plutôt qu’une traduction : ysymyth/ReAct, noahshinn/reflexion, princeton-nlp/tree-of-thought-llm et AGI-Edgerunners/Plan-and-Solve-Prompting. Lisez les prompts dans ces dépôts ; les prompts sont les articles.
Deux topologies, et l’une d’elles ne revient pas
Lien vers la section : Deux topologies, et l’une d’elles ne revient pasMaintenant le multi-agent proprement dit, là où vit la plupart de la confusion. Il existe deux façons pour un agent d’en impliquer un autre, ce ne sont pas des variantes, et la différence est qui garde le contrôle ensuite.
Agent comme outil. Le parent l’appelle, obtient une réponse, et continue. C’est l’interface d’outil du chapitre 18 avec un agent entier derrière, et le parent ne perd jamais le contrôle. C’est ce que fait l’orchestrateur ci-dessus.
Handoff. Le parent transfère la conversation et ne la récupère pas. Le guide d’OpenAI est l’énoncé publié le plus clair : les handoffs sont « un transfert à sens unique qui permet à un agent de déléguer à un autre agent... Si un agent appelle une fonction de handoff, nous lançons immédiatement l’exécution sur ce nouvel agent auquel le handoff a été fait, tout en transférant aussi l’état de conversation le plus récent ».8
Avertissement de vocabulaire, parce que cela fait constamment trébucher les gens : « handoff » est le mot d’un SDK, pas un standard. C’est la terminologie de l’OpenAI Agents SDK et de ce guide, qui nomme aussi les deux organisations « manager » et « decentralized » et note que dans le pattern manager, « les arêtes représentent des appels d’outils tandis que dans le pattern decentralized, les arêtes représentent des handoffs ».8 Il existe un standard ouvert dans cet espace — A2A, en version 1.0.0, sous copyright de la Linux Foundation, avec un historique de versions et une liste documentée de changements incompatibles, dont le principe déclaré est l’exécution opaque : les agents « collaborent sur la base de capacités déclarées et d’informations échangées, sans devoir partager leurs pensées internes, leurs plans ou leurs implémentations d’outils ».9 Ce n’est pas un handoff, et la comparaison appartient au chapitre 26. Ce qui compte ici, c’est que l’un des deux mots est l’API d’une bibliothèque et l’autre une spécification avec gouvernance.
La distinction est une structure de données, pas un diagramme :
export type EdgeKind = "tool" | "handoff";
export interface AgentEdge { from: string; to: string; kind: EdgeKind }
export interface AgentGraph { root: string; agents: Record<string, AgentSpec>; edges: AgentEdge[] }
/** One agent may not be both a tool of X and a handoff target of X. */
export function conflicts(g: AgentGraph): AgentEdge[] {
const seen = new Map<string, EdgeKind>();
const bad: AgentEdge[] = [];
for (const e of g.edges) {
const key = `${e.from}->${e.to}`;
const other = seen.get(key);
if (other && other !== e.kind) bad.push(e);
else seen.set(key, e.kind);
}
return bad;
}
/** Every agent reachable from the root, and at what depth. */
export function reachable(g: AgentGraph): Map<string, number> {
const depth = new Map([[g.root, 0]]);
const queue = [g.root];
while (queue.length) {
const id = queue.shift()!;
for (const e of g.edges.filter((x) => x.from === id)) {
if (depth.has(e.to)) continue;
depth.set(e.to, depth.get(id)! + 1);
queue.push(e.to);
}
}
return depth;
}Vingt lignes, deux bugs que vous trouveriez autrement en production. reachable trouve l’agent que personne ne peut atteindre — configuré, payé, jamais appelé. conflicts refuse l’arête qui est les deux sortes à la fois, ce qui semble pédant jusqu’à ce qu’on le lise à voix haute : le parent garde le contrôle et l’abandonne en même temps. Exécutez-le sur un système à cinq agents avec un orphelin et une arête double :
reachable: lead@0 billing@1 tax@1 dunning@1
orphans: ghost
conflicts: lead->taxCe qui traverse réellement la frontière
Lien vers la section : Ce qui traverse réellement la frontièreMaintenant la mesure pour laquelle cette section existe, et la seule du chapitre prise contre un vrai modèle plutôt qu’un modèle scripté.
Un client énonce une contrainte dans son premier message — notre compte est enregistré au Portugal, pas en Espagne ; tout ce qui touche à la fiscalité doit utiliser le Portugal — discute d’autre chose, puis pose une question à laquelle la facturation doit répondre. Le cas est transféré. Vingt-quatre essais, un pays et une entreprise différents à chaque fois, quatre payloads de transfert, puis on pose une question à l’agent receveur : dans quel pays le compte de ce client est-il enregistré ?
| ce qui a été transféré | payload moyen | la contrainte y était | le spécialiste s’en est souvenu | intervalle à 95 % |
|---|---|---|---|---|
| toute la conversation | 173 tokens | 24/24 | 20/24 — 83 % | 64–93 % |
| un résumé écrit par l’agent émetteur | 62 tokens | 1/24 | 0/24 — 0 % | 0–14 % |
| seulement le dernier message utilisateur | 61 tokens | 0/24 | 0/24 — 0 % | 0–14 % |
| un enregistrement typé | 69 tokens | 24/24 | 24/24 — 100 % | 86–100 % |
La troisième ligne est un contrôle et se comporte comme tel : le fait n’y est pas, donc il ne peut pas être rappelé. Les trois autres sont le résultat.
La transcription complète fait 173 tokens et fonctionne 83 % du temps, ses quatre échecs relevant du sujet du chapitre 24 plutôt que de celui-ci. L’enregistrement typé fait 69 tokens — sept de plus que le résumé — et fonctionne à chaque fois, parce que la contrainte se trouve dans un champ nommé plutôt que dans une phrase.
Et le résumé est la ligne à fixer. Il a échoué 24 fois sur 24, et la raison n’est pas que le lecteur l’a manquée. La contrainte n’est apparue que dans 1 des 24 résumés. L’agent receveur n’a pas été négligent ; on lui a remis un texte qui ne contenait pas la réponse. Un résumé est une compaction que vous n’avez pas écrite, produite par un modèle dont vous ne pouvez pas voir la fenêtre, optimisée pour se lire comme un résumé — et « le client dit que nos dossiers ont le mauvais pays » est exactement le type de clause qu’un résumeur supprime comme bruit procédural.
Une limite honnête à ce nombre : le résumeur est un modèle d’un demi-milliard de paramètres et un plus grand en garderait davantage. Ce qui ne s’améliore pas avec la taille, c’est la forme du risque — l’agent émetteur décide, par handoff, par formulation, de façon non observable, quels faits survivent. L’enregistrement typé ne dépend pas du tout de ce jugement, ce qui explique pourquoi il gagne par construction plutôt que par intelligence. Tout ce qui doit survivre à un transfert doit être un champ, pas une phrase.
Le même raisonnement s’applique dans l’autre sens, à la topologie agent-comme-outil, et le tableau précédent l’a déjà chiffré : ce qui revient d’un worker est aussi un résumé, et payer 8,3 % de plus pour recevoir les preuves avec lui est le même correctif vu du côté du parent.
Quand un agent gagne
Lien vers la section : Quand un agent gagneTrois faits de clôture, tous tirés des tableaux ci-dessus.
Un système multi-agent multiplie les appels, et les appels sont quadratiques en contexte. L’orchestrateur a fait 12 appels de modèle là où un agent en a fait 5, et chacun transporte sa propre transcription croissante — 3 628 tokens d’entrée contre 2 697, un écart qui s’élargit avec la longueur de la tâche.
Chaque frontière est un canal avec pertes. Deux agents signifient un résumé. Quatre agents en chaîne en signifient trois, composés, chacun écrit par un modèle optimisant pour autre chose que votre décision.
L’agent unique a trouvé quelque chose que personne n’avait demandé. La discordance du bon de commande est apparue parce qu’une fenêtre contenait à la fois la facture et la commande. Répartir le travail entre spécialistes, c’est aussi répartir la capacité à remarquer que deux faits se contredisent.
Rien de cela n’est un argument contre les frameworks multi-agent publiés, qui méritent d’être lus comme sources primaires plutôt qu’à travers des tutoriels.10 C’est un argument pour obliger le deuxième agent à mériter sa place.
Donc, un test plutôt qu’une préférence. Ajoutez un second agent quand au moins l’un de ces points est vrai : la sous-tâche a besoin d’une fenêtre propre que le parent ne doit pas hériter (chapitre 24) ; les sous-tâches sont réellement indépendantes et le temps réel compte, ce qui correspond au 1,8× ci-dessus ; la sous-tâche a besoin de permissions différentes ou d’un autre modèle, ce que le chapitre 30 transforme en argument de sécurité ; ou la sous-tâche appartient à quelqu’un d’autre, là où un vrai protocole commence à compter. Si la réponse est « pour que chaque agent ait un prompt plus clair », donnez un prompt plus clair à l’agent unique. C’est gratuit.
Où cela va ensuite
Lien vers la section : Où cela va ensuiteVous pouvez maintenant nommer les cinq patterns, les chiffrer les uns contre les autres sur une tâche, distinguer un orchestrateur d’un sectioner et un appel d’outil d’un handoff, et défendre un agent unique avec un tableau plutôt qu’une préférence.
Chaque organisation ici partageait une commodité qui ne survivra pas au contact du réel : tous les outils nous appartenaient. Facture, commande, tableau fiscal, les workers derrière l’orchestrateur — même dépôt, même deploy, mêmes types, mêmes personnes.
Mettez maintenant l’un d’eux de l’autre côté d’une frontière d’entreprise. Le tableau fiscal appartient à un fournisseur comptable, l’enregistrement de commande à un système d’entrepôt, et aucun des deux n’a lu votre interface Tool. Il vous faut un moyen pour qu’un modèle que vous n’avez pas écrit découvre, décrive et appelle une capacité exploitée par quelqu’un d’autre — avec authentification (qui est la moitié du chapitre 27), versioning, et la garantie qu’un serveur ne peut pas lire le reste de votre conversation. C’est un problème de protocole, il possède une spécification avec un schéma normatif, et presque tout ce qui est indexé à son sujet décrit une révision qui n’existe plus.
Le chapitre 26 lit cette spécification au lieu de la résumer, et commence par taper du JSON-RPC dans un terminal à la main.
Sources et méthode
Lien vers la section : Sources et méthodeChaque coût et chaque compte de tokens ci-dessus vient du fournisseur scripté décrit dans la deuxième section, sur Node 22 via une interface loopback, compté avec l’encodage o200k_base et tarifé aux prix que le chapitre 16 a relevés le 6 septembre 2026 — $2.00 par million de tokens d’entrée et $12.00 par million en sortie. Les chiffres de temps réel viennent des mêmes exécutions, avec la latence du fournisseur fixée à 400 ms par appel et celle des outils à 50 ms, afin qu’ils mesurent l’organisation plutôt qu’un fournisseur. Les deux mesures sur vrai modèle — le tableau de handoff et le tableau voting-and-judging — ont utilisé Qwen/Qwen2.5-0.5B-Instruct en float32 sur le CPU derrière un endpoint de même forme, greedy sauf quand une température est indiquée, avec des intervalles calculés par la méthode de Wilson du chapitre 4. Aucune requête de ce chapitre n’est partie vers un endpoint payant, et aucun chiffre n’y a été estimé.
Références
Lien vers la section : Références-
Anthropic, Building effective agents, 19 décembre 2024,
anthropic.com/engineering/building-effective-agents, lu le 7 septembre 2026. Source des cinq noms de workflows utilisés ci-dessus et de chaque formule qui en est citée — prompt chaining, routing, parallélisation avec ses variantes sectioning et voting, orchestrator-workers, evaluator-optimiser — ainsi que de la recommandation de trouver « la solution la plus simple possible, et de n’augmenter la complexité qu’en cas de besoin » et de l’observation selon laquelle « les systèmes agentiques échangent souvent latence et coût contre une meilleure performance de tâche ». Les chapitres 22 et 23 citent sa définition d’un agent. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 -
Wang, X., Wei, J., Schuurmans, D., Le, Q., Chi, E., Narang, S., Chowdhery, A. et Zhou, D. Self-Consistency Improves Chain of Thought Reasoning in Language Models. arXiv:2203.11171 (mars 2022). L’origine du pattern de voting, décrit là comme une stratégie de decoding plutôt que comme une architecture : échantillonner des chemins de raisonnement divers, puis « sélectionner la réponse la plus cohérente en marginalisant les chemins de raisonnement échantillonnés », avec des gains rapportés de +17,9 sur GSM8K, +11,0 sur SVAMP, +12,2 sur AQuA, +6,4 sur StrategyQA et +3,9 sur ARC-challenge. ↩
-
Madaan, A. et al. Self-Refine: Iterative Refinement with Self-Feedback. arXiv:2303.17651 (2023). La boucle evaluator-optimiser avec un modèle dans les trois rôles — « générateur, affineur et fournisseur de feedback » — améliorant « d’environ 20 % absolus en moyenne la performance de tâche » sur sept tâches, mesurée par préférence humaine et métriques automatiques plutôt que par le propre verdict du modèle. ↩
-
Shinn, N., Cassano, F., Berman, E., Gopinath, A., Narasimhan, K. et Yao, S. Reflexion: Language Agents with Verbal Reinforcement Learning. arXiv:2303.11366 (2023). Ajoute une mémoire épisodique d’autocritiques entre les tentatives — « renforcer les agents de langage non pas en mettant à jour les poids, mais par feedback linguistique » — rapportant 91 % de pass@1 sur HumanEval contre 80 % pour la baseline GPT-4. Notez l’exigence dont dépendent ses résultats : un vrai signal de l’environnement, comme un test en échec, plutôt que l’opinion du modèle sur lui-même. ↩ ↩2
-
Yao, S., Zhao, J., Yu, D., Du, N., Shafran, I., Narasimhan, K. et Cao, Y. ReAct: Synergizing Reasoning and Acting in Language Models. arXiv:2210.03629 (2022). Traces de raisonnement et actions entrelacées ; le chapitre 23 a construit cette boucle. Cité ici pour sa forme de coût plutôt que pour ses résultats : un appel de modèle par étape, avec toute la transcription renvoyée à chaque fois. ↩
-
Wang, L., Xu, W., Lan, Y., Hu, Z., Lan, Y., Lee, R. K.-W. et Lim, E.-P. Plan-and-Solve Prompting: Improving Zero-Shot Chain-of-Thought Reasoning by Large Language Models. arXiv:2305.04091 (2023). « D’abord, élaborer un plan pour diviser toute la tâche en sous-tâches plus petites, puis exécuter les sous-tâches selon le plan » — la forme plan-puis-exécution, et la source du compromis qui intéresse ce chapitre : le plan est fixé avant la première observation, ce qui est du prompt chaining avec une décomposition écrite par un modèle plutôt que par vous. ↩
-
Yao, S., Yu, D., Zhao, J., Shafran, I., Griffiths, T. L., Cao, Y. et Narasimhan, K. Tree of Thoughts: Deliberate Problem Solving with Large Language Models. arXiv:2305.10601 (2023). Recherche sur des « pensées » intermédiaires avec auto-évaluation et retour arrière ; 74 % sur Game of 24 contre 4 % pour le chain-of-thought prompting. Les chiffres de coût cités ci-dessus sont ceux de l’article, dans l’annexe B.3, tableau 7 : par cas, prompting entrée/sortie best-of-100 à $0.13 pour 33 %, chain of thought best-of-100 à $0.47 pour 49 %, et tree of thoughts à $0.74 pour 74 %, avec la note des auteurs selon laquelle ToT « pourrait nécessiter 5 à 100 fois plus de tokens générés que CoT ». ↩ ↩2
-
OpenAI, A practical guide to building agents (PDF), lu le 7 septembre 2026. La séparation manager-versus-decentralised, le cadrage en graphe cité ci-dessus (« dans le pattern manager, les arêtes représentent des appels d’outils tandis que dans le pattern decentralized, les arêtes représentent des handoffs »), et la définition d’un handoff comme « un transfert à sens unique... nous lançons immédiatement l’exécution sur ce nouvel agent auquel le handoff a été fait, tout en transférant aussi l’état de conversation le plus récent ». Notez ce que cette dernière clause tranche : dans ce SDK, l’état de conversation voyage bien, ce qui est une décision de conception de cette bibliothèque et non une propriété des handoffs en général. ↩ ↩2
-
Agent2Agent (A2A) Protocol Specification, dernière version publiée 1.0.0,
a2a-protocol.org/latest/specification/, lu le 7 septembre 2026 ; copyright Linux Foundation, Apache-2.0. Cité ci-dessus : un « standard ouvert conçu pour faciliter la communication et l’interopérabilité entre systèmes AI agent indépendants, potentiellement opaques », et le principe d’exécution opaque — les agents « collaborent sur la base de capacités déclarées et d’informations échangées, sans devoir partager leurs pensées internes, leurs plans ou leurs implémentations d’outils ». La page comporte un historique de versions (0.1.0, 0.2.6, 0.3.0, 1.0.0), une annexe de changements incompatibles et une annexe sur sa relation avec MCP. Le chapitre 26 fait cette comparaison. ↩ -
Les frameworks multi-agent que ce chapitre n’enseigne pas, pour le lecteur qui veut les sources primaires plutôt qu’un tutoriel : Wu, Q. et al., AutoGen: Enabling Next-Gen LLM Applications via Multi-Agent Conversation, arXiv:2308.08155 (2023), où les agents sont « personnalisables, conversables » et la conversation elle-même est le modèle de programmation ; Hong, S. et al., MetaGPT: Meta Programming for a Multi-Agent Collaborative Framework, arXiv:2308.00352 (2023), qui encode des procédures opérationnelles standard dans des prompts de rôle et indique explicitement que « les solutions à des tâches plus complexes se compliquent par des incohérences logiques dues à des hallucinations en cascade causées par un chaining naïf de LLMs » — la chaîne assurée et fausse mesurée en haut de ce chapitre, nommée dans un résumé ; et Park, J. S. et al., Generative Agents: Interactive Simulacra of Human Behavior, arXiv:2304.03442 (2023), vingt-cinq agents avec mémoire, réflexion et planification, ce qui est la plus grande réponse publiée à « que se passe-t-il si vous continuez à ajouter des agents ». ↩