---
title: Ragionamento preservato
url: https://platform.claude.com/docs/it/build-with-claude/preserved-thinking
description: 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](https://platform.claude.com/docs/it/build-with-claude/preserved-thinking#switching-models).
* **Nulla prima del blocco di ragionamento è cambiato.** Il prompt `system` di primo livello, i `tools` e i `messages` che 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](https://platform.claude.com/docs/it/build-with-claude/preserved-thinking#prefix-check).

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](https://platform.claude.com/docs/it/build-with-claude/preserved-thinking#account-bound-thinking) 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`](https://platform.claude.com/docs/it/build-with-claude/preserved-thinking#new-instructions): 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](https://platform.claude.com/docs/it/build-with-claude/preserved-thinking#changing-context)
* [Cancella o accorcia vecchi risultati degli strumenti, o ricodifica vecchie immagini](https://platform.claude.com/docs/it/build-with-claude/preserved-thinking#server-side-trimming)
* [Riassume o scarta vecchi turni sul client](https://platform.claude.com/docs/it/build-with-claude/preserved-thinking#custom-compaction-on-the-client) e mantiene i turni recenti con il loro ragionamento
* [Aggiunge, rimuove o modifica voci in `tools`](https://platform.claude.com/docs/it/build-with-claude/preserved-thinking#tool-changes)
* [Aggiunge un promemoria a un turno utente](https://platform.claude.com/docs/it/build-with-claude/preserved-thinking#per-turn-reminders) e in seguito lo rimuove o lo riscrive
* [Scarta alcuni blocchi `thinking` e mantiene quelli successivi](https://platform.claude.com/docs/it/build-with-claude/preserved-thinking#append-assistant-turns-exactly-as-returned), oppure li rimuove e [in seguito li rimette](https://platform.claude.com/docs/it/build-with-claude/preserved-thinking#prefix-check)
* [Ricostruisce una sessione salvata da template](https://platform.claude.com/docs/it/build-with-claude/preserved-thinking#faq) 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`](https://platform.claude.com/docs/it/build-with-claude/preserved-thinking#preserved-thinking-controls)).

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](https://platform.claude.com/docs/it/build-with-claude/preserved-thinking#account-bound-thinking).

## 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](https://platform.claude.com/docs/it/build-with-claude/refusals-and-fallback#server-side-fallback) 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](https://platform.claude.com/docs/it/build-with-claude/refusals-and-fallback), oppure durante un [fallback lato server](https://platform.claude.com/docs/it/build-with-claude/refusals-and-fallback#server-side-fallback). 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.

<Frame>
  ![Animazione: passando a Claude Opus il ragionamento di Claude Fable 5.1 viene saltato per quel turno; tornando indietro, tutto viene letto di nuovo](https://platform.claude.com/docs/images/preserved-thinking-model-switch.svg)
</Frame>

Con l'[header beta](https://platform.claude.com/docs/it/api/beta-headers) `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"`:

```json
{
  "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](https://platform.claude.com/docs/it/api/beta-headers) `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 `system` di primo livello
* L'insieme dei `tools`
* Ogni `message` prima del blocco

Nota: con la [compattazione](https://platform.claude.com/docs/it/build-with-claude/compaction) 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](https://platform.claude.com/docs/it/build-with-claude/preserved-thinking#what-counts-as-an-edit) 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)](https://platform.claude.com/docs/it/build-with-claude/prompt-caching): 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 400 `invalid_request_error` che 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 in `input_transformations` (nell'evento `message_start` durante lo streaming) con `reason: "prefix_binding_mismatch"`.

<Warning>
  `"drop_block"` fa sì che le richieste vadano a buon fine, ma non corregge la modifica che ha causato la mancata corrispondenza, e ha un costo. La rimozione dei blocchi può aumentare in modo significativo i token di output generati, soprattutto a livelli di effort più alti o quando i blocchi vengono rimossi a ogni turno. Per maggiori informazioni, consulta [Costo in token di output di `"drop_block"`](https://platform.claude.com/docs/it/build-with-claude/preserved-thinking#drop-block-cost). I blocchi rimossi non vengono fatturati, ma Claude ricrea il ragionamento che non può più leggere, quindi genera più token di output. Anche la qualità dell'output potrebbe cambiare nelle attività in cui i turni successivi si basano sul ragionamento precedente. Usa `"drop_block"` come soluzione temporanea mentre correggi la modifica, ma non come impostazione a lungo termine.
</Warning>

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](https://platform.claude.com/docs/it/build-with-claude/preserved-thinking#replace-prefix-edits). 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](https://platform.claude.com/docs/it/api/beta-headers) `thinking-binding-controls-2026-08-01`. [Imposta il comportamento in caso di mancata corrispondenza e leggi `input_transformations`](https://platform.claude.com/docs/it/build-with-claude/preserved-thinking#preserved-thinking-controls) mostra la richiesta in ogni "software development kit" (kit di sviluppo software), o SDK.

Il messaggio 400 inizia così:

```text wrap
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:

```text wrap
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](https://platform.claude.com/docs/it/build-with-claude/thinking-troubleshooting#error-thinking-block-signature) 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](https://platform.claude.com/docs/it/build-with-claude/preserved-thinking#replace-prefix-edits) è 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](https://platform.claude.com/docs/it/build-with-claude/preserved-thinking#drop-block-cost)), 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](https://platform.claude.com/docs/it/api/beta-headers) `thinking-binding-controls-2026-08-01` aggiunge:

* Un array `input_transformations` di primo livello in ogni risposta
* Un oggetto `block_binding` nella configurazione `thinking`, 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:

<CodeGroup>
  ```bash cURL
  curl https://api.anthropic.com/v1/messages \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "anthropic-beta: thinking-binding-controls-2026-08-01" \
    -H "content-type: application/json" \
    -d '{
      "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?"
        }
      ]
    }'
  ```

  ```bash CLI
  ant beta:messages create --beta thinking-binding-controls-2026-08-01 \
    --format yaml <<'YAML'
  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?
  YAML
  ```

  ```python Python
  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 [])}")
  ```

  ```typescript TypeScript
  const client = new Anthropic();

  const response = await 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 (const block of response.content) {
    if (block.type === "text") {
      console.log(block.text);
    }
  }
  console.log(`Input transformations: ${response.input_transformations?.length ?? 0}`);
  ```

  ```csharp C#
  AnthropicClient client = new();

  var response = await client.Beta.Messages.Create(
      new()
      {
          Model = Model.ClaudeFable5_1,
          MaxTokens = 16000,
          Thinking = new BetaThinkingConfigAdaptive
          {
              BlockBinding = new()
              {
                  PrefixMismatchBehavior = BetaThinkingPrefixMismatchBehavior.DropBlock,
              },
          },
          Messages =
          [
              new()
              {
                  Role = Role.User,
                  Content = "What is the greatest common divisor of 1071 and 462?",
              },
          ],
          Betas = [AnthropicBeta.ThinkingBindingControls2026_08_01],
      }
  );

  foreach (var block in response.Content)
  {
      if (block.TryPickText(out var textBlock))
      {
          Console.WriteLine(textBlock.Text);
      }
  }

  Console.WriteLine($"Input transformations: {response.InputTransformations?.Count ?? 0}");
  ```

  ```go Go
  client := anthropic.NewClient()

  response, err := client.Beta.Messages.New(context.TODO(), anthropic.BetaMessageNewParams{
  	Model:     anthropic.ModelClaudeFable5_1,
  	MaxTokens: 16000,
  	Thinking: anthropic.BetaThinkingConfigParamUnion{
  		OfAdaptive: &anthropic.BetaThinkingConfigAdaptiveParam{
  			BlockBinding: anthropic.BetaThinkingBlockBindingParam{
  				PrefixMismatchBehavior: anthropic.BetaThinkingPrefixMismatchBehaviorDropBlock,
  			},
  		},
  	},
  	Messages: []anthropic.BetaMessageParam{
  		anthropic.NewBetaUserMessage(anthropic.NewBetaTextBlock("What is the greatest common divisor of 1071 and 462?")),
  	},
  	Betas: []anthropic.AnthropicBeta{anthropic.AnthropicBetaThinkingBindingControls2026_08_01},
  })
  if err != nil {
  	log.Fatal(err)
  }

  for _, block := range response.Content {
  	if textBlock, ok := block.AsAny().(anthropic.BetaTextBlock); ok {
  		fmt.Println(textBlock.Text)
  	}
  }
  fmt.Printf("Input transformations: %d\n", len(response.InputTransformations))
  ```

  ```java Java
  import com.anthropic.models.beta.AnthropicBeta;
  import com.anthropic.models.beta.messages.BetaMessage;
  import com.anthropic.models.beta.messages.BetaThinkingBlockBinding;
  import com.anthropic.models.beta.messages.BetaThinkingConfigAdaptive;
  import com.anthropic.models.beta.messages.BetaThinkingPrefixMismatchBehavior;
  import com.anthropic.models.beta.messages.MessageCreateParams;
  import com.anthropic.models.messages.Model;

  void main() {
      AnthropicClient client = AnthropicOkHttpClient.fromEnv();

      MessageCreateParams params = MessageCreateParams.builder()
          .model(Model.CLAUDE_FABLE_5_1)
          .maxTokens(16000L)
          .addBeta(AnthropicBeta.THINKING_BINDING_CONTROLS_2026_08_01)
          .thinking(BetaThinkingConfigAdaptive.builder()
              .blockBinding(BetaThinkingBlockBinding.builder()
                  .prefixMismatchBehavior(BetaThinkingPrefixMismatchBehavior.DROP_BLOCK)
                  .build())
              .build())
          .addUserMessage("What is the greatest common divisor of 1071 and 462?")
          .build();

      BetaMessage response = client.beta().messages().create(params);

      response.content().stream()
          .flatMap(block -> block.text().stream())
          .forEach(textBlock -> IO.println(textBlock.text()));
      IO.println("Input transformations: "
          + response.inputTransformations().map(List::size).orElse(0));
  }
  ```

  ```php PHP
  use Anthropic\Beta\AnthropicBeta;
  use Anthropic\Beta\Messages\BetaThinkingBlockBinding;
  use Anthropic\Beta\Messages\BetaThinkingConfigAdaptive;
  use Anthropic\Beta\Messages\BetaThinkingPrefixMismatchBehavior;
  use Anthropic\Client;

  $client = new Client();

  $response = $client->beta->messages->create(
      model: 'claude-fable-5-1',
      maxTokens: 16000,
      thinking: BetaThinkingConfigAdaptive::with(
          blockBinding: BetaThinkingBlockBinding::with(
              prefixMismatchBehavior: BetaThinkingPrefixMismatchBehavior::DROP_BLOCK,
          ),
      ),
      messages: [
          ['role' => 'user', 'content' => 'What is the greatest common divisor of 1071 and 462?'],
      ],
      betas: [AnthropicBeta::THINKING_BINDING_CONTROLS_2026_08_01],
  );

  foreach ($response->content as $block) {
      if ($block->type === 'text') {
          echo $block->text, PHP_EOL;
      }
  }

  echo 'Input transformations: ', count($response->inputTransformations ?? []), PHP_EOL;
  ```

  ```ruby Ruby
  client = Anthropic::Client.new

  response = client.beta.messages.create(
    model: "claude-fable-5-1",
    max_tokens: 16_000,
    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: [Anthropic::AnthropicBeta::THINKING_BINDING_CONTROLS_2026_08_01]
  )

  response.content.each do |block|
    puts block.text if block.type == :text
  end

  puts "Input transformations: #{response.input_transformations&.length || 0}"
  ```
</CodeGroup>

```text Output wrap
The greatest common divisor of 1071 and 462 is 21.
Input transformations: 0
```

Con 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. Il `reason` è `prefix_binding_mismatch` o `model_binding_mismatch` (consulta [Cambiare modello a metà conversazione](https://platform.claude.com/docs/it/build-with-claude/preserved-thinking#switching-models)). Il `reason` può anche essere `organization_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](https://platform.claude.com/docs/it/build-with-claude/preserved-thinking#account-bound-thinking)).
* **`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. Il `reason` è sempre `prefix_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](https://platform.claude.com/docs/it/build-with-claude/preserved-thinking#enforcement)). Impostare `prefix_mismatch_behavior` su 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](https://platform.claude.com/docs/it/build-with-claude/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](https://platform.claude.com/docs/it/build-with-claude/batch-processing), 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](https://platform.claude.com/docs/it/build-with-claude/token-counting) 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 in `input_transformations` come `thinking_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](https://platform.claude.com/docs/it/build-with-claude/preserved-thinking#per-turn-reminders) 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](https://platform.claude.com/docs/it/build-with-claude/compaction-on-demand) sostituisce i messaggi che riassume, alle [condizioni per il ragionamento mantenuto](https://platform.claude.com/docs/it/build-with-claude/compaction-thinking-blocks#conditions-for-kept-thinking-to-stay-valid) |
| 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

<Tip>
  **Automatizza questo controllo con la skill Claude API.** Nell'ultima versione di [Claude Code](https://code.claude.com/docs/en/overview), apri il repository che costruisce le tue richieste ed esegui la [skill Claude API](https://platform.claude.com/docs/it/agents-and-tools/agent-skills/claude-api-skill#checking-an-integration-for-preserved-thinking) inclusa:

  Lascia che Claude Code verifichi il tuo codice per te

  ```text
  /claude-api preserved-thinking-migration
  ```

  La skill acquisisce alcune delle tue sessioni multi-turno e confronta le richieste consecutive per individuare dove il tuo codice modifica il prefisso. Poi riproduce le sessioni con `"drop_block"` e conta i blocchi di ragionamento che l'API scarta. Successivamente, corregge una causa alla volta e misura di nuovo dopo ogni correzione.
</Tip>

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 claude-fable-5-1. 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:

<CodeGroup>
  ```bash cURL
  # Conta i blocchi di ragionamento in una risposta e i blocchi scartati dall'API
  COUNTS='"thinking blocks: \([.content[] | select(.type == "thinking")] | length), " +
    "dropped: \(.input_transformations | length)"'

  FIRST=$(curl -s https://api.anthropic.com/v1/messages \
    -H "content-type: application/json" \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "anthropic-beta: thinking-binding-controls-2026-08-01" \
    -d '{
      "model": "claude-fable-5-1",
      "max_tokens": 16000,
      "thinking": {
        "type": "adaptive",
        "block_binding": { "prefix_mismatch_behavior": "drop_block" }
      },
      "messages": [
        {
          "role": "user",
          "content": "How many positive integers below 500 have exactly 6 positive divisors?"
        }
      ]
    }')
  echo "$FIRST" | jq -r "$COUNTS"

  # Turno 2: il turno dell'assistente viene rinviato esattamente come restituito, poi il messaggio utente successivo
  MESSAGES=$(jq -n --argjson first "$FIRST" '[
    {
      role: "user",
      content: "How many positive integers below 500 have exactly 6 positive divisors?"
    },
    { role: "assistant", content: $first.content },
    { role: "user", content: "How many of those are odd?" }
  ]')

  jq -n --argjson messages "$MESSAGES" '{
    model: "claude-fable-5-1",
    max_tokens: 16000,
    thinking: {
      type: "adaptive",
      block_binding: { prefix_mismatch_behavior: "drop_block" }
    },
    messages: $messages
  }' | curl -s https://api.anthropic.com/v1/messages \
    -H "content-type: application/json" \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "anthropic-beta: thinking-binding-controls-2026-08-01" \
    -d @- | jq -r "$COUNTS"
  ```

  ```bash CLI
  # Conta i blocchi di ragionamento in una risposta e i blocchi scartati dall'API
  COUNTS='"thinking blocks: \([.content[] | select(.type == "thinking")] | length), " +
    "dropped: \(.input_transformations | length)"'

  FIRST=$(ant beta:messages create --beta thinking-binding-controls-2026-08-01 \
    --format json <<'YAML'
  model: claude-fable-5-1
  max_tokens: 16000
  thinking:
    type: adaptive
    block_binding:
      prefix_mismatch_behavior: drop_block
  messages:
    - role: user
      content: How many positive integers below 500 have exactly 6 positive divisors?
  YAML
  )
  echo "$FIRST" | jq -r "$COUNTS"

  # Turno 2: il turno dell'assistente viene rinviato esattamente come restituito, poi il messaggio utente successivo
  ant beta:messages create --beta thinking-binding-controls-2026-08-01 \
    --format json <<YAML | jq -r "$COUNTS"
  model: claude-fable-5-1
  max_tokens: 16000
  thinking:
    type: adaptive
    block_binding:
      prefix_mismatch_behavior: drop_block
  messages:
    - role: user
      content: How many positive integers below 500 have exactly 6 positive divisors?
    - role: assistant
      content: $(echo "$FIRST" | jq -c .content)
    - role: user
      content: How many of those are odd?
  YAML
  ```

  ```python Python
  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}")
  ```

  ```typescript TypeScript
  const client = new Anthropic();

  const userTurns = [
    "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
  const messages: Anthropic.Beta.BetaMessageParam[] = [];
  for (const userTurn of userTurns) {
    messages.push({ role: "user", content: userTurn });
    const response = await client.beta.messages.create({
      model: "claude-fable-5-1",
      max_tokens: 16000,
      thinking: {
        type: "adaptive",
        block_binding: { prefix_mismatch_behavior: "drop_block" }
      },
      messages,
      betas: ["thinking-binding-controls-2026-08-01"]
    });
    messages.push({ role: "assistant", content: response.content });
    const thinkingBlocks = response.content.filter((block) => block.type === "thinking");
    const dropped = response.input_transformations ?? [];
    console.log(`thinking blocks: ${thinkingBlocks.length}, dropped: ${dropped.length}`);
  }
  ```

  ```csharp C#
  AnthropicClient client = new();

  string[] userTurns =
  [
      "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
  List<BetaMessageParam> messages = [];
  foreach (var userTurn in userTurns)
  {
      messages.Add(new() { Role = Role.User, Content = userTurn });
      var response = await client.Beta.Messages.Create(
          new()
          {
              Model = Model.ClaudeFable5_1,
              MaxTokens = 16000,
              Thinking = new BetaThinkingConfigAdaptive
              {
                  BlockBinding = new()
                  {
                      PrefixMismatchBehavior = BetaThinkingPrefixMismatchBehavior.DropBlock,
                  },
              },
              Messages = messages,
              Betas = [AnthropicBeta.ThinkingBindingControls2026_08_01],
          }
      );
      messages.Add(new()
      {
          Role = Role.Assistant,
          Content = response.Content.Select(block => new BetaContentBlockParam(block.Json)).ToList(),
      });
      var thinkingBlocks = response.Content.Count(block => block.TryPickThinking(out _));
      var dropped = response.InputTransformations?.Count ?? 0;
      Console.WriteLine($"thinking blocks: {thinkingBlocks}, dropped: {dropped}");
  }
  ```

  ```go Go
  client := anthropic.NewClient()

  userTurns := []string{
  	"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 := []anthropic.BetaMessageParam{}
  for _, userTurn := range userTurns {
  	messages = append(messages, anthropic.NewBetaUserMessage(anthropic.NewBetaTextBlock(userTurn)))
  	response, err := client.Beta.Messages.New(context.TODO(), anthropic.BetaMessageNewParams{
  		Model:     anthropic.ModelClaudeFable5_1,
  		MaxTokens: 16000,
  		Thinking: anthropic.BetaThinkingConfigParamUnion{
  			OfAdaptive: &anthropic.BetaThinkingConfigAdaptiveParam{
  				BlockBinding: anthropic.BetaThinkingBlockBindingParam{
  					PrefixMismatchBehavior: anthropic.BetaThinkingPrefixMismatchBehaviorDropBlock,
  				},
  			},
  		},
  		Messages: messages,
  		Betas:    []anthropic.AnthropicBeta{anthropic.AnthropicBetaThinkingBindingControls2026_08_01},
  	})
  	if err != nil {
  		log.Fatal(err)
  	}
  	messages = append(messages, response.ToParam())
  	thinkingBlocks := 0
  	for _, block := range response.Content {
  		if block.Type == "thinking" {
  			thinkingBlocks++
  		}
  	}
  	fmt.Printf("thinking blocks: %d, dropped: %d\n", thinkingBlocks, len(response.InputTransformations))
  }
  ```

  ```java Java
  import com.anthropic.models.beta.AnthropicBeta;
  import com.anthropic.models.beta.messages.BetaContentBlock;
  import com.anthropic.models.beta.messages.BetaMessage;
  import com.anthropic.models.beta.messages.BetaThinkingBlockBinding;
  import com.anthropic.models.beta.messages.BetaThinkingConfigAdaptive;
  import com.anthropic.models.beta.messages.BetaThinkingPrefixMismatchBehavior;
  import com.anthropic.models.beta.messages.MessageCreateParams;
  import com.anthropic.models.messages.Model;

  void main() {
      AnthropicClient client = AnthropicOkHttpClient.fromEnv();

      List<String> userTurns = List.of(
          "How many positive integers below 500 have exactly 6 positive divisors?",
          "How many of those are odd?");

      // La lista dei messaggi del builder cresce a ogni turno: ogni turno dell'assistente viene rinviato esattamente come restituito
      MessageCreateParams.Builder conversation = MessageCreateParams.builder()
          .model(Model.CLAUDE_FABLE_5_1)
          .maxTokens(16000L)
          .thinking(BetaThinkingConfigAdaptive.builder()
              .blockBinding(BetaThinkingBlockBinding.builder()
                  .prefixMismatchBehavior(BetaThinkingPrefixMismatchBehavior.DROP_BLOCK)
                  .build())
              .build())
          .addBeta(AnthropicBeta.THINKING_BINDING_CONTROLS_2026_08_01);

      for (String userTurn : userTurns) {
          conversation.addUserMessage(userTurn);
          BetaMessage response = client.beta().messages().create(conversation.build());
          conversation.addMessage(response);
          long thinkingBlocks = response.content().stream()
              .filter(BetaContentBlock::isThinking)
              .count();
          int dropped = response.inputTransformations().map(List::size).orElse(0);
          IO.println("thinking blocks: " + thinkingBlocks + ", dropped: " + dropped);
      }
  }
  ```

  ```php PHP
  use Anthropic\Beta\AnthropicBeta;
  use Anthropic\Beta\Messages\BetaThinkingBlockBinding;
  use Anthropic\Beta\Messages\BetaThinkingConfigAdaptive;
  use Anthropic\Beta\Messages\BetaThinkingPrefixMismatchBehavior;
  use Anthropic\Client;

  $client = new Client();

  $userTurns = [
      '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 = [];
  foreach ($userTurns as $userTurn) {
      $messages[] = ['role' => 'user', 'content' => $userTurn];
      $response = $client->beta->messages->create(
          model: 'claude-fable-5-1',
          maxTokens: 16000,
          thinking: BetaThinkingConfigAdaptive::with(
              blockBinding: BetaThinkingBlockBinding::with(
                  prefixMismatchBehavior: BetaThinkingPrefixMismatchBehavior::DROP_BLOCK,
              ),
          ),
          messages: $messages,
          betas: [AnthropicBeta::THINKING_BINDING_CONTROLS_2026_08_01],
      );
      $messages[] = ['role' => 'assistant', 'content' => $response->content];
      $thinkingBlocks = array_filter($response->content, fn ($block) => $block->type === 'thinking');
      $dropped = $response->inputTransformations ?? [];
      echo 'thinking blocks: ', count($thinkingBlocks), ', dropped: ', count($dropped), PHP_EOL;
  }
  ```

  ```ruby Ruby
  client = Anthropic::Client.new

  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 reinviato esattamente come restituito
  messages = []
  user_turns.each do |user_turn|
    messages << {role: "user", content: user_turn}
    response = client.beta.messages.create(
      model: "claude-fable-5-1",
      max_tokens: 16_000,
      thinking: {
        type: "adaptive",
        block_binding: {prefix_mismatch_behavior: "drop_block"}
      },
      messages: messages,
      betas: [Anthropic::AnthropicBeta::THINKING_BINDING_CONTROLS_2026_08_01]
    )
    messages << {role: "assistant", content: response.content}
    thinking_blocks = response.content.count { |block| block.type == :thinking }
    dropped = (response.input_transformations || []).length
    puts "thinking blocks: #{thinking_blocks}, dropped: #{dropped}"
  end
  ```
</CodeGroup>

```text Output wrap
thinking blocks: 1, dropped: 0
thinking blocks: 1, dropped: 0
```

Nessuno 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:

```json
{
  "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 in `path` è cambiato rispetto alla richiesta precedente. Confronta `system`, `tools` e `messages` fino 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](https://platform.claude.com/docs/it/build-with-claude/preserved-thinking#replace-prefix-edits).
* **`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](https://platform.claude.com/docs/it/build-with-claude/preserved-thinking#switching-models).
* **`reason: "organization_binding_mismatch"`:** il blocco proviene da un altro account. Consulta [I blocchi di ragionamento restano con l'account che li ha prodotti](https://platform.claude.com/docs/it/build-with-claude/preserved-thinking#account-bound-thinking).

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](https://platform.claude.com/docs/it/build-with-claude/preserved-thinking#mismatch-behavior), 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 claude-fable-5-1, 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:

```json
{
  "input_transformations": [
    {
      "type": "thinking_mismatch_allowed",
      "path": "messages.1.content.0",
      "reason": "prefix_binding_mismatch"
    }
  ]
}
```

Esegui l'esempio seguente da un [account più vecchio](https://platform.claude.com/docs/it/build-with-claude/preserved-thinking#enforcement), 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:

<CodeGroup>
  ```bash cURL
  # Conta i blocchi di ragionamento in una risposta e quelli che non hanno superato il controllo del prefisso
  COUNTS='"thinking blocks: \([.content[] | select(.type == "thinking")] | length), " +
    "flagged: \([.input_transformations[] |
      select(.type == "thinking_mismatch_allowed")] | length)"'

  FIRST=$(curl -s https://api.anthropic.com/v1/messages \
    -H "content-type: application/json" \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "anthropic-beta: thinking-binding-controls-2026-08-01" \
    -d '{
      "model": "claude-fable-5-1",
      "max_tokens": 16000,
      "thinking": { "type": "adaptive" },
      "messages": [
        {
          "role": "user",
          "content": "How many positive integers below 500 have exactly 6 positive divisors?"
        }
      ]
    }')
  echo "$FIRST" | jq -r "$COUNTS"

  # Turno 2: il turno dell'assistente viene rinviato esattamente come restituito, poi il messaggio utente successivo
  MESSAGES=$(jq -n --argjson first "$FIRST" '[
    {
      role: "user",
      content: "How many positive integers below 500 have exactly 6 positive divisors?"
    },
    { role: "assistant", content: $first.content },
    { role: "user", content: "How many of those are odd?" }
  ]')

  SECOND=$(jq -n --argjson messages "$MESSAGES" '{
    model: "claude-fable-5-1",
    max_tokens: 16000,
    thinking: { type: "adaptive" },
    messages: $messages
  }' | curl -s https://api.anthropic.com/v1/messages \
    -H "content-type: application/json" \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "anthropic-beta: thinking-binding-controls-2026-08-01" \
    -d @-)
  echo "$SECOND" | jq -r "$COUNTS"

  # Turno 3: solo questa richiesta aggiunge un prompt di sistema, che modifica il prefisso di proposito
  jq -n --argjson messages "$MESSAGES" --argjson second "$SECOND" '{
    model: "claude-fable-5-1",
    max_tokens: 16000,
    thinking: { type: "adaptive" },
    system: "Answer briefly.",
    messages: ($messages + [
      { role: "assistant", content: $second.content },
      { role: "user", content: "And how many of the odd ones are below 100?" }
    ])
  }' | curl -s https://api.anthropic.com/v1/messages \
    -H "content-type: application/json" \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "anthropic-beta: thinking-binding-controls-2026-08-01" \
    -d @- | jq -r "$COUNTS"
  ```

  ```bash CLI
  # Conta i blocchi di ragionamento in una risposta e quelli che non hanno superato il controllo del prefisso
  COUNTS='"thinking blocks: \([.content[] | select(.type == "thinking")] | length), " +
    "flagged: \([.input_transformations[] |
      select(.type == "thinking_mismatch_allowed")] | length)"'

  FIRST=$(ant beta:messages create --beta thinking-binding-controls-2026-08-01 \
    --format json <<'YAML'
  model: claude-fable-5-1
  max_tokens: 16000
  thinking:
    type: adaptive
  messages:
    - role: user
      content: How many positive integers below 500 have exactly 6 positive divisors?
  YAML
  )
  echo "$FIRST" | jq -r "$COUNTS"

  # Turno 2: il turno dell'assistente viene rinviato esattamente come restituito, poi il messaggio utente successivo
  SECOND=$(ant beta:messages create --beta thinking-binding-controls-2026-08-01 \
    --format json <<YAML
  model: claude-fable-5-1
  max_tokens: 16000
  thinking:
    type: adaptive
  messages:
    - role: user
      content: How many positive integers below 500 have exactly 6 positive divisors?
    - role: assistant
      content: $(echo "$FIRST" | jq -c .content)
    - role: user
      content: How many of those are odd?
  YAML
  )
  echo "$SECOND" | jq -r "$COUNTS"

  # Turno 3: solo questa richiesta aggiunge un prompt di sistema, che modifica il prefisso di proposito
  ant beta:messages create --beta thinking-binding-controls-2026-08-01 \
    --format json <<YAML | jq -r "$COUNTS"
  model: claude-fable-5-1
  max_tokens: 16000
  thinking:
    type: adaptive
  system: Answer briefly.
  messages:
    - role: user
      content: How many positive integers below 500 have exactly 6 positive divisors?
    - role: assistant
      content: $(echo "$FIRST" | jq -c .content)
    - role: user
      content: How many of those are odd?
    - role: assistant
      content: $(echo "$SECOND" | jq -c .content)
    - role: user
      content: And how many of the odd ones are below 100?
  YAML
  ```

  ```python Python
  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}")
  ```

  ```typescript TypeScript
  const client = new Anthropic();

  const userTurns = [
    "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
  const messages: Anthropic.Beta.BetaMessageParam[] = [];
  for (const [turnIndex, userTurn] of userTurns.entries()) {
    messages.push({ role: "user", content: userTurn });
    const response = await 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: turnIndex === userTurns.length - 1 ? "Answer briefly." : undefined,
      messages,
      betas: ["thinking-binding-controls-2026-08-01"]
    });
    messages.push({ role: "assistant", content: response.content });
    const thinkingBlocks = response.content.filter((block) => block.type === "thinking");
    const flagged = (response.input_transformations ?? []).filter(
      (transformation) => transformation.type === "thinking_mismatch_allowed"
    );
    console.log(`thinking blocks: ${thinkingBlocks.length}, flagged: ${flagged.length}`);
  }
  ```

  ```csharp C#
  AnthropicClient client = new();

  string[] userTurns =
  [
      "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
  List<BetaMessageParam> messages = [];
  for (var turnIndex = 0; turnIndex < userTurns.Length; turnIndex++)
  {
      messages.Add(new() { Role = Role.User, Content = userTurns[turnIndex] });
      var response = await client.Beta.Messages.Create(
          new()
          {
              Model = Model.ClaudeFable5_1,
              MaxTokens = 16000,
              Thinking = new BetaThinkingConfigAdaptive(),
              // Solo l'ultima richiesta aggiunge un prompt di sistema, che modifica intenzionalmente il prefisso
              System = turnIndex == userTurns.Length - 1 ? new("Answer briefly.") : null,
              Messages = messages,
              Betas = [AnthropicBeta.ThinkingBindingControls2026_08_01],
          }
      );
      messages.Add(new()
      {
          Role = Role.Assistant,
          Content = response.Content.Select(block => new BetaContentBlockParam(block.Json)).ToList(),
      });
      var thinkingBlocks = response.Content.Count(block => block.TryPickThinking(out _));
      var flagged = response.InputTransformations?.Count(transformation =>
          transformation.TryPickThinkingMismatchAllowed(out _)
      ) ?? 0;
      Console.WriteLine($"thinking blocks: {thinkingBlocks}, flagged: {flagged}");
  }
  ```

  ```go Go
  client := anthropic.NewClient()

  userTurns := []string{
  	"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 := []anthropic.BetaMessageParam{}
  for i, userTurn := range userTurns {
  	messages = append(messages, anthropic.NewBetaUserMessage(anthropic.NewBetaTextBlock(userTurn)))
  	// Solo l'ultima richiesta aggiunge un prompt di sistema, che modifica il prefisso di proposito
  	var system []anthropic.BetaTextBlockParam
  	if i == len(userTurns)-1 {
  		system = []anthropic.BetaTextBlockParam{{Text: "Answer briefly."}}
  	}
  	response, err := client.Beta.Messages.New(context.TODO(), anthropic.BetaMessageNewParams{
  		Model:     anthropic.ModelClaudeFable5_1,
  		MaxTokens: 16000,
  		Thinking: anthropic.BetaThinkingConfigParamUnion{
  			OfAdaptive: &anthropic.BetaThinkingConfigAdaptiveParam{},
  		},
  		System:   system,
  		Messages: messages,
  		Betas:    []anthropic.AnthropicBeta{anthropic.AnthropicBetaThinkingBindingControls2026_08_01},
  	})
  	if err != nil {
  		log.Fatal(err)
  	}
  	messages = append(messages, response.ToParam())
  	thinkingBlocks := 0
  	for _, block := range response.Content {
  		if block.Type == "thinking" {
  			thinkingBlocks++
  		}
  	}
  	flagged := 0
  	for _, transformation := range response.InputTransformations {
  		if transformation.Type == "thinking_mismatch_allowed" {
  			flagged++
  		}
  	}
  	fmt.Printf("thinking blocks: %d, flagged: %d\n", thinkingBlocks, flagged)
  }
  ```

  ```java Java
  import com.anthropic.models.beta.AnthropicBeta;
  import com.anthropic.models.beta.messages.BetaContentBlock;
  import com.anthropic.models.beta.messages.BetaInputTransformation;
  import com.anthropic.models.beta.messages.BetaMessage;
  import com.anthropic.models.beta.messages.BetaThinkingConfigAdaptive;
  import com.anthropic.models.beta.messages.MessageCreateParams;
  import com.anthropic.models.messages.Model;

  void main() {
      AnthropicClient client = AnthropicOkHttpClient.fromEnv();

      List<String> userTurns = List.of(
          "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?");

      // L'elenco dei messaggi del builder cresce a ogni turno: ogni turno dell'assistente viene reinviato esattamente come restituito
      MessageCreateParams.Builder conversation = MessageCreateParams.builder()
          .model(Model.CLAUDE_FABLE_5_1)
          .maxTokens(16000L)
          .thinking(BetaThinkingConfigAdaptive.builder().build())
          .addBeta(AnthropicBeta.THINKING_BINDING_CONTROLS_2026_08_01);

      for (int turnIndex = 0; turnIndex < userTurns.size(); turnIndex++) {
          if (turnIndex == userTurns.size() - 1) {
              // Solo l'ultima richiesta aggiunge un prompt di sistema, che modifica intenzionalmente il prefisso
              conversation.system("Answer briefly.");
          }
          conversation.addUserMessage(userTurns.get(turnIndex));
          BetaMessage response = client.beta().messages().create(conversation.build());
          conversation.addMessage(response);
          long thinkingBlocks = response.content().stream()
              .filter(BetaContentBlock::isThinking)
              .count();
          long flagged = response.inputTransformations().stream()
              .flatMap(List::stream)
              .filter(BetaInputTransformation::isThinkingMismatchAllowed)
              .count();
          IO.println("thinking blocks: " + thinkingBlocks + ", flagged: " + flagged);
      }
  }
  ```

  ```php PHP
  use Anthropic\Beta\AnthropicBeta;
  use Anthropic\Beta\Messages\BetaThinkingConfigAdaptive;
  use Anthropic\Beta\Messages\BetaThinkingMismatchAllowedInputTransformation;
  use Anthropic\Client;

  $client = new Client();

  $userTurns = [
      '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 = [];
  foreach ($userTurns as $turnIndex => $userTurn) {
      $messages[] = ['role' => 'user', 'content' => $userTurn];
      $response = $client->beta->messages->create(
          model: 'claude-fable-5-1',
          maxTokens: 16000,
          thinking: BetaThinkingConfigAdaptive::with(),
          // Solo l'ultima richiesta aggiunge un prompt di sistema, che modifica il prefisso di proposito
          system: $turnIndex === array_key_last($userTurns) ? 'Answer briefly.' : null,
          messages: $messages,
          betas: [AnthropicBeta::THINKING_BINDING_CONTROLS_2026_08_01],
      );
      $messages[] = ['role' => 'assistant', 'content' => $response->content];
      $thinkingBlocks = array_filter($response->content, fn ($block) => $block->type === 'thinking');
      $flagged = array_filter(
          $response->inputTransformations ?? [],
          fn ($transformation) => $transformation instanceof BetaThinkingMismatchAllowedInputTransformation,
      );
      echo 'thinking blocks: ', count($thinkingBlocks), ', flagged: ', count($flagged), PHP_EOL;
  }
  ```

  ```ruby Ruby
  client = Anthropic::Client.new

  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 = []
  user_turns.each_with_index do |user_turn, turn_index|
    messages << {role: "user", content: user_turn}
    # Solo l'ultima richiesta aggiunge un prompt di sistema, che modifica il prefisso di proposito
    system_param = (turn_index == user_turns.length - 1) ? {system_: "Answer briefly."} : {}
    response = client.beta.messages.create(
      model: "claude-fable-5-1",
      max_tokens: 16_000,
      thinking: {type: "adaptive"},
      messages: messages,
      betas: [Anthropic::AnthropicBeta::THINKING_BINDING_CONTROLS_2026_08_01],
      **system_param
    )
    messages << {role: "assistant", content: response.content}
    thinking_blocks = response.content.count { |block| block.type == :thinking }
    flagged = (response.input_transformations || []).count do |transformation|
      transformation.type == :thinking_mismatch_allowed
    end
    puts "thinking blocks: #{thinking_blocks}, flagged: #{flagged}"
  end
  ```
</CodeGroup>

```text Output wrap
thinking blocks: 1, flagged: 0
thinking blocks: 1, flagged: 0
thinking blocks: 1, flagged: 2
```

La 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](https://platform.claude.com/docs/it/build-with-claude/preserved-thinking#replace-prefix-edits). 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](https://platform.claude.com/docs/it/build-with-claude/preserved-thinking#new-instructions)                                                                                                                                                                                                                                                                                                                                                                                      | 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](https://platform.claude.com/docs/it/build-with-claude/preserved-thinking#changing-context)                                                                                                                                                                                                                                                                                                               | 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](https://platform.claude.com/docs/it/build-with-claude/preserved-thinking#server-side-trimming) 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](https://platform.claude.com/docs/it/build-with-claude/preserved-thinking#per-turn-reminders) (`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`](https://platform.claude.com/docs/it/build-with-claude/preserved-thinking#tool-changes)                                                                                                                                                                                                                                                                                                                                                                                              | `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](https://platform.claude.com/docs/it/build-with-claude/preserved-thinking#effort-changes)                                                                                                                                                                                                                                                                                                                                                                                                    | `mid-conversation-output-config-2026-07-01`                                                                                                                                                                                                                                         |
| Scartare o riassumere vecchi turni sul client                                                                        | La [compattazione su richiesta](https://platform.claude.com/docs/it/build-with-claude/compaction-on-demand) per mantenere i turni recenti con il loro ragionamento, altre forme di [compattazione o modifica del contesto](https://platform.claude.com/docs/it/build-with-claude/preserved-thinking#server-side-trimming) lato server, oppure una [compattazione lato client](https://platform.claude.com/docs/it/build-with-claude/preserved-thinking#custom-compaction-on-the-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](https://platform.claude.com/docs/it/build-with-claude/preserved-thinking#files-by-id), oppure base64                                                                                                                                                                                                                                                                                                                                                                                            | Nessuno                                                                                                                                                                                                                                                                             |

Tutte queste soluzioni presuppongono che tu [rimandi i turni dell'assistente esattamente come restituiti](https://platform.claude.com/docs/it/build-with-claude/preserved-thinking#append-assistant-turns-exactly-as-returned). 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](https://platform.claude.com/docs/it/build-with-claude/mid-conversation-system-messages) 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`:

```text wrap
anthropic-beta: thinking-binding-controls-2026-08-01,mid-conversation-system-clear-at-2026-08-21,inline-tools-2026-09-15
```

Le altre piattaforme che offrono queste beta usano gli stessi nomi. Per inviarle lì, consulta [Funzionalità beta su altre piattaforme](https://platform.claude.com/docs/it/api/beta-headers#beta-features-on-other-platforms).

### 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"`](https://platform.claude.com/docs/it/build-with-claude/mid-conversation-system-messages) nel punto di `messages` in cui il cambiamento diventa vero:

```json
{
  "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](https://platform.claude.com/docs/it/build-with-claude/mid-conversation-system-messages#limitations)). 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](https://platform.claude.com/docs/it/build-with-claude/preserved-thinking#new-instructions) se il cambiamento proviene da te in qualità di operatore.

```json
{
  "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](https://platform.claude.com/docs/it/build-with-claude/mid-conversation-system-messages) 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:

```json
[
  { "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](https://platform.claude.com/docs/it/build-with-claude/mid-conversation-system-messages#mid-conversation-tool-changes) 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 `tools` alla prima richiesta ogni strumento di cui la sessione potrebbe aver bisogno, con `defer_loading: true` su quelli che il modello non deve ancora vedere. Poi attiva e disattiva gli strumenti con blocchi `tool_addition` e `tool_removal` che li indicano per nome.
* **Parti da un'istantanea e aggiungi strumenti strada facendo.** Inserisci in `tools` alla prima richiesta gli strumenti che conosci. Quando arriva un nuovo strumento, definiscilo all'interno di un blocco `tool_addition` invece di modificare `tools`.

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à:

```json
{
  "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:

```json
{
  "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`:

```json
{
  "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](https://platform.claude.com/docs/it/agents-and-tools/mcp-connector), 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](https://platform.claude.com/docs/it/build-with-claude/effort#change-effort-mid-conversation-beta), 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.

```json
{ "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](https://platform.claude.com/docs/it/build-with-claude/compaction-on-demand) (beta) restituisce il riepilogo da una richiesta separata, che può essere [eseguita in background](https://platform.claude.com/docs/it/build-with-claude/compaction-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](https://platform.claude.com/docs/it/build-with-claude/compaction-thinking-blocks#conditions-for-kept-thinking-to-stay-valid). [Richiedi un riepilogo](https://platform.claude.com/docs/it/build-with-claude/compaction-on-demand#request-a-summary) mostra la richiesta e indica l'header beta necessario.
* La [compattazione a una soglia di token](https://platform.claude.com/docs/it/build-with-claude/compaction-threshold) 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 `instructions`](https://platform.claude.com/docs/it/build-with-claude/compaction-threshold#custom-summarization-instructions) accetta un tuo prompt di riepilogo, ad esempio "preserva ogni ticker, dimensione di posizione e ipotesi dichiarata".
* La [modifica del contesto](https://platform.claude.com/docs/it/build-with-claude/context-editing) 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_20250919` e `clear_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](https://platform.claude.com/docs/it/build-with-claude/compaction-thinking-blocks#conditions-for-kept-thinking-to-stay-valid) 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.

<Frame>
  ![Simple compaction (compattazione semplice): la richiesta 4 invia l'intera cronologia con il ragionamento su ogni turno dell'assistente; la richiesta 5 invia un unico messaggio utente contenente un riepilogo dei turni da 1 a 4 più l'istruzione successiva, quindi nessun ragionamento precedente viene inviato e nulla viene controllato](https://platform.claude.com/docs/images/preserved-thinking-simple-compaction.svg)
</Frame>

```json
[
  {
    "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](https://platform.claude.com/docs/it/build-with-claude/compaction-keep-recent-turns) mostra come fare, e [Condizioni affinché il ragionamento mantenuto rimanga valido](https://platform.claude.com/docs/it/build-with-claude/compaction-thinking-blocks#conditions-for-kept-thinking-to-stay-valid) elenca quando il ragionamento mantenuto rimane valido.

Il resto di questa sezione riguarda un riepilogo scritto da te.

<Frame>
  ![Keep-tail compaction (compattazione keep-tail): la cronologia viene sostituita da un riepilogo dei turni 1 e 2 seguito dai turni da 3 a 5 alla lettera; il ragionamento sui turni 3 e 4 dell'assistente è stato prodotto dopo i turni originali, non dopo il riepilogo, quindi non supera il controllo; la stessa richiesta inviata con prefix\_mismatch\_behavior drop\_block ha esito positivo, l'API elimina quei due blocchi e li elenca in input\_transformations](https://platform.claude.com/docs/images/preserved-thinking-keep-tail-compaction.svg)
</Frame>

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:

<CodeGroup>
  ```bash cURL
  curl https://api.anthropic.com/v1/messages \
    -H "content-type: application/json" \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "anthropic-beta: thinking-binding-controls-2026-08-01" \
    -d "{
      \"model\": \"claude-fable-5-1\",
      \"max_tokens\": 16000,
      \"thinking\": {
        \"type\": \"adaptive\",
        \"block_binding\": { \"prefix_mismatch_behavior\": \"drop_block\" }
      },
      \"messages\": $COMPACTED_MESSAGES
    }"
  ```

  ```bash CLI
  ant beta:messages create --beta thinking-binding-controls-2026-08-01 <<YAML
  model: claude-fable-5-1
  max_tokens: 16000
  thinking:
    type: adaptive
    block_binding:
      prefix_mismatch_behavior: drop_block
  messages: $COMPACTED_MESSAGES
  YAML
  ```

  ```python Python
  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)
  ```

  ```typescript TypeScript
  const client = new Anthropic();

  // compactedMessages: il messaggio di riepilogo, poi i turni mantenuti così come restituiti
  const response = await client.beta.messages.create({
    model: "claude-fable-5-1",
    max_tokens: 16000,
    thinking: {
      type: "adaptive",
      block_binding: { prefix_mismatch_behavior: "drop_block" }
    },
    messages: compactedMessages,
    betas: ["thinking-binding-controls-2026-08-01"]
  });

  console.log(response.input_transformations);
  ```

  ```csharp C#
  AnthropicClient client = new();

  // compactedMessages: il messaggio di riepilogo, seguito dai turni mantenuti così come restituiti
  var response = await client.Beta.Messages.Create(
      new()
      {
          Model = Model.ClaudeFable5_1,
          MaxTokens = 16000,
          Thinking = new BetaThinkingConfigAdaptive
          {
              BlockBinding = new()
              {
                  PrefixMismatchBehavior = BetaThinkingPrefixMismatchBehavior.DropBlock,
              },
          },
          Messages = compactedMessages,
          Betas = [AnthropicBeta.ThinkingBindingControls2026_08_01],
      }
  );

  Console.WriteLine(response.InputTransformations?.Count ?? 0);
  ```

  ```go Go
  client := anthropic.NewClient()

  // compactedMessages: il messaggio di riepilogo, poi i turni mantenuti così come restituiti
  response, err := client.Beta.Messages.New(context.TODO(), anthropic.BetaMessageNewParams{
  	Model:     anthropic.ModelClaudeFable5_1,
  	MaxTokens: 16000,
  	Thinking: anthropic.BetaThinkingConfigParamUnion{
  		OfAdaptive: &anthropic.BetaThinkingConfigAdaptiveParam{
  			BlockBinding: anthropic.BetaThinkingBlockBindingParam{
  				PrefixMismatchBehavior: anthropic.BetaThinkingPrefixMismatchBehaviorDropBlock,
  			},
  		},
  	},
  	Messages: compactedMessages,
  	Betas:    []anthropic.AnthropicBeta{anthropic.AnthropicBetaThinkingBindingControls2026_08_01},
  })
  if err != nil {
  	log.Fatal(err)
  }

  fmt.Println(len(response.InputTransformations))
  ```

  ```java Java
  import com.anthropic.models.beta.AnthropicBeta;
  import com.anthropic.models.beta.messages.BetaMessage;
  import com.anthropic.models.beta.messages.BetaThinkingBlockBinding;
  import com.anthropic.models.beta.messages.BetaThinkingConfigAdaptive;
  import com.anthropic.models.beta.messages.BetaThinkingPrefixMismatchBehavior;
  import com.anthropic.models.beta.messages.MessageCreateParams;
  import com.anthropic.models.messages.Model;

  void main() {
      AnthropicClient client = AnthropicOkHttpClient.fromEnv();

      // compactedMessages: il messaggio di riepilogo, poi i turni mantenuti così come restituiti
      MessageCreateParams params = MessageCreateParams.builder()
          .model(Model.CLAUDE_FABLE_5_1)
          .maxTokens(16000L)
          .thinking(BetaThinkingConfigAdaptive.builder()
              .blockBinding(BetaThinkingBlockBinding.builder()
                  .prefixMismatchBehavior(BetaThinkingPrefixMismatchBehavior.DROP_BLOCK)
                  .build())
              .build())
          .messages(compactedMessages)
          .addBeta(AnthropicBeta.THINKING_BINDING_CONTROLS_2026_08_01)
          .build();

      BetaMessage response = client.beta().messages().create(params);

      IO.println(response.inputTransformations());
  }
  ```

  ```php PHP
  use Anthropic\Beta\AnthropicBeta;
  use Anthropic\Beta\Messages\BetaThinkingBlockBinding;
  use Anthropic\Beta\Messages\BetaThinkingConfigAdaptive;
  use Anthropic\Beta\Messages\BetaThinkingPrefixMismatchBehavior;
  use Anthropic\Client;

  $client = new Client();

  // $compactedMessages: il messaggio di riepilogo, poi i turni mantenuti così come restituiti
  $response = $client->beta->messages->create(
      model: 'claude-fable-5-1',
      maxTokens: 16000,
      thinking: BetaThinkingConfigAdaptive::with(
          blockBinding: BetaThinkingBlockBinding::with(
              prefixMismatchBehavior: BetaThinkingPrefixMismatchBehavior::DROP_BLOCK,
          ),
      ),
      messages: $compactedMessages,
      betas: [AnthropicBeta::THINKING_BINDING_CONTROLS_2026_08_01],
  );

  var_dump($response->inputTransformations);
  ```

  ```ruby Ruby
  client = Anthropic::Client.new

  # compacted_messages: il messaggio di riepilogo, poi i turni mantenuti così come restituiti
  response = client.beta.messages.create(
    model: "claude-fable-5-1",
    max_tokens: 16_000,
    thinking: {
      type: "adaptive",
      block_binding: {prefix_mismatch_behavior: "drop_block"}
    },
    messages: compacted_messages,
    betas: [Anthropic::AnthropicBeta::THINKING_BINDING_CONTROLS_2026_08_01]
  )

  puts response.input_transformations
  ```
</CodeGroup>

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:

```json
{
  "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](https://platform.claude.com/docs/it/build-with-claude/compaction-background) descrive i passaggi, e quel ragionamento resta valido alle stesse [condizioni per il ragionamento mantenuto](https://platform.claude.com/docs/it/build-with-claude/compaction-thinking-blocks#conditions-for-kept-thinking-to-stay-valid) 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](https://platform.claude.com/docs/it/build-with-claude/preserved-thinking#new-instructions). Per rimuovere selettivamente vecchi risultati degli strumenti o vecchio thinking, usa il "context editing" (modifica del contesto) lato server: consulta [modifica del contesto](https://platform.claude.com/docs/it/build-with-claude/context-editing).
* **Compattare nel mezzo di un round di strumenti.** Non compattare tra il `tool_use` di un turno dell'assistente e il `tool_result` che 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](https://platform.claude.com/docs/it/build-with-claude/thinking#preserving-thinking-blocks).

### 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](https://platform.claude.com/docs/it/build-with-claude/files) 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-beta` e `thinking.block_binding` del chiamante, e restituiscigli `input_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 campo `system` di primo livello modifica `system` in 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 rimuovere `tools`.
* **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

<AccordionGroup>
  <Accordion title="Ho bisogno di un nuovo account per testare il ragionamento preservato?">
    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](https://platform.claude.com/docs/it/build-with-claude/preserved-thinking#how-to-tell-whether-your-integration-is-impacted).
  </Accordion>

  <Accordion title="Se qualcosa prima di un blocco di ragionamento cambia, anche solo la descrizione di uno strumento, la conversazione diventa inutilizzabile?">
    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](https://platform.claude.com/docs/it/build-with-claude/preserved-thinking#mismatch-behavior). [Cosa conta come modifica](https://platform.claude.com/docs/it/build-with-claude/preserved-thinking#what-counts-as-an-edit) elenca quali modifiche sono rilevanti.
  </Accordion>

  <Accordion title="Cambiare l'effort o altre impostazioni di ragionamento tra una richiesta e l'altra invalida il ragionamento precedente?">
    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](https://platform.claude.com/docs/it/build-with-claude/preserved-thinking#effort-changes), 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.
  </Accordion>

  <Accordion title="Il mio elenco di strumenti cambia a metà sessione. Come evito di invalidare la conversazione?">
    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`](https://platform.claude.com/docs/it/build-with-claude/preserved-thinking#tool-changes).
  </Accordion>

  <Accordion title="Compatto riassumendo i turni più vecchi e mantenendo alla lettera quelli recenti. Funziona ancora?">
    Sì, se il riepilogo lo scrive l'API. La [compattazione su richiesta](https://platform.claude.com/docs/it/build-with-claude/compaction-on-demand) (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](https://platform.claude.com/docs/it/build-with-claude/compaction-thinking-blocks#conditions-for-kept-thinking-to-stay-valid).

    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](https://platform.claude.com/docs/it/build-with-claude/compaction) e la [modifica del contesto](https://platform.claude.com/docs/it/build-with-claude/context-editing) lato server non contano come modifiche. Consulta [Compattare sul client](https://platform.claude.com/docs/it/build-with-claude/preserved-thinking#custom-compaction-on-the-client).
  </Accordion>

  <Accordion title="Come gestisco file di istruzioni come AGENTS.md o CLAUDE.md che cambiano a metà sessione?">
    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](https://platform.claude.com/docs/it/build-with-claude/mid-conversation-system-messages) 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](https://platform.claude.com/docs/it/build-with-claude/preserved-thinking#new-instructions) e [Limitazioni](https://platform.claude.com/docs/it/build-with-claude/mid-conversation-system-messages#limitations).
  </Accordion>

  <Accordion title="Posso riprendere una sessione salvata in seguito, dopo un riavvio o il giorno dopo?">
    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](https://platform.claude.com/docs/it/build-with-claude/preserved-thinking#append-assistant-turns-exactly-as-returned).
  </Accordion>

  <Accordion title="Una sessione salvata ora fallisce a ogni richiesta. Come la faccio funzionare di nuovo?">
    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](https://platform.claude.com/docs/it/build-with-claude/preserved-thinking#handle-the-error-in-code).
  </Accordion>

  <Accordion title="Il mio harness può instradare un turno verso un modello non Claude. Quei turni invalidano il ragionamento precedente di Claude?">
    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`.
  </Accordion>

  <Accordion title="Posso trasferire il ragionamento di una conversazione in una nuova conversazione?">
    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](https://platform.claude.com/docs/it/build-with-claude/preserved-thinking#custom-compaction-on-the-client): 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](https://platform.claude.com/docs/it/build-with-claude/preserved-thinking#account-bound-thinking)).
  </Accordion>
</AccordionGroup>

## Passaggi successivi

<CardGroup cols={2}>
  <Card title="Risoluzione dei problemi del ragionamento" icon="hammer" href="https://platform.claude.com/docs/it/build-with-claude/thinking-troubleshooting">
    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.
  </Card>

  <Card title="Messaggi di sistema e modifiche degli strumenti a metà conversazione" icon="messages" href="https://platform.claude.com/docs/it/build-with-claude/mid-conversation-system-messages">
    Modifica le istruzioni di sistema o la disponibilità degli strumenti a metà di una conversazione senza invalidare il prefisso in cache che le precede.
  </Card>

  <Card title="Compattazione" icon="stack" href="https://platform.claude.com/docs/it/build-with-claude/compaction">
    Compattazione del contesto lato server per gestire conversazioni lunghe che si avvicinano ai limiti della finestra di contesto.
  </Card>

  <Card title="Cache dei prompt" icon="database" href="https://platform.claude.com/docs/it/build-with-claude/prompt-caching">
    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.
  </Card>
</CardGroup>
