Esecuzioni di workflow
Segui le esecuzioni di workflow di un agente: i loro stati ed eventi, quando il lavoro è terminato, cosa viene bloccato da un'esecuzione, budget e limiti.
Un workflow (flusso di lavoro) è un programma che un agente scrive per eseguire molti agenti e combinare ciò che restituiscono. Un workflow run (esecuzione di workflow) è l'esecuzione di un workflow. Dynamic workflows (workflow dinamici) è la funzionalità che consente a un agente di scrivere workflow e avviare esecuzioni. La attivi o disattivi con l'impostazione workflows nel blocco multiagent dell'agente.
Il server esegue un workflow in background. I suoi agenti lavorano in thread di sessione che il server crea man mano che il workflow ne ha bisogno. Segui le esecuzioni sullo stream di eventi della sessione. Solo l'agente avvia un'esecuzione. Nessun evento che invii ne termina una; l'archiviazione della sessione può farlo.
Come funzionano i workflow dinamici
L'agente eseguito dalla sessione scrive ogni workflow per il lavoro che descrivi. Un workflow è un programma: esegue altri agenti, raccoglie ciò che ciascuno restituisce e combina i risultati. In questo modo, l'agente può affrontare un'attività troppo grande per una singola conversazione, come la revisione di centinaia di documenti. Durante un'esecuzione, l'agente può continuare a lavorare o terminare il proprio turno, e può controllare lo stato dell'esecuzione.
Il diagramma mostra un esempio. Ogni workflow che l'agente scrive ha le proprie fasi e i propri agenti. Un'esecuzione ha questi livelli:
- Esecuzione di workflow: Il server esegue il workflow in background, come un'unica esecuzione di workflow. Una sessione può avere diverse esecuzioni aperte contemporaneamente.
- Fasi: Un workflow può suddividere il proprio lavoro in fasi. Una fase è uno stadio dell'esecuzione con un proprio nome, come "Leggi i contratti". Segui l'avanzamento di un'esecuzione tramite i suoi eventi di fase.
- Thread degli agenti: In una fase, il programma esegue agenti. Ogni agente lavora nel proprio thread di sessione, su un prompt scritto dal programma. Un agente in un'esecuzione può essere un agente inline, che il programma definisce da sé, oppure un agente predefinito, che elenchi in
workflows.predefined_agents. Per ciò che mostra ciascun thread, consulta I thread di un'esecuzione.
Il programma può fare quanto segue:
- Eseguire agenti contemporaneamente: Il programma può eseguire molti agenti contemporaneamente, operazione chiamata "fan-out" (distribuzione in parallelo). Nel diagramma, tre agenti leggono contratti nella prima fase.
- Passare risultati da un agente all'altro: Ogni agente restituisce il proprio risultato al programma. Il programma può passare quel risultato a un altro agente. Nel diagramma, l'agente nella seconda fase lavora con ciò che i primi tre hanno restituito. Gli agenti di un'esecuzione lavorano anche con gli stessi file, nella sandbox della sessione.
- Compiere il passo successivo da solo: Il risultato di un agente va al programma, non all'agente eseguito dalla sessione. Il programma determina quali agenti eseguire successivamente e scrive i loro prompt.
- Ripetere e scegliere: All'interno di una fase, il programma può ripetere il lavoro e scegliere il passo successivo in base a ciò che un agente ha restituito. Ad esempio, può far rivedere una bozza finché una revisione non viene superata o non si esaurisce un numero prestabilito di cicli. Nel diagramma, il programma può ripetere un passaggio all'interno della seconda fase.
- Gestire un agente che fallisce: Quando uno dei suoi agenti fallisce, il programma può gestire l'errore o lasciare che termini l'esecuzione.
Quando l'esecuzione termina, l'agente eseguito dalla sessione ottiene un turno per leggere ciò che l'esecuzione ha fatto. Può quindi risponderti o avviare un'altra esecuzione. Eventi dell'esecuzione elenca i casi in cui quel turno arriva più tardi o non arriva.
Puoi indicare come un'esecuzione svolge il lavoro, ad esempio come suddivide il lavoro e cosa fa quando un agente fallisce. Consulta Indicare all'agente quando usare un'esecuzione.
Come un'esecuzione passa da uno stato all'altro
Un'esecuzione inizia come in corso o come inattiva. Il raggiungimento del budget, ad esempio, mette in pausa un'esecuzione in corso, rendendola inattiva; aumentare o rimuovere il budget la fa poi ripartire, a meno che non l'abbia messa in pausa anche un'interruzione. Un'esecuzione in corso termina quando il suo workflow finisce, l'agente la ferma, fallisce, la sua durata massima scade o la sessione viene archiviata. Anche un'esecuzione inattiva può terminare, ad esempio quando l'agente la ferma o la sessione viene archiviata.
Un'esecuzione è aperta dal suo evento workflow_run.created fino al suo evento workflow_run.status_ended, che sia in corso o inattiva. Un'esecuzione è inattiva mentre è in pausa, ad esempio al raggiungimento del budget della sessione. La durata massima di un'esecuzione è di 24 ore per impostazione predefinita. L'agente può impostare una durata più breve quando avvia l'esecuzione. Il tempo che un'esecuzione trascorre in attesa del tuo client conta ai fini di tale durata. Una pausa non impedisce lo scorrere della durata di un'esecuzione, quindi un'esecuzione che rimane in pausa può terminare con timeout_error. I seguenti eventi segnalano l'avvio di un'esecuzione, le sue fasi e la sua fine. Anche una pausa al raggiungimento del budget ne invia uno. Una pausa dopo un'interruzione potrebbe non inviarne nessuno. Ogni evento workflow_run.* include workflow_run_id, che è null solo in un workflow_run.error quando non è stata creata alcuna esecuzione.
Eventi dell'esecuzione
Gli eventi dell'esecuzione arrivano sullo stream di eventi della sessione, che è lo stream del thread principale, e anche l'elenco degli eventi della sessione li restituisce. Gli eventi dell'esecuzione non attivano i webhook. Gli eventi di stato dei thread dell'esecuzione arrivano sullo stesso stream. Ciascuno indica il proprio thread in session_thread_id, e i thread di un'esecuzione sono quelli il cui evento session.thread_created aveva il workflow_run_id dell'esecuzione.
| Evento | Quando arriva | Cosa fare |
|---|---|---|
workflow_run.created | L'agente ha avviato un'esecuzione. Include workflow_run_id (wrun_…), il name e la description dell'esecuzione, e phases, le fasi dichiarate dal workflow, ciascuna con un id, un name e una description. Una description è null quando il workflow non ne fornisce una. phases è sempre presente e può essere vuoto. Il name e la description dell'esecuzione e delle fasi sono testo scritto dal modello, quindi possono ripetere parole della tua richiesta. Il name di un'esecuzione può anche essere assegnato dal server. | Tieni traccia dell'esecuzione come aperta. Mostra il suo name e l'avanzamento rispetto a phases. |
workflow_run.status_running | Quando l'esecuzione inizia a essere eseguita, il che può avvenire un po' dopo created, e ogni volta che riprende dopo una pausa al raggiungimento del budget. Una ripresa dopo un'interruzione potrebbe non inviarlo. Un'esecuzione che inizia inattiva potrebbe ricevere prima workflow_run.status_idle. | Mostra l'esecuzione come in corso. |
workflow_run.status_idle | L'esecuzione è stata messa in pausa, ad esempio al raggiungimento del budget della sessione. L'evento non dice perché. Una pausa dopo un'interruzione potrebbe non inviarlo. | Per continuare, consulta Budget e limiti o Interrompere una sessione con esecuzioni aperte. |
workflow_run.phase_started, workflow_run.phase_ended | Il workflow è entrato in una fase o ne è uscito, oppure la fine dell'esecuzione ha chiuso una fase ancora aperta. L'evento di fine non dice se il lavoro della fase è stato completato. Entrambi includono workflow_run_phase_id. L'evento di fine ha anche phase_started_id, l'id dell'evento di inizio che chiude. Nessuno dei due contiene il nome della fase: cercalo tramite workflow_run_phase_id nelle phases di workflow_run.created. | Aggiorna l'avanzamento. Le fasi vengono eseguite una alla volta, nell'ordine di phases, ciascuna al massimo una volta, ma l'API non lo garantisce. Associa la fine di una fase al suo inizio tramite phase_started_id. Gestisci più di una fase aperta, una fase che non è in phases e una fase elencata che non inizia mai, anche in un'esecuzione che viene completata. Ogni fase che inizia termina anche, prima del workflow_run.status_ended dell'esecuzione. |
workflow_run.status_ended | L'esecuzione è terminata. È sempre l'ultimo degli eventi workflow_run.* dell'esecuzione. Include result. | Leggi result (tabella successiva). L'agente ottiene quindi un turno per leggere come è terminata l'esecuzione. Al raggiungimento del budget, o mentre il thread principale attende il tuo client, quel turno arriva più tardi. Dopo un'interruzione, quel turno potrebbe non arrivare: invia un user.message o leggi tu stesso result. Dopo un'archiviazione o una terminazione, non arriva. |
workflow_run.error | Il server segnala un errore di un'esecuzione, o un avvio che ha rifiutato. Un'esecuzione che termina in error riceve questo evento, con lo stesso errore, prima del suo workflow_run.status_ended. Include error: un type e un message che è sicuro registrare nei log. workflow_run_id è null quando non è stata creata alcuna esecuzione. | Registralo nei log e non considerarlo come la fine dell'esecuzione. Se workflow_run_id è null, nessuna esecuzione è stata avviata. Altrimenti continua a tenere traccia dell'esecuzione fino al suo workflow_run.status_ended. |
result | Significato |
|---|---|
{"type": "completed"} | Il workflow ha terminato l'esecuzione. Il risultato non dice se il lavoro è andato a buon fine. Un'esecuzione può terminare completed anche se il lavoro sui suoi thread è fallito, o non è stato possibile creare un thread. Per trovare il lavoro non riuscito, leggi gli eventi di ciascuno dei thread dell'esecuzione. |
{"type": "stopped"} | L'agente ha fermato l'esecuzione, oppure la sessione è stata archiviata. L'evento non dice quale dei due, e versioni future potrebbero aggiungere altre cause. |
error con timeout_error | L'esecuzione ha raggiunto la sua durata massima: 24 ore per impostazione predefinita, o quella impostata dall'agente. |
error con program_error | Il workflow è fallito. Il suo codice è fallito, oppure ha violato una regola per i workflow, diversa da un limite. Oppure uno dei thread dell'esecuzione è fallito, o non è stato possibile crearlo, e il workflow ha lasciato che ciò terminasse l'esecuzione. |
error con thread_limit_error | L'esecuzione ha superato il suo limite sugli agenti che un workflow avvia. |
error con unknown_error | Il server non ha potuto proseguire l'esecuzione, oppure l'esecuzione ha superato uno degli altri limiti del server sui workflow. |
Un risultato di errore ha l'aspetto di {"type": "error", "error": {"type": "timeout_error", "message": "..."}}, dove message è sicuro da registrare nei log. Tratta un result.type non riconosciuto come un'esecuzione terminata in qualche altro modo, e un error.type non riconosciuto come un errore. Quando qualcosa da cui la sessione dipende fallisce, come il modello, un server MCP, le credenziali o la fatturazione, lo stream del thread che fallisce riceve un session.error. Questo di per sé non termina un'esecuzione. Ma se fa fallire uno dei thread dell'esecuzione, e il workflow lascia che ciò termini l'esecuzione, l'esecuzione termina con program_error.
Ad esempio, chiedi all'agente di revisione dei contratti quali tra 300 contratti contengono una clausola di cambio di controllo, e l'agente avvia un'esecuzione:
workflow_run.createdassegna all'esecuzione il nome "Find change-of-control clauses" ed elenca le fasi "Read the contracts" e "Reconcile the findings" inphases. Segue poiworkflow_run.status_running.- Gli eventi di fase segnano ciascuna fase, e ogni thread creato dall'esecuzione invia
session.thread_createdcon ilworkflow_run_iddell'esecuzione. workflow_run.status_endedarriva conresult: {"type": "completed"}.- L'agente risponde "41 dei 300 contratti ne contengono una", e
session.status_idlearriva conend_turn.
Il primo evento dell'esecuzione elenca le sue fasi:
{
"type": "workflow_run.created",
"id": "sevt_01abc...",
"workflow_run_id": "wrun_01J8XkN5uT3vHpLqRfWdY2",
"name": "Find change-of-control clauses",
"description": "Reads each contract and lists those that have the clause.",
"phases": [
{
"id": "wrph_01Kd3a1f3",
"name": "Read the contracts",
"description": "Reads each contract for the clause."
},
{ "id": "wrph_01Kd3b7c9", "name": "Reconcile the findings", "description": null }
],
"processed_at": "2026-10-09T14:01:45Z"
}Ogni evento di fase indica la propria fase tramite workflow_run_phase_id. Si tratta di un id in phases, ma l'API non lo garantisce:
{
"type": "workflow_run.phase_started",
"id": "sevt_01def...",
"workflow_run_id": "wrun_01J8XkN5uT3vHpLqRfWdY2",
"workflow_run_phase_id": "wrph_01Kd3a1f3",
"processed_at": "2026-10-09T14:01:46Z"
}L'ultimo evento dell'esecuzione riporta come è terminata:
{
"type": "workflow_run.status_ended",
"id": "sevt_01ghi...",
"workflow_run_id": "wrun_01J8XkN5uT3vHpLqRfWdY2",
"result": { "type": "completed" },
"processed_at": "2026-10-09T14:09:12Z"
}I thread di un'esecuzione
Ogni agente in un'esecuzione lavora nel proprio thread di sessione, che il server crea man mano che il workflow ne ha bisogno. Puoi elencare, leggere e seguire in streaming i thread di un'esecuzione come qualsiasi thread figlio, e rispondere alle loro chiamate agli strumenti dallo stream principale. Per fermarli, chiedi all'agente di fermare l'esecuzione (consulta Interrompere una sessione con esecuzioni aperte). Non puoi fermarne uno tramite il suo ID, né archiviarne uno mentre la sua esecuzione è aperta.
- Raggruppamento: Un thread di un'esecuzione riporta il
workflow_run_iddell'esecuzione, così come l'eventosession.thread_createdche lo annuncia. Gli altri thread, e gli eventisession.thread_createdche li annunciano, hannoworkflow_run_idimpostato sunull. - Agente:
agentmostra l'agente eseguito dal thread. Per un agente che hai elencato inmultiagent.workflows.predefined_agents,agentcontiene l'ide laversiondi quell'agente, come nel thread di un subagente che hai elencato. Per un agente definito dal workflow (un agente inline),agenthatypeinlinee nessunidoversion. Ha il prompt di sistema scritto dal workflow, non quello dell'agente della sessione. Ha anche il nome e la descrizione che il workflow gli ha dato; il server assegna un nome se il workflow non ne ha fornito uno. Usa il modello dell'agente della sessione, l'agente eseguito dalla sessione. I suoi strumenti, server MCP e skill sono un sottoinsieme di quelli dell'agente della sessione. Li riceve tutti, ma l'API non lo garantisce. I suoi strumenti mantengono le proprie policy di autorizzazione. - Cosa condividono i thread: I thread di un'esecuzione lavorano nella sandbox della sessione, quindi ogni thread lavora con gli stessi file. Ciò include i file di un "memory store" (archivio di memoria) montato dalla sessione. Un agente definito dal workflow usa i propri server MCP con le credenziali che la sessione risolve per essi. Ogni thread ha la propria cronologia di conversazione.
- Eventi: Gli eventi
session.thread_created,session.thread_status_running,session.thread_status_idleesession.thread_status_terminateddi un thread di un'esecuzione arrivano anche sullo stream principale (consulta Eventi dell'esecuzione). I suoi eventi di messaggio restano sul suo stream. I suoi webhook di thread vengono inviati come per qualsiasi thread figlio. Per ciò che registra lo stream del thread stesso, consulta Eventi dei thread di sessione. - Fasi: Nessun evento o campo indica in quale fase lavora un thread, e i thread di una stessa esecuzione possono avere lo stesso
agent_name. Segui l'avanzamento di un'esecuzione tramite i suoi eventi di fase e distingui i suoi thread tramitesession_thread_id. - Limite di thread: I thread di un'esecuzione sono esenti dal limite di thread figli della sessione.
- Avvio di esecuzioni: Solo l'agente sul thread principale della sessione avvia esecuzioni. Un agente che lavora nel thread di un'esecuzione non può avviare un'esecuzione propria, quindi le esecuzioni non si annidano.
- Archiviazione: Il server archivia ogni thread non oltre la fine della sua esecuzione. Può archiviarne uno prima, una volta che il thread restituisce il suo risultato o l'esecuzione ha finito con esso. Se a quel punto il thread è ancora in esecuzione o in attesa del tuo client, il server prima lo ferma. Un thread archiviato rimane nell'elenco dei thread, con stato
terminated. Non è necessario che archivi tu stesso i thread di un'esecuzione. Mentre l'esecuzione è aperta, una richiesta di archiviare un thread che il server non ha ancora archiviato restituisce 400 conerror.details.error_code: "workflow_run_open". - Visibilità: Non vedi il codice del workflow, ma puoi chiedere il workflow all'agente, come descritto nel suggerimento dopo questo elenco. Inoltre non vedi le chiamate agli strumenti che l'agente effettua per avviare e gestire le esecuzioni, né il risultato che ciascun thread restituisce al workflow.
Sapere quando il lavoro è terminato
Mentre un'esecuzione è in corso, aspettati che la sessione rimanga running, anche quando nessuno dei suoi thread sta lavorando. Passa a idle con requires_action quando nessun thread sta lavorando e un thread attende il tuo client. Uno stato di inattività di per sé non significa che il lavoro sia terminato. Il lavoro è terminato quando entrambe le condizioni sono vere:
- Ogni esecuzione di cui hai visto la creazione ha il suo
workflow_run.status_ended. - Dopodiché, arriva un
session.status_idleconstop_reasonend_turn, e non è stato causato da una tua richiesta, come un'interruzione. Dopo un'interruzione, considera solo uno stato di inattività che arriva dopo il tuo successivouser.messageouser.define_outcome.
- Esecuzioni in pausa: Un'esecuzione in pausa non mantiene la sessione
running, quindi la sessione può diventare inattiva mentre l'esecuzione è ancora aperta. Al raggiungimento del budget, ad esempio, la sessione diventa inattiva conbudget_reached. Il lavoro non è terminato finché l'esecuzione non termina. - Un'altra esecuzione: L'agente può avviare una nuova esecuzione quando legge un risultato, quindi controlla di nuovo.
- Esiti: Se hai definito un esito, nessuna valutazione inizia mentre un'esecuzione è aperta, che sia in corso o inattiva. Il turno in cui l'agente legge il risultato dell'esecuzione può avviarne una.
retries_exhausted: Il turno dell'agente è fallito a causa di un errore: i tentativi si sono esauriti, oppure l'errore non può essere ritentato, come un errore di fatturazione. Un'esecuzione potrebbe essere ancora in corso quando arriva questo stato di inattività. Se un'esecuzione è terminata e l'agente non ha ancora letto il suo risultato, il server avvia un nuovo turno senza alcun input da parte tua. La sessione tornarunning, quindi attendi il successivo stato di inattività. Se la sessione rimane inattiva, leggi ilsession.errorche lo ha preceduto e correggi la causa. Quindi invia unuser.message, oppure leggi tu stesso ilresultdi ciascuna esecuzione.
Seguire un'esecuzione
Questo esempio segue una sessione dal tuo messaggio alla risposta dell'agente. Apre lo stream e invia il messaggio. Quindi fa quanto segue:
- Tiene traccia di ogni esecuzione dal suo
workflow_run.createdal suoworkflow_run.status_ended, e stampa ogni fase quando inizia. - Risponde alle chiamate agli strumenti personalizzati quando arriva ciascun
agent.custom_tool_use, perché un thread di un'esecuzione può attendere il tuo client mentre la sessione rimanerunning. Se gli strumenti del tuo agente chiedono conferma, aggiungi un ramo che risponda a ogniagent.tool_useoagent.mcp_tool_useil cuievaluated_permissionèask. L'esempio non ne ha, perché un ramo che consente ogni chiamata trasformerebbealways_askin un consenso sempre concesso. - Si ferma quando il lavoro è terminato: nessuna esecuzione è aperta e la sessione diventa inattiva con
end_turn. Si ferma anche se la sessione termina. In caso di stato di inattività con qualsiasi altro motivo di arresto trannerequires_action, comebudget_reached,retries_exhaustedorefusal, stampa il motivo e si ferma, quindi gestisci questi casi nel tuo codice. Si ferma suretries_exhaustedanche quando il server sta per avviare un nuovo turno da solo. Continua ad attendere surequires_action, e suend_turnmentre un'esecuzione è aperta.
open_runs: dict[str, str] = {} # workflow_run_id -> run name
phase_names: dict[tuple[str, str], str] = {} # (run ID, phase ID) -> phase name
# Apri prima lo stream, poi invia il messaggio dell'utente
with client.beta.sessions.events.stream(session_id) as stream:
client.beta.sessions.events.send(
session_id,
events=[
{
"type": "user.message",
"content": [
{
"type": "text",
"text": "Which contracts in /contracts have a change-of-control clause?",
},
],
},
],
)
for event in stream:
match event.type:
case "workflow_run.created":
open_runs[event.workflow_run_id] = event.name
for phase in event.phases:
phase_names[event.workflow_run_id, phase.id] = phase.name
print(f"Run started: {event.name}")
case "workflow_run.phase_started":
phase_id = event.workflow_run_phase_id
key = (event.workflow_run_id, phase_id)
print(f" Phase: {phase_names.get(key, phase_id)}")
case "workflow_run.status_ended":
name = open_runs.pop(event.workflow_run_id, event.workflow_run_id)
print(f"Run ended: {name} ({event.result.type})")
case "agent.custom_tool_use":
# Rispondi quando arriva l'evento. Il thread di un'esecuzione può attendere il tuo
# client mentre la sessione resta in esecuzione.
result = call_tool(event.name, event.input)
try:
client.beta.sessions.events.send(
session_id,
events=[
{
"type": "user.custom_tool_result",
"custom_tool_use_id": event.id,
"content": [{"type": "text", "text": result}],
},
],
)
except anthropic.BadRequestError as error:
# Il server rifiuta un risultato che arriva troppo tardi, dopo che
# ha archiviato il thread della chiamata. Continua a seguire l'esecuzione.
print(f" Answer to {event.name} refused: {error.message}")
case "session.status_idle":
# Finito quando ogni esecuzione è terminata e l'agente ha concluso il suo turno
if not open_runs and event.stop_reason.type == "end_turn":
break
# Un idle con requires_action attende il tuo client, quindi continua a leggere.
# Per qualsiasi altro motivo di arresto, stampalo e fermati.
if event.stop_reason.type not in ("end_turn", "requires_action"):
print(f"Session idle: {event.stop_reason.type}")
break
case "session.status_terminated":
breakInterrompere una sessione con esecuzioni aperte
Invia user.interrupt senza session_thread_id, oppure con l'ID del thread principale. Interrompe il turno dell'agente. Non termina alcuna esecuzione. Le esecuzioni della sessione potrebbero andare in pausa o continuare, e i loro eventi potrebbero non indicare quale delle due. La durata di un'esecuzione in pausa continua a scorrere, quindi l'esecuzione può terminare con timeout_error mentre è in pausa.
- Chiamate agli strumenti in attesa: Dopo l'interruzione, una chiamata a uno strumento di un thread di un'esecuzione potrebbe ancora attendere il tuo client. Rispondi a ciascuna. Per annullare una chiamata che chiede conferma, negala. Per annullare una chiamata a uno strumento personalizzato, invia un risultato con
is_errorimpostato sutruee un testo incontentche spieghi il motivo. Mentre la sessione èidleconrequires_action, unuser.messagerestituisce 400, quindi rispondi prima alle chiamate. - Per fermare le esecuzioni: Invia un
user.messagechiedendo all'agente di fermare le sue esecuzioni. Un'esecuzione fermata termina conresult{"type": "stopped"}. Mentre la sessione èidleconbudget_reached, unuser.messagerestituisce 400 finché non aumenti o rimuovi il budget. Aumentarlo o rimuoverlo riprende anche le esecuzioni che il budget aveva messo in pausa, a meno che non le abbia messe in pausa anche l'interruzione. - Per continuare: Invia un
user.messagechiedendo all'agente di continuare le sue esecuzioni. Dopo un'interruzione, le esecuzioni potrebbero attendere questo messaggio. Se la sessione èidleconbudget_reached, aumenta o rimuovi prima il budget. - Risultati delle esecuzioni: Un'esecuzione che termina dopo l'interruzione invia comunque
workflow_run.status_ended.
Mentre un'esecuzione è aperta
| Richiesta | Mentre un'esecuzione è aperta | Cosa fare |
|---|---|---|
| Archiviare o eliminare la sessione | Potrebbe restituire 400 mentre un'esecuzione è aperta, qualunque sia lo stato della sessione. L'error.details.error_code dell'errore può essere "workflow_run_open". Potrebbe anche riuscire. | Chiedi all'agente di fermare le sue esecuzioni, oppure attendi che ogni esecuzione sia terminata. Un'esecuzione in pausa termina da sola soltanto quando la sua durata massima scade. Quindi invia la richiesta una volta che la sessione è idle. Un'archiviazione riuscita termina ogni esecuzione aperta con {"type": "stopped"}. Dopo un'archiviazione, il workflow_run.status_ended di un'esecuzione, e il workflow_run.phase_ended di una fase ancora aperta, non arrivano sullo stream. Elenca gli eventi della sessione per leggerli. Dopo un'eliminazione riuscita, nessun evento workflow_run segnala la fine delle esecuzioni della sessione. |
| Archiviare uno dei thread di un'esecuzione | Restituisce 400 con error.details.error_code: "workflow_run_open" mentre l'esecuzione è aperta, in corso o inattiva, a meno che il server non abbia già archiviato il thread. | Niente. Il server archivia i thread di un'esecuzione. |
Aggiornare l'agent della sessione | Restituisce 400 con error.details.error_code: "workflow_run_open" mentre una qualsiasi esecuzione è aperta, anche se in pausa. L'aggiornamento dell'agente sottostante è comunque accettato, e la sessione mantiene la propria copia. Una richiesta che invia anche altri campi, come budget, viene rifiutata per intero. | Attendi che ogni esecuzione abbia il suo workflow_run.status_ended, oppure chiedi all'agente di fermare le sue esecuzioni. |
| Rispondere a una chiamata a uno strumento o a una conferma di strumento da un thread di un'esecuzione | Consentito. Arriva sullo stream principale, e il suo session_thread_id indica il thread. | Rispondi non appena arriva l'evento, passando l'id dell'evento come tool_use_id o custom_tool_use_id. Non attendere session.status_idle: la sessione può rimanere running mentre gli altri thread dell'esecuzione lavorano. Una volta che il server ha archiviato il thread, un risultato di strumento per una delle sue chiamate non ha effetto e può restituire 400. Quando un risultato di strumento restituisce 400, trova il thread della chiamata nell'elenco dei thread. Se il suo stato è terminated, il risultato è arrivato troppo tardi, quindi scartalo. Invia ogni risultato di strumento in una richiesta separata, perché il server rifiuta un'intera richiesta quando ne rifiuta uno degli eventi. Una conferma di strumento che arriva troppo tardi restituisce 200, il che non significa che lo strumento sia stato eseguito. |
Ricostruire lo stato delle esecuzioni dopo la riconnessione
Ricostruisci lo stato di ogni esecuzione dagli eventi della sessione. Lo stream non riproduce ciò che ti sei perso: una nuova connessione consegna solo gli eventi emessi dopo la sua apertura. Quindi elenca gli eventi con un filtro types, una voce types[] per ciascun tipo di evento, come in Elencare gli eventi passati. Passa il next_page di ogni risposta come page finché next_page non è null o assente. workflow_run.created, workflow_run.status_running, workflow_run.status_idle e workflow_run.status_ended forniscono lo stato di ogni esecuzione, tranne che un'esecuzione messa in pausa dopo un'interruzione potrebbe ancora risultare in corso. workflow_run.phase_started e workflow_run.phase_ended ricostruiscono l'avanzamento. Un'esecuzione senza ancora alcun evento di stato non ha ancora iniziato a essere eseguita. Nessun endpoint elenca le esecuzioni.
Budget e limiti
Le richieste al modello di un'esecuzione contano ai fini del budget della sessione. Un'esecuzione non ha un prezzo proprio. I token usati dai suoi agenti vengono fatturati come gli altri token della sessione, alle tariffe di ciascun modello. Per tutti gli addebiti di una sessione, consulta Prezzi di Claude Managed Agents.
- Utilizzo di una singola esecuzione: Elenca i thread della sessione e somma i conteggi dei token in
usagedei thread con ilworkflow_run_iddell'esecuzione. L'elenco include i thread archiviati, il cui stato èterminated, quindi i thread di un'esecuzione terminata vengono conteggiati. Passa ilnext_pagedi ogni risposta comepagefinchénext_pagenon ènullo assente, e salta un thread il cuiusageènull. Se invece sommi illist_costdei thread, il totale esclude il tempo di esecuzione della sessione, e ogni valore è arrotondato separatamente. - Al raggiungimento del budget: Ogni esecuzione aperta va in pausa, e la sessione riporta
idleconbudget_reached, oppurerequires_actionse è in attesa anche una chiamata a uno strumento. Ogni thread completa la richiesta al modello che ha già avviato, quindi un'esecuzione può superare il budget di una richiesta per ogni thread attivo. Aumentare o rimuovere il budget riprende le esecuzioni che aveva messo in pausa, a meno che non le abbia messe in pausa anche un'interruzione. Se l'utilizzo della sessione include un modello senza prezzo di listino, solo la rimozione del budget lo fa; consulta Modelli senza prezzo di listino.
| Limite | Valore | Al raggiungimento del limite |
|---|---|---|
| Thread attivi contemporaneamente in un'esecuzione | 64 | L'esecuzione non ne crea altri finché uno non termina. L'API non garantisce questo numero, quindi può cambiare. |
| Agenti che un workflow avvia nell'intera durata dell'esecuzione | 1.000 | Quando il workflow ne richiede di più, il server non avvia un altro agente e l'esecuzione termina con thread_limit_error. Il server può eseguire di nuovo un agente fallito su un nuovo thread, quindi un'esecuzione potrebbe avere più di 1.000 thread. |
| Durata massima dell'esecuzione | 24 ore per impostazione predefinita, o la durata impostata dall'agente | L'esecuzione termina con timeout_error. Nessun evento indica quale durata ha impostato l'agente. |
| Esecuzioni aperte contemporaneamente in una sessione | 10 per impostazione predefinita | Il server rifiuta di avviare un'altra esecuzione. La chiamata allo strumento dell'agente riceve un errore, e tu ricevi un workflow_run.error il cui error.type è max_workflow_runs_error. Le esecuzioni inattive contano ai fini del limite. |
Il server accorcia il name di un'esecuzione o di una fase a 64 caratteri e la sua description a 256. Il server ha altri limiti sui workflow, e regole per essi, che non sono elencati qui. Ciò che vedi dipende da quando il server rileva il problema:
| Cosa succede | Cosa vedi |
|---|---|
| Il workflow supera uno degli altri limiti quando l'agente avvia l'esecuzione | L'avvio viene rifiutato. Ricevi un workflow_run.error e nessuna esecuzione. |
| L'esecuzione supera uno degli altri limiti in seguito | Ricevi un workflow_run.error, e poi l'esecuzione può terminare con unknown_error. |
| Il server rileva dopo l'avvio che il workflow viola una regola per i workflow, diversa da un limite | Ricevi un workflow_run.error, e l'esecuzione può quindi terminare con program_error. |
Una sessione può avviare un numero qualsiasi di esecuzioni nel corso della sua durata.
Limiti di velocità
Il lavoro di un'esecuzione conta ai fini dei "rate limits" (limiti di velocità) che la tua organizzazione ha già.
| Cosa | Conta ai fini di | Cosa fare |
|---|---|---|
| Le richieste del tuo client per recuperare o elencare la sessione, i suoi thread e i loro eventi | Il limite di lettura per gli endpoint di Managed Agents | Segui un'esecuzione sullo stream di eventi della sessione invece di effettuare polling. |
| Le richieste al modello dai thread di un'esecuzione | I tuoi limiti di velocità della Messages API per il modello usato da ciascun thread, insieme al resto del tuo traffico | Lascia spazio per un'esecuzione in quei limiti, oppure richiedi limiti più elevati. |
Quando una richiesta al modello da uno dei thread di un'esecuzione è soggetta a limite di velocità, o il modello è sovraccarico, lo stream del thread stesso può ricevere un session.error di tipo model_rate_limited_error o model_overloaded_error:
- Se il suo
retry_status.typeèretrying, il server sta ritentando la richiesta e il thread sta ancora lavorando. - Se è
exhausted, il thread è fallito. Se il workflow lascia che quell'errore termini l'esecuzione, l'esecuzione termina conprogram_error, che non indica la causa. Leggi gli eventi dei thread falliti per trovarla.
Il server limita anche quanto possono fare ogni minuto tutte le sessioni della tua organizzazione. Un thread che raggiunge questo limite si ferma, con un session.error sul proprio stream il cui messaggio menziona un limite di velocità. Attendi un minuto prima di chiedere all'agente di continuare.
Un'esecuzione può creare più di un thread per lo stesso lavoro, quindi rendi gli strumenti chiamati dai tuoi agenti sicuri da chiamare due volte.
Was this page helpful?