Ragionamento preservato
Il ragionamento preservato consente a un modello di usare un blocco di ragionamento di un turno precedente solo se lo ha prodotto quel modello o uno di un insieme fisso di altri modelli e se nulla prima del blocco è cambiato.
Il "preserved thinking" (ragionamento preservato) è una proprietà dei modelli Claude più recenti che protegge dalla distillazione. Determina se il modello può usare un blocco di ragionamento che rimandi da un turno precedente. A partire da Claude Fable 5.1, quando un blocco thinking o redacted_thinking torna in una richiesta, l'API controlla la signature del blocco per due aspetti:
- Il modello può leggere il blocco. Ogni modello legge i propri blocchi di ragionamento e quelli di un insieme fisso di altri modelli. Claude Fable 5.1 legge i blocchi di Claude Opus 5 e, sulla Claude API, di Claude Opus 5.5; né Claude Opus 5 né Claude Opus 5.5 leggono i blocchi di Claude Fable 5.1. Se il modello corrente non può leggere un blocco, l'API lo scarta da quella richiesta senza errori. Consulta Cambiare modello a metà conversazione.
- Nulla prima del blocco di ragionamento è cambiato. Il prompt
systemdi primo livello, itoolse imessagesche precedono il blocco costituiscono il suo "prefix" (prefisso). Se il prefisso differisce da quello che hai inviato quando il blocco è stato prodotto, quel blocco e ogni blocco di ragionamento successivo non sono validi, e l'API rifiuta la richiesta con un errore 400 oppure scarta i blocchi non validi, a tua scelta. Consulta Mantenere invariato il prefisso.
Anche i blocchi di ragionamento di Claude Sonnet 5.5 e Claude Haiku 5.5 sono legati all'account che li ha prodotti. Consulta I blocchi di ragionamento restano con l'account che li ha prodotti per sapere dove l'API applica questa regola.
Il controllo del modello si applica a ogni account. L'API applica il controllo del prefisso per impostazione predefinita agli account creati a partire dal 31 agosto 2026, 00:00 UTC. Sugli account più vecchi, applica il controllo del prefisso solo alle richieste che impostano thinking.block_binding.prefix_mismatch_behavior. Rendi la tua integrazione append-only indipendentemente dall'età del tuo account, così lo stesso codice funziona su ogni account, inclusi gli account più recenti soggetti al controllo per impostazione predefinita.
Chi deve modificare qualcosa
Non cambia nulla per te se le tue richieste vengono costruite da Claude Code, claude.ai, Claude Managed Agents o dal Claude Agent SDK, oppure se il tuo codice mantiene system e tools fissi per una sessione e si limita ad aggiungere elementi a messages. Claude Mythos 5.1 e i modelli precedenti a Claude Fable 5.1 non eseguono il controllo del prefisso. Se non rimandi mai i blocchi di ragionamento, il controllo del prefisso non ha nulla da rifiutare, e il modello non riceve nulla del suo ragionamento precedente.
Controlla la tua integrazione se, tra due richieste nella stessa conversazione, esegue una delle seguenti operazioni. Ogni voce rimanda a cosa fare invece:
- Ricostruisce il prompt
system: la data, un flag di modalità, istruzioni di progetto rilette, oppure un plugin o un server MCP che si connette dopo il primo turno - Rigenera il contesto nel primo messaggio utente
- Cancella o accorcia vecchi risultati degli strumenti, o ricodifica vecchie immagini
- Riassume o scarta vecchi turni sul client e mantiene i turni recenti con il loro ragionamento
- Aggiunge, rimuove o modifica voci in
tools - Aggiunge un promemoria a un turno utente e in seguito lo rimuove o lo riscrive
- Scarta alcuni blocchi
thinkinge mantiene quelli successivi, oppure li rimuove e in seguito li rimette - Ricostruisce una sessione salvata da template invece di riprodurre ciò che ha inviato
Su un account più vecchio, nessuna di queste operazioni produce un errore a meno che la richiesta non imposti prefix_mismatch_behavior, quindi un'esecuzione senza errori con la tua chiave non dimostra se il tuo codice è interessato. Se altre persone eseguono il tuo strumento con le proprie chiavi API, quelle con account più recenti riceveranno l'errore 400 prima di te. Per vedere ciò che vedono loro senza cambiare il comportamento delle tue richieste, invia l'header beta thinking-binding-controls-2026-08-01. Su un account più vecchio, ogni risposta segnala quindi i blocchi che non superano il controllo, e il modello continua a leggerli (consulta Imposta il comportamento in caso di mancata corrispondenza e leggi input_transformations).
Controlla la tua integrazione anche se invia blocchi di ragionamento di Claude Sonnet 5.5 o Claude Haiku 5.5 provenienti da un account in una richiesta effettuata da un account diverso. Consulta I blocchi di ragionamento restano con l'account che li ha prodotti.
Cambiare modello a metà conversazione
Claude Fable 5.1 e Claude Mythos 5.1 leggono i blocchi di ragionamento prodotti l'uno dall'altro e dai modelli Claude precedenti. Nessun altro modello legge i blocchi di ragionamento di Claude Fable 5.1 o Claude Mythos 5.1.
Claude Opus 5.5 legge i blocchi di ragionamento di Claude Opus 5, dei modelli Opus, Sonnet e Haiku precedenti e, sulla Claude API e su Google Cloud, di Claude Sonnet 5.5 e Claude Haiku 5.5, ma non dei modelli Claude Fable o Claude Mythos. Sulla Claude API, Claude Fable 5.1 e Claude Mythos 5.1 leggono i blocchi di ragionamento di Claude Opus 5.5; nessun altro modello lo fa. Quindi una conversazione che passa da Claude Opus 5 a Claude Opus 5.5 mantiene il suo ragionamento, e lo stesso vale per una che passa da Claude Opus 5.5 a Claude Fable 5.1 o Claude Mythos 5.1 sulla Claude API. Una conversazione che passa da Claude Fable 5.1 o Claude Mythos 5.1 a Claude Opus 5.5, oppure da Claude Opus 5.5 a qualsiasi modello diverso da quei due, esegue i turni successivi al cambio senza il ragionamento del modello precedente. I blocchi vengono scartati, non rifiutati, come descritto più avanti in questa sezione.
Claude Sonnet 5.5 legge i blocchi di ragionamento di Claude Sonnet 5, Claude Opus 4.8, Claude Haiku 4.5 e dei modelli precedenti e, sulla Claude API e su Google Cloud, di Claude Haiku 5.5, ma non di Claude Opus 5, Claude Opus 5.5 o di qualsiasi modello Claude Fable o Claude Mythos. Sulla Claude API e su Google Cloud, Claude Opus 5.5 legge i blocchi di ragionamento di Claude Sonnet 5.5; nessun altro modello lo fa. Quindi una conversazione che passa da Claude Sonnet 5 a Claude Sonnet 5.5 mantiene il suo ragionamento, e lo stesso vale per una che passa da Claude Sonnet 5.5 a Claude Opus 5.5 sulla Claude API e su Google Cloud. Una conversazione che passa a Claude Sonnet 5.5 da Claude Opus 5, Claude Opus 5.5 o da un modello Claude Fable o Claude Mythos esegue i turni successivi al cambio senza il ragionamento del modello precedente. Lo stesso vale per qualsiasi altro passaggio da Claude Sonnet 5.5, ad esempio un fallback lato server a Claude Sonnet 5.
Claude Haiku 5.5 legge i blocchi di ragionamento di Claude Sonnet 5, Claude Opus 4.8, Claude Haiku 4.5 e dei modelli precedenti, ma non di Claude Opus 5, Claude Opus 5.5, Claude Sonnet 5.5 o di qualsiasi modello Claude Fable o Claude Mythos. Sulla Claude API e su Google Cloud, Claude Opus 5.5 e Claude Sonnet 5.5 leggono i blocchi di ragionamento di Claude Haiku 5.5; nessun altro modello lo fa. Quindi una conversazione che passa da Claude Haiku 4.5 a Claude Haiku 5.5 mantiene il suo ragionamento, così come una che passa da Claude Haiku 5.5 a Claude Opus 5.5 o Claude Sonnet 5.5 sulla Claude API e su Google Cloud. Una conversazione che passa a Claude Haiku 5.5 da Claude Opus 5, Claude Opus 5.5, Claude Sonnet 5.5 o da un modello Claude Fable o Claude Mythos esegue i turni successivi al cambio senza il ragionamento del modello precedente, e lo stesso vale per qualsiasi altro passaggio da Claude Haiku 5.5.
- Una conversazione che passa a Claude Fable 5.1 da un modello precedente, o da Claude Opus 5.5 sulla Claude API, mantiene il suo ragionamento. I blocchi di ragionamento del modello precedente restano leggibili, quindi il modello ragiona normalmente fin dal primo turno dopo il cambio.
- Una conversazione che passa da Claude Fable 5.1 a qualsiasi modello diverso da Claude Mythos 5.1 perde il ragionamento di Claude Fable 5.1 per quella richiesta. Questo accade quando un router invia un turno a un modello più economico, dopo un fallback per rifiuto del classificatore, oppure durante un fallback lato server. L'API rimuove i blocchi illeggibili prima che il prompt raggiunga il modello. Non vengono fatturati e non contano ai fini di
input_tokens.
Continua a inviare la cronologia completa a ogni richiesta, blocchi di ragionamento inclusi, e lascia che l'API scarti ciò che il modello corrente non può leggere. L'API non modifica mai il tuo array messages, quindi i blocchi scartati restano nella tua cronologia. Quando la stessa cronologia torna a Claude Fable 5.1, i suoi blocchi sono di nuovo leggibili, insieme al ragionamento del modello precedente. Il ragionamento va perso definitivamente solo se è il tuo client a rimuovere i blocchi, ad esempio un harness che elimina il ragionamento a ogni cambio di modello o che ricostruisce la cronologia in base a ciò che ogni modello ha usato.
Con l'header beta thinking-binding-controls-2026-08-01, la risposta elenca ogni blocco scartato in un array input_transformations di primo livello con reason: "model_binding_mismatch":
{
"input_transformations": [
{
"type": "thinking_dropped",
"path": "messages.3.content.0",
"reason": "model_binding_mismatch"
}
]
}Senza l'header, lo scarto avviene in modo silenzioso. Questa voce non indica un bug nella tua integrazione, e prefix_mismatch_behavior non ha alcun effetto su di essa: un blocco che il modello corrente non può leggere viene sempre scartato.
I blocchi di ragionamento restano con l'account che li ha prodotti
I blocchi di ragionamento prodotti da Claude Sonnet 5.5 o Claude Haiku 5.5 funzionano solo nell'account che li ha prodotti, o in un account collegato a esso. Quando un altro account invia uno di questi blocchi, l'API scarta il blocco prima che il modello lo veda, e la richiesta va a buon fine. Il modello risponde senza il ragionamento contenuto nei blocchi scartati. I blocchi dei modelli precedenti non sono interessati.
Sulla Claude API e su Google Cloud, con l'header beta thinking-binding-controls-2026-08-01, la risposta elenca ogni blocco scartato in input_transformations come voce thinking_dropped con reason: "organization_binding_mismatch". Senza l'header, lo scarto avviene in modo silenzioso.
Mantenere invariato il prefisso
Su Claude Fable 5.1, Claude Opus 5.5, Claude Sonnet 5.5 e Claude Haiku 5.5, un blocco di ragionamento resta valido solo finché tutto ciò che hai inviato prima di esso rimane invariato nelle richieste successive. Il prefisso controllato ha tre parti:
- Il prompt
systemdi primo livello - L'insieme dei
tools - Ogni
messageprima del blocco
Nota: con la compattazione lato server, il prefisso controllato inizia dal blocco di compattazione più recente.
I parametri della richiesta al di fuori di questi tre campi, come effort, max_tokens, output_config, tool_choice e metadata, non fanno parte del controllo del prefisso, e nemmeno i marcatori cache_control. Cosa conta come modifica contiene l'elenco completo.
I blocchi di ragionamento precedenti non fanno parte del prefisso, ma ogni blocco di ragionamento registra quale blocco di ragionamento lo ha preceduto, attraverso i turni. Puoi rimuovere blocchi di ragionamento dall'inizio della cronologia (dal più vecchio), dalla fine, oppure tutti. Ciò che non funziona è un buco: i blocchi di ragionamento che mantieni devono formare una sequenza ininterrotta di quella originale, quindi rimuoverne uno dal centro invalida i blocchi di ragionamento successivi. Una volta rimosso un blocco, lascialo fuori. Rimetterlo invalida i blocchi di ragionamento prodotti mentre era assente.
Mantieni system e tools fissi per la sessione e tratta messages come append-only. La stessa disciplina mantiene stabile il prefisso per il "prompt caching" (cache dei prompt): le modifiche che invalidano il ragionamento sono le stesse che fanno ripartire la cache.
Cosa fa l'API con un blocco non valido
Lo scegli con thinking.block_binding.prefix_mismatch_behavior:
"error"(predefinito): l'API rifiuta la richiesta con un errore 400invalid_request_errorche indica il primo blocco non valido."drop_block": l'API rimuove ogni blocco non valido e ogni blocco di ragionamento successivo, e la richiesta va a buon fine. I blocchi rimossi non vengono fatturati. Il modello risponde a quel turno senza usare il ragionamento dei blocchi rimossi, e la cache dei prompt riparte dal punto della modifica. La risposta elenca ogni blocco rimosso ininput_transformations(nell'eventomessage_startdurante lo streaming) conreason: "prefix_binding_mismatch".
Conta le risposte di ogni sessione il cui input_transformations contiene una voce prefix_binding_mismatch, imposta avvisi su di esse e sostituisci ogni modifica con lo schema corrispondente in Apportare modifiche senza modificare il prefisso. Nella Message Batches API, un elemento che lascia il campo non impostato non fallisce. Dove l'API applica il controllo per impostazione predefinita, rimuove invece i blocchi non validi. In quel caso, imposta esplicitamente "error" se vuoi che gli elementi del batch falliscano.
Sia il campo sia l'array input_transformations richiedono l'header beta thinking-binding-controls-2026-08-01. Imposta il comportamento in caso di mancata corrispondenza e leggi input_transformations mostra la richiesta in ogni "software development kit" (kit di sviluppo software), o SDK.
Il messaggio 400 inizia così:
messages.1.content.0: Invalid `signature` in `thinking` block. The block is bound to a different conversation. Remove the block, or set `thinking.block_binding.prefix_mismatch_behavior` to "drop_block".Se la richiesta non ha inviato l'header beta, il messaggio prosegue:
That setting requires the `thinking-binding-controls-2026-08-01` value in the `anthropic-beta` header.Di solito termina con una frase che indica cosa è cambiato, ad esempio che il prompt di sistema system o l'elenco tools differisce da quando il blocco è stato creato. Risoluzione dei problemi del ragionamento descrive cosa può indicare quella frase.
Una firma manomessa o non decifrabile è un errore diverso. Restituisce sempre un 400 (Invalid `signature` in `thinking` block senza alcuna frase sulla conversazione), e prefix_mismatch_behavior non si applica.
Costo in token di output di "drop_block"
Nei test di Anthropic su un benchmark di coding multi-turno, rimuovere i blocchi di ragionamento una volta per sessione ha aumentato i token di output del 2,5% con effort basso, del 3,9% con medio, del 4,5% con alto e del 20,1% con max. Rimuoverli a ogni turno dopo il primo ha aumentato i token di output del 4,6% con effort basso, del 9,7% con medio, del 10,3% con alto e del 67,1% con max. Queste cifre sono stime con ampi margini di errore, e l'impatto sul tuo carico di lavoro dipende dal tuo harness.
Quando Claude non può più leggere il ragionamento dei turni precedenti, lo ricrea, quindi le richieste che rimuovono blocchi di ragionamento generano più token di output e possono richiedere più tempo per rispondere. Una rimozione a ogni turno costa più di una rimozione occasionale, e quanto di più dipende dal tuo harness: quanto spesso modifica il prefisso e quanto ogni turno si basa sul ragionamento precedente.
Prima di affidarti a "drop_block", esegui valutazioni sul tuo carico di lavoro per misurare l'aumento. Se è piccolo, "drop_block" può far andare a buon fine le richieste mentre correggi la modifica. In ogni caso, correggere la modifica con uno degli schemi in Apportare modifiche senza modificare il prefisso è una soluzione migliore a lungo termine.
Gestisci l'errore nel codice
Si tratta dell'errore 400 invalid_request_error mostrato in precedenza in questa sezione. Non reinviare lo stesso corpo: fallisce allo stesso modo ogni volta. Riprova una volta con l'header beta e prefix_mismatch_behavior: "drop_block", come soluzione temporanea ("drop_block" può aumentare i token di output), e memorizza questa scelta con la sessione in modo che anche ogni richiesta successiva la invii, anche dopo un riavvio. Su Claude Sonnet 5.5 e Claude Haiku 5.5, block_binding funziona solo con thinking: {"type": "adaptive"}. Con between_tools su Claude Sonnet 5.5, o thinking: {"type": "disabled"} su Claude Haiku 5.5, mantieni la cronologia in sola aggiunta, oppure elimina i blocchi di ragionamento dal turno modificato in poi. Se non puoi inviare l'header beta, rimuovi una volta ogni blocco thinking e redacted_thinking dalla cronologia, lasciali fuori e continua. Poi correggi la modifica che ha causato la mancata corrispondenza.
Imposta il comportamento in caso di mancata corrispondenza e leggi input_transformations
L'header beta thinking-binding-controls-2026-08-01 aggiunge:
- Un array
input_transformationsdi primo livello in ogni risposta - Un oggetto
block_bindingnella configurazionethinking, il cui unico campo èprefix_mismatch_behavior
block_binding è accettato insieme a thinking.type: "adaptive" e thinking.type: "enabled". Su Claude Sonnet 5.5 e Claude Haiku 5.5, block_binding funziona solo con thinking: {"type": "adaptive"}. Inviarlo con between_tools su Claude Sonnet 5.5, o con thinking: {"type": "disabled"} su Claude Haiku 5.5, restituisce un errore 400. Inviarlo senza l'header beta restituisce un errore 400 il cui messaggio termina con block_binding: Extra inputs are not permitted. I modelli che non eseguono il controllo del prefisso accettano l'oggetto e segnalano solo gli scarti dovuti al controllo del modello, quindi un unico corpo di richiesta funziona con tutti i modelli. Il riferimento dell'API chiama il controllo del prefisso "conversation check" (controllo della conversazione).
La seguente richiesta sceglie di scartare anziché rifiutare. In un primo turno non c'è nulla da riprodurre, quindi input_transformations torna vuoto:
client = anthropic.Anthropic()
response = client.beta.messages.create(
model="claude-fable-5-1",
max_tokens=16000,
thinking={
"type": "adaptive",
"block_binding": {"prefix_mismatch_behavior": "drop_block"},
},
messages=[
{
"role": "user",
"content": "What is the greatest common divisor of 1071 and 462?",
}
],
betas=["thinking-binding-controls-2026-08-01"],
)
for block in response.content:
if block.type == "text":
print(block.text)
print(f"Input transformations: {len(response.input_transformations or [])}")The greatest common divisor of 1071 and 462 is 21.
Input transformations: 0Con l'header beta, ogni risposta di un modello con capacità di ragionamento contiene input_transformations. Ogni voce identifica un blocco di ragionamento tramite il suo path (ad esempio messages.1.content.0) e fornisce un reason. Esistono due tipi di voce:
thinking_dropped: l'API scarta il blocco prima che il modello lo legga, e il blocco non viene fatturato. Ilreasonèprefix_binding_mismatchomodel_binding_mismatch(consulta Cambiare modello a metà conversazione). Ilreasonpuò anche essereorganization_binding_mismatch, che significa che il blocco proviene da un altro account (consulta I blocchi di ragionamento restano con l'account che li ha prodotti).thinking_mismatch_allowed: il blocco non supera il controllo del prefisso, ma l'API non applica quel controllo per questa richiesta, quindi il blocco raggiunge il modello invariato e viene fatturato. Ilreasonè sempreprefix_binding_mismatch. Questa voce compare solo nelle richieste in cui l'API non applica il controllo per impostazione predefinita, come quelle di un account più vecchio (consulta Quando l'API applica il controllo). Impostareprefix_mismatch_behaviorsu uno qualsiasi dei due valori attiva l'applicazione del controllo per la richiesta, quindi una richiesta che lo imposta non riceve mai questa voce.
L'array è vuoto quando nessun blocco è stato scartato e nessuno ha fallito il controllo del prefisso. Ignora le voci il cui type o reason non riconosci, perché controlli futuri aggiungeranno nuovi valori.
Durante lo streaming, l'array arriva nell'oggetto message dell'evento message_start. Dopo un fallback lato server a metà stream, l'evento message_delta finale lo riporta di nuovo con le voci del modello che ha servito la richiesta. In un batch di messaggi, un elemento il cui blocco non supera il controllo del prefisso con un "error" esplicito si risolve come errored. Un elemento che lascia il campo non impostato non fallisce. Dove l'API applica il controllo per impostazione predefinita, scarta invece i blocchi non validi. L'endpoint di conteggio dei token esegue lo stesso controllo del prefisso e restituisce lo stesso 400.
Quando l'API applica il controllo
L'API applica il controllo del prefisso su Claude Fable 5.1, Claude Opus 5.5, Claude Sonnet 5.5 e Claude Haiku 5.5 per i nuovi account.
- Account creati a partire dal 31 agosto 2026, 00:00 UTC: l'API controlla le richieste a Claude Fable 5.1, Claude Opus 5.5, Claude Sonnet 5.5 e Claude Haiku 5.5 e applica
"error"a meno che tu non imposti"drop_block". La stessa definizione di nuovo account si applica alla Claude API e alle piattaforme cloud. - Account più vecchi: l'API applica il controllo solo alle richieste che impostano
prefix_mismatch_behavior. Impostare il campo attiva il controllo per una richiesta, così puoi vedere ciò che vede un nuovo account senza crearne uno. Nelle richieste che lo lasciano non impostato, l'API esegue comunque il controllo ma lascia passare i blocchi non validi al modello. Con l'header beta, la risposta elenca ciascuno di essi ininput_transformationscomethinking_mismatch_allowed, così puoi individuare le modifiche al prefisso senza cambiare ciò che il modello riceve.
Per scoprire a quale gruppo appartiene il tuo account, prendi una conversazione con Claude Fable 5.1 che contiene un blocco di ragionamento, modifica qualcosa prima di quel blocco e inviala a Claude Fable 5.1 senza l'header beta né il campo block_binding. Una risposta 400 che menziona l'header significa che il tuo account è soggetto al controllo per impostazione predefinita. Una risposta 200 significa che non lo è. Per conferma, invia di nuovo la stessa richiesta con l'header beta, sempre senza block_binding: la risposta elenca ogni blocco di ragionamento successivo alla tua modifica in input_transformations come thinking_mismatch_allowed.
Cosa conta come modifica
Ogni riga confronta due richieste consecutive:
| Modifica tra le richieste | Blocchi di ragionamento successivi |
|---|---|
| Aggiungere messaggi alla fine | Validi |
Aggiungere uno strumento con defer_loading: true a cui nulla ha ancora fatto riferimento | Validi |
Rimuovere blocchi thinking dall'inizio della cronologia, dalla fine, oppure rimuoverli tutti | Validi (il modello perde quel ragionamento) |
Modificare qualsiasi parametro della richiesta al di fuori di system, tools e messages (effort, max_tokens, output_config, tool_choice, metadata, thinking.display e così via) | Validi |
Aggiungere, spostare o rimuovere marcatori cache_control | Validi |
| Un URL firmato a rotazione che restituisce gli stessi byte | Validi |
| La compattazione lato server o la modifica del contesto rimuove o sostituisce contenuti | Validi (il controllo confronta ciò che hai inviato, non la copia modificata dal server) |
| Un messaggio di sistema con ambito di turno già cancellato e lasciato al suo posto | Validi |
Modificare, riordinare o eliminare qualsiasi messaggio user, assistant o system precedente | Non validi, tranne quando il blocco firmato della compattazione on-demand sostituisce i messaggi che riassume, alle condizioni per il ragionamento mantenuto |
| Rigenerare con un valore modificato il contesto inserito nel primo messaggio utente | Non validi per ogni blocco di ragionamento |
Cancellare o accorciare un tool_result precedente, ricodificare un'immagine precedente o modificare l'input di un tool_use precedente | Non validi per ogni blocco di ragionamento successivo |
| Aggiungere un blocco di testo a un turno utente precedente, o rimuoverne uno aggiunto l'ultima volta | Non validi |
Modificare la stringa o i blocchi system di primo livello | Non validi |
Aggiungere, rimuovere, rinominare o modificare uno strumento in tools | Non validi |
Rimuovere un blocco thinking dal centro della cronologia e mantenere quelli successivi | Non validi per ogni blocco di ragionamento successivo |
Reinserire un blocco thinking rimosso in una richiesta precedente | Non validi per i blocchi di ragionamento prodotti mentre era assente |
| Un URL di immagine o documento che restituisce byte diversi alla richiesta successiva | Non validi |
| Lo stesso messaggio con ambito di turno eliminato o riformulato in una richiesta successiva | Non validi |
Verifica se il tuo codice modifica il prefisso
Per prima cosa, confronta ciò che invii. Acquisisci i corpi delle richieste che la tua integrazione invia nel corso di alcuni turni normali, inclusa una compattazione o una modifica degli strumenti. Per ogni coppia di richieste consecutive, confronta system, tools e i messages che hanno in comune. Devono essere identici fino ai turni appena aggiunti.
Poi verifica con l'API. Aggiungi l'header beta thinking-binding-controls-2026-08-01, imposta prefix_mismatch_behavior su "drop_block" ed esegui una normale sessione multi-turno tramite la tua integrazione su . L'esempio seguente esegue due turni nel modo in cui dovrebbe farlo la tua integrazione: messages cresce soltanto, ogni turno dell'assistente viene rimandato esattamente come l'API lo ha restituito, blocchi thinking inclusi, e block_binding è impostato in ogni richiesta. Dopo ogni turno stampa il numero di blocchi thinking nella risposta e il numero di blocchi scartati:
client = anthropic.Anthropic()
user_turns = [
"How many positive integers below 500 have exactly 6 positive divisors?",
"How many of those are odd?",
]
# messages cresce a ogni turno: ogni turno dell'assistente viene rinviato esattamente come restituito
messages = []
for user_turn in user_turns:
messages.append({"role": "user", "content": user_turn})
response = client.beta.messages.create(
model="claude-fable-5-1",
max_tokens=16000,
thinking={
"type": "adaptive",
"block_binding": {"prefix_mismatch_behavior": "drop_block"},
},
messages=messages,
betas=["thinking-binding-controls-2026-08-01"],
)
messages.append({"role": "assistant", "content": response.content})
thinking_blocks = sum(block.type == "thinking" for block in response.content)
dropped = len(response.input_transformations or [])
print(f"thinking blocks: {thinking_blocks}, dropped: {dropped}")thinking blocks: 1, dropped: 0
thinking blocks: 1, dropped: 0Nessuno dei due turni scarta un blocco perché nulla di precedente è cambiato. Verifica che la prima risposta contenga un blocco thinking. Con il ragionamento adattivo, alcune risposte non ne hanno. Se nessuna risposta della sessione ne contiene uno, non c'è nulla da controllare e il conteggio degli scarti è 0 qualunque cosa tu modifichi, quindi esegui di nuovo l'esempio.
Registra input_transformations a ogni turno della tua integrazione. Quando l'API scarta un blocco, la voce ha il seguente aspetto:
{
"input_transformations": [
{
"type": "thinking_dropped",
"path": "messages.1.content.0",
"reason": "prefix_binding_mismatch"
}
]
}- Vuoto a ogni turno di una sessione che contiene blocchi
thinking: la tua integrazione mantiene intatto il prefisso. reason: "prefix_binding_mismatch": qualcosa prima del blocco inpathè cambiato rispetto alla richiesta precedente. Confrontasystem,toolsemessagesfino a quel turno per individuarlo, oppure reinvia la richiesta con"error": il 400 di solito termina con una frase che indica cosa è cambiato. Poi trova la sostituzione corrispondente in Apportare modifiche senza modificare il prefisso.reason: "model_binding_mismatch": la conversazione è passata a un modello che non può leggere i blocchi del modello precedente. Non si tratta di una modifica al prefisso. Consulta Cambiare modello a metà conversazione.reason: "organization_binding_mismatch": il blocco proviene da un altro account. Consulta I blocchi di ragionamento restano con l'account che li ha prodotti.
Per provocare volutamente un errore, invia un terzo turno dall'esempio precedente e aggiungi un prompt system solo a quella richiesta, in modo che differisca dalle prime due richieste, che non ne avevano. Con "drop_block", il conteggio degli scarti non è più 0: la risposta contiene una voce per ogni blocco di ragionamento nella cronologia, ciascuna con reason: "prefix_binding_mismatch". Con "error", la richiesta restituisce il 400 descritto in Cosa fa l'API con un blocco non valido, e la sua ultima frase menziona il prompt system. Nelle schede cURL e CLI, rimuovi il filtro jq per vedere il corpo dell'errore. Se il conteggio è ancora 0, non c'era nulla da controllare: verifica che il modello sia , che la richiesta imposti block_binding, che la cronologia inviata contenga blocchi thinking e che le prime due richieste non avessero un prompt system.
Due semplici turni raramente mostrano il problema. Esegui una sessione per ciascuno dei seguenti casi, con "error" impostato in modo che una regressione faccia fallire la tua CI:
- La prima compattazione o riduzione lato client
- Uno strumento, un plugin o un server MCP che si connette dopo il primo turno
- Un cambio di modalità o di istruzioni
- Un lungo ciclo di strumenti, se aggiungi promemoria o accorci vecchi risultati degli strumenti
- Un passaggio a un altro modello e ritorno
- Un salvataggio, un riavvio e una ripresa in una data successiva
Su un account più vecchio, puoi anche monitorare il traffico di produzione senza attivare l'applicazione del controllo: invia l'header beta, ometti block_binding e registra input_transformations. Inviare solo l'header non cambia ciò che il modello riceve. Ogni blocco di ragionamento che segue il contenuto modificato non supera il controllo e riceve una propria voce thinking_mismatch_allowed, con gli stessi campi path e reason di una voce thinking_dropped. I blocchi precedenti alla modifica continuano a superarlo. Una modifica a system o tools precede ogni blocco, quindi fa fallire ogni blocco di ragionamento della richiesta. Una voce ha questo aspetto:
{
"input_transformations": [
{
"type": "thinking_mismatch_allowed",
"path": "messages.1.content.0",
"reason": "prefix_binding_mismatch"
}
]
}Esegui l'esempio seguente da un account più vecchio, perché un account più recente rifiuta la sua terza richiesta con il 400. Invia l'header senza block_binding ed estende la sessione precedente con una terza richiesta che aggiunge un prompt di sistema, modificando volutamente il prefisso. Dopo ogni turno stampa il numero di blocchi thinking e di blocchi segnalati:
client = anthropic.Anthropic()
user_turns = [
"How many positive integers below 500 have exactly 6 positive divisors?",
"How many of those are odd?",
"And how many of the odd ones are below 100?",
]
# messages cresce a ogni turno: ogni turno dell'assistente viene rinviato esattamente come restituito
messages = []
for turn, user_turn in enumerate(user_turns, start=1):
messages.append({"role": "user", "content": user_turn})
response = client.beta.messages.create(
model="claude-fable-5-1",
max_tokens=16000,
thinking={"type": "adaptive"},
# Solo l'ultima richiesta aggiunge un prompt di sistema, che modifica il prefisso di proposito
system="Answer briefly." if turn == len(user_turns) else anthropic.omit,
messages=messages,
betas=["thinking-binding-controls-2026-08-01"],
)
messages.append({"role": "assistant", "content": response.content})
thinking_blocks = sum(block.type == "thinking" for block in response.content)
flagged = sum(
transformation.type == "thinking_mismatch_allowed"
for transformation in response.input_transformations or []
)
print(f"thinking blocks: {thinking_blocks}, flagged: {flagged}")thinking blocks: 1, flagged: 0
thinking blocks: 1, flagged: 0
thinking blocks: 1, flagged: 2La terza risposta segnala ogni blocco di ragionamento dei turni precedenti, uno per turno in questa esecuzione, perché il nuovo prompt di sistema li precede tutti. Il modello li ha comunque letti.
Gestisci queste voci come faresti con gli scarti prefix_binding_mismatch. La modifica si trova prima del primo blocco elencato: confronta system, tools e messages fino al path di quel blocco con la richiesta precedente per individuarla, poi sostituiscila con lo schema corrispondente in Apportare modifiche senza modificare il prefisso. Su un nuovo account, o in qualsiasi richiesta che imposta prefix_mismatch_behavior, l'API invece rifiuta la richiesta o scarta i blocchi non validi. Le voci rappresentano un limite inferiore di ciò che l'applicazione del controllo rimuoverebbe: con "drop_block", un blocco non valido si porta dietro anche il resto dei blocchi di ragionamento di quel turno, e rimuovere un blocco può far fallire anche il successivo. Quando l'API si limita a registrare il controllo, giudica ogni blocco singolarmente ed elenca un blocco solo se quel blocco fallisce.
Apportare modifiche senza modificare il prefisso
Ogni modifica comune al prefisso ha una sostituzione che fornisce al modello le stesse informazioni e lascia invariati i byte precedenti, così il ragionamento successivo resta valido. Trova nella prima colonna la modifica che il tuo codice esegue oggi:
| Invece di | Usa | Header beta |
|---|---|---|
Ricostruire il prompt system di primo livello | Un messaggio di sistema a metà conversazione | Nessuno |
| Rigenerare il contesto nel primo messaggio utente (ambiente, data, memoria, istruzioni di progetto) a ogni richiesta | Generalo una volta e reinvialo invariato. Quando qualcosa cambia, inserisci la nuova versione nel turno più recente | Nessuno |
Cancellare o accorciare sul posto vecchi contenuti tool_result, o ricodificare vecchie immagini | Accorcia un risultato dello strumento o riduci la risoluzione di un'immagine prima di inviarli per la prima volta, non dopo. Per cancellare vecchi risultati in seguito, riduci il contesto sul server con clear_tool_uses_20250919 | context-management-2025-06-27 |
| Inserire un promemoria ed eliminarlo alla richiesta successiva | Un messaggio di sistema con ambito di turno (clear_at: "next_user_message") | mid-conversation-system-clear-at-2026-08-21 |
Aggiungere o rimuovere voci in tools | Blocchi tool_addition e tool_removal | inline-tools-2026-09-15 (aggiungi mcp-client-2026-09-15 quando lo strumento proviene da un server MCP connesso tramite il connettore MCP), oppure il più vecchio mid-conversation-tool-changes-2026-07-01, che funziona sulla Claude API, su Amazon Bedrock e su Google Cloud |
Modificare output_config.effort di primo livello (fa ripartire la cache, non influisce sul ragionamento) | Un output_config per messaggio | mid-conversation-output-config-2026-07-01 |
| Scartare o riassumere vecchi turni sul client | La compattazione su richiesta per mantenere i turni recenti con il loro ragionamento, altre forme di compattazione o modifica del contesto lato server, oppure una compattazione lato client che non mantiene ragionamento obsoleto | compact-2026-09-04 |
| Un URL di immagine o documento i cui byte cambiano tra le richieste | Un file_id dalla Files API, oppure base64 | Nessuno |
Tutte queste soluzioni presuppongono che tu rimandi i turni dell'assistente esattamente come restituiti. I messaggi di sistema a metà conversazione, i messaggi di sistema con ambito di turno e le modifiche agli strumenti non sono disponibili su tutti i modelli: Messaggi di sistema e modifiche agli strumenti a metà conversazione elenca i modelli che li accettano. Se il tuo codice serve più modelli, continua a modificare il prompt system di primo livello per i modelli che non li accettano.
Per usare più beta in una sola richiesta sulla Claude API, combina i loro nomi in un unico header anthropic-beta:
anthropic-beta: thinking-binding-controls-2026-08-01,mid-conversation-system-clear-at-2026-08-21,inline-tools-2026-09-15Le altre piattaforme che offrono queste beta usano gli stessi nomi. Per inviarle lì, consulta Funzionalità beta su altre piattaforme.
Rimanda i turni dell'assistente esattamente come restituiti
Memorizza l'array content di ogni risposta e rimandalo invariato come turno dell'assistente: ogni tipo di blocco, nell'ordine ricevuto, inclusi i blocchi thinking il cui campo thinking è vuoto. Un serializzatore che scarta tipi di blocco sconosciuti, scarta campi vuoti o riordina i blocchi modifica il prefisso per ogni turno successivo.
Su Claude Fable 5.1, Claude Opus 5.5, Claude Sonnet 5.5 e Claude Haiku 5.5, il campo thinking è vuoto per impostazione predefinita e la signature contiene il ragionamento, quindi un serializzatore che salta i blocchi vuoti rimuove il ragionamento. Se li rimuove tutti, nulla fallisce e il modello perde il suo ragionamento precedente a ogni turno. Se analizzi lo stream autonomamente, mantieni il blocco anche quando non arriva alcun testo di ragionamento: si apre, riceve la sua signature in un evento signature_delta e si chiude. Un blocco rimandato con una signature vuota fallisce.
Aggiungi istruzioni con un messaggio di sistema a metà conversazione
Alcuni harness ricostruiscono il prompt di sistema system di primo livello a ogni richiesta per includere l'ora corrente, un budget di token, un flag di modalità o contesto di progetto appena scoperto. Questo invalida ogni blocco di ragionamento della conversazione. Invece, congela system all'inizio della sessione. Quando qualcosa cambia, aggiungi un messaggio role: "system" nel punto di messages in cui il cambiamento diventa vero:
{
"role": "system",
"content": "The user switched the workspace to read-only mode. Do not write files until told otherwise."
}Il modello tratta questo messaggio con l'autorità di un prompt di sistema, e tutto ciò che lo precede resta invariato. In un ciclo di strumenti, posiziona il messaggio dopo il messaggio utente con il tool_result, mai tra un tool_use dell'assistente e il relativo tool_result (consulta Limitazioni). Una volta inviato, il messaggio fa parte del prefisso per il ragionamento successivo: lascialo al suo posto nelle richieste successive.
Inserisci il contesto che cambia nel turno più recente
Alcuni harness inseriscono un blocco di ambiente nel primo messaggio utente (directory di lavoro, branch, data, memoria, istruzioni di progetto) e lo rigenerano a ogni richiesta. Quando un valore cambia, messages[0] cambia, e ogni blocco di ragionamento della conversazione non è più valido. Genera quel blocco una volta e invialo di nuovo così com'era. Quando un valore cambia, segnalalo nel turno più recente: aggiungi un blocco di testo al messaggio utente che stai per inviare, oppure aggiungi un messaggio di sistema a metà conversazione se il cambiamento proviene da te in qualità di operatore.
{
"role": "user",
"content": [
{
"type": "text",
"text": "Environment update: the current branch is now release-2."
},
{ "type": "text", "text": "Run the tests again." }
]
}Una volta inviato, quel blocco di testo fa parte del prefisso per il ragionamento successivo: lascialo al suo posto nelle richieste successive.
Invia i promemoria per turno come messaggi di sistema con ambito di turno
Una modifica comune del prefisso è il promemoria per turno: una riga come "esegui insieme le letture indipendenti" o "non aggiorni l'utente da un po'" che il tuo codice aggiunge dopo ogni gruppo di risultati degli strumenti. Per evitare che i promemoria si accumulino, invia ogni promemoria come messaggio di sistema a metà conversazione con clear_at: "next_user_message", posizionato dopo il messaggio utente con il tool_result. clear_at richiede l'header beta mid-conversation-system-clear-at-2026-08-21. Il seguente array messages è la richiesta dopo due chiamate agli strumenti e i relativi risultati. messages[3] è il promemoria della richiesta precedente, lasciato al suo posto, e messages[6] è la copia di questa richiesta:
[
{ "role": "user", "content": "Fix the failing test." },
{
"role": "assistant",
"content": [
{ "type": "thinking", "thinking": "", "signature": "..." },
{
"type": "tool_use",
"id": "toolu_01",
"name": "read_file",
"input": { "path": "tests/test_auth.py" }
}
]
},
{
"role": "user",
"content": [{ "type": "tool_result", "tool_use_id": "toolu_01", "content": "..." }]
},
{
"role": "system",
"clear_at": "next_user_message",
"content": "Request every independent read in one turn."
},
{
"role": "assistant",
"content": [
{ "type": "thinking", "thinking": "", "signature": "..." },
{
"type": "tool_use",
"id": "toolu_02",
"name": "read_file",
"input": { "path": "src/auth.py" }
}
]
},
{
"role": "user",
"content": [{ "type": "tool_result", "tool_use_id": "toolu_02", "content": "..." }]
},
{
"role": "system",
"clear_at": "next_user_message",
"content": "Request every independent read in one turn."
}
]Un messaggio utente che contiene solo blocchi tool_result conta come "next user message" (messaggio utente successivo), quindi messages[3] è già cancellato. Non aggiunge nulla a ciò che il modello vede e non costa token di input, ma poiché è ancora nell'array, il ragionamento in messages[4] resta valido. messages[6] è la copia che il modello vede in questo turno. Nelle richieste successive, mantieni entrambi dove sono e aggiungi una nuova copia dopo il successivo messaggio tool_result.
Aggiungi o rimuovi strumenti con tool_addition e tool_removal
Modificare l'array tools a metà sessione invalida i "thinking blocks" (blocchi di ragionamento) preservati. Lascia l'array così come lo hai inviato la prima volta e cambia gli strumenti che il modello può usare aggiungendo un messaggio role: "system" che contiene blocchi tool_addition o tool_removal. Queste sono modifiche agli strumenti a metà conversazione e richiedono l'header beta inline-tools-2026-09-15, disponibile sulla Claude API. Il vecchio header mid-conversation-tool-changes-2026-07-01 funziona ancora per le modifiche che indicano uno strumento per riferimento, sulla Claude API, su Amazon Bedrock e su Google Cloud.
Hai due modi per usare questi blocchi:
- Dichiara ogni strumento in anticipo. Inserisci in
toolsalla prima richiesta ogni strumento di cui la sessione potrebbe aver bisogno, condefer_loading: truesu quelli che il modello non deve ancora vedere. Poi attiva e disattiva gli strumenti con blocchitool_additionetool_removalche li indicano per nome. - Parti da un'istantanea e aggiungi strumenti strada facendo. Inserisci in
toolsalla prima richiesta gli strumenti che conosci. Quando arriva un nuovo strumento, definiscilo all'interno di un bloccotool_additioninvece di modificaretools.
In entrambi i casi, tools non cambia mai, quindi il ragionamento precedente rimane valido e la cache dei prompt continua a trovare corrispondenze, con l'unica eccezione indicata più avanti in questa sezione.
Ad esempio, per ritirare uno strumento pericoloso dopo un cambio di modalità:
{
"role": "system",
"content": [
{ "type": "tool_removal", "tool": { "type": "tool_reference", "name": "delete_branch" } },
{ "type": "text", "text": "Branch deletion is disabled for the rest of this session." }
]
}Per attivare uno strumento dichiarato con defer_loading: true, aggiungi un blocco tool_addition che lo indica per nome:
{
"role": "system",
"content": [
{ "type": "tool_addition", "tool": { "type": "tool_reference", "name": "deploy" } },
{ "type": "text", "text": "Authentication succeeded. Deployment is now available." }
]
}A volte non puoi dichiarare uno strumento in anticipo perché non ne conosci ancora lo schema: uno strumento che la tua applicazione scopre in fase di esecuzione, o un server MCP che si connette dopo il primo turno. Definiscilo all'interno del blocco tool_addition invece di toccare tools. Con inline-tools-2026-09-15, il tool del blocco può essere {"type": "tool_definition", "definition": {...}}, contenente la stessa voce che avresti inserito in tools:
{
"role": "system",
"content": [
{
"type": "tool_addition",
"tool": {
"type": "tool_definition",
"definition": {
"name": "db_query",
"description": "Run a read-only SQL query against the analytics database.",
"input_schema": {
"type": "object",
"properties": { "sql": { "type": "string" } },
"required": ["sql"]
}
}
}
}
]
}Il nuovo strumento arriva in messages, tools non cambia mai e il ragionamento precedente resta valido. Mantieni in tools almeno uno strumento senza defer_loading: true: se tutti gli strumenti lì sono differiti, il primo strumento che definisci in questo modo costa un "cache miss" (mancato riscontro nella cache) completo della cache dei prompt.
Se l'API si connette al server MCP per tuo conto tramite il connettore MCP, invia anche mcp-client-2026-09-15. Copre tutto ciò che fa mcp-client-2025-11-20, quindi invialo al posto di quello. Il definition del blocco può quindi essere un mcp_toolset per un server elencato in mcp_servers. Quando l'API deve recuperare l'elenco degli strumenti di un server, la risposta inizia con un blocco mcp_tool_listing per quel server. Rimandalo invariato insieme al resto del turno dell'assistente, e continua a inviare mcp-client-2026-09-15 in ogni richiesta successiva che lo contiene. Il blocco vincola il toolset a quell'elenco, quindi l'API non contatta di nuovo il server per ottenerlo. Queste funzionalità del connettore MCP sono disponibili sulla Claude API.
Con il solo header precedente, puoi comunque aggiungere a tools uno strumento scoperto a metà sessione con defer_loading: true, e poi offrirlo con un blocco tool_addition. È sicuro perché il controllo del prefisso ignora uno strumento differito finché un blocco tool_addition non vi fa riferimento. Aggiungere uno strumento senza defer_loading: true modifica il prefisso e invalida il ragionamento precedente.
I messaggi role: "system" che contengono questi blocchi entrano a far parte del prefisso per il ragionamento successivo. Lasciali al loro posto nelle richieste successive.
Cambia l'effort con un output_config per messaggio
Cambiare output_config.effort di primo livello tra una richiesta e l'altra non invalida il ragionamento, perché l'effort non fa parte del prefisso. Cambiare l'effort di primo livello fa però ripartire la cache dei prompt. Dove il modello e la piattaforma supportano l'effort per messaggio, usalo al suo posto: accoda un messaggio role: "system" con content vuoto e il nuovo livello. Richiede l'header beta mid-conversation-output-config-2026-07-01. Su Claude Haiku 5.5, l'effort per messaggio è disponibile sulla Claude API e su Google Cloud e richiede il ragionamento adattivo.
{ "role": "system", "content": [], "output_config": { "effort": "low" } }Il momento in cui il nuovo livello entra in vigore dipende da dove inserisci il messaggio. Subito dopo un messaggio user con un nuovo input, si applica a partire dalla risposta di Claude a quel messaggio. In qualsiasi altra posizione, ad esempio dopo un messaggio assistant o dopo un messaggio user che contiene solo blocchi tool_result, si applica a partire dal successivo messaggio user con un nuovo input, quindi un ciclo di strumenti già in corso mantiene il livello attuale fino ad allora. Una volta inviato, il messaggio fa parte di messages e quindi del prefisso per il ragionamento successivo: lascialo al suo posto nelle richieste successive e accodane un altro per cambiare di nuovo l'effort.
Riduci il contesto sul server
Un'altra modifica comune del prefisso è il "trimming" (riduzione) lato client: eliminare o riassumere i turni più vecchi mantenendo alla lettera quelli recenti. I blocchi di ragionamento dei turni mantenuti sono stati prodotti quando la cronologia rimossa era ancora presente, quindi non superano il controllo. Gli equivalenti lato server non contano come modifiche, perché il controllo confronta la conversazione così come l'hai inviata:
- La compattazione su richiesta (beta) restituisce il riepilogo da una richiesta separata, che può essere eseguita in background, e tu invii il blocco restituito al posto dei messaggi che riassume. Il controllo accetta questa sostituzione, quindi i turni che mantieni possono restare validi con il loro ragionamento, alle condizioni per il ragionamento mantenuto. Richiedi un riepilogo mostra la richiesta e indica l'header beta necessario.
- La compattazione a una soglia di token riassume i turni più vecchi in un blocco di compattazione quando il contesto si avvicina a una soglia da te impostata, e il prefisso controllato riparte da quel blocco. Il suo parametro
instructionsaccetta un tuo prompt di riepilogo, ad esempio "preserva ogni ticker, dimensione di posizione e ipotesi dichiarata". - La modifica del contesto cancella i vecchi risultati degli strumenti o i vecchi blocchi di ragionamento in base a regole, a partire dai più vecchi. Le strategie sono
clear_tool_uses_20250919eclear_thinking_20251015.
Compattare sul client
Puoi comunque compattare sul client. Se scrivi tu il riepilogo, non rimandare un blocco di ragionamento prodotto prima della riscrittura. Se lo scrive l'API con la compattazione su richiesta, Condizioni affinché il ragionamento mantenuto resti valido elenca quando il ragionamento mantenuto resta valido.
Compattazione semplice (consigliata)
Quando la conversazione diventa troppo lunga, riassumi l'intera sessione in un unico messaggio utente e invia solo quel messaggio più l'istruzione successiva. Nulla di precedente viene riprodotto, quindi non rimane alcun ragionamento che possa non superare il controllo, e il modello ragiona da capo a partire dal riepilogo.
[
{
"role": "user",
"content": "<summary of the session so far>\n\n<the next instruction>"
}
]I modelli Claude sono addestrati su attività a lungo orizzonte con questo schema, che offre buone prestazioni per la maggior parte dei carichi di lavoro.
Compattazione keep-tail
La "keep-tail compaction" (compattazione con mantenimento della coda) riassume i turni più vecchi e mantiene alla lettera i turni più recenti, così il modello vede ancora parola per parola gli ultimi scambi. Se scrivi tu il riepilogo, viola la regola: i turni dell'assistente mantenuti contengono ancora blocchi di ragionamento prodotti quando erano preceduti dai turni originali, non dal riepilogo. Quei blocchi non superano il controllo.
Per mantenere quel ragionamento, fai scrivere il riepilogo all'API con la compattazione su richiesta. Compattazione che mantiene i turni recenti mostra come fare, e Condizioni affinché il ragionamento mantenuto rimanga valido elenca quando il ragionamento mantenuto rimane valido.
Il resto di questa sezione riguarda un riepilogo scritto da te.
Soluzione: mantieni i turni esattamente come sono e invia prefix_mismatch_behavior: "drop_block". L'API elimina i blocchi di ragionamento obsoleti, il modello legge i blocchi text e tool_use dei turni mantenuti e la richiesta ha esito positivo.
Passa la cronologia compattata come messages e imposta block_binding nella configurazione thinking. Nell'esempio seguente, compacted_messages è l'array prodotto dal tuo passaggio di compattazione: il messaggio di riepilogo seguito dai turni mantenuti esattamente come li ha restituiti l'API, blocchi thinking inclusi:
client = anthropic.Anthropic()
# compacted_messages: il messaggio di riepilogo, seguito dai turni mantenuti così come restituiti
response = client.beta.messages.create(
model="claude-fable-5-1",
max_tokens=16000,
thinking={
"type": "adaptive",
"block_binding": {"prefix_mismatch_behavior": "drop_block"},
},
messages=compacted_messages,
betas=["thinking-binding-controls-2026-08-01"],
)
print(response.input_transformations)La risposta contiene come di consueto il nuovo turno dell'assistente, più una voce input_transformations per ogni blocco eliminato. Per la cronologia nel diagramma, si tratta del ragionamento sui turni 3 e 4 dell'assistente:
{
"input_transformations": [
{
"type": "thinking_dropped",
"path": "messages.2.content.0",
"reason": "prefix_binding_mismatch"
},
{
"type": "thinking_dropped",
"path": "messages.4.content.0",
"reason": "prefix_binding_mismatch"
}
]
}Continua a inviare "drop_block" nelle richieste successive finché quei due turni rimangono nella cronologia. Il ragionamento che il modello produce da questa richiesta in poi segue il riepilogo e rimane valido. Se preferisci non dipendere dall'header beta, l'alternativa è rimuovere tu stesso i blocchi thinking e redacted_thinking dai turni dell'assistente mantenuti quando costruisci la cronologia compattata.
Compattazione in background (asincrona)
La compattazione in background costruisce il riepilogo al di fuori del percorso critico mentre la conversazione prosegue, poi lo sostituisce qualche richiesta dopo. Per mantenere il ragionamento prodotto nel frattempo, fai scrivere il riepilogo all'API con la compattazione su richiesta: Compattazione in background descrive i passaggi, e quel ragionamento resta valido alle stesse condizioni per il ragionamento mantenuto dei turni recenti mantenuti.
Un riepilogo che costruisci tu stesso viola la regola allo stesso modo della compattazione keep-tail, ma con un ritardo: ogni turno dell'assistente prodotto mentre il riepilogo veniva costruito contiene thinking antecedente alla sostituzione, e tutto questo thinking non supera il controllo nel momento in cui il riepilogo viene inserito. Se ne usi uno, tratta la sostituzione come nella compattazione keep-tail e invia "drop_block" dalla sostituzione in poi, oppure compatta in modo sincrono.
Schemi che non funzionano con il ragionamento preservato
- Tagliare turni dal mezzo. La rimozione di singoli turni invalida ogni blocco di thinking successivo, e nessuno schema di compattazione lo evita. Se stavi tagliando un turno per modificare un'istruzione, aggiungi invece un messaggio di sistema a metà conversazione. Per rimuovere selettivamente vecchi risultati degli strumenti o vecchio thinking, usa il "context editing" (modifica del contesto) lato server: consulta modifica del contesto.
- Compattare nel mezzo di un round di strumenti. Non compattare tra il
tool_usedi un turno dell'assistente e iltool_resultche gli risponde. Rinvia quel turno dell'assistente con il suo thinking intatto, così il modello completa il round con il suo ragionamento. Consulta Preservare i blocchi di ragionamento.
Fai riferimento ai file tramite ID, non tramite un URL il cui contenuto cambia
Per un blocco image o document con una sorgente url, il controllo riguarda i byte recuperati, non la stringa dell'URL. Un URL il cui contenuto cambia invalida il thinking successivo: ad esempio un endpoint "ultimo screenshot", o un documento che qualcuno modifica tra un turno e l'altro. Un URL firmato a rotazione per lo stesso file non lo invalida. Per i contenuti a cui fai riferimento in più turni, caricali una volta con la Files API e usa il file_id, oppure inviali in base64.
Librerie, proxy e gateway
Una libreria, un proxy o un gateway si trova tra la cronologia di qualcun altro e l'API, quindi le sue riscritture contano come modifiche, e i suoi utenti non possono vederle né correggerle.
- Inoltra ciò che non riconosci. Inoltra invariati i valori
anthropic-betaethinking.block_bindingdel chiamante, e restituiscigliinput_transformations. Uno schema di opzioni che rifiuta le chiavi sconosciute impedisce ai tuoi utenti di scegliere"drop_block". - Lascia un messaggio
role: "system"dove il chiamante lo ha messo. Spostarlo nel camposystemdi primo livello modificasystemin quella richiesta e invalida ogni blocco di thinking nella conversazione. - Per disattivare l'uso degli strumenti per una richiesta, invia
tool_choice: {"type": "none"}. Non rimuoveretools. - Non nascondere il 400. Se il tuo codice lo intercetta, rimuove il thinking e riprova per conto del chiamante, registra che lo ha fatto: la cronologia del chiamante risulta comunque modificata, e il modello perde il suo ragionamento precedente in ogni richiesta successiva.
Domande frequenti
No. Invia l'header beta thinking-binding-controls-2026-08-01 e imposta thinking.block_binding.prefix_mismatch_behavior. Impostare il campo attiva l'applicazione del controllo per quella richiesta indipendentemente dall'anzianità dell'account. "error" rifiuta una cronologia modificata con lo stesso 400 che riceve un nuovo account, e "drop_block" lascia passare la richiesta ed elenca ciò che è stato eliminato in input_transformations. Per individuare le modifiche del prefisso da un account più vecchio senza applicare il controllo, invia l'header e lascia il campo non impostato: i blocchi che non superano il controllo raggiungono comunque il modello, e input_transformations li elenca come thinking_mismatch_allowed. Consulta Verifica se il tuo codice modifica il prefisso.
No. Ciò che non supera il controllo è il ragionamento già presente nella cronologia dopo il punto che hai modificato, e sei tu a scegliere cosa succede. Con prefix_mismatch_behavior: "drop_block", l'API elimina quei blocchi e la richiesta ha esito positivo: il modello risponde a quel turno senza quel ragionamento, e la cache dei prompt riparte dalla modifica. Con il valore predefinito "error", l'API rifiuta la richiesta con un 400 finché non annulli la modifica o non la reinvii con "drop_block". Consulta Cosa fa l'API con un blocco non valido. Cosa conta come modifica elenca quali modifiche sono rilevanti.
No. output_config.effort, max_tokens e la configurazione thinking non fanno parte del prefisso controllato, che copre solo system, tools e messages. Un cambio di effort di primo livello invalida la maggior parte della cache dei prompt. Dove il modello e la piattaforma supportano l'effort per messaggio, un cambio di effort per messaggio mantiene la cache dei prompt e viene usato come nuovo livello di effort finché non viene cambiato di nuovo.
Non modificare tools. Dichiara l'insieme completo all'inizio della sessione, contrassegna gli strumenti non ancora disponibili con defer_loading: true e offrili o ritirali con blocchi tool_addition e tool_removal. Se conosci lo schema di uno strumento solo a metà sessione, definiscilo all'interno del blocco tool_addition (inline-tools-2026-09-15, più mcp-client-2026-09-15 per un server raggiunto dal connettore MCP dell'API) e lascia tools invariato. I messaggi role: "system" che contengono questi blocchi entrano a far parte del prefisso per il ragionamento successivo, quindi non spostarli, riformularli o eliminarli in seguito. Consulta Aggiungi o rimuovi strumenti con tool_addition e tool_removal.
Sì, se il riepilogo lo scrive l'API. La compattazione su richiesta (header beta compact-2026-09-04) riassume i turni più vecchi in un blocco firmato che invii al loro posto. I turni recenti mantengono il loro ragionamento alle condizioni per il ragionamento mantenuto.
Se scrivi tu il riepilogo, il ragionamento dei turni mantenuti non supera il controllo, perché quei blocchi sono stati prodotti rispetto alla cronologia che hai sostituito. Rimuovi i blocchi thinking e redacted_thinking dai turni che riporti e mantieni i loro blocchi text e tool_use, oppure invia prefix_mismatch_behavior: "drop_block" e lascia che sia l'API a eliminarli. La compattazione semplice non lascia alcun ragionamento che possa non superare il controllo ed è l'approccio consigliato: un messaggio di riepilogo più il turno utente successivo, senza riprodurre turni precedenti. La compattazione e la modifica del contesto lato server non contano come modifiche. Consulta Compattare sul client.
Caricali una volta all'inizio della sessione e mantieni fissi il prompt system di primo livello e tools. Quando un file cambia, accoda la nuova versione in quel punto di messages invece di modificare l'originale. Usa un messaggio di sistema a metà conversazione per le istruzioni che provengono da te in qualità di operatore. Per il testo di file che consideri non attendibile, che non dovrebbe avere l'autorità del prompt di sistema, inserisci invece il contenuto nel turno user successivo. Consulta Aggiungi istruzioni con un messaggio di sistema a metà conversazione e Limitazioni.
Sì. Una sessione ripresa è una normale richiesta successiva: system, tools e i messages precedenti devono avere lo stesso contenuto di quanto hai inviato l'ultima volta. La formattazione JSON e l'ordine delle chiavi non contano; i valori sì. Salva esattamente ciò che hai inviato e ricevuto, e riproducilo: il prompt di sistema generato, le definizioni degli strumenti e ogni turno dell'assistente così come è stato restituito. Non rigenerare a partire da input che potrebbero essere cambiati nel frattempo, come la data, un file di istruzioni aggiornato o una nuova versione di uno strumento. Qualsiasi novità va in un messaggio accodato. Consulta Rimanda i turni dell'assistente esattamente come restituiti.
La cronologia memorizzata contiene una modifica, quindi riprodurla non può avere esito positivo. Da ora in poi invia quella sessione con prefix_mismatch_behavior: "drop_block", oppure rimuovi una volta i suoi blocchi thinking e redacted_thinking e continua. Su Claude Sonnet 5.5 e Claude Haiku 5.5, block_binding funziona solo con thinking: {"type": "adaptive"}. Con between_tools su Claude Sonnet 5.5, o thinking: {"type": "disabled"} su Claude Haiku 5.5, mantieni la cronologia in sola aggiunta, oppure rimuovi i blocchi di ragionamento dal turno modificato in poi. Il ragionamento che il modello produce da quel punto in poi rimane valido finché nulla di precedente cambia di nuovo. Poi individua la modifica, in modo che le nuove sessioni non la incontrino. Consulta Gestisci l'errore nel codice.
No, a condizione che vengano accodati dopo la cronologia esistente e che nulla di precedente cambi: un messaggio dell'assistente senza blocchi di ragionamento è un messaggio accodato come qualsiasi altro. Invia l'output dell'altro modello come contenuto text e tool_use.
Non in una conversazione diversa. Un blocco di ragionamento è utilizzabile solo quando segue esattamente i system, tools e messages da cui è stato prodotto. Un ramo che riproduce quella cronologia invariata fino al punto di biforcazione mantiene il suo ragionamento. Una conversazione che parte da qualsiasi altra cosa non può usarlo, quindi avvia quella conversazione da un riepilogo dello stato dell'attività, come nella compattazione semplice: l'obiettivo, le decisioni prese, i file e i risultati finora ottenuti e il passaggio successivo. I blocchi di ragionamento di Claude Sonnet 5.5 e Claude Haiku 5.5 inoltre non possono essere riutilizzati da un altro account (consulta I blocchi di ragionamento restano con l'account che li ha prodotti).
Passaggi successivi
Diagnostica e correggi i fallimenti più comuni del ragionamento: errori 400 di configurazione, blocchi di ragionamento vuoti o mancanti, arresti per max_tokens e cache miss.
Modifica le istruzioni di sistema o la disponibilità degli strumenti a metà di una conversazione senza invalidare il prefisso in cache che le precede.
Compattazione del contesto lato server per gestire conversazioni lunghe che si avvicinano ai limiti della finestra di contesto.
Metti in cache i prefissi dei prompt con cache_control per ridurre costi e latenza, usando la cache automatica o breakpoint espliciti con TTL di 5 minuti o 1 ora.
Was this page helpful?