Claude Platform Docs
Managed AgentsOrchestration avancée

Orchestration multi-agents

Coordonnez plusieurs agents au sein d'une même session.

L'orchestration multi-agents permet à un agent de se coordonner avec d'autres pour accomplir un travail complexe. Les agents peuvent agir en parallèle avec leur propre contexte isolé, ce qui contribue à améliorer la qualité des résultats et peut également réduire le délai d'achèvement.

Vous n'êtes pas sûr qu'une configuration multi-agents convienne à votre problème ? Consultez quand utiliser des systèmes multi-agents (et quand ne pas le faire).

Fonctionnement

Tous les agents partagent le même sandbox, le même système de fichiers et les mêmes identifiants de coffre-fort, mais chaque agent s'exécute dans son propre « session thread » (fil de session), un flux d'événements isolé en contexte avec son propre historique de conversation. Le coordinateur rapporte son activité dans le « primary thread » (fil principal) (qui est identique au flux d'événements au niveau de la session) ; des fils supplémentaires sont créés à l'exécution lorsque le coordinateur délègue du travail.

Les fils sont persistants : le coordinateur peut envoyer un message de suivi à un agent qu'il a appelé précédemment, et cet agent conserve tout ce qui provient de ses tours précédents.

Chaque agent utilise sa propre configuration : modèle, invite système, outils, serveurs MCP et skills. Les surcharges de configuration d'agent au niveau de la session constituent l'exception ; elles s'appliquent au coordinateur et à ses copies self. Les outils, les serveurs MCP et le contexte ne sont pas partagés.

Que déléguer

La coordination multi-agents convient le mieux aux tâches complexes qui nécessitent soit un travail sur une variété de surfaces, soit plusieurs tâches bien délimitées contribuant à un objectif global.

Modèles qui fonctionnent bien :

  • Parallélisation : répartissez simultanément des sous-tâches indépendantes (recherche dans plusieurs sources, analyse de fichiers distincts) et laissez le coordinateur synthétiser les résultats.
  • Spécialisation : orientez vers des agents dotés d'invites système et d'outils axés sur un domaine, comme un agent de sécurité ou un agent de documentation, plutôt que de charger un seul agent de toutes les capacités.
  • Escalade : consultez un agent ou un modèle plus performant pour un sous-ensemble de sous-tâches complexes.

Configurer le coordinateur

Lors de la définition de votre agent, définissez multiagent pour déclarer la liste des agents auxquels le coordinateur peut déléguer :

ant beta:agents create < coordinator.agent.yaml
coordinator.agent.yaml
name: Engineering Lead
model: claude-opus-5
system: You coordinate engineering work. Delegate code review to the reviewer agent and test writing to the test agent.
tools:
  - type: agent_toolset_20260401
multiagent:
  type: coordinator
  agents:
    - type: agent
      id: $REVIEWER_AGENT_ID # replace before running command
    - type: agent
      id: $TEST_WRITER_AGENT_ID # replace before running command

multiagent.agents peut accepter l'une des formes suivantes :

  • {"type": "agent", "id": agent.id} référence un agent précédemment créé par son ID. Si aucune version n'est spécifiée, la référence est épinglée à la dernière version de cet agent au moment de la création du coordinateur.
  • {"type": "agent", "id": agent.id, "version": agent.version} épingle une version spécifique de l'agent.
  • {"type": "self"} permet au coordinateur de créer des copies de lui-même. Si la session a été créée avec des surcharges de configuration d'agent, ces surcharges s'appliquent également à ces copies ; les entrées de la liste référencées par ID ne sont pas affectées.
  • {"type": "advisor", "model": "<model id>"} donne au fil principal de la session un conseiller qu'il peut consulter en cours de tour. Au plus une entrée de conseiller par liste. Consultez Donner un conseiller à la session.

La configuration du coordinateur, y compris sa liste multiagent.agents, fait l'objet d'un instantané lorsque le coordinateur est créé ou mis à jour. Les agents référencés restent épinglés aux versions résolues à ce moment-là et ne récupèrent pas automatiquement les mises à jour ultérieures de leurs définitions. Pour déléguer à une version plus récente d'un agent référencé, mettez à jour le coordinateur afin que sa liste référence cette version.

Le coordinateur ne peut déléguer qu'à un seul niveau d'agents ; référencer un agent qui possède sa propre liste multiagent.agents fait échouer la requête de création ou de mise à jour avec une erreur de validation. Un maximum de 20 agents uniques peuvent être listés dans multiagent.agents, mais le coordinateur peut appeler plusieurs copies de chaque agent.

Lorsque les agents épinglent une géographie d'inférence (model.inference_geo dans la définition de l'agent), l'épinglage du coordinateur et celui de chaque membre de la liste doivent soit tous être définis à la même valeur, soit tous être non définis. Une liste incohérente est rejetée avec une erreur de validation 400, aussi bien lorsque l'agent est enregistré que lorsqu'une surcharge à la création de session modifie l'un des épinglages.

