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 temps d'exécution.
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).
Les requêtes de l'API Managed Agents nécessitent l'en-tête bêta managed-agents-2026-04-01, à l'exception des points de terminaison du magasin de mémoire, qui utilisent agent-memory-2026-07-22 à la place. Le SDK définit automatiquement l'en-tête bêta correct. Consultez En-têtes bêta.
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 fil de session (session thread), un flux d'événements isolé au niveau du contexte avec son propre historique de conversation. Le coordinateur rapporte l'activité dans le fil principal (primary thread) (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 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 compétences. Les remplacements de configuration d'agent au niveau de la session constituent l'exception ; ils s'appliquent au coordinateur et à ses copies self. Les outils, les serveurs MCP et le contexte ne sont pas partagés.
La coordination multi-agents convient le mieux aux tâches complexes qui nécessitent soit un travail sur une variété de surfaces, soit lorsque plusieurs tâches bien délimitées contribuent à un objectif global.
Modèles qui fonctionnent bien :
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 <<YAML
name: Engineering Lead
model: claude-opus-4-8
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
- type: agent
id: $TEST_WRITER_AGENT_ID
YAMLmultiagent.agents peut accepter l'un des éléments suivants :
{"type": "agent", "id": agent.id} référence un agent créé précédemment 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 remplacements de configuration d'agent, ces remplacements s'appliquent également à ces copies ; les entrées de la liste référencées par ID ne sont pas affectées.La configuration du coordinateur, y compris sa liste multiagent.agents, est capturée lors de la création ou de la mise à jour du coordinateur. 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 peut être listé dans multiagent.agents, mais le coordinateur peut appeler plusieurs copies de chaque agent.
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,
)Les serveurs MCP sont limités à l'agent (chaque définition d'agent déclare ses propres serveurs et outils), tandis que les identifiants de coffre-fort sont limités à la session (les vault_ids transmis à la création de la session s'appliquent à chaque fil). Deux implications pour votre intégration :
Les remplacements 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-4-8",
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, donc le coordinateur n'y a pas accès. Les vault_ids de la session fournissent l'identifiant GitHub au fil du chercheur.
Si les appels MCP d'un agent échouent à s'authentifier après que vous avez déclaré le serveur, vérifiez que le mcp_server_url de l'identifiant fait référence au même serveur que le mcp_servers[].url de l'agent. Les deux URL sont normalisées avant la correspondance (schéma et hôte en minuscules, ports par défaut et barres obliques finales supprimés), de sorte que les différences de casse de l'hôte, un port par défaut ou une barre oblique finale n'empêchent pas une correspondance ; un chemin, un sous-domaine ou un port non par défaut différent, si.
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é sur tous les 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 de permission d'outil.
Les fils de session sont l'endroit où vous explorez 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 maximum de 25 fils simultanés est pris en charge. Le coordinateur peut appeler plusieurs copies d'un même agent de la liste, créant ainsi plusieurs fils associés à un seul agent.
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.
Ces événements font apparaître l'activité multi-agents sur le fil principal à /v1/sessions/{session_id}/events/stream. Les événements de direction de message sont nommés par rapport 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.
| Type | Description |
|---|---|
session.thread_created | Un fil a été créé. Inclut session_thread_id et agent_name. |
session.thread_status_running | Un fil a démarré une activité. |
session.thread_status_idle | L'agent associé au fil attend une entrée. Inclut un stop_reason indiquant pourquoi l'agent s'est arrêté. |
session.thread_status_terminated | Un fil a été archivé ou a rencontré une erreur terminale. |
agent.thread_message_received | Sur 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_sent | Sur 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 é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 ou listez les événements du fil de session associé.
Chaque fil de session possède son propre flux d'événements à /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 prévisualisations d'un fil enfant n'apparaissent jamais sur le flux au niveau de la session, donc pour observer un sous-agent en direct, ouvrez son propre flux de fil. Consultez Prévisualiser les événements de fil de session pour l'activation, l'accumulation et la réconciliation des prévisualisations.
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":
breakSi un sous-agent a besoin de quelque chose de votre client, comme une permission pour exécuter un outil always_ask, ou le résultat d'un outil personnalisé, l'événement est publié en parallèle 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": ["toolu_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?