Stream di eventi della sessione
Invia eventi, ricevi le risposte in streaming e interrompi o reindirizza la sessione durante l'esecuzione.
La comunicazione con Claude Managed Agents è basata su eventi. Invii eventi utente all'agente e ricevi in risposta eventi dell'agente e della sessione per monitorarne lo stato.
Tipi di eventi
Gli eventi fluiscono in due direzioni.
- Gli eventi utente e gli eventi di sistema sono ciò che invii all'agente: gli eventi
user.*avviano una sessione e la guidano man mano che procede;system.messageaggiunge contesto a livello di sistema che si applica al turno che lo accompagna e a tutti i turni successivi. - Gli eventi di sessione, gli eventi span e gli eventi dell'agente ti vengono inviati per offrirti osservabilità sullo stato della sessione e sull'avanzamento dell'agente. Le connessioni stream che aderiscono ricevono anche i delta degli eventi.
Le stringhe dei tipi di evento di sessione, span, agente, utente e sistema seguono una convenzione di denominazione {domain}.{action}. Gli eventi di anteprima delta disponibili solo sullo stream (event_start, event_delta) sono l'eccezione. Consulta Tipi di eventi nel riferimento per il catalogo completo. I tipi di eventi webhook sono separati, e alcuni dei loro nomi differiscono da quelli dello stream (ad esempio, session.status_idled anziché session.status_idle).
Ogni evento persistito include un timestamp processed_at impostato quando l'evento termina l'elaborazione. Sugli eventi che invii, processed_at è null 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.
Integrazione degli 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",
},
],
},
],
)Invia un evento user.interrupt per fermare l'agente durante l'esecuzione, quindi prosegui con un evento user.message per reindirizzarlo:
# Agent is currently analyzing a file...
# Interrupt with a new direction:
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 ritorna non appena gli eventi sono in coda, e il processed_at dell'interruzione rimane null finché l'agente non la applica. Una risposta del modello in corso si ferma immediatamente. L'interruzione può richiedere più tempo per essere applicata mentre sono in esecuzione chiamate a strumenti, e la sessione rimane running finché ciò non avviene. L'evento user.interrupt appare quindi sullo stream, e il turno interrotto termina con un evento session.status_idle. Il suo stop_reason è end_turn, lo stesso valore di un turno che termina da solo; non esiste uno stop reason specifico per l'interruzione. L'agente inizia il turno successivo con il user.message che hai inviato dopo l'interruzione.
Ricevi in streaming gli eventi dalla sessione per ottenere aggiornamenti in tempo reale mentre l'agente lavora. Vengono consegnati solo gli eventi emessi dopo l'apertura dello stream, quindi apri lo stream prima di inviare eventi per evitare una race condition.
# Open the stream first, then send the user message
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}]")
breakPer riconnetterti a una sessione esistente senza perdere eventi:
- Apri un nuovo stream.
- Elenca la cronologia completa degli eventi per inizializzare un insieme di ID di eventi già visti.
- Segui lo stream live, saltando gli eventi già restituiti dall'elenco della cronologia.
with client.beta.sessions.events.stream(session.id) as stream:
# Stream is open and buffering. List history before tailing live.
history = client.beta.sessions.events.list(session.id)
seen_event_ids = {past_event.id for past_event in history}
# Tail live events, skipping anything already seen
for event in stream:
if event.type == "event_start" or event.type == "event_delta":
# Delta previews aren't enabled on this connection.
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":
breakRecupera 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 evento 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}")Delta degli eventi
Per impostazione predefinita, il testo di risposta dell'agente raggiunge lo stream come eventi agent.message bufferizzati, ciascuno emesso solo dopo che la richiesta al modello che lo ha prodotto è terminata. Gli "event deltas" (delta degli eventi) ti permettono di visualizzare quel testo in modo incrementale, come anteprima live, mentre il modello lo sta ancora generando. Un'anteprima non è la risposta: le anteprime sono un ausilio di visualizzazione best-effort, e l'agent.message bufferizzato è sempre il record autorevole. Un client che ignora le anteprime riceve comunque uno stream completo e corretto.
Aderire alle anteprime
Le anteprime sono opt-in per ogni connessione stream. Aggiungi il parametro di query event_deltas[] allo stream che stai leggendo, ripetendolo una volta per ogni tipo di evento di cui vuoi l'anteprima. Poiché [] è un pattern glob della shell, racchiudi l'URL tra virgolette ogni volta che costruisci la richiesta in una shell; gli esempi codificano in percentuale le parentesi quadre come %5B%5D, il che funziona ugualmente. Entrambi gli endpoint stream accettano il parametro: lo stream a livello di sessione su GET /v1/sessions/{session_id}/events/stream, e lo stream proprio di ciascun thread di sessione su GET /v1/sessions/{session_id}/threads/{thread_id}/stream. I valori accettati sono agent.message e agent.thinking; qualsiasi altro valore restituisce un errore 400, così come una richiesta con più di 100 valori. Le anteprime di un subagente appaiono sullo stream del thread proprio di quel subagente.
Quando inizia un evento in anteprima, lo stream emette un event_start che riporta il tipo e l'id dell'evento imminente:
{
"type": "event_start",
"event": {
"type": "agent.message",
"id": "sevt_01abc..."
}
}Per agent.message, lo start è seguito da eventi event_delta che trasportano testo incrementale. Ogni delta indica l'evento che estende in event_id e il blocco di contenuto che estende in delta.index:
{
"type": "event_delta",
"event_id": "sevt_01abc...",
"delta": {
"type": "content_delta",
"index": 0,
"content": {
"type": "text",
"text": "Here is the summary"
}
}
}Quando un evento agent.thinking è in anteprima, viene emesso solo l'event_start. Non seguono eventi event_delta, e l'evento agent.thinking bufferizzato che conclude l'anteprima non trasporta alcun contenuto di ragionamento; è un segnale di avanzamento, non un vettore di contenuto.
A differenza degli eventi persistiti, event_start ed event_delta non hanno un proprio id o processed_at. L'unico identificatore che trasportano è l'id dell'evento di cui sono l'anteprima.
Accumulare e riconciliare
Ogni SDK che supporta i delta degli eventi include un helper accumulatore che gestisce per te la contabilità degli index. Gli helper Go, Java, Ruby e C# indicizzano inoltre l'anteprima in accumulo tramite l'id dell'evento; con gli helper Python, TypeScript e PHP mantieni tu stesso quella mappa e incorpori ogni delta nella voce corrispondente al suo id. Il pattern manuale funziona anche in ogni linguaggio quando hai bisogno di una contabilità personalizzata: applicalo ai tipi di evento generati.
Nel pattern manuale, tratta l'anteprima come un buffer temporaneo e l'evento bufferizzato come il record. Indicizza il buffer per (event_id, index). Riconcilia per richiesta al modello: un turno si apre con un singolo evento session.status_running, poi in un turno che si completa normalmente ogni richiesta al modello produce, in ordine, span.model_request_start, event_start, gli eventi event_delta, l'agent.message bufferizzato e infine span.model_request_end (nella scheda Span events). Sulla connessione, questa è la porzione in anteprima di quella sequenza, intercalata con gli altri eventi bufferizzati della connessione:
event_start {"event": {"type": "agent.message", "id": "sevt_01abc..."}}
event_delta {"event_id": "sevt_01abc...", "delta": {"type": "content_delta", "index": 0, "content": {"type": "text", "text": "..."}}}
...
agent.message {"id": "sevt_01abc...", "content": [...]}La riga event_delta si ripete una volta per ogni frammento di testo. Elabora ogni evento man mano che arriva:
- Su
event_start, annota l'idannunciato. Gli identificatori coincidono sempre:event_start.event.id, ognievent_delta.event_ide l'iddell'agent.messagebufferizzato sono lo stesso valore. - Su ogni
event_delta, aggiungidelta.content.textalla voce in(event_id, delta.index)e visualizza il testo corrente. Il primo delta per unindexcrea quella voce. - Quando arriva l'
agent.messagebufferizzato, abbinalo perid, scarta l'anteprima accumulata e visualizza invece il contenuto del messaggio. - Su
span.model_request_end, chiudi qualsiasi anteprima che non sia stata riconciliata dal suo evento bufferizzato. Non arriveranno altri delta per essa. Se il turno va in errore o viene interrotto, l'evento bufferizzato potrebbe non arrivare mai;span.model_request_endarriva comunque.
Garanzie su cui si basa il pattern:
- Concatenare i delta di un'anteprima in ordine di arrivo, indicizzati per
(event_id, index), fornisce un prefisso dicontent[index].textnell'evento bufferizzato (un prefisso, non necessariamente l'intero testo, perché i delta potrebbero essere scartati sotto carico). - Una connessione emette al massimo un
event_startperevent_id, e l'evento bufferizzato è l'ultima cosa che quella connessione consegna per quell'id.
# Preview snapshots, keyed by event id. accumulate_managed_agents_event folds each
# event_start / event_delta into an agent.message snapshot; the buffered
# agent.message replaces it.
previews: dict[str, BetaManagedAgentsAgentMessageEvent] = {}
# Opt in to agent.message previews on this connection
with client.beta.sessions.events.stream(
session.id, event_deltas=["agent.message"]
) as stream:
client.beta.sessions.events.send(
session.id,
events=[
{
"type": "user.message",
"content": [{"type": "text", "text": "Describe the repo in one sentence."}],
},
],
)
for event in stream:
match event.type:
case "event_start":
snapshot = accumulate_managed_agents_event(None, event)
if snapshot is not None:
previews[event.event.id] = snapshot
print(f"event_start {event.event.type} {event.event.id}")
case "event_delta":
preview = accumulate_managed_agents_event(previews.get(event.event_id), event)
if preview is not None:
previews[event.event_id] = preview
text = "".join(block.text for block in preview.content)
print(f"event_delta preview: {text!r}")
case "agent.message":
# The buffered event is the record: it replaces and closes the preview
preview = accumulate_managed_agents_event(previews.pop(event.id, None), event)
text = "".join(block.text for block in preview.content)
print(f"agent.message {event.id} {text!r}")
case "span.model_request_end":
# No more deltas are coming. Close any preview whose
# buffered event never arrived.
for event_id in previews:
print(f"span.model_request_end closing preview for {event_id}")
previews.clear()
case "session.status_idle":
breakAnteprima degli eventi dei thread di sessione
In una sessione multiagente, ogni thread di sessione ha il proprio stream di eventi su GET /v1/sessions/{session_id}/threads/{thread_id}/stream, e accetta lo stesso parametro event_deltas[] con gli stessi valori. Le anteprime sono limitate al thread per progettazione: una connessione mostra in anteprima solo il thread che sta leggendo. Le anteprime di un thread figlio vengono consegnate sullo stream proprio di quel figlio e non vengono mai pubblicate anche sullo stream a livello di sessione, le cui anteprime restano limitate al thread primario. Per osservare il testo di un subagente mentre il modello lo genera, apri lo stream del thread di quel subagente.
Il percorso dello stream del thread è facile da sbagliare: è /threads/{thread_id}/stream, non /events/stream (che esiste solo a livello di sessione), e non esiste un endpoint /threads/{thread_id}/events/stream.
Gli eventi di anteprima in sé non cambiano. event_start ed event_delta hanno la stessa forma su uno stream di thread e sullo stream a livello di sessione, e il pattern accumulare e riconciliare si applica così come descritto. L'unico adattamento riguarda la contabilità: esegui un'istanza di accumulatore per ogni connessione stream.
# List the session's threads and pick a child: child threads carry a non-null
# parent_thread_id, and the primary thread's parent_thread_id is null.
child_thread = next(
thread
for thread in client.beta.sessions.threads.list(session.id)
if thread.parent_thread_id is not None
)
# The child thread's stream takes the same event_deltas parameter as the
# session stream.
with client.beta.sessions.threads.events.stream(
child_thread.id,
session_id=session.id,
event_deltas=["agent.message"],
) as stream:
for event in stream:
match event.type:
case "event_delta":
print(event.delta.content.text, end="")
case "agent.message":
# The buffered event is the authoritative record; render its content
print()
for block in event.content:
if block.type == "text":
print(block.text, end="")
print()
case "session.thread_status_idle":
breakIl ciclo di lettura termina su session.thread_status_idle, l'evento emesso quando il turno del thread di sessione finisce e il thread diventa inattivo.
Limitazioni
Le anteprime sono ottimizzate per la reattività. Sviluppa tenendo conto di questi vincoli:
- Best effort: Sotto carico, il server potrebbe scartare i delta di un evento. Quando lo fa, ricevi un prefisso contiguo del testo e poi nessun altro delta per quell'evento. L'
agent.messagebufferizzato arriva comunque completo. Non trattare mai un'anteprima accumulata come definitiva. - Nessun replay alla riconnessione: I delta vengono consegnati solo alla connessione che ha aderito, mentre è aperta. Questo vale allo stesso modo per lo stream a livello di sessione e per ogni stream di thread di sessione, e una connessione aperta dopo l'inizio di una richiesta al modello non riceve delta per quell'evento in corso. Se lo stream cade, segui la procedura di riconnessione nella scheda Streaming degli eventi: riapri lo stream ed elenca la cronologia degli eventi. La cronologia include tutti gli eventi bufferizzati emessi mentre eri disconnesso, compreso l'
agent.messageche la tua anteprima stava aspettando. Non c'è modo di richiedere nuovamente i delta persi. - Un solo thread, solo testo: Le anteprime coprono il testo dell'assistente sul thread che la connessione sta leggendo. L'uso degli strumenti, i risultati degli strumenti, i risultati MCP e l'attività su qualsiasi altro thread di sessione non vengono mai mostrati in anteprima su quella connessione.
agent.thinkingsolo start: Un'anteprimaagent.thinkingemette solo l'event_startcome segnale che un blocco di ragionamento è iniziato; non seguono eventievent_delta.- Mai persistiti:
event_startedevent_deltaesistono solo sullo stream live. Non appaiono nella cronologia degli eventi della sessione (GET /v1/sessions/{session_id}/events) né nella cronologia degli eventi di alcun thread di sessione.
Risoluzione dei problemi delle anteprime
Se lo stream non si comporta come ti aspetti:
| Cosa vedi | Cosa significa |
|---|---|
Uno stream con eventi bufferizzati ma nessun event_start o event_delta | La connessione che stai leggendo non ha aderito (event_deltas[] si applica per connessione, non per sessione), oppure il turno non ha mai toccato il thread di cui stai facendo lo streaming. Le anteprime sono limitate al thread, quindi elenca i thread della sessione (GET /v1/sessions/{session_id}/threads) per trovare quale è stato eseguito. |
| Un 404 sull'URL dello stream | Il percorso o un ID è errato, oppure la richiesta non include alcun header beta managed-agents. Gli endpoint dei thread sono protetti dalla beta, quindi senza l'header non esistono. |
Un 400 che menziona event_deltas | Sono accettati solo agent.message e agent.thinking. |
Scenari aggiuntivi
Gestione delle chiamate a strumenti personalizzati
Quando l'agente invoca uno strumento personalizzato:
- La sessione emette un evento
agent.custom_tool_usecontenente il nome dello strumento e l'input. - La sessione si mette in pausa con un evento
session.status_idlecontenentestop_reason: requires_action. Gli ID degli eventi bloccanti si trovano nell'arraystop_reason.event_ids. - Esegui lo strumento nel tuo sistema e invia un evento
user.custom_tool_resultper ciascuno, passando l'ID dell'evento nel parametrocustom_tool_use_idinsieme al contenuto del risultato. - Una volta risolti tutti gli eventi bloccanti, la sessione torna a
running.
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:
# Look up the custom tool use event and execute it
tool_event = events_by_id[event_id]
result = call_tool(tool_event.name, tool_event.input)
# Send the result back
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 "end_turn":
breakConferma degli strumenti
Una chiamata a uno strumento attende la tua conferma con una policy di autorizzazione always_ask, oppure con auto quando il server non giunge a una determinazione. Quando ciò accade:
- La sessione emette un evento
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. - Invia un evento
user.tool_confirmationper ciascuno, passando l'ID dell'evento nel parametrotool_use_id. Impostaresultsu"allow"o"deny". Usadeny_messageper spiegare un rifiuto. - Una volta risolti tutti gli eventi bloccanti, la sessione torna allo stato
running.
Ogni evento agent.tool_use e agent.mcp_tool_use riporta evaluated_permission (allow, ask o deny), e solo gli eventi il cui evaluated_permission è "ask" attendono una conferma. La maggior parte degli eventi riporta anche un oggetto evaluation che registra quale policy ha prodotto quel risultato, descritto in Vedere come è stata valutata ogni chiamata. Ad esempio, una chiamata bash messa in pausa con una policy always_ask appare nello stream come segue:
{
"type": "agent.tool_use",
"id": "sevt_01def...",
"name": "bash",
"input": {
"command": "pip install -r requirements.txt"
},
"evaluated_permission": "ask",
"evaluation": {
"type": "always_ask"
},
"processed_at": "2026-03-25T14:01:45Z"
}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:
# Approve the pending tool call
client.beta.sessions.events.send(
session.id,
events=[
{
"type": "user.tool_confirmation",
"tool_use_id": event_id,
"result": "allow",
},
],
)
case "end_turn":
breakRipresa di una sessione inattiva
Le sessioni persistono tra le interazioni. 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, preservando l'intero stato della sandbox, inclusi il filesystem, i pacchetti installati e tutti i file creati dall'agente. Questo ti permette di riprendere in modo pulito dopo un periodo di inattività.
Per riprendere una sessione, inviale un evento user.message come di consueto:
# Resume a previously created session by sending it a new user.message event.
# In production, pass the stored ID of the session you want to resume.
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.",
},
],
},
],
)Raggiungimento del budget di una sessione
Una sessione creata con un budget si mette in pausa invece di spendere oltre il limite. Quando il costo di listino tracciato della sessione raggiunge il tetto, la piattaforma mette in pausa ogni thread prima della sua successiva richiesta al modello, e la sessione diventa inattiva con uno stop_reason di budget_reached anziché terminare. La richiesta che ha portato il totale oltre il tetto viene eseguita fino al completamento, quindi il list_cost riportato dallo snapshot session.usage può risultare pari o leggermente superiore al tetto. Sullo stream, la pausa arriva come tre eventi, in ordine:
session.thread_status_idleconstop_reason: budget_reached, per ogni thread man mano che si mette in pausa.session.usage, uno snapshot dell'utilizzo cumulativo della sessione e del costo di listino tracciato.session.status_idleconstop_reason: budget_reached. L'eventosession.usageprecede sempre immediatamente questo idle.
Un thread la cui richiesta finale supera il tetto e al tempo stesso completa il proprio turno riporta end_turn sul proprio evento session.thread_status_idle mentre la sessione riporta comunque budget_reached; basati sullo stop_reason a livello di sessione per rilevare la pausa.
Mentre la sessione è al suo tetto, accetta solo gli eventi che concludono il lavoro già in corso: user.tool_confirmation, user.tool_result, user.custom_tool_result e user.interrupt. Qualsiasi evento che avvierebbe nuovo lavoro, incluso user.message, viene rifiutato con un errore 400 che elenca tale lista. Quando una sessione ha sia un thread in attesa di una richiesta di strumento sia un thread in pausa al tetto, lo stop_reason a livello di sessione è requires_action, non budget_reached: risolvere la richiesta non attiva una richiesta al modello, quindi rispondi come di consueto.
Nessun evento riprende una sessione in pausa al suo tetto. Aggiorna invece il budget della sessione: modificare il tetto a qualsiasi valore superiore al costo di listino consumato, oppure rimuovere il budget aggiornando la sessione con "budget": null, riprende automaticamente il lavoro in pausa. Consulta Budget delle sessioni per sapere come viene tracciato il costo di listino e per la semantica completa dell'aggiornamento del budget.
Invio di messaggi di sistema
Invia un evento system.message per fornire all'agente contesto privilegiato a livello di sistema che si applica al turno che lo accompagna e a tutti i turni successivi. A differenza del campo system nella definizione dell'agente (che imposta il prompt di sistema di primo livello), il contenuto di system.message viene aggiunto al contesto di sistema della sessione come turno role: "system" anziché sostituire quel prompt. Usalo quando l'agente ha bisogno di indicazioni aggiornate a livello di sistema a metà sessione: una persona diversa, vincoli rivisti o contesto recuperato a runtime che dovrebbe modellare il comportamento del modello da quel momento in poi.
client.beta.sessions.events.send(
session.id,
events=[
{
"type": "system.message",
"content": [
{
"type": "text",
"text": "The user's current timezone is America/New_York.",
},
],
},
],
)Mentre la sessione è inattiva con stop_reason: requires_action, un system.message viene accettato solo quando segue un evento di risultato di strumento nella stessa richiesta; inviato da solo o con un user.message, viene rifiutato finché gli eventi di strumento in sospeso non sono risolti. content accetta da 1 a 1000 elementi di testo.
Monitoraggio dell'utilizzo
L'oggetto sessione include un campo usage con l'utilizzo cumulativo della sessione: conteggi dei token, uso degli strumenti lato server, tempo attivo e il costo di listino tracciato. Recupera la sessione dopo che è diventata inattiva per leggere i totali più recenti.
{
"id": "sesn_01...",
"status": "idle",
"usage": {
"input_tokens": 5000,
"output_tokens": 3200,
"cache_read_input_tokens": 20000,
"cache_creation": {
"ephemeral_5m_input_tokens": 2000,
"ephemeral_1h_input_tokens": 0
},
"list_cost": {
"amount": "187",
"currency": "USD"
},
"active_seconds": 342.5,
"server_tool_use": {
"web_search_requests": 3,
"web_fetch_requests": 0
}
}
}input_tokens riporta i token di input non in cache e output_tokens riporta i token di output totali su tutte le chiamate al modello nella sessione. Il campo cache_read_input_tokens riporta i token letti dalla cache dei prompt, e l'oggetto cache_creation suddivide i token di creazione della cache per durata della cache (ephemeral_5m_input_tokens e ephemeral_1h_input_tokens). Le voci della cache usano un TTL di 5 minuti per impostazione predefinita, quindi i turni consecutivi all'interno di quella finestra beneficiano delle letture dalla cache, che riducono il costo per token.
list_cost è il consumo cumulativo della sessione valutato alle tariffe di listino pubbliche, espresso come numero intero di centesimi in una stringa, con un codice valuta. active_seconds è il tempo cumulativo durante il quale la sessione aveva almeno un thread in esecuzione; l'attività sovrapposta di thread concorrenti viene conteggiata una sola volta, a differenza di active_seconds nell'oggetto stats della sessione, che somma il tempo attivo proprio di ciascun thread. Questo valore deduplicato è la durata su cui viene calcolato il costo di runtime della sessione. server_tool_use conta le richieste di strumenti eseguiti lato server ai fini della tariffazione: le richieste di ricerca web sono incluse nel costo di listino per richiesta, mentre le richieste di web fetch non comportano alcun addebito per richiesta e non vengono misurate, quindi web_fetch_requests riporta 0. Anche il campo usage di ciascun thread di sessione contiene list_cost e active_seconds. I valori per thread sono arrotondati in modo indipendente ed escludono il costo del tempo di esecuzione della sessione, quindi la loro somma non corrisponde esattamente al list_cost della sessione; il valore della sessione è quello autorevole.
Non è necessario interrogare periodicamente la sessione per osservare questi totali. L'evento session.usage trasporta la stessa istantanea cumulativa (l'oggetto usage, più il budget della sessione, che è null quando la sessione non ne ha uno) sullo stream della sessione e nella cronologia degli eventi. Viene emesso nelle transizioni verso lo stato inattivo anziché a intervalli regolari: la sessione ne emette uno immediatamente prima di diventare inattiva, qualunque sia il motivo di arresto, e uno quando un thread si mette in pausa al raggiungimento di un budget di sessione. Un lettore dello stream vede quindi il costo finale di un turno, o del lavoro che ha raggiunto un budget, senza un recupero aggiuntivo.
Per applicare un limite di spesa, imposta un budget di sessione anziché interrogare l'utilizzo e arrestare la sessione manualmente. La piattaforma valuta continuamente il consumo della sessione e mette in pausa ciascun thread prima della sua successiva richiesta al modello una volta che il costo di listino della sessione raggiunge il limite; consulta Raggiungere un budget di sessione per vedere come appare sullo stream.
Osservabilità nella Console
La Claude Console include un visualizzatore di sessioni per ispezionare ciò che un agente ha fatto senza scrivere codice. Nella barra laterale della Console, sotto Managed Agents, seleziona Sessions per vedere ogni sessione nel workspace con il suo stato, agente, utilizzo dei token, costo e ora di creazione, quindi seleziona una sessione per aprirla. Il visualizzatore di sessioni è accessibile solo a Developer e Admin. Mostra:
- Minimappa della timeline: Una panoramica con zoom dell'attività della sessione nel tempo, con una corsia per thread nelle sessioni multiagente. Seleziona una corsia per visualizzare quel thread, oppure seleziona un indicatore per passare al relativo evento.
- Trascrizione: La conversazione raggruppata per richiesta al modello, inclusi il ragionamento, le chiamate agli strumenti con i relativi input e risultati, e il testo dei messaggi man mano che arriva in streaming. Puoi filtrare gli eventi e copiarli o scaricarli come JSON.
- Inspector: Un pannello laterale ridimensionabile con dettagli sulla sessione, in cinque schede:
- Session mostra i dettagli e i metadati della sessione, il suo costo cumulativo nel tempo e la spesa rispetto al budget della sessione quando ne è impostato uno.
- Events elenca ogni evento grezzo sul thread corrente nell'ordine in cui il server lo ha inviato; seleziona un evento per vederne il JSON. Un messaggio trasmesso in streaming mentre la pagina era aperta dispone anche di una vista Deltas dei suoi delta degli eventi.
- Tools elenca gli strumenti con cui sono configurati gli agenti della sessione, insieme al numero di chiamate, agli errori e alla durata mediana; seleziona uno strumento per vederne le chiamate e passare a una di esse nella trascrizione.
- Resources elenca i file, i repository e i memory store montati nei rispettivi percorsi del container, incluse le memorie in ciascuno store e le modifiche apportate da questa sessione, oltre ai file che l'agente ha scritto in
/mnt/session/outputse alle skill associate agli agenti della sessione. - Threads elenca ogni thread con il suo stato, dimensione del contesto e costo. Seleziona un thread per visualizzarne i dettagli, come agente, modello, utilizzo del contesto e costo.
Aggiungi ?event={event_id} all'URL di una sessione per aprire la sessione in corrispondenza di un evento specifico.
Con ant beta:sessions connect, puoi aprire lo stesso visualizzatore dalla CLI ant oppure seguire la sessione nel tuo terminale. Consulta Connettersi a una sessione di Managed Agents dal terminale.
Suggerimenti per il debug
- Controlla gli eventi della sessione: Gli errori della sessione vengono comunicati tramite l'evento
session.error - Esamina i risultati degli strumenti: Gli errori di esecuzione degli strumenti spesso spiegano comportamenti inattesi dell'agente
- Monitora l'utilizzo dei token: Tieni sotto controllo il consumo di token per ottimizzare i prompt e ridurre i costi
- Usa i prompt di sistema: Aggiungi istruzioni di logging al prompt di sistema per far sì che l'agente spieghi il proprio ragionamento
- Risolvi i problemi delle anteprime: Se uno stream che aderisce ai delta degli eventi non si comporta come previsto, consulta Risolvere i problemi delle anteprime
Was this page helpful?