Flusso di eventi della sessione
Invia eventi, trasmetti le risposte in streaming e interrompi o reindirizza la tua sessione durante l'esecuzione.
La comunicazione con Claude Managed Agents è basata sugli eventi. Apri uno stream per seguire una sessione, invii eventi per dirigerla e le rispondi quando si mette in pausa in attesa di input.
Tipi di eventi
Gli eventi fluiscono in due direzioni: tu invii eventi all'agente e la sessione ti invia eventi di ritorno.
- Eventi che invii: gli eventi
user.*avviano una sessione e la guidano mentre procede. Gli eventisystem.messageaggiungono contesto a livello di sistema. - Eventi che ricevi: gli eventi di sessione, gli eventi di span e gli eventi dell'agente riportano lo stato della sessione e i progressi dell'agente.
Queste stringhe di tipo di evento seguono una convenzione di denominazione {domain}.{action}. Consulta Tipi di eventi nel riferimento per il catalogo completo.
I tipi di eventi dei webhook sono separati e alcuni dei loro nomi differiscono da quelli dello stream. Ad esempio, i webhook usano session.status_idled anziché session.status_idle.
Trasmettere eventi in streaming
Trasmetti in "streaming" (flusso continuo) gli eventi dalla sessione per ricevere aggiornamenti in tempo reale mentre l'agente lavora. Uno stream consegna solo gli eventi emessi dopo la sua apertura, quindi apri lo stream prima di inviare eventi per evitare una "race condition" (condizione di competizione).
# 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": "Summarize the repo README"}],
},
],
)
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.status_idle":
break
case "session.error":
error_message = event.error.message if event.error else "unknown"
print(f"\n[Error: {error_message}]")
breakLa sessione segnala gli errori tramite l'evento session.error. Consulta Tipi di eventi per i suoi campi.
Il testo della risposta dell'agente arriva come eventi agent.message bufferizzati, ciascuno emesso solo dopo il completamento della richiesta al modello che lo ha prodotto. Per visualizzare il testo mentre il modello lo sta ancora generando, consulta Anteprima delle risposte con i delta degli eventi.
Riconnettersi senza perdere eventi
Per riconnetterti a una sessione esistente senza perdere eventi, combina un nuovo stream con la cronologia degli eventi:
- Apri un nuovo stream.
- Elenca la cronologia completa degli eventi per popolare un insieme di ID di eventi già visti.
- Segui lo stream in tempo reale, saltando tutti gli eventi già restituiti dall'elenco della cronologia.
with client.beta.sessions.events.stream(session.id) as stream:
# Lo stream è aperto e in buffering. Elenca la cronologia prima di seguire il live.
history = client.beta.sessions.events.list(session.id)
seen_event_ids = {past_event.id for past_event in history}
# Segui gli eventi live, saltando quelli già visti
for event in stream:
if event.type == "event_start" or event.type == "event_delta":
# Le anteprime dei delta non sono abilitate su questa connessione.
continue
if event.id in seen_event_ids:
continue
seen_event_ids.add(event.id)
match event.type:
case "agent.message":
for block in event.content:
if block.type == "text":
print(block.text, end="")
case "session.status_idle":
breakInviare eventi
Invia un evento user.message per avviare o continuare il lavoro dell'agente:
client.beta.sessions.events.send(
session.id,
events=[
{
"type": "user.message",
"content": [
{
"type": "text",
"text": "Analyze the performance of the sort function in utils.py",
},
],
},
],
)Ogni evento nella cronologia della sessione include un timestamp processed_at, impostato quando l'evento termina l'elaborazione. Negli eventi che invii, processed_at è None finché l'evento è ancora in coda dietro eventi precedenti. Le eccezioni sono user.define_outcome, user.custom_tool_result e user.tool_result, che vengono elaborati alla ricezione e restituiti con processed_at già popolato.
Rispondere quando la sessione diventa inattiva
Un evento session.status_idle significa che l'agente si è fermato ed è in attesa di input. Il suo stop_reason.type indica il motivo:
stop_reason.type | Perché la sessione si è fermata | Cosa fare |
|---|---|---|
end_turn | L'agente ha terminato il suo turno, oppure lo hai interrotto. | Invia un user.message quando hai altro lavoro per l'agente. |
requires_action | Una o più chiamate agli strumenti richiedono una tua risposta, come una chiamata a uno strumento personalizzato o una richiesta di conferma. | Rispondi a ogni chiamata agli strumenti bloccante. |
budget_reached | Il costo di listino tracciato della sessione ha raggiunto il suo budget. | Modifica o rimuovi il budget. |
Nessun evento che invii riprende una sessione messa in pausa al raggiungimento del budget. Il lavoro messo in pausa dal budget riprende automaticamente quando modifichi il budget impostandolo a un valore superiore al costo di listino consumato, oppure lo rimuovi. Quando il lavoro riprende, la sessione emette un evento workflow_run.status_running per ogni esecuzione di workflow messa in pausa dal budget. Un'esecuzione messa in pausa da un'interruzione rimane in pausa; consulta Riprendere una sessione al raggiungimento del budget. Consulta Quando una sessione raggiunge il suo budget per gli eventi che segnalano la pausa e gli eventi che la sessione accetta ancora.
Rispondere alle chiamate agli strumenti che mettono in pausa la sessione
Una sessione si mette in pausa quando l'agente invoca uno strumento personalizzato e quando una chiamata a uno strumento richiede la tua conferma in base a una policy di autorizzazione. Entrambe le pause seguono la stessa sequenza:
- La sessione emette la chiamata allo strumento come evento
agent.custom_tool_use,agent.tool_useoagent.mcp_tool_use. - La sessione si mette in pausa con un evento
session.status_idleil cuistop_reason.typeèrequires_action. Gli ID degli eventi bloccanti si trovano nell'arraystop_reason.event_ids. - Per ogni ID di evento bloccante, invia un evento
user.custom_tool_resultouser.tool_confirmation. Il risultato di uno strumento personalizzato non deve attendere il passaggio 2. - Una volta risolti tutti gli eventi bloccanti, la sessione torna allo stato
running.
In una sessione multiagente, gli eventi bloccanti di un subagente vengono ripubblicati anche sul thread principale. Consulta Autorizzazioni degli strumenti e strumenti personalizzati.
Restituire il risultato di uno strumento personalizzato
L'evento agent.custom_tool_use contiene il nome e l'input dello strumento. Esegui lo strumento nel tuo sistema. Quindi invia un evento user.custom_tool_result, passando l'ID dell'evento nel parametro custom_tool_use_id insieme al contenuto del risultato.
Puoi inviare il risultato non appena arriva l'evento agent.custom_tool_use, senza attendere session.status_idle. La sessione emette comunque session.status_idle con un motivo di arresto requires_action per la chiamata, e il tuo client può ignorarlo. Un secondo risultato per la stessa chiamata viene accettato e non ha alcun effetto.
Quando ti riconnetti a una sessione in pausa, stop_reason.event_ids sull'ultimo evento session.status_idle elenca le chiamate a cui rispondere.
L'esempio seguente risponde a ogni chiamata man mano che arriva:
with client.beta.sessions.events.stream(session.id) as stream:
for event in stream:
match event.type:
case "agent.custom_tool_use":
# Esegui lo strumento
result = call_tool(event.name, event.input)
# Invia il risultato
client.beta.sessions.events.send(
session.id,
events=[
{
"type": "user.custom_tool_result",
"custom_tool_use_id": event.id,
"content": [{"type": "text", "text": result}],
},
],
)
case "session.status_idle":
if event.stop_reason and event.stop_reason.type == "end_turn":
breakSe l'agente ha esecuzioni di workflow aperte, una chiamata a uno strumento personalizzato può arrivare mentre la sessione rimane running. L'evento di inattività requires_action arriva solo quando nessuno dei thread della sessione è al lavoro. Non attenderlo: rispondi a ogni chiamata quando arriva il relativo evento agent.custom_tool_use. L'esempio in Seguire un'esecuzione mostra come fare.
Confermare una chiamata a uno strumento
Invia un evento user.tool_confirmation, passando l'ID dell'evento nel parametro tool_use_id. Imposta result su "allow" o "deny". Consulta Rispondere alle richieste di conferma per sapere quali chiamate attendono una conferma e come spiegare un rifiuto.
L'esempio seguente approva ogni chiamata in sospeso:
with client.beta.sessions.events.stream(session.id) as stream:
for event in stream:
if event.type == "session.status_idle" and (stop_reason := event.stop_reason):
match stop_reason.type:
case "requires_action":
for event_id in stop_reason.event_ids:
# Approva la chiamata allo strumento in sospeso
client.beta.sessions.events.send(
session.id,
events=[
{
"type": "user.tool_confirmation",
"tool_use_id": event_id,
"result": "allow",
},
],
)
case "end_turn":
breakL'esempio precedente approva ogni chiamata dopo che la sessione diventa inattiva. Se l'agente ha esecuzioni di workflow aperte, una chiamata a uno strumento può attendere la tua conferma mentre la sessione rimane running. Non attendere l'evento di inattività: quando arriva un evento agent.tool_use o agent.mcp_tool_use il cui evaluated_permission è ask, rispondi. L'esempio in Seguire un'esecuzione risponde in questo modo alle chiamate agli strumenti personalizzati, e la sua introduzione spiega come aggiungere le conferme.
Riprendere una sessione inattiva
Le sessioni persistono tra un'interazione e l'altra. Per riprendere una sessione, inviale un evento user.message come di consueto:
# Riprendi una sessione creata in precedenza inviandole un nuovo evento user.message.
# In produzione, passa l'ID memorizzato della sessione che vuoi riprendere.
client.beta.sessions.events.send(
session.id,
events=[
{
"type": "user.message",
"content": [
{
"type": "text",
"text": "Now run the tests against the changes you made earlier.",
},
],
},
],
)La cronologia della conversazione viene conservata a meno che la sessione non venga eliminata esplicitamente. Quando una sessione diventa inattiva, viene creato un checkpoint della sua sandbox. Il checkpoint conserva lo stato completo della sandbox, inclusi il filesystem, i pacchetti installati e tutti i file creati dall'agente.
Interrompere l'agente
Invia un evento user.interrupt per fermare l'agente durante l'esecuzione, quindi prosegui con un evento user.message per reindirizzarlo:
# L'agente sta attualmente analizzando un file...
# Interrompi con una nuova direzione:
client.beta.sessions.events.send(
session.id,
events=[
{"type": "user.interrupt"},
{
"type": "user.message",
"content": [
{
"type": "text",
"text": "Instead, focus on fixing the bug in line 42.",
},
],
},
],
)La chiamata restituisce il controllo non appena gli eventi vengono messi in coda. L'interruzione ha quindi effetto in questo ordine:
- L'agente applica l'interruzione. Fino ad allora, il
processed_atdell'interruzione rimaneNonee la sessione rimanerunning. Una risposta del modello in corso si ferma immediatamente, ma l'applicazione dell'interruzione può richiedere più tempo mentre sono in esecuzione chiamate agli strumenti. - L'evento
user.interruptcompare nello stream e il turno interrotto termina con un eventosession.status_idle. - L'agente inizia il turno successivo con il
user.messageche hai inviato dopo l'interruzione.
Il stop_reason.type dell'evento di inattività è end_turn, lo stesso valore di un turno che termina da solo. Se ci sono esecuzioni di workflow aperte, l'interruzione non ne termina nessuna. Un'esecuzione in corso può mantenere la sessione running, quindi l'evento session.status_idle del passaggio 2 potrebbe non arrivare. Consulta Interrompere una sessione con esecuzioni aperte.
Elencare gli eventi passati
Recupera la cronologia completa degli eventi di una sessione:
events = client.beta.sessions.events.list(session.id)
for event in events.data:
print(f"[{event.type}] {event.processed_at}")Passa un filtro types per restituire solo tipi di eventi specifici:
events = client.beta.sessions.events.list(
session.id,
types=["agent.tool_use", "agent.tool_result"],
)
for event in events.data:
print(f"[{event.type}] {event.processed_at}")Inviare messaggi di sistema
Su un modello supportato, invia un evento system.message per fornire all'agente un contesto privilegiato a livello di sistema. Il contesto si applica al turno corrispondente e a tutti i turni successivi. Usalo quando l'agente ha bisogno di indicazioni aggiornate a livello di sistema durante la sessione, ad esempio una persona diversa, vincoli rivisti o contesto recuperato in fase di esecuzione.
Il content dell'evento accetta da 1 a 1000 elementi di testo. Il contenuto viene aggiunto al contesto di sistema della sessione come turno role: "system". Non sostituisce il "system prompt" (prompt di sistema) di primo livello, impostato dal campo system nella definizione dell'agente.
client.beta.sessions.events.send(
session.id,
events=[
{
"type": "system.message",
"content": [
{
"type": "text",
"text": "The user's current timezone is America/New_York.",
},
],
},
],
)Modelli supportati
system.message è supportato da questi modelli:
- Claude Fable 5.1
- Claude Mythos 5.1
- Claude Fable 5
- Claude Mythos 5
- Claude Opus 5.5
- Claude Opus 5
- Claude Opus 4.8
- Claude Sonnet 5.5
- Claude Haiku 5.5
Se il modello principale dell'agente non supporta l'inserimento di messaggi di sistema a metà conversazione, l'evento viene rifiutato con un errore di validazione model_does_not_support_mid_conversation_system. I modelli dei subagenti non vengono verificati, perché system.message arriva solo sul thread principale.
Messaggi di sistema mentre una chiamata a uno strumento è in sospeso
Mentre la sessione è inattiva con un motivo di arresto requires_action, un system.message deve seguire un evento di risultato dello strumento nella stessa richiesta. Se inviato da solo o con un user.message, viene rifiutato finché gli eventi degli strumenti in sospeso non vengono risolti.
Passaggi successivi
Visualizza il testo della risposta dell'agente mentre il modello lo sta ancora generando.
Ispeziona una sessione nella Claude Console e consulta il suo utilizzo di token e il costo di listino.
Ricevi notifiche quando si verificano eventi importanti senza polling.
Consulta ogni tipo di evento che una sessione può inviare o ricevere.
Was this page helpful?