Donner un conseiller à la session

Une entrée de conseiller dans multiagent.agents donne au fil principal de la session un « advisor » (conseiller) : un modèle qu'il peut consulter en cours de tour pour obtenir des orientations stratégiques, comme planifier une approche, se débloquer ou relire un travail avant de terminer. L'entrée comporte exactement deux champs, type et model :

cURL
curl -fsS https://api.anthropic.com/v1/agents \
  -H "x-api-key: $ANTHROPIC_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "anthropic-beta: managed-agents-2026-04-01" \
  -H "content-type: application/json" \
  -d '{
    "name": "Backend engineer",
    "model": "claude-sonnet-5",
    "system": "You implement backend features end to end. Consult the advisor before major backend design decisions.",
    "multiagent": {
      "type": "coordinator",
      "agents": [
        {"type": "advisor", "model": "claude-opus-5"}
      ]
    }
  }'

Une liste peut contenir au plus une entrée de conseiller, aux côtés de n'importe laquelle des autres formes d'entrée. L'entrée occupe le nom réservé anthropic.advisor : une liste qui contient à la fois une entrée de conseiller et un membre littéralement nommé anthropic.advisor est rejetée avec une erreur de validation 400. Dans les réponses, l'entrée de conseiller est renvoyée en dernier dans la liste, quelle que soit la position à laquelle elle a été soumise.

Le modèle conseiller doit satisfaire un seuil minimal de capacité, et le propre modèle de l'agent ne doit pas être plus performant que son conseiller ; des modèles de capacité égale peuvent être associés. Une association invalide est rejetée avec une erreur de validation 400 lorsque l'agent est enregistré. Les associations valides suivent le tableau de compatibilité des modèles de l'outil conseiller.

Le conseiller est également disponible en tant qu'outil serveur sur l'API Messages. La surface Managed Agents diffère en matière de configuration et de livraison : l'entrée de liste ne comporte pas de champs max_uses, max_tokens ni caching, et les conseils arrivent via des événements de fil plutôt que via des blocs advisor_tool_result.

Fonctionnement des consultations

Chaque consultation s'exécute sous la forme d'un fil créé par la plateforme, nommé anthropic.advisor, qui se termine de lui-même lorsque la consultation est achevée, et le conseil est livré au fil principal sous la forme d'un événement agent.thread_message_received. Une consultation émet les événements de fil standard, identifiés par le nom réservé anthropic.advisor (les événements de cycle de vie du fil le portent en tant que agent_name, et la livraison du conseil le porte en tant que from_agent_name), généralement dans cet ordre :

  1. session.thread_created
  2. session.thread_status_running
  3. agent.thread_message_received (le conseil)
  4. session.thread_status_idle (stop_reason: end_turn)
  5. session.thread_status_terminated

Aucun événement agent.tool_use n'est émis pour une consultation, et aucun événement agent.thread_message_sent n'apparaît sur le flux d'événements de la session, car l'entrée de la consultation est composée par la plateforme plutôt qu'envoyée par l'agent. Si vous listez les propres événements du fil du conseiller, le conseil y apparaît également sous la forme d'un événement agent.thread_message_sent. Il n'est pas garanti que la livraison du conseil (événement 3) arrive avant les événements idle et terminated du fil du conseiller ; ne considérez donc pas ceux-ci comme un signal indiquant que le conseil a déjà été livré.

La possibilité pour votre client de lire le conseil relève de la politique du modèle conseiller, et elle reflète la distinction des variantes de résultat de l'outil conseiller de l'API Messages. Les modèles conseillers qui y renvoient des résultats en texte clair livrent ici le conseil sous forme de contenu textuel lisible ; les modèles conseillers qui y renvoient des résultats masqués livrent un espace réservé [{"type": "redacted"}] comme contenu du message sur toutes les surfaces client, tandis que l'agent lui-même lit toujours le conseil complet côté serveur. Dans l'exemple précédent, Claude Opus 5 est un conseiller à résultat masqué ; votre client voit donc l'espace réservé tandis que l'agent lit le conseil complet ; choisissez plutôt Claude Opus 4.8 comme conseiller si vous souhaitez que le conseil soit lisible sur le flux d'événements. La réflexion du conseiller n'est jamais exposée. Les clients ne peuvent pas envoyer eux-mêmes de blocs redacted ; un événement en contenant un est rejeté avec une erreur de validation 400.

