+210 XP

Orchestration multi-agents avec l'ADK

Un seul agent ne suffit souvent pas : dès qu'un workflow nécessite un chercheur, un rédacteur et un relecteur, tout entasser dans un seul prompt donne un fouillis fragile d'instructions « fais d'abord ceci, puis cela, mais seulement si… » que le modèle suit à moitié. L'Agent Development Kit (ADK) existe pour découper ce travail en spécialistes et les relier par un flux de contrôle explicite.

Vous savez déjà ce qu'est un agent : un modèle, des tools et une boucle. Cette leçon porte sur **la composition de *plusieurs* d'entre eux en un seul système, et sur le moment où cette mécanique supplémentaire est rentable**.

Les trois primitives d'orchestration

L'ADK vous donne des agents sous forme d'objets composables. Un LlmAgent classique raisonne et appelle des tools. Mais l'ADK fournit aussi des workflow agents : des agents dont le seul rôle est d'exécuter *d'autres* agents selon un schéma défini. Il y en a trois à connaître.

Sequential : les étapes d'un pipeline

SequentialAgent exécute ses sous-agents l'un après l'autre. La sortie circule vers l'avant via un état de session partagé. À utiliser quand l'étape B dépend réellement du résultat de l'étape A : recherche, puis rédaction, puis édition.

Parallel : répartir du travail indépendant

ParallelAgent exécute ses sous-agents en simultané. Chacun écrit dans sa propre clé de l'état de session. À utiliser quand les tâches sont indépendantes et que vous voulez qu'elles se terminent dans le temps de la plus lente, pas dans la somme de toutes. Par exemple : résumer trois documents d'un coup, ou interroger trois sources de données en parallèle.

Coordinator : aiguiller par décision

Un coordinator est un LlmAgent normal auquel d'autres agents sont enregistrés comme sub_agents. Au lieu de tout exécuter, le coordinator *lit la requête et décide* quel spécialiste doit la traiter, puis lui transfère le contrôle. C'est le pattern dynamique : le modèle fait le routage au runtime plutôt que de suivre un ordre figé.

La distinction clé : sequential et parallel sont *déterministes* (vous avez décidé le flux au moment de la construction). Un coordinator est *piloté par le modèle* (le LLM décide du flux requête par requête). Les vrais systèmes mélangent les trois.

Quand le multi-agents l'emporte sur l'agent unique

Découper a un coût réel, il faut donc le justifier. Une conception multi-agents gagne quand :

  • Les rôles ont besoin de tools ou d'instructions différents. Un agent de recherche a besoin du grounding Google Search ; un agent de rédaction a besoin d'une charte éditoriale et d'aucun accès au web. Des agents séparés gardent chaque prompt court et chaque ensemble de tools bien cadré.
  • Vous voulez du parallélisme. Un agent seul ne peut pas vraiment faire deux choses à la fois. Répartir réduit le temps réel écoulé.
  • Vous voulez de l'isolation et de la testabilité. Vous pouvez tester unitairement l'agent « relecteur » seul, passer son modèle de Gemini Pro à Flash, sans toucher au reste.
  • Le contexte devient encombré. Même avec le contexte long de Gemini, entasser notes de recherche, règles de style et historique de rédaction dans une même fenêtre dégrade la concentration. Les spécialistes gardent chaque contexte léger.

Ce que ça vous coûte : plus de pièces mobiles, plus d'endroits où la latence s'accumule, un debug plus difficile (quel agent a produit la mauvaise sortie ?), et plus de tokens au total parce que les agents rétablissent le contexte à chaque passage de relais. Si un prompt clair avec deux tools fait le travail, utilisez un seul agent. Passez à l'orchestration quand les coutures ci-dessus commencent à faire mal.

Un exemple concret : un coordinator qui répartit entre recherche et rédaction

Construisons le pipeline de contenu classique. Un coordinator reçoit un sujet. Il répartit vers un agent de recherche (qui utilise le grounding Google Search) et un agent de rédaction en parallèle, puis une étape finale assemble les résultats.

Ici la répartition est réellement parallèle : la recherche et un plan peuvent démarrer simultanément, puis un rédacteur les combine. Nous composons un `ParallelAgent` à l'intérieur d'un `SequentialAgent`.

python
from google.adk.agents import LlmAgent, ParallelAgent, SequentialAgent
from google.adk.tools import google_search

