Il ciclo a colpo d’occhio
Ogni sessione dell’agente segue lo stesso ciclo:- Ricevere il prompt. Claude riceve il vostro prompt, insieme al prompt di sistema, alle definizioni degli strumenti e alla cronologia della conversazione. L’SDK produce un
SystemMessagecon sottotipo"init"contenente i metadati della sessione. - Valutare e rispondere. Claude valuta lo stato attuale e determina come procedere. Può rispondere con testo, richiedere una o più chiamate di strumenti, o entrambi. L’SDK produce uno o più oggetti
AssistantMessage, uno per ogni blocco di contenuto, come un blocco di testo o una richiesta di chiamata di strumento. - Eseguire gli strumenti. L’SDK esegue ogni strumento richiesto e raccoglie i risultati. Ogni set di risultati degli strumenti viene restituito a Claude per la decisione successiva. Potete utilizzare hooks per intercettare, modificare o bloccare le chiamate di strumenti prima che vengano eseguite.
- Ripetere. I passaggi 2 e 3 si ripetono come un ciclo. Ogni ciclo completo è un turno. Claude continua a chiamare gli strumenti ed elaborare i risultati fino a quando non produce una risposta senza chiamate di strumenti.
- Restituire il risultato. L’SDK produce un
AssistantMessagefinale con la risposta di testo (senza chiamate di strumenti), seguito da unResultMessagecon il testo finale, l’utilizzo dei token, il costo e l’ID della sessione.
Glob e risposta con i risultati. Un’attività complessa (“refactorizza il modulo di autenticazione e aggiorna i test”) può concatenare dozzine di chiamate di strumenti su molti turni, leggendo file, modificando codice ed eseguendo test, con Claude che adatta il suo approccio in base a ogni risultato.
Turni e messaggi
Un turno è un viaggio di andata e ritorno all’interno del ciclo: Claude produce output che include chiamate di strumenti, l’SDK esegue quegli strumenti e i risultati vengono restituiti a Claude automaticamente. Questo accade senza cedere il controllo al vostro codice. I turni continuano fino a quando Claude non produce output senza chiamate di strumenti, a quel punto il ciclo termina e il risultato finale viene consegnato. Considerate come potrebbe apparire una sessione completa per il prompt “Correggi i test falliti in auth.ts”. Per prima cosa, l’SDK invia il vostro prompt a Claude e produce unSystemMessage con i metadati della sessione. Poi il ciclo inizia:
- Turno 1: Claude chiama
Bashper eseguirenpm test. L’SDK produce unAssistantMessagecon la chiamata dello strumento, esegue il comando, poi produce unUserMessagecon l’output (tre errori). - Turno 2: Claude chiama
Readsuauth.tseauth.test.ts. L’SDK produce unAssistantMessageper ogni chiamata e restituisce il contenuto dei file. - Turno 3: Claude chiama
Editper correggereauth.ts, poi chiamaBashper rieseguirenpm test. Tutti e tre i test passano. L’SDK produce unAssistantMessageper ogni chiamata. - Turno finale: Claude produce una risposta solo di testo senza chiamate di strumenti: “Corretto il bug di autenticazione, tutti e tre i test passano ora.” L’SDK produce un
AssistantMessagefinale con questo testo, poi unResultMessagecon lo stesso testo più costo e utilizzo.
max_turns / maxTurns, che conta solo i turni di utilizzo degli strumenti. Ad esempio, max_turns=2 nel ciclo precedente si sarebbe fermato prima del passaggio di modifica. Potete anche utilizzare max_budget_usd / maxBudgetUsd per limitare i turni in base a una soglia di spesa.
Senza limiti, il ciclo viene eseguito fino a quando Claude non termina da solo, il che va bene per attività ben definite ma può durare a lungo su prompt aperti (“migliora questo codebase”). Impostare un budget è una buona impostazione predefinita per gli agenti di produzione. Vedere Turni e budget di seguito per il riferimento alle opzioni.
Tipi di messaggi
Mentre il ciclo viene eseguito, l’SDK produce un flusso di messaggi. Ogni messaggio ha un tipo che vi dice da quale fase del ciclo proviene. I cinque tipi principali sono:-
SystemMessage: eventi del ciclo di vita della sessione. Il camposubtypeli distingue:"init": metadati della sessione per l’esecuzione. Quando un hookSessionStartoSetupviene eseguito durante l’avvio della sessione, i suoi messaggi del ciclo di vita dell’hook arrivano prima del messaggioinit"compact_boundary": si attiva dopo la compattazione"informational": banner di stato in testo semplice dal ciclo"worker_shutting_down": l’host sta uscendo o Remote Control si è disconnesso
"init"è il suo proprio tipo nell’unioneSDKMessagepiuttosto che un sottotipo diSDKSystemMessage. -
AssistantMessage: emesso per ogni blocco di contenuto nelle risposte di Claude, incluso quello finale solo di testo. Ogni messaggio contiene un singolo blocco di contenuto, come testo o una chiamata di strumento, e i messaggi da una risposta condividono un ID messaggio. -
UserMessage: emesso dopo ogni esecuzione di strumento con il risultato dello strumento inviato di nuovo a Claude. Emesso anche per qualsiasi input dell’utente che trasmettete a metà ciclo. -
StreamEvent: emesso solo quando i messaggi parziali sono abilitati. Contiene eventi di streaming API grezzi (delta di testo, chunk di input dello strumento). Vedere Stream responses. -
ResultMessage: segna la fine del ciclo dell’agente. Contiene il risultato di testo finale, l’utilizzo dei token, il costo e l’ID della sessione. Controllate il camposubtypeper determinare se l’attività ha avuto successo o ha raggiunto un limite. Un piccolo numero di eventi di sistema finali, comeprompt_suggestion, può arrivare dopo di esso, quindi iterate il flusso fino al completamento piuttosto che interrompere al risultato. Vedere Gestire il risultato.
Gestire i messaggi
Quali messaggi gestite dipende da ciò che state costruendo:- Solo risultati finali: gestite
ResultMessageper ottenere l’output, il costo e se l’attività ha avuto successo o ha raggiunto un limite. - Aggiornamenti di progresso: gestite
AssistantMessageper vedere cosa sta facendo Claude ad ogni turno, inclusi gli strumenti che ha chiamato. - Streaming in tempo reale: abilitate i messaggi parziali (
include_partial_messagesin Python,includePartialMessagesin TypeScript) per ottenere messaggiStreamEventin tempo reale. Vedere Stream responses in real-time.
- Python: controllate i tipi di messaggi con
isinstance()rispetto alle classi importate daclaude_agent_sdk(ad esempio,isinstance(message, ResultMessage)). - TypeScript: controllate il campo stringa
type(ad esempio,message.type === "result").AssistantMessageeUserMessageavvolgono il messaggio API grezzo in un campo.message, quindi i blocchi di contenuto si trovano inmessage.message.content, non inmessage.content.
Esempio: Controllare i tipi di messaggi e gestire i risultati
Esempio: Controllare i tipi di messaggi e gestire i risultati
Esecuzione degli strumenti
Gli strumenti danno al vostro agente la capacità di agire. Senza strumenti, Claude può solo rispondere con testo. Con gli strumenti, Claude può leggere file, eseguire comandi, cercare codice e interagire con servizi esterni.Strumenti integrati
L’SDK include gli stessi strumenti che alimentano Claude Code:
Sui modelli che non ottengono gli strumenti di tracciamento delle attività, Claude Code fornisce
TaskCreate e TaskUpdate solo quando vi iscrivete.
Oltre agli strumenti integrati, potete:
- Connettere servizi esterni con server MCP (database, browser, API)
- Definire strumenti personalizzati con gestori di strumenti personalizzati
- Caricare skills del progetto tramite setting sources per flussi di lavoro riutilizzabili
Autorizzazioni degli strumenti
Claude determina quali strumenti chiamare in base all’attività, ma voi controllate se quelle chiamate sono autorizzate a essere eseguite. Potete approvare automaticamente strumenti specifici, bloccare altri completamente, o richiedere l’approvazione per tutto. Tre opzioni lavorano insieme per determinare cosa viene eseguito:allowed_tools/allowedToolsapprova automaticamente gli strumenti elencati. Un agente di sola lettura con["Read", "Glob", "Grep"]nel suo elenco di strumenti consentiti esegue quegli strumenti senza chiedere, tranne per le letture da percorsi di rete. Gli strumenti non elencati sono ancora disponibili, e le chiamate a essi che necessitano di approvazione ricadono nella modalità di permesso e incanUseTool.disallowed_tools/disallowedToolsblocca gli strumenti elencati, indipendentemente da altre impostazioni. Vedere Autorizzazioni per l’ordine in cui le regole vengono controllate prima che uno strumento venga eseguito.permission_mode/permissionModecontrolla quanto controllo umano desiderate. L’SDK valuta la modalità attiva insieme alle vostre regole di consentimento e negazione in un ordine fisso, descritto in Come vengono valutate le autorizzazioni. Vedere Modalità di autorizzazione per le modalità disponibili.
"Bash(npm *)" per consentire solo comandi specifici. Vedere Autorizzazioni per la sintassi completa delle regole.
Quando uno strumento viene negato, Claude riceve un messaggio di rifiuto come risultato dello strumento e in genere tenta un approccio diverso o segnala che non potrebbe procedere.
Esecuzione parallela degli strumenti
Quando Claude richiede più chiamate di strumenti in un singolo turno, entrambi gli SDK possono eseguirli contemporaneamente o sequenzialmente a seconda dello strumento. Gli strumenti di sola lettura (comeRead, Glob, Grep e strumenti MCP contrassegnati come di sola lettura) possono essere eseguiti contemporaneamente. Gli strumenti che modificano lo stato (come Edit, Write e Bash) vengono eseguiti sequenzialmente per evitare conflitti.
Gli strumenti personalizzati predefiniti per l’esecuzione sequenziale. Per abilitare l’esecuzione parallela per uno strumento personalizzato, impostare readOnlyHint nelle sue annotazioni. Sia l’SDK TypeScript che Python utilizzano questo nome di campo dall’SDK MCP.
Controllare come viene eseguito il ciclo
Potete limitare quanti turni il ciclo prende, quanto costa, quanto profondamente Claude ragiona e se gli strumenti richiedono approvazione prima di essere eseguiti. Tutti questi sono campi suClaudeAgentOptions (Python) / Options (TypeScript).
Turni e budget
Quando uno dei due limiti viene raggiunto, l’SDK restituisce un
ResultMessage con un sottotipo di errore corrispondente (error_max_turns o error_max_budget_usd). Vedere Gestire il risultato per come controllare questi sottotipi e ClaudeAgentOptions / Options per la sintassi.
Il limite di budget copre i subagenti: la loro spesa conta verso il totale. Una volta che la spesa raggiunge il limite, generare un altro subagente fallisce con Budget limit reached, e Claude Code interrompe tutti i subagenti in background ancora in esecuzione. I comportamenti di applicazione del limite richiedono Claude Code v2.1.217 o successivo.
Con streaming input, un messaggio che è ancora in coda quando un turno termina al limite di max-turni rimane in coda. Claude Code non lo aggiunge alla chiamata del modello finale di quel turno. Inizia un nuovo turno per il messaggio e il conteggio di max-turni ricomincia da capo per quel turno. Il totale del budget continua ad accumularsi tra i messaggi e una volta che la spesa raggiunge maxBudgetUsd, i messaggi successivi nella stessa conversazione terminano con il risultato error_max_budget_usd. Un /clear ricomincia il budget da capo.
Margine del budget
Claude Code confronta la spesa con il limitemax_budget_usd / maxBudgetUsd dopo l’arrivo delle risposte del modello, perché il costo di ogni risposta deriva dall’utilizzo di token che l’API restituisce insieme ad essa. La risposta che raggiunge il limite viene comunque completata e conta in total_cost_usd. La spesa può quindi superare il limite fino al costo di quella singola risposta, più quanto spendono i subagent ancora in esecuzione in quel momento prima di fermarsi. Lascia un margine per questo quando imposti il limite.
Livello di sforzo
L’opzioneeffort controlla quanto ragionamento Claude applica. I livelli di sforzo inferiori utilizzano meno token per turno e riducono il costo. Non tutti i modelli supportano il parametro di sforzo. Vedere Effort per quali modelli lo supportano.
Se non impostate
effort, Claude Code risolve il livello di sforzo da solo, nell’ordine che Regolare il livello di sforzo descrive.
effort scambia latenza e costo dei token per profondità di ragionamento all’interno di ogni risposta. Extended thinking è una funzione separata che produce blocchi di thinking nell’output, e il campo display su ThinkingConfig per Python o TypeScript controlla se ricevete il loro testo. Sono indipendenti: potete impostare effort: "low" con extended thinking abilitato, o effort: "max" senza di esso.effort nelle opzioni di livello superiore query() per l’intera sessione, o per subagente con il campo effort su AgentDefinition per sovrascrivere il livello di sessione.
Modalità di autorizzazione
L’opzione della modalità di autorizzazione (permission_mode in Python, permissionMode in TypeScript) controlla se l’agente chiede l’approvazione prima di utilizzare gli strumenti:
Per le applicazioni interattive, utilizzate
"default" con un callback di approvazione dello strumento per visualizzare i prompt di approvazione. Per gli agenti autonomi su una macchina di sviluppo, "acceptEdits" approva automaticamente le modifiche ai file e i comandi comuni del filesystem (mkdir, touch, mv, cp, ecc.) mentre ancora limita altri comandi Bash dietro le regole di consentimento. Riservate "bypassPermissions" per CI, container o altri ambienti isolati. Vedere Autorizzazioni per i dettagli completi.
Modello
Impostare l’opzionemodel per scegliere quale modello esegue la sessione. Per ulteriori informazioni, vedere Scegliere un modello.
La finestra di contesto
La finestra di contesto è la quantità totale di informazioni disponibili a Claude durante una sessione. Non si ripristina tra i turni all’interno di una sessione. Tutto si accumula: il prompt di sistema, le definizioni degli strumenti, la cronologia della conversazione, gli input degli strumenti e gli output degli strumenti. Il contenuto che rimane lo stesso tra i turni (prompt di sistema, definizioni degli strumenti, CLAUDE.md) viene automaticamente prompt cached, il che riduce il costo e la latenza per i prefissi ripetuti. Per come un prompt di sistema personalizzato o il testoappend influisce sul riutilizzo della cache tra le sessioni, vedere Modifying system prompts.
Cosa consuma il contesto
Ecco come ogni componente influisce sul contesto nell’SDK:
I grandi output degli strumenti consumano un contesto significativo. Leggere un file grande o eseguire un comando con output dettagliato può utilizzare migliaia di token in un singolo turno. Il contesto si accumula nel corso dei turni, quindi le sessioni più lunghe con molte chiamate di strumenti accumulano significativamente più contesto rispetto a quelle brevi.
Compattazione automatica
Quando la finestra di contesto si avvicina al suo limite, l’SDK compatta automaticamente la conversazione: riassume la cronologia più vecchia per liberare spazio, mantenendo intatti gli scambi più recenti e le decisioni chiave. L’SDK emette un messaggio contype: "system" e subtype: "compact_boundary" nel flusso quando questo accade (in Python questo è un SystemMessage; in TypeScript è un tipo separato SDKCompactBoundaryMessage).
La compattazione sostituisce i messaggi più vecchi con un riassunto, quindi le istruzioni specifiche dall’inizio della conversazione potrebbero non essere preservate. Le regole persistenti appartengono a CLAUDE.md (caricato tramite settingSources) piuttosto che al prompt iniziale, perché il contenuto di CLAUDE.md viene reiniettato ad ogni richiesta.
Potete personalizzare il comportamento della compattazione in diversi modi:
- Istruzioni di riassunto in CLAUDE.md: Il compattatore legge il vostro CLAUDE.md come qualsiasi altro contesto, quindi potete includere una sezione che gli dice cosa preservare quando riassume. Il compattatore corrisponde all’intento, quindi l’intestazione della sezione è libera.
- Hook
PreCompact: Eseguire logica personalizzata prima che si verifichi la compattazione, ad esempio per archiviare la trascrizione completa. L’hook riceve un campotrigger(manualoauto). Vedere hooks. - Compattazione manuale: Inviare
/compactcome stringa di prompt per attivare la compattazione su richiesta. I comandi inviati in questo modo sono input SDK ordinari. Vedere dispatch commands by name.
Esempio: Istruzioni di riassunto in CLAUDE.md
Esempio: Istruzioni di riassunto in CLAUDE.md
Aggiungete una sezione al vostro CLAUDE.md del progetto dicendo al compattatore cosa preservare. Il nome dell’intestazione non è speciale; utilizzate qualsiasi etichetta chiara.
CLAUDE.md
Mantenere il contesto efficiente
Alcune strategie per gli agenti a lunga durata:- Usa i subagent per le sottoattività. Ogni subagent inizia con una conversazione nuova (nessuna cronologia di messaggi precedenti, anche se carica il proprio prompt di sistema e il contesto a livello di progetto come CLAUDE.md). Non vede i turni del genitore e solo la sua risposta finale ritorna al genitore. Il contesto dell’agente principale cresce per quel riassunto, non per la trascrizione completa della sottoattività. Consulta Cosa ereditano i subagent per i dettagli.
- Essere selettivi con gli strumenti. Ogni definizione di strumento occupa spazio di contesto. Utilizzate il campo
toolssuAgentDefinitionper limitare i subagenti al set minimo di cui hanno bisogno. - Controllare i costi dei server MCP. MCP tool search differisce gli schemi degli strumenti MCP per impostazione predefinita e li carica su richiesta. Quando la ricerca degli strumenti è disattivata o ha ricaduto nel caricamento anticipato, ogni server MCP aggiunge tutti i suoi schemi di strumenti ad ogni richiesta, quindi pochi server con molti strumenti possono consumare un contesto significativo prima che l’agente faccia qualsiasi lavoro. Vedere Configure tool search per le configurazioni in cui si applica il fallback.
- Utilizzare uno sforzo inferiore per attività di routine. Impostare effort a
"low"per gli agenti che hanno solo bisogno di leggere file o elencare directory. Questo riduce l’utilizzo dei token e il costo.
Sessioni e continuità
Ogni interazione con l’SDK crea o continua una sessione. Catturate l’ID della sessione daResultMessage.session_id (disponibile in entrambi gli SDK) per riprendere in seguito. L’SDK TypeScript lo espone anche come campo diretto sul SystemMessage init; in Python è annidato in SystemMessage.data.
Quando riprendete, il contesto completo dai turni precedenti viene ripristinato: file che sono stati letti, analisi che è stata eseguita e azioni che sono state intraprese. Potete anche fare un fork di una sessione per diramarvisi in un approccio diverso senza modificare l’originale.
Vedere Gestione della sessione per la guida completa sui pattern di ripresa, continuazione e fork. Per riprendere sessioni tra container stateless o host serverless, passate un adattatore session_store / sessionStore in modo che l’SDK rispecchi i transcript nel vostro backend e un altro host possa riprenderli. Il subprocess Claude Code scrive comunque prima su disco locale. Vedere Architettura dual-write per quale copia sopravvive a una sessione nuova rispetto a un’esecuzione ripresa dallo store, e come mantenere la copia locale effimera.
In Python,
ClaudeSDKClient gestisce gli ID di sessione automaticamente tra più chiamate. Vedere il riferimento SDK Python per i dettagli.Gestire il risultato
Quando il ciclo termina, ilResultMessage vi dice cosa è successo e vi fornisce l’output. Il campo subtype (disponibile in entrambi gli SDK) è il modo principale per controllare lo stato di terminazione.
Il campo
result contiene l’output di testo finale ed è presente solo sulla variante success, quindi controllate sempre il sottotipo prima di leggerlo.
Tutti i sottotipi di risultato portano total_cost_usd, usage, num_turns e session_id in modo che possiate tracciare il costo e riprendere anche dopo gli errori. Proteggete questi casi:
- Dopo un arresto anomalo della sessione, il risultato finale è un
error_during_executioni cui campi di costo possono essere azzerati e il cuistop_reasonènull, e il processo esce dopo averlo emesso. Vedere Recuperare i totali dopo un arresto anomalo della sessione. - In Python,
total_cost_usd,usageemodel_usagesono tipizzati come opzionali, quindi controllate che non sianoNoneprima di leggerli.
usage copre solo il ciclo principale dell’agente. Utilizzate modelUsage, o model_usage in Python, per la contabilità completa dei token e dei costi dell’albero. Vedere Tracciamento di costi e utilizzo per i dettagli sull’interpretazione dei campi usage.
Quando una query termina con un risultato di errore:
- Una singola chiamata
query()produce il messaggio di risultato finale, quindi genera un errore che include il testo dell’errore, comeReached maximum number of turns. L’eccezione è intenzionale. Avvolgete il ciclo in un blocco try se il vostro codice deve continuare oltre. Anche il processo Claude Code sottostante esce con un codice diverso da zero. - Una sessione di input in streaming rimane attiva e potete continuare a inviare messaggi, tranne dopo un arresto anomalo della sessione, che emette un risultato
error_during_executionfinale e esce dal processo.
stop_reason (string | null in TypeScript, str | None in Python) che indica perché il modello ha smesso di generare al suo turno finale. I valori comuni sono end_turn (il modello ha terminato normalmente), max_tokens (ha raggiunto il limite di token di output) e refusal (il modello ha rifiutato la richiesta). Su risultati di errore che il ciclo ha prodotto, stop_reason porta il valore dall’ultima risposta dell’assistente prima che il ciclo terminasse; il risultato che Claude Code sintetizza dopo un arresto anomalo della sessione porta null.
Per rilevare i rifiuti, controllate stop_reason === "refusal" (TypeScript) o stop_reason == "refusal" (Python). Vedere SDKResultMessage (TypeScript) o ResultMessage (Python) per il tipo completo.
Hooks
Hooks sono callback che si attivano in punti specifici del ciclo: prima che uno strumento venga eseguito, dopo che ritorna, quando l’agente termina e così via. Alcuni hook comunemente utilizzati sono:
Gli hook vengono eseguiti nel vostro processo di applicazione, non all’interno della finestra di contesto dell’agente, quindi non consumano contesto. Gli hook possono anche cortocircuitare il ciclo: un hook
PreToolUse che rifiuta una chiamata di strumento impedisce che venga eseguita e Claude riceve il messaggio di rifiuto invece.
Entrambi gli SDK supportano tutti gli eventi precedenti. L’SDK TypeScript include eventi aggiuntivi che Python non supporta ancora. Vedere Controllare l’esecuzione con gli hooks per l’elenco completo degli eventi, la disponibilità per SDK e l’API di callback completa.
Mettere tutto insieme
Questo esempio combina i concetti chiave di questa pagina in un singolo agente che corregge i test falliti. Configura l’agente con strumenti consentiti (pre-approvati in modo che l’agente funzioni autonomamente), impostazioni del progetto e limiti di sicurezza su turni e sforzo di ragionamento. Mentre il ciclo viene eseguito, cattura l’ID della sessione per una potenziale ripresa, gestisce il risultato finale e stampa il costo totale. Poiché una singola chiamataquery() genera un’eccezione dopo aver restituito un risultato di errore, il ciclo è avvolto in un blocco try in modo che lo script esca correttamente quando viene raggiunto un limite.
Done: con il riepilogo della correzione dell’agente, quindi una riga come Cost: $0.0312.
Passaggi successivi
Ora che comprendete il ciclo, ecco dove andare a seconda di ciò che state costruendo:- Non avete ancora eseguito un agente? Iniziate con la quickstart per ottenere l’SDK installato e vedere un esempio completo in esecuzione da capo a fondo.
- Pronti a collegarvi al vostro progetto? Caricate CLAUDE.md, skills e filesystem hooks in modo che l’agente segua automaticamente le convenzioni del vostro progetto.
- State costruendo un’interfaccia utente interattiva? Abilitate lo streaming per mostrare testo e chiamate di strumenti in tempo reale mentre il ciclo viene eseguito.
- Avete bisogno di un controllo più stretto su ciò che l’agente può fare? Bloccate l’accesso agli strumenti con autorizzazioni e utilizzate hooks per controllare, bloccare o trasformare le chiamate di strumenti prima che vengano eseguite.
- State eseguendo attività lunghe o costose? Delegate il lavoro isolato ai subagenti per mantenere il vostro contesto principale snello.
- Distribuendo come servizio? Consultate Hosting dell’Agent SDK per indicazioni su container e serverless, e Archiviazione della sessione per persistere le sessioni al vostro backend.