Une consultation échouée ou interrompue ne fait jamais échouer le tour de l'agent : l'agent poursuit après un avis générique indiquant que la consultation a échoué. Un user.interrupt au niveau de la session pendant une consultation termine le fil du conseiller sans qu'aucun conseil ne soit livré ; un user.interrupt avec le session_thread_id du fil du conseiller abandonne uniquement cette consultation.

Fils du conseiller

Le conseiller n'est pas un agent de la liste : il est invisible pour l'outil list_agents du coordinateur, il ne peut pas recevoir de message via send_to_agent, et seul le fil principal de la session peut le consulter. Les agents de la liste ne le peuvent pas.

Les fils du conseiller sont exemptés de la limite de fils simultanés. Ils apparaissent dans la liste des fils de la session avec agent défini sur la forme conseiller exactement telle que configurée ({"type": "advisor", "model": ...}) et parent_thread_id défini sur le fil principal.

La mise en cache des prompts du côté du conseiller est automatique ; il n'y a rien à configurer. Les consultations sont facturées aux tarifs du modèle conseiller, et leurs jetons apparaissent dans l'utilisation du fil du conseiller et dans les totaux d'utilisation de la session.

Supprimer le conseiller

Pour supprimer le conseiller, mettez à jour l'agent avec une liste qui n'inclut plus l'entrée de conseiller. Si le conseiller est la seule entrée de la liste, videz entièrement la liste en définissant "multiagent": null.

Créer la session

Créez une session référençant le coordinateur. Le coordinateur délègue aux agents de sa liste selon les besoins.

session = client.beta.sessions.create(
    agent=coordinator.id,
    environment_id=environment.id,
)

Connecter les agents aux serveurs MCP