# Spécialiste 1 : collecte des faits sourcés avec Google Search
researcher = LlmAgent(
    name="researcher",
    model="gemini-2.5-flash",
    instruction=(
        "Research the given topic. Return 5-7 concise, cited bullet points "
        "of current, verifiable facts. Do not write prose."
    ),
    tools=[google_search],
    output_key="research_notes",
)

# Spécialiste 2 : propose une structure en parallèle, sans accès au web
outliner = LlmAgent(
    name="outliner",
    model="gemini-2.5-flash",
    instruction=(
        "Propose a tight 4-section outline for an article on the topic. "
        "Headings only, no body text."
    ),
    output_key="outline",
)

# Répartition : recherche et plan s'exécutent en même temps
gather = ParallelAgent(
    name="gather",
    sub_agents=[researcher, outliner],
)

# Étape finale : lit les deux clés d'état et écrit le brouillon
writer = LlmAgent(
    name="writer",
    model="gemini-2.5-pro",
    instruction=(
        "Write a 500-word article. Use the outline in {outline} for "
        "structure and only the facts in {research_notes} for claims. "
        "House style: plain, direct, no hype."
    ),
    output_key="draft",
)

# Coordinator : collecte en parallèle, puis rédaction
content_pipeline = SequentialAgent(
    name="content_pipeline",
    sub_agents=[gather, writer],
)

Lisez le flux de données, car c'est là que se joue réellement l'orchestration :

  • output_key="research_notes" indique à l'ADK d'écrire la sortie finale du chercheur dans l'état de session sous cette clé.
  • L'outliner écrit dans outline, en s'exécutant en simultané au sein de gather.
  • Le writer lit les deux via les placeholders de template {research_notes} et {outline} dans son instruction. L'ADK substitue les valeurs d'état avant l'envoi du prompt.
  • SequentialAgent garantit que gather se termine entièrement avant que writer ne démarre, donc les deux clés existent au moment où le rédacteur s'exécute.

Notez le choix des modèles. La recherche et le plan vont à Gemini Flash : rapide, peu coûteux, gros volume. Le brouillon final, là où la qualité compte le plus, va à Gemini Pro. Mélanger les gammes de modèles par agent est l'un des plus grands gains pratiques du design multi-agents, et quelque chose qu'un agent unique ne peut pas faire.

L'exécuter

L'ADK vous donne une boucle de développement locale. Depuis le répertoire de votre projet :

bash
pip install google-adk
adk web

adk web lance une interface navigateur où vous envoyez des entrées, regardez chaque sous-agent se déclencher et inspectez l'état de session clé par clé. Quand le rédacteur produit n'importe quoi, vous regardez d'abord research_notes et outline : s'ils étaient mauvais, la faute est en amont, pas chez le rédacteur. Cette traçabilité est le bénéfice pratique d'une orchestration explicite.

Le coordinator comme routeur : la variante dynamique

L'exemple ci-dessus fige le flux dans le code. Parfois, vous voulez que le modèle décide. Supposons que certaines requêtes nécessitent de la recherche et d'autres soient de pures réécritures. Faites du coordinator un `LlmAgent` avec les spécialistes en `sub_agents` :

python
coordinator = LlmAgent(
    name="coordinator",
    model="gemini-2.5-pro",
    instruction=(
        "You route requests. If the user asks for new content about a "
        "topic, delegate to 'content_pipeline'. If they paste existing "
        "text to improve, delegate to 'editor'. Never answer directly."
    ),
    sub_agents=[content_pipeline, editor],
)

Le LLM lit désormais l'intention et *transfère* au bon sous-agent. C'est ce qu'on appelle l'agent transfer dans l'ADK : le contrôle (et la conversation) passe au sous-agent choisi, qui peut le retransférer en arrière ou à un pair. Puissant, mais le compromis est réel : le routage est maintenant une décision du modèle, donc il peut être faux. Pour les flux à fort enjeu, préférez SequentialAgent/ParallelAgent déterministes et gardez le routage piloté par le modèle pour les intentions réellement ramifiées.

Build multi-agent systems with the Agent Development Kit

Watch on YouTube

Vérification des acquis

1. Qu'est-ce qui distingue fondamentalement un coordinator d'un SequentialAgent ou d'un ParallelAgent ?

2. Dans quel scénario un SequentialAgent est-il le choix le plus approprié ?

3. Pourquoi un ParallelAgent termine-t-il un ensemble de tâches dans le temps de la plus lente plutôt que dans la somme de toutes ?

CHOIX MULTIPLES

4. Sélectionnez TOUTES les raisons données par la leçon pour découper un workflow en plusieurs agents plutôt que d'en utiliser un seul.

