---
title: Compattazione e ragionamento preservato
url: https://platform.claude.com/docs/it/build-with-claude/compaction-thinking-blocks
description: Quando i blocchi di ragionamento nei turni mantenuti dopo la compattazione on-demand restano validi sui modelli con ragionamento preservato, e come verificarlo.
featureMetadata:
  status: beta
  betaHeader: compact-2026-09-04
  supportedModels:
    - claude-fable-5-1
    - claude-mythos-5-1
    - claude-fable-5
    - claude-mythos-5
    - claude-mythos-preview
    - claude-opus-5-5
    - claude-opus-5
    - claude-opus-4-8
    - claude-opus-4-7
    - claude-opus-4-6
    - claude-sonnet-5-5
    - claude-sonnet-5
    - claude-sonnet-4-6
    - claude-haiku-5-5
  supportedPlatforms:
    Claude API: beta
    Claude Platform on AWS: beta
    Google Cloud: beta
    Microsoft Foundry: beta
---

Salta questa pagina a meno che tu non rimandi i "thinking blocks" (blocchi di ragionamento) a un modello con ["preserved thinking" (ragionamento preservato)](https://platform.claude.com/docs/it/build-with-claude/preserved-thinking) e mantenga dei turni dopo il blocco di "compaction" (compattazione). I "kept turns" (turni mantenuti) sono i turni che seguono il blocco: i turni recenti che hai escluso dalla richiesta di compattazione, come in [Compattazione che mantiene i turni recenti](https://platform.claude.com/docs/it/build-with-claude/compaction-keep-recent-turns), oppure i turni arrivati mentre veniva scritto il riepilogo, come in [Compattazione in background](https://platform.claude.com/docs/it/build-with-claude/compaction-background).

I modelli con ragionamento preservato verificano i blocchi di ragionamento precedenti rispetto alla conversazione che li ha prodotti. Un riepilogo sostituisce parte di quella conversazione, ma il controllo accetta la sostituzione quando è stata l'API a scrivere il riepilogo, quindi il ragionamento nei turni mantenuti può rimanere valido.

## Condizioni affinché il ragionamento mantenuto rimanga valido

I blocchi di ragionamento nei turni mantenuti rimangono validi finché valgono tutte queste condizioni:

* **La richiesta di compattazione viene eseguita su un modello con ragionamento preservato.** Questa condizione riguarda ogni richiesta di compattazione successiva alla produzione di un blocco di ragionamento, non solo la più recente. Un modo per soddisfarla è inviare ogni richiesta di compattazione al modello usato dalla conversazione.
* **I turni mantenuti seguono direttamente i messaggi riepilogati e li invii senza modifiche.** Invia ogni messaggio mantenuto esattamente com'è nella tua cronologia. Non saltare né aggiungere messaggi tra l'ultimo messaggio riepilogato e il primo mantenuto. Il primo messaggio mantenuto deve inoltre avere un ruolo diverso dall'ultimo messaggio riepilogato, e non può essere un messaggio `role: "system"` a metà conversazione. Altrimenti, l'API lo unisce all'ultimo messaggio riepilogato. Un modo per impostare correttamente il primo messaggio mantenuto è compattare esattamente i `messages` di una richiesta che hai già inviato. I turni mantenuti iniziano quindi con la risposta di Claude a quella richiesta.
* **`system` e i `tools` non contrassegnati con `defer_loading: true` non cambiano.** Sono gli stessi nella richiesta di compattazione e nelle richieste che hanno prodotto il ragionamento mantenuto, e rimangono gli stessi nelle richieste successive. [Modificare il prompt di sistema o gli strumenti](https://platform.claude.com/docs/it/build-with-claude/compaction-thinking-blocks#change-the-system-prompt-or-tools) spiega come modificarli in sicurezza.

Se una condizione non è soddisfatta, nulla fallisce al momento della compattazione, e l'API accetta comunque il blocco nelle richieste successive. L'errore si verifica alla prima richiesta successiva che invia il ragionamento mantenuto dove l'API applica il controllo: un errore 400 per impostazione predefinita, oppure blocchi di ragionamento scartati se la richiesta imposta `thinking.block_binding.prefix_mismatch_behavior` su `"drop_block"`. Nella Message Batches API, un elemento che lascia il campo non impostato non fallisce. Dove il controllo si applica per impostazione predefinita, l'API scarta invece i blocchi. [Cosa fa l'API con un blocco non valido](https://platform.claude.com/docs/it/build-with-claude/preserved-thinking#mismatch-behavior) descrive entrambi gli esiti, e [Quando l'API applica il controllo](https://platform.claude.com/docs/it/build-with-claude/preserved-thinking#enforcement) indica quali richieste vengono controllate.

## Compattare di nuovo senza invalidare il ragionamento precedente

Puoi [compattare di nuovo](https://platform.claude.com/docs/it/build-with-claude/compaction-on-demand#compact-again) e mantenere dei turni: il nuovo blocco copre il vecchio riepilogo e ogni messaggio che lo segue nella richiesta di compattazione, e tutti i turni che escludi da quella richiesta sono turni mantenuti del nuovo blocco.

La prima delle [condizioni per il ragionamento mantenuto](https://platform.claude.com/docs/it/build-with-claude/compaction-thinking-blocks#conditions-for-kept-thinking-to-stay-valid) conta ogni compattazione successiva alla produzione di un blocco di ragionamento, quindi un turno che mantieni attraverso due compattazioni richiede che entrambe siano state eseguite su un modello con ragionamento preservato.

Le compattazioni precedenti alla produzione di un blocco di ragionamento non contano ai suoi fini. Il ragionamento prodotto dopo che un blocco è in posizione è vincolato a quel blocco, e rimane valido attraverso le compattazioni successive che soddisfano le condizioni.

## Modificare il prompt di sistema o gli strumenti

Una richiesta successiva può usare un `system` diverso, `tools` diversi o un modello diverso rispetto alla richiesta di compattazione, e l'API accetta comunque il blocco. Una modifica di questo tipo può invalidare il ragionamento nei turni mantenuti, ma non ha altri effetti.

Per modificare `system` o `tools` senza invalidare alcun ragionamento mantenuto, compatta prima l'intera conversazione, in modo che nessun turno venga mantenuto. Poi modificali nella richiesta successiva.

Per aggiungere un'istruzione o modificare gli strumenti disponibili senza toccare `system` o `tools`, aggiungi la modifica in coda a `messages`, come descritto in [Apportare modifiche senza modificare il prefisso](https://platform.claude.com/docs/it/build-with-claude/preserved-thinking#replace-prefix-edits).

Anche i messaggi di sistema a metà conversazione all'interno dei turni riepilogati vengono riepilogati, quindi le loro istruzioni testuali smettono di applicarsi dopo la sostituzione. Nemmeno un livello di [effort per messaggio](https://platform.claude.com/docs/it/build-with-claude/effort#change-effort-mid-conversation-beta) da essi impostato viene trasferito: finché un messaggio successivo non imposta un livello, i turni vengono eseguiti con l'`output_config.effort` di primo livello della richiesta, oppure con il valore predefinito del modello se non ne imposti uno. Per mantenere in vigore un'istruzione o un livello di effort, ribadiscilo in un messaggio `role: "system"` subito dopo il primo nuovo turno `user` che segue i turni mantenuti. Le modifiche agli strumenti all'interno di quei turni vengono trasferite automaticamente quando anche la richiesta di compattazione include `inline-tools-2026-09-15`: il blocco restituito registra il loro effetto netto nel campo `tool_changes`, quindi rimanda il blocco senza modificarlo. Se il blocco non ha un campo `tool_changes`, ribadisci quelle modifiche agli strumenti nello stesso modo. Un messaggio di sistema posizionato tra il blocco e i turni mantenuti invalida il loro ragionamento.

## Verificare che il ragionamento mantenuto abbia retto

La risposta di compattazione non indica se il ragionamento mantenuto regge. Lo indica la prima richiesta dopo la sostituzione. Per verificarlo nei tuoi test:

1. Avvia una breve conversazione con il ragionamento attivo. Usa un modello su cui l'API esegue il controllo (vedi [Quando l'API applica il controllo](https://platform.claude.com/docs/it/build-with-claude/preserved-thinking#enforcement)), e usalo per ogni passaggio, perché un modello che non può leggere un blocco di ragionamento lo scarta senza errori.
2. Compatta i turni più vecchi e mantieni almeno un turno che contenga un blocco di ragionamento.
3. Invia la richiesta successiva, con prima il blocco, poi il turno mantenuto, poi un nuovo messaggio `user`, e con `thinking.block_binding.prefix_mismatch_behavior` impostato su `"error"`.
4. Leggi il risultato. Una risposta 200 il cui array `input_transformations` è vuoto significa che tutti i blocchi di ragionamento hanno superato il controllo e nessuno è stato scartato. Un errore 400 che indica che il blocco è vincolato a una conversazione diversa significa che uno di essi non l'ha superato. Il messaggio inizia con il percorso del primo blocco che non ha superato il controllo, e [Cosa fa l'API con un blocco non valido](https://platform.claude.com/docs/it/build-with-claude/preserved-thinking#mismatch-behavior) lo mostra per intero.

Il campo `prefix_mismatch_behavior` richiede l'header beta `thinking-binding-controls-2026-08-01` oltre all'[header beta `compact-2026-09-04`](https://platform.claude.com/docs/it/build-with-claude/compaction-on-demand#request-a-summary). Impostare il campo attiva inoltre il controllo per la richiesta sugli account in cui il controllo non è attivo per impostazione predefinita.

Il seguente programma esegue i quattro passaggi. Stampa quanti blocchi di ragionamento contiene il turno mantenuto e quante voci ha `input_transformations`; nessuna voce significa che il ragionamento mantenuto ha retto:

<CodeGroup exclude="shell">
  ```python Python
  from anthropic.types.beta import BetaMessageParam, BetaThinkingConfigParam

  client = anthropic.Anthropic()

  # Claude Fable 5.1 è il primo modello che verifica il thinking rinviato rispetto alla conversazione.
  MODEL = "claude-fable-5-1"
  BETAS = ["compact-2026-09-04", "thinking-binding-controls-2026-08-01"]
  SYSTEM = "You help plan a recipe app's release. Keep answers short."
  # Con "error", un blocco di thinking che non supera la verifica fa fallire la richiesta con un 400.
  THINKING: BetaThinkingConfigParam = {
      "type": "adaptive",
      "block_binding": {"prefix_mismatch_behavior": "error"},
  }

  # 1. Avvia una breve conversazione con il thinking attivo.
  history: list[BetaMessageParam] = [
      {"role": "user", "content": "What are the main entities in the app's data model?"}
  ]
  first = client.beta.messages.create(
      model=MODEL,
      max_tokens=8192,
      system=SYSTEM,
      betas=BETAS,
      thinking=THINKING,
      messages=history,
  )
  history += [
      {"role": "assistant", "content": first.content},
      {
          "role": "user",
          "content": "Testing starts on Tuesday, March 3, 2026, takes 10 weekdays, and pauses on March 9 and March 16. On which date does it end?",
      },
  ]
  second = client.beta.messages.create(
      model=MODEL,
      max_tokens=8192,
      system=SYSTEM,
      betas=BETAS,
      thinking=THINKING,
      messages=history,
  )
  history.append({"role": "assistant", "content": second.content})
  thinking_blocks = sum(block.type == "thinking" for block in second.content)
  print(f"Thinking blocks in the kept turn: {thinking_blocks}")

  # 2. Riassumi il primo turno. Il secondo turno resta fuori dalla richiesta.
  summary = client.beta.messages.create(
      model=MODEL,
      max_tokens=4096,
      system=SYSTEM,
      betas=BETAS,
      thinking=THINKING,
      messages=history[:2],
      compaction={"type": "summarize"},
  )
  if summary.stop_reason != "compaction":
      raise SystemExit(f"No summary: {summary.stop_reason}")

  # 3. Metti il blocco davanti al turno mantenuto e poni la domanda successiva.
  history = [
      {"role": "assistant", "content": summary.content},
      *history[2:],
      {"role": "user", "content": "Which day should the release go out?"},
  ]
  third = client.beta.messages.create(
      model=MODEL,
      max_tokens=8192,
      system=SYSTEM,
      betas=BETAS,
      thinking=THINKING,
      messages=history,
  )

  # 4. Un 200 senza blocchi scartati indica che il thinking mantenuto è stato accettato.
  print(f"Dropped thinking blocks: {len(third.input_transformations)}")
  ```

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

  // Claude Fable 5.1 è il primo modello che verifica il thinking rinviato confrontandolo con la conversazione.
  const model: Anthropic.Model = "claude-fable-5-1";
  const betas: Anthropic.Beta.AnthropicBeta[] = [
    "compact-2026-09-04",
    "thinking-binding-controls-2026-08-01"
  ];
  const systemPrompt = "You help plan a recipe app's release. Keep answers short.";
  // Con "error", un blocco di thinking che non supera la verifica fa fallire la richiesta con un 400.
  const thinking: Anthropic.Beta.Messages.BetaThinkingConfigParam = {
    type: "adaptive",
    block_binding: { prefix_mismatch_behavior: "error" }
  };

  // 1. Avvia una breve conversazione con il thinking attivo.
  let history: Anthropic.Beta.Messages.BetaMessageParam[] = [
    { role: "user", content: "What are the main entities in the app's data model?" }
  ];
  const first = await client.beta.messages.create({
    model,
    max_tokens: 8192,
    system: systemPrompt,
    betas,
    thinking,
    messages: history
  });
  history.push(
    { role: "assistant", content: first.content },
    {
      role: "user",
      content:
        "Testing starts on Tuesday, March 3, 2026, takes 10 weekdays, and pauses on March 9 and March 16. On which date does it end?"
    }
  );
  const second = await client.beta.messages.create({
    model,
    max_tokens: 8192,
    system: systemPrompt,
    betas,
    thinking,
    messages: history
  });
  history.push({ role: "assistant", content: second.content });
  const thinkingBlocks = second.content.filter((block) => block.type === "thinking").length;
  console.log(`Thinking blocks in the kept turn: ${thinkingBlocks}`);

  // 2. Riassumi il primo turno. Il secondo turno resta fuori dalla richiesta.
  const summary = await client.beta.messages.create({
    model,
    max_tokens: 4096,
    system: systemPrompt,
    betas,
    thinking,
    messages: history.slice(0, 2),
    compaction: { type: "summarize" }
  });
  if (summary.stop_reason !== "compaction") {
    throw new Error(`No summary: ${summary.stop_reason}`);
  }

  // 3. Metti il blocco davanti al turno mantenuto e poni la domanda successiva.
  history = [
    { role: "assistant", content: summary.content },
    ...history.slice(2),
    { role: "user", content: "Which day should the release go out?" }
  ];
  const third = await client.beta.messages.create({
    model,
    max_tokens: 8192,
    system: systemPrompt,
    betas,
    thinking,
    messages: history
  });

  // 4. Un 200 senza blocchi scartati indica che il thinking mantenuto è stato accettato.
  console.log(`Dropped thinking blocks: ${third.input_transformations?.length ?? 0}`);
  ```

  ```csharp C#
  using Anthropic.Models.Beta;
  using Anthropic.Models.Beta.Messages;
  using Model = Anthropic.Models.Messages.Model;

  AnthropicClient client = new();

  // Claude Fable 5.1 è il primo modello che verifica il thinking rinviato rispetto alla conversazione.
  const Model ModelId = Model.ClaudeFable5_1;
  AnthropicBeta[] betas = [AnthropicBeta.Compact2026_09_04, AnthropicBeta.ThinkingBindingControls2026_08_01];
  const string SystemPrompt = "You help plan a recipe app's release. Keep answers short.";
  // Con "error", un blocco di thinking che non supera la verifica fa fallire la richiesta con un 400.
  BetaThinkingConfigAdaptive thinking = new()
  {
      BlockBinding = new() { PrefixMismatchBehavior = BetaThinkingPrefixMismatchBehavior.Error },
  };

  // 1. Avvia una breve conversazione con il thinking attivo.
  List<BetaMessageParam> history =
  [
      new() { Role = Role.User, Content = "What are the main entities in the app's data model?" },
  ];
  var first = await client.Beta.Messages.Create(new MessageCreateParams
  {
      Model = ModelId,
      MaxTokens = 8192,
      System = SystemPrompt,
      Betas = [.. betas],
      Thinking = thinking,
      Messages = history,
  });
  history.AddRange(
  [
      new()
      {
          Role = Role.Assistant,
          Content = first.Content.Select(block => new BetaContentBlockParam(block.Json)).ToList(),
      },
      new()
      {
          Role = Role.User,
          Content = "Testing starts on Tuesday, March 3, 2026, takes 10 weekdays, and pauses on March 9 and March 16. On which date does it end?",
      },
  ]);
  var second = await client.Beta.Messages.Create(new MessageCreateParams
  {
      Model = ModelId,
      MaxTokens = 8192,
      System = SystemPrompt,
      Betas = [.. betas],
      Thinking = thinking,
      Messages = history,
  });
  history.Add(new()
  {
      Role = Role.Assistant,
      Content = second.Content.Select(block => new BetaContentBlockParam(block.Json)).ToList(),
  });
  var thinkingBlocks = second.Content.Count(block => block.TryPickThinking(out _));
  Console.WriteLine($"Thinking blocks in the kept turn: {thinkingBlocks}");

  // 2. Riassumi il primo turno. Il secondo turno resta fuori dalla richiesta.
  var summary = await client.Beta.Messages.Create(new MessageCreateParams
  {
      Model = ModelId,
      MaxTokens = 4096,
      System = SystemPrompt,
      Betas = [.. betas],
      Thinking = thinking,
      Messages = history[..2],
      Compaction = new BetaCompactionConfig(), // type defaults to "summarize"
  });
  if (summary.StopReason != BetaStopReason.Compaction)
  {
      throw new InvalidOperationException($"No summary: {summary.StopReason?.Raw()}");
  }

  // 3. Metti il blocco davanti al turno mantenuto e poni la domanda successiva.
  history =
  [
      new()
      {
          Role = Role.Assistant,
          Content = summary.Content.Select(block => new BetaContentBlockParam(block.Json)).ToList(),
      },
      .. history[2..],
      new() { Role = Role.User, Content = "Which day should the release go out?" },
  ];
  var third = await client.Beta.Messages.Create(new MessageCreateParams
  {
      Model = ModelId,
      MaxTokens = 8192,
      System = SystemPrompt,
      Betas = [.. betas],
      Thinking = thinking,
      Messages = history,
  });

  // 4. Un 200 senza blocchi scartati significa che il thinking mantenuto è stato accettato.
  Console.WriteLine($"Dropped thinking blocks: {third.InputTransformations?.Count ?? 0}");
  ```

  ```go Go
  ctx := context.Background()
  client := anthropic.NewClient()

  // Claude Fable 5.1 è il primo modello che verifica il thinking rinviato confrontandolo con la conversazione.
  const model = anthropic.ModelClaudeFable5_1
  betas := []anthropic.AnthropicBeta{
  	anthropic.AnthropicBetaCompact2026_09_04,
  	anthropic.AnthropicBetaThinkingBindingControls2026_08_01,
  }
  system := []anthropic.BetaTextBlockParam{{Text: "You help plan a recipe app's release. Keep answers short."}}
  // Con "error", un blocco di thinking che non supera la verifica fa fallire la richiesta con un 400.
  thinking := anthropic.BetaThinkingConfigParamUnion{
  	OfAdaptive: &anthropic.BetaThinkingConfigAdaptiveParam{
  		BlockBinding: anthropic.BetaThinkingBlockBindingParam{
  			PrefixMismatchBehavior: anthropic.BetaThinkingPrefixMismatchBehaviorError,
  		},
  	},
  }

  // 1. Avvia una breve conversazione con il thinking attivo.
  history := []anthropic.BetaMessageParam{
  	anthropic.NewBetaUserMessage(anthropic.NewBetaTextBlock("What are the main entities in the app's data model?")),
  }
  first, err := client.Beta.Messages.New(ctx, anthropic.BetaMessageNewParams{
  	Model:     model,
  	MaxTokens: 8192,
  	System:    system,
  	Betas:     betas,
  	Thinking:  thinking,
  	Messages:  history,
  })
  if err != nil {
  	log.Fatal(err)
  }
  history = append(history,
  	first.ToParam(),
  	anthropic.NewBetaUserMessage(anthropic.NewBetaTextBlock("Testing starts on Tuesday, March 3, 2026, takes 10 weekdays, and pauses on March 9 and March 16. On which date does it end?")),
  )
  second, err := client.Beta.Messages.New(ctx, anthropic.BetaMessageNewParams{
  	Model:     model,
  	MaxTokens: 8192,
  	System:    system,
  	Betas:     betas,
  	Thinking:  thinking,
  	Messages:  history,
  })
  if err != nil {
  	log.Fatal(err)
  }
  history = append(history, second.ToParam())
  thinkingBlocks := 0
  for _, block := range second.Content {
  	if _, ok := block.AsAny().(anthropic.BetaThinkingBlock); ok {
  		thinkingBlocks++
  	}
  }
  fmt.Printf("Thinking blocks in the kept turn: %d\n", thinkingBlocks)

  // 2. Riassumi il primo turno. Il secondo turno resta fuori dalla richiesta.
  summary, err := client.Beta.Messages.New(ctx, anthropic.BetaMessageNewParams{
  	Model:     model,
  	MaxTokens: 4096,
  	System:    system,
  	Betas:     betas,
  	Thinking:  thinking,
  	Messages:  history[:2],
  	Compaction: anthropic.BetaCompactionConfigUnionParam{
  		OfSummarize: &anthropic.BetaSummarizeCompactionParam{},
  	},
  })
  if err != nil {
  	log.Fatal(err)
  }
  if summary.StopReason != anthropic.BetaStopReasonCompaction {
  	log.Fatalf("No summary: %s", summary.StopReason)
  }

  // 3. Metti il blocco davanti al turno mantenuto e poni la domanda successiva.
  history = slices.Concat(
  	[]anthropic.BetaMessageParam{summary.ToParam()},
  	history[2:],
  	[]anthropic.BetaMessageParam{anthropic.NewBetaUserMessage(anthropic.NewBetaTextBlock("Which day should the release go out?"))},
  )
  third, err := client.Beta.Messages.New(ctx, anthropic.BetaMessageNewParams{
  	Model:     model,
  	MaxTokens: 8192,
  	System:    system,
  	Betas:     betas,
  	Thinking:  thinking,
  	Messages:  history,
  })
  if err != nil {
  	log.Fatal(err)
  }

  // 4. Un 200 senza blocchi scartati indica che il thinking mantenuto è stato accettato.
  fmt.Printf("Dropped thinking blocks: %d\n", len(third.InputTransformations))
  ```

  ```java Java
  import com.anthropic.models.beta.AnthropicBeta;
  import com.anthropic.models.beta.messages.BetaCompactionConfig;
  import com.anthropic.models.beta.messages.BetaContentBlock;
  import com.anthropic.models.beta.messages.BetaMessageParam;
  import com.anthropic.models.beta.messages.BetaStopReason;
  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;

  // Claude Fable 5.1 è il primo modello che verifica il thinking rinviato rispetto alla conversazione.
  static final Model MODEL = Model.CLAUDE_FABLE_5_1;
  static final List<AnthropicBeta> BETAS = List.of(
      AnthropicBeta.COMPACT_2026_09_04,
      AnthropicBeta.THINKING_BINDING_CONTROLS_2026_08_01
  );
  static final String SYSTEM = "You help plan a recipe app's release. Keep answers short.";
  // Con "error", un blocco di thinking che non supera la verifica fa fallire la richiesta con un 400.
  static final BetaThinkingConfigAdaptive THINKING = BetaThinkingConfigAdaptive.builder()
      .blockBinding(BetaThinkingBlockBinding.builder()
          .prefixMismatchBehavior(BetaThinkingPrefixMismatchBehavior.ERROR)
          .build())
      .build();

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

      // 1. Avvia una breve conversazione con il thinking attivo.
      var history = new ArrayList<BetaMessageParam>();
      history.add(BetaMessageParam.builder()
          .role(BetaMessageParam.Role.USER)
          .content("What are the main entities in the app's data model?")
          .build());
      var firstParams = MessageCreateParams.builder()
          .model(MODEL)
          .maxTokens(8192)
          .system(SYSTEM)
          .betas(BETAS)
          .thinking(THINKING)
          .messages(history)
          .build();
      var first = client.beta().messages().create(firstParams);
      history.add(first.toParam());
      history.add(BetaMessageParam.builder()
          .role(BetaMessageParam.Role.USER)
          .content("Testing starts on Tuesday, March 3, 2026, takes 10 weekdays, and pauses on March 9 and March 16. On which date does it end?")
          .build());
      var secondParams = MessageCreateParams.builder()
          .model(MODEL)
          .maxTokens(8192)
          .system(SYSTEM)
          .betas(BETAS)
          .thinking(THINKING)
          .messages(history)
          .build();
      var second = client.beta().messages().create(secondParams);
      history.add(second.toParam());
      long thinkingBlocks = second.content().stream().filter(BetaContentBlock::isThinking).count();
      IO.println("Thinking blocks in the kept turn: " + thinkingBlocks);

      // 2. Riassumi il primo turno. Il secondo turno resta fuori dalla richiesta.
      var firstTurn = history.subList(0, 2);
      var summaryParams = MessageCreateParams.builder()
          .model(MODEL)
          .maxTokens(4096)
          .system(SYSTEM)
          .betas(BETAS)
          .thinking(THINKING)
          .messages(firstTurn)
          .compaction(BetaCompactionConfig.builder().build()) // type defaults to "summarize"
          .build();
      var summary = client.beta().messages().create(summaryParams);
      if (!summary.stopReason().map(BetaStopReason.COMPACTION::equals).orElse(false)) {
          throw new IllegalStateException("No summary: " + summary.stopReason().orElseThrow());
      }

      // 3. Metti il blocco davanti al turno mantenuto e poni la domanda successiva.
      firstTurn.clear();
      history.addFirst(summary.toParam());
      history.add(BetaMessageParam.builder()
          .role(BetaMessageParam.Role.USER)
          .content("Which day should the release go out?")
          .build());
      var thirdParams = MessageCreateParams.builder()
          .model(MODEL)
          .maxTokens(8192)
          .system(SYSTEM)
          .betas(BETAS)
          .thinking(THINKING)
          .messages(history)
          .build();
      var third = client.beta().messages().create(thirdParams);

      // 4. Un 200 senza blocchi scartati indica che il thinking mantenuto è stato accettato.
      IO.println("Dropped thinking blocks: " + third.inputTransformations().map(List::size).orElse(0));
  }
  ```

  ```php PHP
  use Anthropic\Beta\AnthropicBeta;
  use Anthropic\Beta\Messages\BetaCompactionConfig;
  use Anthropic\Beta\Messages\BetaMessageParam;
  use Anthropic\Beta\Messages\BetaMessageParam\Role;
  use Anthropic\Beta\Messages\BetaStopReason;
  use Anthropic\Beta\Messages\BetaThinkingBlock;
  use Anthropic\Beta\Messages\BetaThinkingBlockBinding;
  use Anthropic\Beta\Messages\BetaThinkingConfigAdaptive;
  use Anthropic\Beta\Messages\BetaThinkingPrefixMismatchBehavior;

  $client = new Client();

  // Claude Fable 5.1 è il primo modello che verifica il ragionamento rinviato rispetto alla conversazione.
  const MODEL = Model::CLAUDE_FABLE_5_1;
  const BETAS = [AnthropicBeta::COMPACT_2026_09_04, AnthropicBeta::THINKING_BINDING_CONTROLS_2026_08_01];
  const SYSTEM = "You help plan a recipe app's release. Keep answers short.";
  // Con "error", un blocco di ragionamento che non supera il controllo fa fallire la richiesta con un 400.
  $thinking = BetaThinkingConfigAdaptive::with(
      blockBinding: BetaThinkingBlockBinding::with(
          prefixMismatchBehavior: BetaThinkingPrefixMismatchBehavior::ERROR,
      ),
  );

  // 1. Avvia una breve conversazione con il ragionamento attivo.
  $history = [
      BetaMessageParam::with(role: Role::USER, content: "What are the main entities in the app's data model?"),
  ];
  $first = $client->beta->messages->create(
      model: MODEL,
      maxTokens: 8192,
      system: SYSTEM,
      betas: BETAS,
      thinking: $thinking,
      messages: $history,
  );
  $history[] = BetaMessageParam::with(role: Role::ASSISTANT, content: $first->content);
  $history[] = BetaMessageParam::with(
      role: Role::USER,
      content: 'Testing starts on Tuesday, March 3, 2026, takes 10 weekdays, and pauses on March 9 and March 16. On which date does it end?',
  );
  $second = $client->beta->messages->create(
      model: MODEL,
      maxTokens: 8192,
      system: SYSTEM,
      betas: BETAS,
      thinking: $thinking,
      messages: $history,
  );
  $history[] = BetaMessageParam::with(role: Role::ASSISTANT, content: $second->content);
  $thinkingBlocks = count(array_filter($second->content, fn ($block) => $block instanceof BetaThinkingBlock));
  printf("Thinking blocks in the kept turn: %d\n", $thinkingBlocks);

  // 2. Riassumi il primo turno. Il secondo turno resta fuori dalla richiesta.
  $summary = $client->beta->messages->create(
      model: MODEL,
      maxTokens: 4096,
      system: SYSTEM,
      betas: BETAS,
      thinking: $thinking,
      messages: array_slice($history, 0, 2),
      compaction: new BetaCompactionConfig(), // type defaults to 'summarize'
  );
  if ($summary->stopReason !== BetaStopReason::COMPACTION->value) {
      throw new \RuntimeException("No summary: {$summary->stopReason}");
  }

  // 3. Metti il blocco davanti al turno mantenuto e poni la domanda successiva.
  $history = [
      BetaMessageParam::with(role: Role::ASSISTANT, content: $summary->content),
      ...array_slice($history, 2),
      BetaMessageParam::with(role: Role::USER, content: 'Which day should the release go out?'),
  ];
  $third = $client->beta->messages->create(
      model: MODEL,
      maxTokens: 8192,
      system: SYSTEM,
      betas: BETAS,
      thinking: $thinking,
      messages: $history,
  );

  // 4. Un 200 senza blocchi scartati significa che il ragionamento mantenuto è stato accettato.
  printf("Dropped thinking blocks: %d\n", count($third->inputTransformations));
  ```

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

  # Claude Fable 5.1 è il primo modello che verifica il thinking rinviato rispetto alla conversazione.
  MODEL = Anthropic::Model::CLAUDE_FABLE_5_1
  BETAS = [
    Anthropic::AnthropicBeta::COMPACT_2026_09_04,
    Anthropic::AnthropicBeta::THINKING_BINDING_CONTROLS_2026_08_01
  ]
  SYSTEM = "You help plan a recipe app's release. Keep answers short."
  # Con "error", un blocco di thinking che non supera la verifica fa fallire la richiesta con un 400.
  THINKING = Anthropic::Beta::BetaThinkingConfigAdaptive.new(
    block_binding: Anthropic::Beta::BetaThinkingBlockBinding.new(
      prefix_mismatch_behavior: Anthropic::Beta::BetaThinkingPrefixMismatchBehavior::ERROR
    )
  )

  # 1. Avvia una breve conversazione con il thinking attivo.
  history = [{ role: "user", content: "What are the main entities in the app's data model?" }]
  first = client.beta.messages.create(
    model: MODEL,
    max_tokens: 8192,
    system_: SYSTEM,
    betas: BETAS,
    thinking: THINKING,
    messages: history
  )
  history += [
    { role: "assistant", content: first.content },
    {
      role: "user",
      content: "Testing starts on Tuesday, March 3, 2026, takes 10 weekdays, and pauses on March 9 and March 16. On which date does it end?"
    }
  ]
  second = client.beta.messages.create(
    model: MODEL,
    max_tokens: 8192,
    system_: SYSTEM,
    betas: BETAS,
    thinking: THINKING,
    messages: history
  )
  history << { role: "assistant", content: second.content }
  thinking_blocks = second.content.count { it.is_a?(Anthropic::Beta::BetaThinkingBlock) }
  puts "Thinking blocks in the kept turn: #{thinking_blocks}"

  # 2. Riassumi il primo turno. Il secondo turno resta fuori dalla richiesta.
  summary = client.beta.messages.create(
    model: MODEL,
    max_tokens: 4096,
    system_: SYSTEM,
    betas: BETAS,
    thinking: THINKING,
    messages: history.first(2),
    compaction: { type: "summarize" }
  )
  abort "No summary: #{summary.stop_reason}" unless summary.stop_reason == :compaction

  # 3. Metti il blocco davanti al turno mantenuto e poni la domanda successiva.
  history = [
    { role: "assistant", content: summary.content },
    *history.drop(2),
    { role: "user", content: "Which day should the release go out?" }
  ]
  third = client.beta.messages.create(
    model: MODEL,
    max_tokens: 8192,
    system_: SYSTEM,
    betas: BETAS,
    thinking: THINKING,
    messages: history
  )

  # 4. Un 200 senza blocchi scartati indica che il thinking mantenuto ha retto.
  puts "Dropped thinking blocks: #{third.input_transformations.length}"
  ```
</CodeGroup>

```text Output wrap
Thinking blocks in the kept turn: 1
Dropped thinking blocks: 0
```

In produzione, `"drop_block"` fa sì che le richieste abbiano successo quando una condizione non vale, e segnala ogni blocco scartato in `input_transformations` con `reason: "prefix_binding_mismatch"`. Una voce il cui `path` ricade in un turno mantenuto significa che il ragionamento di quel turno non è rimasto valido. [Cosa fa l'API con un blocco non valido](https://platform.claude.com/docs/it/build-with-claude/preserved-thinking#mismatch-behavior) descrive cosa viene scartato e spiega come impostare avvisi al riguardo. Su Claude Sonnet 5.5 e Claude Haiku 5.5, `block_binding` funziona solo con `thinking: {"type": "adaptive"}`. Una richiesta che lo imposta con `thinking: {"type": "between_tools"}` su Claude Sonnet 5.5, o con `thinking: {"type": "disabled"}` su Claude Haiku 5.5, restituisce un errore 400. In quelle richieste, assicurati che ogni condizione valga, oppure rimuovi i blocchi `thinking` e `redacted_thinking` dai turni mantenuti.