Les serveurs MCP ont une portée au niveau de l'agent (chaque définition d'agent déclare ses propres serveurs et outils), tandis que les identifiants de coffre-fort ont une portée au niveau de la session (les vault_ids transmis à la création de la session s'appliquent à chaque fil). Deux implications pour votre intégration :

  • Pour authentifier les serveurs MCP, incluez un identifiant de coffre-fort pour chaque serveur MCP utilisé par l'ensemble des agents.
  • Pour limiter l'accès d'un agent, déclarez uniquement les serveurs dont il a besoin dans sa définition d'agent.

Les surcharges de configuration d'agent à la création de la session peuvent remplacer les serveurs MCP du coordinateur et ceux de ses copies self.

research_agent = client.beta.agents.create(
    name="researcher",
    model="claude-haiku-4-5",
    mcp_servers=[
        {"type": "url", "name": "github", "url": "https://api.githubcopilot.com/mcp/"},
    ],
    tools=[{"type": "mcp_toolset", "mcp_server_name": "github"}],
)

coordinator = client.beta.agents.create(
    name="coordinator",
    model="claude-opus-5",
    tools=[{"type": "agent_toolset_20260401"}],
    multiagent={
        "type": "coordinator",
        "agents": [{"type": "agent", "id": research_agent.id}],
    },
)

session = client.beta.sessions.create(
    agent=coordinator.id,
    environment_id=environment.id,
    vault_ids=[vault.id],
)
print(session.id)

Dans cet exemple, seul le chercheur déclare le serveur MCP GitHub ; le coordinateur n'y a donc pas accès. Les vault_ids de la session fournissent l'identifiant GitHub au fil du chercheur.

Fils

Le flux d'événements au niveau de la session (/v1/sessions/{session_id}/events/stream) est considéré comme le fil principal, contenant une vue condensée de toute l'activité de l'ensemble des fils. Vous ne voyez pas l'activité complète des sous-agents, mais vous voyez le début et la fin de leur travail, ainsi que les événements bloquants tels que les demandes d'autorisation d'outil.

Les fils de session sont l'endroit où vous explorez en détail l'activité d'un agent spécifique.

Le status de la session est une agrégation de toute l'activité des agents ; si au moins un fil est running, alors le statut global de la session est également running.

Un budget de session est un plafond unique partagé entre tous les fils d'une session. Lorsque le plafond est atteint, les fils se mettent en pause indépendamment, et le coût de chaque fil est calculé au tarif du modèle effectivement servi pour ce fil.

Listez tous les fils associés à une session comme suit :

for thread in client.beta.sessions.threads.list(session.id):
    print(f"[{thread.agent.name}] {thread.status}")

La liste complète inclut le fil principal. parent_thread_id est null pour le fil principal.

Événements du fil principal

Ces événements exposent l'activité multi-agents sur le fil principal à l'adresse /v1/sessions/{session_id}/events/stream. Les événements de direction de message sont nommés relativement au fil sur le flux duquel ils apparaissent : agent.thread_message_received signifie qu'un message est arrivé sur ce fil depuis un autre fil, et agent.thread_message_sent signifie que ce fil en a envoyé un. La tâche que le coordinateur délègue, par exemple, arrive sur le propre flux de l'enfant sous la forme d'un événement agent.thread_message_received.

TypeDescription
session.thread_createdUn fil a été créé. Inclut session_thread_id et agent_name.
session.thread_status_runningUn fil a démarré une activité.
session.thread_status_idleL'agent associé au fil attend une entrée. Inclut un stop_reason indiquant pourquoi l'agent s'est arrêté.
session.thread_status_terminatedUn fil a été archivé ou a rencontré une erreur terminale.
agent.thread_message_receivedSur le fil principal, un agent a envoyé un rapport ou une question au coordinateur. Inclut from_session_thread_id, from_agent_name et content.
agent.thread_message_sentSur le fil principal, le coordinateur a envoyé une tâche ou un message de suivi à un autre agent. Inclut to_session_thread_id, to_agent_name et content.

Les consultations du conseiller émettent ces mêmes événements de fil sous le nom réservé anthropic.advisor (en tant que agent_name sur les événements de cycle de vie du fil et from_agent_name sur la livraison du conseil) ; consultez Donner un conseiller à la session pour la séquence.

Événements des fils de session

Les événements critiques sont relayés vers le fil principal. Cependant, vous pourriez tout de même vouloir examiner le raisonnement et les appels d'outils d'un agent spécifique. Pour ce faire, diffusez en streaming ou listez les événements du fil de session associé.

Chaque fil de session possède son propre flux d'événements à l'adresse /v1/sessions/{session_id}/threads/{thread_id}/stream, et il accepte le même paramètre event_deltas[] que le flux au niveau de la session, de sorte que vous pouvez prévisualiser le texte d'un sous-agent au fur et à mesure que le modèle le génère. Une connexion ne prévisualise que le fil qu'elle lit : les aperçus d'un fil enfant n'apparaissent jamais sur le flux au niveau de la session ; pour suivre un sous-agent en direct, ouvrez donc son propre flux de fil. Consultez Prévisualiser les événements des fils de session pour savoir comment activer, accumuler et rapprocher les aperçus.

with client.beta.sessions.threads.events.stream(
    thread.id,
    session_id=session.id,
) as stream:
    for event in stream:
        match event.type:
            case "agent.message":
                for block in event.content:
                    if block.type == "text":
                        print(block.text, end="")
            case "session.thread_status_idle":
                break

Autorisations d'outils et outils personnalisés

Si un sous-agent a besoin de quelque chose de la part de votre client, comme une autorisation pour exécuter un outil always_ask, ou le résultat d'un outil personnalisé, l'événement est republié sur le fil principal avec session_thread_id identifiant le fil de session d'origine.

{
  "type": "session.thread_status_idle",
  "id": "sevt_01ABC...",
  "session_thread_id": "sth_01DEF...",
  "agent_name": "code-reviewer",
  "stop_reason": {
    "type": "requires_action",
    "event_ids": ["sevt_01XYZ..."]
  }
}

Publiez user.tool_confirmation (avec tool_use_id) ou user.custom_tool_result (avec custom_tool_use_id) ; le serveur achemine automatiquement la réponse vers le bon fil.

L'exemple suivant étend le gestionnaire de confirmation d'outil pour acheminer les réponses. Le même modèle s'applique à user.custom_tool_result.

for event_id in stop.event_ids:
    client.beta.sessions.events.send(
        session.id,
        events=[
            {
                "type": "user.tool_confirmation",
                "tool_use_id": event_id,
                "result": "allow",
            }
        ],
    )

Was this page helpful?