Sélectionnez toutes les réponses correctes.

CHOIX MULTIPLES

5. Sélectionnez TOUTES les affirmations qui décrivent correctement les primitives d'orchestration de l'ADK.

Sélectionnez toutes les réponses correctes.

Tools, grounding et environnement d'exécution

Deux choses rendent ces agents utiles plutôt qu'académiques.

Le grounding avec Google Search. Le tool google_search donne au chercheur des résultats en direct et sourcés au lieu de données d'entraînement périmées. C'est la différence entre « les faits à la date de coupure d'entraînement du modèle » et « les faits de ce matin ». Réservez-le au seul agent qui en a besoin : votre agent de rédaction ne doit pas inventer discrètement des citations, alors ne lui donnez aucun tool de recherche et forcez-le à s'appuyer sur l'état.

Les sous-agents peuvent aussi être des tools. Au-delà des sub_agents (qui passent le contrôle), l'ADK vous permet d'encapsuler un agent en tool appelable via AgentTool. La différence compte : un sous-agent prend en charge le tour de parole, tandis qu'un agent-en-tant-que-tool renvoie un résultat à l'appelant, comme n'importe quelle fonction. Utilisez AgentTool quand le coordinator doit rester aux commandes et simplement « consulter » un spécialiste en cours de raisonnement ; utilisez sub_agents quand vous voulez un passage de relais net.

Où ça se déploie. Vous prototypez en local avec adk web ou adk run. Pour la production, la même définition d'agent se déploie sur Vertex AI Agent Engine, le runtime managé de Google qui gère les sessions, le scaling et le tracing, pour que vous n'exécutiez pas la boucle d'orchestration sur votre propre serveur. Vous pouvez aussi la containeriser et l'exécuter sur Cloud Run. L'essentiel : le code ci-dessus ne change pas entre votre laptop et la production. Vous configurez des identifiants et une cible, pas une architecture.

Garde-fous pratiques

Quelques points qui séparent une démo de quelque chose que vous mettriez en production :

  • Nommez et décrivez chaque agent clairement. Quand un coordinator route par décision du modèle, il s'appuie sur le name et la description de chaque sous-agent pour choisir. Des descriptions vagues provoquent des erreurs de routage. Écrivez-les comme si vous rédigiez une doc de tool pour le modèle, car c'est exactement ce qu'elles sont.
  • Gardez des clés d'état explicites et peu nombreuses. Chaque output_key est un contrat entre un producteur et un consommateur. Moins de clés, bien nommées, signifie moins de décalages silencieux.
  • Surveillez le coût en tokens aux coutures. Chaque passage de relais peut rejouer le contexte. Si vos branches parallèles sont volumineuses, elles se multiplient. Envoyez la recherche volumineuse à Flash, réservez Pro pour l'étape de synthèse, et élaguez ce que chaque agent transmet en aval.
  • Testez d'abord les agents isolément. Exécutez le chercheur seul avec un sujet fixe jusqu'à ce que sa sortie soit fiable. Ensuite seulement, branchez-le dans le pipeline. Debugger un système de cinq agents de bout en bout est pénible ; debugger un agent est facile.
  • Échouez bruyamment. Décidez ce que fait le rédacteur si research_notes revient vide. Une instruction de production doit dire « si aucune recherche n'est fournie, arrête-toi et signale-le », pas halluciner en silence.

Points clés à retenir

  • Utilisez `SequentialAgent` pour les étapes dépendantes, `ParallelAgent` pour le travail indépendant, et un coordinator `LlmAgent` pour le routage au runtime. Un flux déterministe est plus fiable ; gardez le routage piloté par le modèle pour les intentions réellement ramifiées.
  • Les clés d'état sont le câblage. output_key écrit dans l'état de session et {placeholder} le relit. Gardez peu de clés, nommées, et traitées comme des contrats entre agents.
  • Mélangez les gammes de modèles par agent. Envoyez la recherche et le plan à gros volume vers Gemini Flash, réservez Gemini Pro pour l'étape de synthèse critique en qualité. Ce choix par agent est une raison centrale de découper.
  • Réservez les tools à l'agent qui en a besoin. Donnez le grounding Google Search uniquement au chercheur ; refusez-le au rédacteur pour qu'il ne puisse pas inventer de citations.
  • Prototypez avec `adk web`, déployez le même code sur Vertex AI Agent Engine. Ne découpez en plusieurs agents que lorsque les rôles, les tools, le parallélisme ou la pression sur le contexte justifient la surface de debug supplémentaire.