Orchestrazione multiagente
Coordina più agenti all'interno di una singola sessione.
L'orchestrazione multiagente ("multiagent orchestration") consente a un agente di coordinarsi con altri per completare lavori complessi. Gli agenti possono agire in parallelo con il proprio contesto isolato, il che aiuta a migliorare la qualità dell'output e può anche ridurre il tempo di completamento.
Non sei sicuro che una configurazione multiagente sia adatta al tuo problema? Consulta quando usare i sistemi multiagente (e quando no).
Come funziona
Tutti gli agenti condividono la stessa sandbox, lo stesso filesystem e le stesse credenziali del vault, ma ogni agente viene eseguito nel proprio session thread (thread di sessione), un flusso di eventi con contesto isolato e una propria cronologia di conversazione. Il coordinatore riporta l'attività nel primary thread (thread principale), che coincide con l'event stream (flusso di eventi) a livello di sessione; thread aggiuntivi vengono generati a runtime quando il coordinatore delega il lavoro.
I thread sono persistenti: il coordinatore può inviare un messaggio di follow-up a un agente che ha chiamato in precedenza, e quell'agente conserva tutto ciò che riguarda i suoi turni precedenti.
Ogni agente usa la propria configurazione: modello, prompt di sistema, strumenti, server MCP e skill. Gli override della configurazione dell'agente a livello di sessione sono l'eccezione; si applicano al coordinatore e alle sue copie self. Strumenti, server MCP e contesto non sono condivisi.
Cosa delegare
Il coordinamento multiagente è più adatto a compiti complessi che richiedono lavoro su una varietà di superfici, oppure in cui più compiti ben delimitati contribuiscono a un obiettivo complessivo.
Pattern che funzionano bene:
- Parallelizzazione: Distribuisci simultaneamente sottocompiti indipendenti (ricerca su più fonti, analisi di file separati) e fai sintetizzare i risultati al coordinatore.
- Specializzazione: Instrada verso agenti con prompt di sistema e strumenti focalizzati su un dominio, come un agente per la sicurezza o un agente per la documentazione, invece di caricare un singolo agente con ogni capacità.
- Escalation: Consulta un agente o un modello più capace per un sottoinsieme di sottocompiti complessi.
Configura il coordinatore
Quando definisci il tuo agente, imposta multiagent per dichiarare il roster di agenti a cui il coordinatore può delegare:
ant beta:agents create < coordinator.agent.yamlname: 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 commandmultiagent.agents può accettare uno qualsiasi dei seguenti valori:
{"type": "agent", "id": agent.id}fa riferimento tramite ID a unagentcreato in precedenza. Se non viene specificata alcunaversion, il riferimento viene fissato all'ultima versione di quell'agente al momento della creazione del coordinatore.{"type": "agent", "id": agent.id, "version": agent.version}fissa una versione specifica dell'agente.{"type": "self"}consente al coordinatore di generare copie di se stesso. Se la sessione è stata creata con override della configurazione dell'agente, tali override si applicano anche a queste copie; le voci del roster referenziate tramite ID non ne sono influenzate.{"type": "advisor", "model": "<model id>"}fornisce al thread principale della sessione un advisor che può consultare a metà turno. Al massimo una voce advisor per roster. Consulta Assegna un advisor alla sessione.
La configurazione del coordinatore, incluso il suo roster multiagent.agents, viene salvata come snapshot quando il coordinatore viene creato o aggiornato. Gli agenti referenziati restano fissati alle versioni risolte in quel momento e non recepiscono automaticamente gli aggiornamenti successivi alle loro definizioni. Per delegare a una versione più recente di un agente referenziato, aggiorna il coordinatore in modo che il suo roster faccia riferimento a quella versione.
Il coordinatore può delegare a un solo livello di agenti; fare riferimento a un agente che ha un proprio roster multiagent.agents fa fallire la richiesta di creazione o aggiornamento con un errore di validazione. In multiagent.agents possono essere elencati al massimo 20 agenti unici, ma il coordinatore può chiamare più copie di ciascun agente.
Quando gli agenti fissano una geografia di inferenza (model.inference_geo nella definizione dell'agente), il valore fissato dal coordinatore e quello di ogni membro del roster devono essere tutti impostati sullo stesso valore oppure tutti non impostati. Un roster non coerente viene rifiutato con un errore di validazione 400, sia quando l'agente viene salvato sia quando un override alla creazione della sessione modifica uno qualsiasi dei valori fissati.
Assegna un advisor alla sessione
Una voce advisor in multiagent.agents fornisce al thread principale della sessione un advisor (consulente): un modello che può consultare a metà turno per ottenere indicazioni strategiche, come pianificare un approccio, sbloccarsi o rivedere il lavoro prima di concludere. La voce ha esattamente due campi, type e model:
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"}
]
}
}'Un roster può contenere al massimo una voce advisor, insieme a qualsiasi altra forma di voce del roster. La voce occupa il nome di roster riservato anthropic.advisor: un roster che elenca sia una voce advisor sia un membro chiamato letteralmente anthropic.advisor viene rifiutato con un errore di validazione 400. Nelle risposte, la voce advisor viene restituita per ultima nel roster indipendentemente dalla posizione in cui è stata inviata.
Il modello advisor deve soddisfare una soglia minima di capacità, e il modello dell'agente stesso non deve essere più capace del suo advisor; modelli di pari capacità possono essere abbinati. Un abbinamento non valido viene rifiutato con un errore di validazione 400 quando l'agente viene salvato. Gli abbinamenti validi seguono la tabella di compatibilità dei modelli dello strumento advisor.
L'advisor è disponibile anche come strumento server nella Messages API. La superficie Managed Agents differisce per configurazione e modalità di consegna: la voce del roster non ha i campi max_uses, max_tokens o caching, e i consigli arrivano tramite eventi di thread anziché blocchi advisor_tool_result.
Come funzionano le consultazioni
Ogni consultazione viene eseguita come un thread generato dalla piattaforma chiamato anthropic.advisor, che termina da solo al completamento della consultazione, e il consiglio viene consegnato al thread principale come evento agent.thread_message_received. Una consultazione emette gli eventi di thread standard, identificati dal nome riservato anthropic.advisor (gli eventi del ciclo di vita del thread lo riportano come agent_name, e la consegna del consiglio lo riporta come from_agent_name), tipicamente in questo ordine:
session.thread_createdsession.thread_status_runningagent.thread_message_received(il consiglio)session.thread_status_idle(stop_reason: end_turn)session.thread_status_terminated
Per una consultazione non vengono emessi eventi agent.tool_use, e nessun evento agent.thread_message_sent appare nel flusso di eventi della sessione, perché l'input della consultazione è composto dalla piattaforma anziché inviato dall'agente. Se elenchi gli eventi del thread dell'advisor stesso, il consiglio appare anche lì come evento agent.thread_message_sent. Non è garantito che la consegna del consiglio (evento 3) arrivi prima degli eventi idle e terminated del thread dell'advisor, quindi non considerare questi ultimi come un segnale che il consiglio sia già stato consegnato.
Se il tuo client può leggere il consiglio dipende dalla policy del modello advisor, e rispecchia la distinzione tra varianti di risultato dello strumento advisor della Messages API. I modelli advisor che lì restituiscono risultati in testo semplice consegnano qui il consiglio come contenuto testuale leggibile; i modelli advisor che lì restituiscono risultati oscurati consegnano un placeholder [{"type": "redacted"}] come contenuto del messaggio su ogni superficie client, mentre l'agente stesso legge comunque il consiglio completo lato server. Nell'esempio precedente, Claude Opus 5 è un advisor con risultati oscurati, quindi il tuo client vede il placeholder mentre l'agente legge il consiglio completo; scegli invece Claude Opus 4.8 come advisor se vuoi che il consiglio sia leggibile nel flusso di eventi. Il pensiero dell'advisor non viene mai esposto. I client non possono inviare blocchi redacted autonomamente; un evento che ne contiene uno viene rifiutato con un errore di validazione 400.
Una consultazione fallita o interrotta non fa mai fallire il turno dell'agente: l'agente prosegue dopo un avviso generico che la consultazione è fallita. Un user.interrupt a livello di sessione durante una consultazione termina il thread dell'advisor senza che venga consegnato alcun consiglio; un user.interrupt con il session_thread_id del thread dell'advisor abbandona solo quella consultazione.
Thread dell'advisor
L'advisor non è un agente del roster: è invisibile allo strumento list_agents del coordinatore, non può ricevere messaggi tramite send_to_agent, e solo il thread principale della sessione può consultarlo. Gli agenti del roster non possono.
I thread dell'advisor sono esenti dal limite di thread concorrenti. Appaiono nell'elenco dei thread della sessione con agent impostato sulla forma advisor esattamente come configurata ({"type": "advisor", "model": ...}) e parent_thread_id impostato sul thread principale.
La cache dei prompt lato advisor è automatica; non c'è nulla da configurare. Le consultazioni vengono fatturate alle tariffe del modello advisor, e i relativi token appaiono nell'utilizzo del thread dell'advisor e nei totali di utilizzo della sessione.
Rimuovere l'advisor
Per rimuovere l'advisor, aggiorna l'agente con un roster che non includa più la voce advisor. Se l'advisor è l'unica voce del roster, svuota completamente il roster impostando "multiagent": null.
Crea la sessione
Crea una sessione che faccia riferimento al coordinatore. Il coordinatore delega agli agenti del suo roster secondo necessità.
session = client.beta.sessions.create(
agent=coordinator.id,
environment_id=environment.id,
)Connetti gli agenti ai server MCP
I server MCP hanno ambito a livello di agente (ogni definizione di agente dichiara i propri server e strumenti), mentre le credenziali del vault hanno ambito a livello di sessione (i vault_ids passati alla creazione della sessione si applicano a ogni thread). Due implicazioni per la tua integrazione:
- Per autenticare i server MCP, includi una credenziale del vault per ogni server MCP usato da tutti gli agenti.
- Per limitare l'accesso di un agente, dichiara nella sua definizione solo i server di cui ha bisogno.
Gli override della configurazione dell'agente alla creazione della sessione possono sostituire i server MCP del coordinatore e quelli delle sue copie 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)In questo esempio, solo il researcher dichiara il server MCP di GitHub, quindi il coordinatore non vi ha accesso. I vault_ids della sessione forniscono la credenziale GitHub al thread del researcher.
Thread
Il flusso di eventi a livello di sessione (/v1/sessions/{session_id}/events/stream) è considerato il thread principale e contiene una vista condensata di tutta l'attività su tutti i thread. Non vedi l'attività completa dei subagenti, ma vedi l'inizio e la fine del loro lavoro, oltre agli eventi bloccanti come le richieste di permesso per gli strumenti.
I thread di sessione sono il punto in cui approfondisci l'attività di un agente specifico.
Lo status della sessione è un'aggregazione di tutta l'attività degli agenti; se almeno un thread è running, anche lo stato complessivo della sessione è running.
Un budget di sessione è un unico limite condiviso tra tutti i thread di una sessione. Al raggiungimento del limite, i thread vanno in pausa in modo indipendente, e il costo di ciascun thread è calcolato in base al modello effettivamente servito per quel thread.
Elenca tutti i thread associati a una sessione come segue:
for thread in client.beta.sessions.threads.list(session.id):
print(f"[{thread.agent.name}] {thread.status}")L'elenco completo include il thread principale. parent_thread_id è null per il thread principale.
Eventi del thread principale
Questi eventi espongono l'attività multiagente sul thread principale in /v1/sessions/{session_id}/events/stream. Gli eventi relativi alla direzione dei messaggi sono denominati in relazione al thread sul cui flusso appaiono: agent.thread_message_received significa che un messaggio è arrivato su questo thread da un altro thread, e agent.thread_message_sent significa che questo thread ne ha inviato uno. Il compito che il coordinatore delega, ad esempio, arriva sul flusso del thread figlio come evento agent.thread_message_received.
| Tipo | Descrizione |
|---|---|
session.thread_created | È stato creato un thread. Include session_thread_id e agent_name. |
session.thread_status_running | Un thread ha iniziato l'attività. |
session.thread_status_idle | L'agente associato al thread è in attesa di input. Include uno stop_reason che indica perché l'agente si è fermato. |
session.thread_status_terminated | Un thread è stato archiviato o ha incontrato un errore terminale. |
agent.thread_message_received | Sul thread principale, un agente ha inviato un report o una domanda al coordinatore. Include from_session_thread_id, from_agent_name e content. |
agent.thread_message_sent | Sul thread principale, il coordinatore ha inviato un compito o un messaggio di follow-up a un altro agente. Include to_session_thread_id, to_agent_name e content. |
Le consultazioni dell'advisor emettono questi stessi eventi di thread con il nome riservato anthropic.advisor (come agent_name negli eventi del ciclo di vita del thread e from_agent_name nella consegna del consiglio); consulta Assegna un advisor alla sessione per la sequenza.
Eventi dei thread di sessione
Gli eventi critici vengono inoltrati al thread principale. Tuttavia, potresti comunque voler esaminare il ragionamento e le chiamate di strumenti di un agente specifico. Per farlo, esegui lo streaming o elenca gli eventi del thread di sessione associato.
Ogni thread di sessione ha il proprio flusso di eventi in /v1/sessions/{session_id}/threads/{thread_id}/stream, e accetta lo stesso parametro event_deltas[] del flusso a livello di sessione, così puoi visualizzare in anteprima il testo di un subagente mentre il modello lo genera. Una connessione mostra in anteprima solo il thread che sta leggendo: le anteprime di un thread figlio non appaiono mai sul flusso a livello di sessione, quindi per osservare un subagente in tempo reale apri il flusso del suo thread. Consulta Anteprima degli eventi dei thread di sessione per l'attivazione, l'accumulo e la riconciliazione delle anteprime.
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":
breakPermessi degli strumenti e strumenti personalizzati
Se un subagente ha bisogno di qualcosa dal tuo client, come il permesso di eseguire uno strumento always_ask, oppure il risultato di uno strumento personalizzato, l'evento viene pubblicato anche sul thread principale con session_thread_id che identifica il thread di sessione di 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..."]
}
}Invia user.tool_confirmation (con tool_use_id) oppure user.custom_tool_result (con custom_tool_use_id); il server instrada automaticamente la risposta al thread corretto.
L'esempio seguente estende il gestore di conferma degli strumenti per instradare le risposte. Lo stesso pattern si applica a 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?