---
title: Pensamento preservado
url: https://platform.claude.com/docs/pt-BR/build-with-claude/preserved-thinking
description: O pensamento preservado permite que um modelo use um bloco de pensamento de um turno anterior somente se esse modelo ou um de um conjunto fixo de outros modelos o tiver produzido e nada antes do bloco tiver mudado.
---

O "preserved thinking" (pensamento preservado) é uma propriedade dos modelos Claude mais recentes que protege contra "distillation" (destilação). Ele determina se o modelo pode usar um "thinking block" (bloco de pensamento) que você envia de volta de um turno anterior. A partir do Claude Fable 5.1, quando um bloco `thinking` ou `redacted_thinking` volta em uma requisição, a API verifica a `signature` do bloco quanto a duas coisas:

* **O modelo consegue ler o bloco.** Cada modelo lê seus próprios blocos de pensamento e os de um conjunto fixo de outros modelos. O Claude Fable 5.1 lê blocos do Claude Opus 5 e, na Claude API, do Claude Opus 5.5; nem o Claude Opus 5 nem o Claude Opus 5.5 leem blocos do Claude Fable 5.1. Se o modelo atual não consegue ler um bloco, a API o descarta dessa requisição sem erro. Consulte [Trocar de modelo no meio da conversa](https://platform.claude.com/docs/pt-BR/build-with-claude/preserved-thinking#switching-models).
* **Nada antes do bloco de pensamento mudou.** O prompt `system` de nível superior, as `tools` e as `messages` antes do bloco formam seu "prefix" (prefixo). Se o prefixo for diferente do que você enviou quando o bloco foi produzido, esse bloco e todos os blocos de pensamento posteriores são inválidos, e a API rejeita a requisição com um erro 400 ou descarta os blocos inválidos, conforme sua escolha. Consulte [Manter o prefixo inalterado](https://platform.claude.com/docs/pt-BR/build-with-claude/preserved-thinking#prefix-check).

Os blocos de pensamento do Claude Sonnet 5.5 e do Claude Haiku 5.5 também estão vinculados à conta que os produziu. Consulte [Os blocos de pensamento permanecem com a conta que os produziu](https://platform.claude.com/docs/pt-BR/build-with-claude/preserved-thinking#account-bound-thinking) para saber onde a API aplica isso.

A verificação de modelo se aplica a todas as contas. A API aplica a verificação de prefixo por padrão para contas criadas em ou após 31 de agosto de 2026, 00:00 UTC. Em contas mais antigas, ela aplica a verificação de prefixo apenas em requisições que definem `thinking.block_binding.prefix_mismatch_behavior`. **Torne sua integração "append-only" (somente de acréscimo), independentemente da idade da sua conta**, para que o mesmo código funcione em todas as contas, incluindo as contas mais novas, em que a verificação é aplicada por padrão.

## Quem precisa mudar alguma coisa

Nada muda para você se o Claude Code, o claude.ai, o Claude Managed Agents ou o Claude Agent SDK constroem suas requisições, ou se seu código mantém `system` e `tools` fixos durante uma sessão e apenas acrescenta itens a `messages`. O Claude Mythos 5.1 e os modelos anteriores ao Claude Fable 5.1 não executam a verificação de prefixo. Se você nunca envia blocos de pensamento de volta, a verificação de prefixo não tem nada a rejeitar, e o modelo não recebe nada do seu raciocínio anterior.

Verifique sua integração se, entre duas requisições em uma conversa, ela fizer qualquer uma das seguintes ações. Cada item leva ao que fazer em vez disso:

* [Reconstrói o prompt `system`](https://platform.claude.com/docs/pt-BR/build-with-claude/preserved-thinking#new-instructions): a data, um sinalizador de modo, instruções de projeto relidas, ou um plugin ou servidor MCP que se conecta após o primeiro turno
* [Renderiza novamente o contexto na primeira mensagem do usuário](https://platform.claude.com/docs/pt-BR/build-with-claude/preserved-thinking#changing-context)
* [Limpa ou encurta resultados de ferramentas antigos, ou recodifica imagens antigas](https://platform.claude.com/docs/pt-BR/build-with-claude/preserved-thinking#server-side-trimming)
* [Resume ou descarta turnos antigos no cliente](https://platform.claude.com/docs/pt-BR/build-with-claude/preserved-thinking#custom-compaction-on-the-client) e mantém os turnos recentes com seu pensamento
* [Adiciona, remove ou edita entradas em `tools`](https://platform.claude.com/docs/pt-BR/build-with-claude/preserved-thinking#tool-changes)
* [Adiciona um lembrete a um turno do usuário](https://platform.claude.com/docs/pt-BR/build-with-claude/preserved-thinking#per-turn-reminders) e o remove ou reescreve depois
* [Descarta alguns blocos `thinking` e mantém os posteriores](https://platform.claude.com/docs/pt-BR/build-with-claude/preserved-thinking#append-assistant-turns-exactly-as-returned), ou os remove e [depois os coloca de volta](https://platform.claude.com/docs/pt-BR/build-with-claude/preserved-thinking#prefix-check)
* [Reconstrói uma sessão salva a partir de templates](https://platform.claude.com/docs/pt-BR/build-with-claude/preserved-thinking#faq) em vez de reproduzir o que enviou

Em uma conta mais antiga, nenhuma dessas ações produz um erro, a menos que a requisição defina `prefix_mismatch_behavior`, então uma execução sem erros com sua própria chave não mostra se seu código é afetado. Se as pessoas executam sua ferramenta com suas próprias chaves de API, aquelas em contas mais novas recebem o erro 400 antes de você. Para ver o que elas veem sem mudar o comportamento das suas requisições, envie o cabeçalho beta `thinking-binding-controls-2026-08-01`. Em uma conta mais antiga, cada resposta então sinaliza os blocos que falham na verificação, e o modelo ainda os lê (consulte [Definir o comportamento de incompatibilidade e ler `input_transformations`](https://platform.claude.com/docs/pt-BR/build-with-claude/preserved-thinking#preserved-thinking-controls)).

Verifique também sua integração se ela enviar blocos de pensamento do Claude Sonnet 5.5 ou do Claude Haiku 5.5 de uma conta em uma requisição feita por uma conta diferente. Consulte [Os blocos de pensamento permanecem com a conta que os produziu](https://platform.claude.com/docs/pt-BR/build-with-claude/preserved-thinking#account-bound-thinking).

## Trocar de modelo no meio da conversa

O Claude Fable 5.1 e o Claude Mythos 5.1 leem blocos de pensamento produzidos um pelo outro e por modelos Claude anteriores. Nenhum outro modelo lê blocos de pensamento do Claude Fable 5.1 ou do Claude Mythos 5.1.

O Claude Opus 5.5 lê blocos de pensamento do Claude Opus 5, de modelos Opus, Sonnet e Haiku anteriores e, na Claude API e no Google Cloud, do Claude Sonnet 5.5 e do Claude Haiku 5.5, mas não de modelos Claude Fable ou Claude Mythos. Na Claude API, o Claude Fable 5.1 e o Claude Mythos 5.1 leem blocos de pensamento do Claude Opus 5.5; nenhum outro modelo o faz. Assim, uma conversa que passa do Claude Opus 5 para o Claude Opus 5.5 mantém seu raciocínio, assim como uma que sobe do Claude Opus 5.5 para o Claude Fable 5.1 ou o Claude Mythos 5.1 na Claude API. Uma que passa do Claude Fable 5.1 ou do Claude Mythos 5.1 para o Claude Opus 5.5, ou do Claude Opus 5.5 para qualquer modelo que não seja esses dois, executa os turnos após a troca sem o raciocínio do modelo anterior. Os blocos são descartados, não rejeitados, conforme descrito mais adiante nesta seção.

O Claude Sonnet 5.5 lê blocos de pensamento do Claude Sonnet 5, do Claude Opus 4.8, do Claude Haiku 4.5 e de modelos anteriores, e, na Claude API e no Google Cloud, do Claude Haiku 5.5, mas não do Claude Opus 5, do Claude Opus 5.5 ou de qualquer modelo Claude Fable ou Claude Mythos. Na Claude API e no Google Cloud, o Claude Opus 5.5 lê blocos de pensamento do Claude Sonnet 5.5; nenhum outro modelo o faz. Assim, uma conversa que passa do Claude Sonnet 5 para o Claude Sonnet 5.5 mantém seu raciocínio, assim como uma que sobe do Claude Sonnet 5.5 para o Claude Opus 5.5 na Claude API e no Google Cloud. Uma que passa para o Claude Sonnet 5.5 a partir do Claude Opus 5, do Claude Opus 5.5 ou de um modelo Claude Fable ou Claude Mythos executa os turnos após a troca sem o raciocínio do modelo anterior. O mesmo acontece com qualquer outra troca que saia do Claude Sonnet 5.5, por exemplo um [fallback do lado do servidor](https://platform.claude.com/docs/pt-BR/build-with-claude/refusals-and-fallback#server-side-fallback) para o Claude Sonnet 5.

O Claude Haiku 5.5 lê blocos de pensamento do Claude Sonnet 5, do Claude Opus 4.8, do Claude Haiku 4.5 e de modelos anteriores, mas não do Claude Opus 5, do Claude Opus 5.5, do Claude Sonnet 5.5 ou de qualquer modelo Claude Fable ou Claude Mythos. Na Claude API e no Google Cloud, o Claude Opus 5.5 e o Claude Sonnet 5.5 leem blocos de pensamento do Claude Haiku 5.5; nenhum outro modelo lê. Assim, uma conversa que passa do Claude Haiku 4.5 para o Claude Haiku 5.5 mantém seu raciocínio, assim como uma que sobe do Claude Haiku 5.5 para o Claude Opus 5.5 ou o Claude Sonnet 5.5 na Claude API e no Google Cloud. Uma que passa para o Claude Haiku 5.5 a partir do Claude Opus 5, do Claude Opus 5.5, do Claude Sonnet 5.5 ou de um modelo Claude Fable ou Claude Mythos executa os turnos após a troca sem o raciocínio do modelo anterior, e o mesmo acontece com qualquer outra troca que saia do Claude Haiku 5.5.

* **Uma conversa que passa para o Claude Fable 5.1 a partir de um modelo anterior, ou do Claude Opus 5.5 na Claude API, mantém seu raciocínio.** Os blocos de pensamento do modelo anterior continuam legíveis, então o modelo pensa normalmente desde o primeiro turno após a troca.
* **Uma conversa que passa do Claude Fable 5.1 para qualquer modelo que não seja o Claude Mythos 5.1 perde o raciocínio do Claude Fable 5.1 nessa requisição.** Isso ocorre quando um roteador envia um turno para um modelo mais barato, após um [fallback por recusa do classificador](https://platform.claude.com/docs/pt-BR/build-with-claude/refusals-and-fallback) ou durante um [fallback do lado do servidor](https://platform.claude.com/docs/pt-BR/build-with-claude/refusals-and-fallback#server-side-fallback). A API remove os blocos ilegíveis antes que o prompt chegue ao modelo. Eles não são cobrados e não contam para `input_tokens`.

Continue enviando o histórico completo em cada requisição, incluindo os blocos de pensamento, e deixe a API descartar o que o modelo atual não consegue ler. A API nunca edita seu array `messages`, então os blocos descartados permanecem no seu histórico. Quando o mesmo histórico volta para o Claude Fable 5.1, seus blocos ficam legíveis novamente, junto com o pensamento do modelo anterior. O raciocínio só é perdido definitivamente se o seu cliente remover os blocos por conta própria, por exemplo um harness que remove o pensamento em uma troca de modelo ou reconstrói o histórico a partir do que cada modelo usou.

<Frame>
  ![Animação: trocar para o Claude Opus ignora o pensamento do Claude Fable 5.1 naquele turno; ao voltar, tudo é lido novamente](https://platform.claude.com/docs/images/preserved-thinking-model-switch.svg)
</Frame>

Com o [cabeçalho beta](https://platform.claude.com/docs/pt-BR/api/beta-headers) `thinking-binding-controls-2026-08-01`, a resposta lista cada bloco descartado em um array `input_transformations` de nível superior com `reason: "model_binding_mismatch"`:

```json
{
  "input_transformations": [
    {
      "type": "thinking_dropped",
      "path": "messages.3.content.0",
      "reason": "model_binding_mismatch"
    }
  ]
}
```

Sem o cabeçalho, o descarte é silencioso. Essa entrada não é um bug na sua integração, e `prefix_mismatch_behavior` não tem efeito sobre ela: um bloco que o modelo atual não consegue ler é sempre descartado.

## Os blocos de pensamento permanecem com a conta que os produziu

Os blocos de pensamento que o Claude Sonnet 5.5 ou o Claude Haiku 5.5 produz funcionam apenas na conta que os produziu, ou em uma conta vinculada a ela. Quando outra conta envia um desses blocos, a API descarta o bloco antes que o modelo o veja, e a requisição é bem-sucedida. O modelo responde sem o raciocínio dos blocos descartados. Blocos de modelos anteriores não são afetados.

Na Claude API e no Google Cloud, com o [cabeçalho beta](https://platform.claude.com/docs/pt-BR/api/beta-headers) `thinking-binding-controls-2026-08-01`, a resposta lista cada bloco descartado em `input_transformations` como uma entrada `thinking_dropped` com `reason: "organization_binding_mismatch"`. Sem o cabeçalho, o descarte é silencioso.

## Manter o prefixo inalterado

No Claude Fable 5.1, no Claude Opus 5.5, no Claude Sonnet 5.5 e no Claude Haiku 5.5, um bloco de pensamento permanece válido apenas enquanto tudo o que você enviou antes dele permanecer inalterado nas requisições posteriores. O prefixo verificado tem três partes:

* O prompt `system` de nível superior
* O conjunto de `tools`
* Cada `message` antes do bloco

Observação: com a [compactação](https://platform.claude.com/docs/pt-BR/build-with-claude/compaction) do lado do servidor, o prefixo verificado começa no bloco de compactação mais recente.

Parâmetros da requisição fora desses três campos, como `effort`, `max_tokens`, `output_config`, `tool_choice` e `metadata`, não fazem parte da verificação de prefixo, e os marcadores `cache_control` também não. [O que conta como edição](https://platform.claude.com/docs/pt-BR/build-with-claude/preserved-thinking#what-counts-as-an-edit) tem a lista completa.

Blocos de pensamento anteriores não estão no prefixo, mas cada bloco de pensamento registra qual bloco de pensamento veio antes dele, entre turnos. Você pode remover blocos de pensamento do início do histórico (os mais antigos primeiro), do final, ou todos eles. O que falha é uma lacuna: os blocos de pensamento que você mantém devem ser uma sequência ininterrupta da sequência original, então remover um do meio invalida os blocos de pensamento posteriores a ele. Depois de remover um bloco, deixe-o de fora. Colocá-lo de volta invalida os blocos de pensamento produzidos enquanto ele estava ausente.

Mantenha `system` e `tools` fixos durante a sessão e trate `messages` como somente de acréscimo. A mesma disciplina mantém o prefixo estável para o [cache de prompt](https://platform.claude.com/docs/pt-BR/build-with-claude/prompt-caching): as edições que invalidam o pensamento são as edições que reiniciam o cache.

### O que a API faz com um bloco inválido

Você escolhe com `thinking.block_binding.prefix_mismatch_behavior`:

* **`"error"` (o padrão):** a API rejeita a requisição com um 400 `invalid_request_error` que nomeia o primeiro bloco com falha.
* **`"drop_block"`:** a API descarta cada bloco com falha e todos os blocos de pensamento posteriores a ele, e a requisição é bem-sucedida. Blocos descartados não são cobrados. O modelo responde a esse turno sem usar o raciocínio dos blocos descartados, e o cache de prompt reinicia no ponto da edição. A resposta lista cada bloco descartado em `input_transformations` (no evento `message_start` ao usar streaming) com `reason: "prefix_binding_mismatch"`.

<Warning>
  `"drop_block"` mantém as requisições bem-sucedidas, mas não corrige a edição que causou a incompatibilidade, e tem um custo. Descartar blocos pode aumentar significativamente os tokens de saída gerados, especialmente em níveis de esforço mais altos ou quando blocos são descartados em todos os turnos. Para mais informações, consulte [Custo em tokens de saída de `"drop_block"`](https://platform.claude.com/docs/pt-BR/build-with-claude/preserved-thinking#drop-block-cost). Os blocos descartados não são cobrados, mas o Claude recria o raciocínio que não consegue mais ler, então gera mais tokens de saída. A qualidade da saída também pode mudar em tarefas em que turnos posteriores se baseiam em raciocínio anterior. Use `"drop_block"` como solução temporária enquanto corrige a edição, mas não como configuração de longo prazo.
</Warning>

Conte, em cada sessão, as respostas cujo `input_transformations` contém uma entrada `prefix_binding_mismatch`, configure alertas para elas e substitua cada edição pelo padrão correspondente em [Fazer mudanças sem editar o prefixo](https://platform.claude.com/docs/pt-BR/build-with-claude/preserved-thinking#replace-prefix-edits). Na Message Batches API, um item que não define o campo não falha. Onde a API aplica a verificação por padrão, ela descarta os blocos com falha em vez disso. Defina `"error"` explicitamente nesse caso se quiser que os itens do lote falhem.

Tanto o campo quanto o array `input_transformations` exigem o [cabeçalho beta](https://platform.claude.com/docs/pt-BR/api/beta-headers) `thinking-binding-controls-2026-08-01`. [Definir o comportamento de incompatibilidade e ler `input_transformations`](https://platform.claude.com/docs/pt-BR/build-with-claude/preserved-thinking#preserved-thinking-controls) mostra a requisição em cada SDK.

A mensagem do 400 começa assim:

```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 a requisição não enviou o cabeçalho beta, a mensagem continua:

```text wrap
That setting requires the `thinking-binding-controls-2026-08-01` value in the `anthropic-beta` header.
```

Ela geralmente termina com uma frase que nomeia o que mudou, por exemplo, que o prompt `system` ou a lista `tools` difere de quando o bloco foi criado. [Solução de problemas de pensamento](https://platform.claude.com/docs/pt-BR/build-with-claude/thinking-troubleshooting#error-thinking-block-signature) descreve o que essa frase pode nomear.

Uma assinatura adulterada ou impossível de descriptografar é uma falha diferente. Ela sempre retorna um 400 (``Invalid `signature` in `thinking` block`` sem nenhuma frase sobre a conversa), e `prefix_mismatch_behavior` não se aplica a ela.

#### Custo em tokens de saída de `"drop_block"`

Nos testes da Anthropic em um benchmark de programação com múltiplos turnos, descartar blocos de pensamento uma vez por sessão aumentou os tokens de saída em 2,5% com esforço baixo, 3,9% com médio, 4,5% com alto e 20,1% com máximo. Descartá-los em todos os turnos após o primeiro aumentou os tokens de saída em 4,6% com esforço baixo, 9,7% com médio, 10,3% com alto e 67,1% com máximo. Esses números são estimativas com amplas margens de erro, e o impacto na sua carga de trabalho depende do seu harness.

Quando o Claude não consegue mais ler o raciocínio de turnos anteriores, ele recria esse raciocínio, então requisições que descartam blocos de pensamento geram mais tokens de saída e podem demorar mais para responder. Um descarte em todos os turnos custa mais do que um descarte ocasional, e o quanto a mais depende do seu harness: com que frequência ele edita o prefixo e quanto cada turno se baseia em raciocínio anterior.

Antes de depender de `"drop_block"`, execute avaliações na sua própria carga de trabalho para medir o aumento. Se for pequeno, `"drop_block"` pode manter as requisições bem-sucedidas enquanto você corrige a edição. De qualquer forma, corrigir a edição com um padrão de [Fazer mudanças sem editar o prefixo](https://platform.claude.com/docs/pt-BR/build-with-claude/preserved-thinking#replace-prefix-edits) é uma solução melhor a longo prazo.

#### Tratar o erro no código

Este é o 400 `invalid_request_error` mostrado anteriormente nesta seção. Não reenvie o mesmo corpo: ele falha da mesma forma todas as vezes. Tente novamente uma vez com o cabeçalho beta e `prefix_mismatch_behavior: "drop_block"`, como solução temporária ([`"drop_block"` pode aumentar os tokens de saída](https://platform.claude.com/docs/pt-BR/build-with-claude/preserved-thinking#drop-block-cost)), e armazene essa escolha com a sessão para que todas as requisições posteriores também a enviem, inclusive após uma reinicialização. No Claude Sonnet 5.5 e no Claude Haiku 5.5, `block_binding` funciona apenas com `thinking: {"type": "adaptive"}`. Com `between_tools` no Claude Sonnet 5.5, ou `thinking: {"type": "disabled"}` no Claude Haiku 5.5, mantenha o histórico somente de acréscimo, ou remova os blocos de pensamento a partir do turno editado. Se você não puder enviar o cabeçalho beta, remova todos os blocos `thinking` e `redacted_thinking` do histórico uma vez, deixe-os de fora e continue. Depois, corrija a edição que causou a incompatibilidade.

### Definir o comportamento de incompatibilidade e ler `input_transformations`

O [cabeçalho beta](https://platform.claude.com/docs/pt-BR/api/beta-headers) `thinking-binding-controls-2026-08-01` adiciona:

* Um array `input_transformations` de nível superior em cada resposta
* Um objeto `block_binding` na configuração `thinking`, cujo único campo é `prefix_mismatch_behavior`

`block_binding` é aceito junto com `thinking.type: "adaptive"` e `thinking.type: "enabled"`. No Claude Sonnet 5.5 e no Claude Haiku 5.5, `block_binding` funciona apenas com `thinking: {"type": "adaptive"}`. Enviá-lo com `between_tools` no Claude Sonnet 5.5, ou com `thinking: {"type": "disabled"}` no Claude Haiku 5.5, retorna um erro 400. Enviá-lo sem o cabeçalho beta retorna um erro 400 cuja mensagem termina com `block_binding: Extra inputs are not permitted`. Modelos que não executam a verificação de prefixo aceitam o objeto e relatam apenas descartes da verificação de modelo, então um único corpo de requisição funciona entre modelos. A referência da API chama a verificação de prefixo de verificação de conversa.

A requisição a seguir opta por descartar em vez de rejeitar. Em um primeiro turno não há nada para reproduzir, então `input_transformations` volta vazio:

<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
```

Com o cabeçalho beta, toda resposta de um modelo com capacidade de pensamento traz `input_transformations`. Cada entrada nomeia um bloco de pensamento pelo seu `path` (por exemplo `messages.1.content.0`) e fornece um `reason`. Há dois tipos de entrada:

* **`thinking_dropped`:** a API descarta o bloco antes que o modelo o leia, e o bloco não é cobrado. O `reason` é `prefix_binding_mismatch` ou `model_binding_mismatch` (consulte [Trocar de modelo no meio da conversa](https://platform.claude.com/docs/pt-BR/build-with-claude/preserved-thinking#switching-models)). O `reason` também pode ser `organization_binding_mismatch`, o que significa que o bloco veio de outra conta (consulte [Os blocos de pensamento permanecem com a conta que os produziu](https://platform.claude.com/docs/pt-BR/build-with-claude/preserved-thinking#account-bound-thinking)).
* **`thinking_mismatch_allowed`:** o bloco falha na verificação de prefixo, mas a API não aplica essa verificação para esta requisição, então o bloco chega ao modelo inalterado e é cobrado. O `reason` é sempre `prefix_binding_mismatch`. Essa entrada aparece apenas em requisições em que a API não aplica a verificação por padrão, como as de uma conta mais antiga (consulte [Quando a API aplica a verificação](https://platform.claude.com/docs/pt-BR/build-with-claude/preserved-thinking#enforcement)). Definir `prefix_mismatch_behavior` com qualquer um dos valores ativa a aplicação da verificação na requisição, então uma requisição que o define nunca recebe essa entrada.

O array fica vazio quando nenhum bloco foi descartado e nenhum falhou na verificação de prefixo. Ignore entradas cujo `type` ou `reason` você não reconheça, porque verificações futuras adicionam valores.

Ao usar [streaming](https://platform.claude.com/docs/pt-BR/build-with-claude/streaming), o array chega no objeto `message` no evento `message_start`. Após um fallback do lado do servidor no meio do stream, o evento `message_delta` final o traz novamente com as entradas do modelo que está atendendo. Em um [lote de mensagens](https://platform.claude.com/docs/pt-BR/build-with-claude/batch-processing), um item cujo bloco falha na verificação de prefixo com um `"error"` explícito é resolvido como `errored`. Um item que deixa o campo sem definir não falha. Onde a API aplica a verificação por padrão, ela descarta os blocos com falha em vez disso. O endpoint de [contagem de tokens](https://platform.claude.com/docs/pt-BR/build-with-claude/token-counting) executa a mesma verificação de prefixo e retorna o mesmo 400.

### Quando a API aplica a verificação

A API aplica a verificação de prefixo no Claude Fable 5.1, no Claude Opus 5.5, no Claude Sonnet 5.5 e no Claude Haiku 5.5 para contas novas.

* **Contas criadas em ou após 31 de agosto de 2026, 00:00 UTC:** a API verifica as requisições ao Claude Fable 5.1, ao Claude Opus 5.5, ao Claude Sonnet 5.5 e ao Claude Haiku 5.5 e aplica `"error"`, a menos que você defina `"drop_block"`. A mesma definição de conta nova se aplica à Claude API e às plataformas de nuvem.
* **Contas mais antigas:** a API aplica a verificação apenas em requisições que definem `prefix_mismatch_behavior`. Definir o campo ativa a verificação na requisição, então você pode ver o que uma conta nova vê sem criar uma. Em requisições que o deixam sem definir, a API ainda executa a verificação, mas deixa os blocos com falha passarem para o modelo. Com o cabeçalho beta, a resposta lista cada um deles em `input_transformations` como `thinking_mismatch_allowed`, para que você possa encontrar edições de prefixo sem mudar o que o modelo recebe.

Para descobrir em qual grupo sua conta está, pegue uma conversa do Claude Fable 5.1 que contenha um bloco de pensamento, altere algo antes desse bloco e envie-a ao Claude Fable 5.1 sem o cabeçalho beta ou o campo `block_binding`. Uma resposta 400 que nomeia o cabeçalho significa que a verificação é aplicada por padrão na sua conta. Uma resposta 200 significa que não é. Para confirmar, envie a mesma requisição novamente com o cabeçalho beta, ainda sem `block_binding`: a resposta lista todos os blocos de pensamento após sua edição em `input_transformations` como `thinking_mismatch_allowed`.

### O que conta como edição

Cada linha compara duas requisições consecutivas:

| Alteração entre requisições                                                                                                                                                                 | Blocos de pensamento posteriores                                                                                                                                                                                                                                                                                                                                          |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Acrescentar mensagens no final                                                                                                                                                              | Válidos                                                                                                                                                                                                                                                                                                                                                                   |
| Adicionar uma ferramenta com `defer_loading: true` que nada referenciou ainda                                                                                                               | Válidos                                                                                                                                                                                                                                                                                                                                                                   |
| Remover blocos `thinking` do início do histórico, do final, ou todos eles                                                                                                                   | Válidos (o modelo perde esse raciocínio)                                                                                                                                                                                                                                                                                                                                  |
| Alterar qualquer parâmetro de requisição fora de `system`, `tools` e `messages` (`effort`, `max_tokens`, `output_config`, `tool_choice`, `metadata`, `thinking.display` e assim por diante) | Válidos                                                                                                                                                                                                                                                                                                                                                                   |
| Adicionar, mover ou remover marcadores `cache_control`                                                                                                                                      | Válidos                                                                                                                                                                                                                                                                                                                                                                   |
| Uma URL assinada rotativa que retorna os mesmos bytes                                                                                                                                       | Válidos                                                                                                                                                                                                                                                                                                                                                                   |
| A compactação ou a edição de contexto no lado do servidor remove ou substitui conteúdo                                                                                                      | Válidos (a verificação compara o que você enviou, não a cópia editada pelo servidor)                                                                                                                                                                                                                                                                                      |
| Uma [mensagem do sistema com escopo de turno](https://platform.claude.com/docs/pt-BR/build-with-claude/preserved-thinking#per-turn-reminders) já limpa, mantida no lugar                    | Válidos                                                                                                                                                                                                                                                                                                                                                                   |
| Editar, reordenar ou excluir qualquer mensagem `user`, `assistant` ou `system` anterior                                                                                                     | Inválidos, exceto quando o bloco assinado da [compactação sob demanda](https://platform.claude.com/docs/pt-BR/build-with-claude/compaction-on-demand) substitui as mensagens que ele resume, sob as [condições para o pensamento mantido](https://platform.claude.com/docs/pt-BR/build-with-claude/compaction-thinking-blocks#conditions-for-kept-thinking-to-stay-valid) |
| Renderizar novamente, com um valor alterado, o contexto que você colocou na primeira mensagem do usuário                                                                                    | Inválidos para todos os blocos de pensamento                                                                                                                                                                                                                                                                                                                              |
| Limpar ou encurtar um `tool_result` anterior, recodificar uma imagem anterior ou alterar a entrada de um `tool_use` anterior                                                                | Inválidos para todos os blocos de pensamento posteriores                                                                                                                                                                                                                                                                                                                  |
| Adicionar um bloco de texto a um turno do usuário anterior, ou remover um que você adicionou da última vez                                                                                  | Inválidos                                                                                                                                                                                                                                                                                                                                                                 |
| Alterar a string ou os blocos do `system` de nível superior                                                                                                                                 | Inválidos                                                                                                                                                                                                                                                                                                                                                                 |
| Adicionar, remover, renomear ou editar uma ferramenta em `tools`                                                                                                                            | Inválidos                                                                                                                                                                                                                                                                                                                                                                 |
| Remover um bloco `thinking` do meio do histórico e manter os posteriores                                                                                                                    | Inválidos para todos os blocos de pensamento posteriores                                                                                                                                                                                                                                                                                                                  |
| Colocar de volta um bloco `thinking` que você removeu em uma requisição anterior                                                                                                            | Inválidos para os blocos de pensamento produzidos enquanto ele estava ausente                                                                                                                                                                                                                                                                                             |
| Uma URL de imagem ou documento que retorna bytes diferentes na requisição seguinte                                                                                                          | Inválidos                                                                                                                                                                                                                                                                                                                                                                 |
| A mesma mensagem com escopo de turno excluída ou reescrita em uma requisição posterior                                                                                                      | Inválidos                                                                                                                                                                                                                                                                                                                                                                 |

### Verificar se seu código edita o prefixo

<Tip>
  **Automatize esta verificação com a skill Claude API.** Na versão mais recente do [Claude Code](https://code.claude.com/docs/en/overview), abra o repositório que constrói suas requisições e execute a [skill Claude API](https://platform.claude.com/docs/pt-BR/agents-and-tools/agent-skills/claude-api-skill#checking-an-integration-for-preserved-thinking) incluída:

  Deixe o Claude Code verificar seu código para você

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

  A skill captura algumas das suas próprias sessões de vários turnos e compara requisições consecutivas para encontrar onde seu código edita o prefixo. Em seguida, ela reproduz as sessões com `"drop_block"` e conta os blocos de pensamento que a API descarta. Depois disso, ela corrige uma causa de cada vez e mede novamente após cada correção.
</Tip>

Primeiro, compare o que você envia. Capture os corpos das requisições que sua integração envia ao longo de alguns turnos normais, incluindo uma compactação ou uma alteração de ferramenta. Para cada par de requisições consecutivas, compare `system`, `tools` e as `messages` que elas compartilham. Elas devem ser idênticas até os turnos recém-acrescentados.

Depois, confirme com a API. Adicione o cabeçalho beta `thinking-binding-controls-2026-08-01`, defina `prefix_mismatch_behavior` como `"drop_block"` e execute uma sessão normal de vários turnos pela sua integração no claude-fable-5-1. O exemplo a seguir executa dois turnos da forma como sua integração deveria: `messages` apenas cresce, cada turno do assistente volta exatamente como a API o retornou, incluindo os blocos `thinking`, e `block_binding` é definido em cada requisição. Após cada turno, ele imprime o número de blocos `thinking` na resposta e o número de blocos descartados:

<CodeGroup>
  ```bash cURL
  # Conta os blocos de pensamento em uma resposta e os blocos que a API descartou
  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: o turno do assistente é reenviado exatamente como retornado, seguido da próxima mensagem do usuário
  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 os blocos de pensamento em uma resposta e os blocos que a API descartou
  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: o turno do assistente é reenviado exatamente como retornado, seguido da próxima mensagem do usuário
  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 cada turno: cada turno do assistente é reenviado exatamente como retornado
  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 cada turno: cada turno do assistente é reenviado exatamente como retornado
  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 cada turno: cada turno do assistente é reenviado exatamente como foi retornado
  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 cada turno: cada turno do assistente é reenviado exatamente como retornado
  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?");

      // A lista de mensagens do builder cresce a cada turno: cada turno do assistente é reenviado exatamente como retornado
      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 cada turno: cada turno do assistente é reenviado exatamente como foi retornado
  $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 cada turno: cada turno do assistente é reenviado exatamente como retornado
  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
```

Nenhum dos turnos descarta um bloco, porque nada anterior mudou. Verifique se a primeira resposta contém um bloco `thinking`. Com o pensamento adaptativo, algumas respostas não têm nenhum. Se nenhuma resposta na sessão tiver um, não há nada para verificar e a contagem de descartados é 0 independentemente do que você alterar, então execute o exemplo novamente.

Registre `input_transformations` em cada turno da sua própria integração. Quando a API descarta um bloco, a entrada se parece com o seguinte:

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

* **Vazio em todos os turnos de uma sessão que contém blocos `thinking`:** sua integração mantém o prefixo intacto.
* **`reason: "prefix_binding_mismatch"`:** algo antes do bloco em `path` mudou desde a requisição anterior. Compare `system`, `tools` e `messages` até esse turno para encontrá-lo, ou reenvie a requisição com `"error"`: o 400 geralmente termina com uma frase que nomeia o que mudou. Depois, encontre a substituição correspondente em [Fazer mudanças sem editar o prefixo](https://platform.claude.com/docs/pt-BR/build-with-claude/preserved-thinking#replace-prefix-edits).
* **`reason: "model_binding_mismatch"`:** a conversa passou para um modelo que não consegue ler os blocos do modelo anterior. Isso não é uma edição de prefixo. Consulte [Trocar de modelo no meio da conversa](https://platform.claude.com/docs/pt-BR/build-with-claude/preserved-thinking#switching-models).
* **`reason: "organization_binding_mismatch"`:** o bloco veio de outra conta. Consulte [Os blocos de pensamento permanecem com a conta que os produziu](https://platform.claude.com/docs/pt-BR/build-with-claude/preserved-thinking#account-bound-thinking).

Para ver uma falha de propósito, envie um terceiro turno a partir do exemplo anterior e adicione um prompt `system` apenas a essa requisição, de modo que ela seja diferente das duas primeiras requisições, que não tinham nenhum. Com `"drop_block"`, a contagem de descartados deixa de ser 0: a resposta tem uma entrada para cada bloco de pensamento no histórico, cada uma com `reason: "prefix_binding_mismatch"`. Com `"error"`, a requisição retorna o 400 descrito em [O que a API faz com um bloco inválido](https://platform.claude.com/docs/pt-BR/build-with-claude/preserved-thinking#mismatch-behavior), e sua última frase nomeia o prompt `system`. Nas abas cURL e CLI, remova o filtro `jq` para ver o corpo do erro. Se a contagem ainda for 0, não havia nada para verificar: confirme que o modelo é o claude-fable-5-1, que a requisição define `block_binding`, que o histórico que você enviou contém blocos `thinking` e que as duas primeiras requisições não tinham prompt `system`.

Dois turnos simples raramente mostram o problema. Execute uma sessão passando por cada um dos seguintes casos, com `"error"` definido para que uma regressão faça seu CI falhar:

* A primeira compactação ou corte do lado do cliente
* Uma ferramenta, plugin ou servidor MCP que se conecta após o primeiro turno
* Uma mudança de modo ou de instrução
* Um loop de ferramentas longo, se você adiciona lembretes ou encurta resultados de ferramentas antigos
* Uma troca para outro modelo e de volta
* Um salvamento, uma reinicialização e uma retomada em uma data posterior

Em uma conta mais antiga, você também pode observar o tráfego de produção sem optar pela aplicação da verificação: envie o cabeçalho beta, deixe `block_binding` de fora e registre `input_transformations`. Enviar apenas o cabeçalho não muda o que o modelo recebe. Cada bloco de pensamento que vem depois do conteúdo que você editou falha na verificação e recebe sua própria entrada `thinking_mismatch_allowed`, com os mesmos campos `path` e `reason` de uma entrada `thinking_dropped`. Os blocos antes da edição ainda passam. Uma edição em `system` ou `tools` vem antes de todos os blocos, então faz todos os blocos de pensamento da requisição falharem. Uma entrada se parece com isto:

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

Execute o exemplo a seguir a partir de uma [conta mais antiga](https://platform.claude.com/docs/pt-BR/build-with-claude/preserved-thinking#enforcement), porque uma conta mais nova rejeita sua terceira requisição com o 400. Ele envia o cabeçalho sem `block_binding` e estende a sessão anterior com uma terceira requisição que adiciona um prompt do sistema, o que altera o prefixo de propósito. Após cada turno, ele imprime o número de blocos `thinking` e de blocos sinalizados:

<CodeGroup>
  ```bash cURL
  # Conta os blocos de pensamento em uma resposta e os blocos que falharam na verificação de prefixo
  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: o turno do assistente é reenviado exatamente como retornado, seguido da próxima mensagem do usuário
  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: só esta requisição adiciona um prompt do sistema, o que altera o prefixo de propósito
  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 os blocos de pensamento em uma resposta e os blocos que falharam na verificação de prefixo
  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: o turno do assistente é reenviado exatamente como retornado, seguido da próxima mensagem do usuário
  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: só esta requisição adiciona um prompt do sistema, o que altera o prefixo de propósito
  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 cada turno: cada turno do assistente é reenviado exatamente como foi retornado
  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"},
          # Só a última requisição adiciona um prompt do sistema, o que altera o prefixo de propósito
          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 cada turno: cada turno do assistente é reenviado exatamente como foi retornado
  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" },
      // Só a última requisição adiciona um prompt do sistema, o que altera o prefixo de propósito
      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 cada turno: cada turno do assistente é reenviado exatamente como foi retornado
  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(),
              // Só a última requisição adiciona um prompt do sistema, o que altera o prefixo de propósito
              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 cada turno: cada turno do assistente é reenviado exatamente como foi retornado
  messages := []anthropic.BetaMessageParam{}
  for i, userTurn := range userTurns {
  	messages = append(messages, anthropic.NewBetaUserMessage(anthropic.NewBetaTextBlock(userTurn)))
  	// Só a última requisição adiciona um prompt do sistema, o que altera o prefixo de propósito
  	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?");

      // A lista de mensagens do builder cresce a cada turno: cada turno do assistente é reenviado exatamente como foi retornado
      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) {
              // Apenas a última requisição adiciona um prompt do sistema, o que altera o prefixo de propósito
              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 cada turno: cada turno do assistente é reenviado exatamente como foi retornado
  $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(),
          // Só a última requisição adiciona um prompt do sistema, o que altera o prefixo de propósito
          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 cada turno: cada turno do assistente é reenviado exatamente como foi retornado
  messages = []
  user_turns.each_with_index do |user_turn, turn_index|
    messages << {role: "user", content: user_turn}
    # Só a última requisição adiciona um prompt do sistema, o que altera o prefixo de propósito
    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
```

A terceira resposta sinaliza todos os blocos de pensamento dos turnos anteriores, um por turno nesta execução, porque o novo prompt do sistema vem antes de todos eles. O modelo ainda os leu.

Trate essas entradas como você trataria descartes `prefix_binding_mismatch`. A edição está antes do primeiro bloco listado: compare `system`, `tools` e `messages` até o `path` desse bloco com a requisição anterior para encontrá-la e, em seguida, substitua-a pelo padrão correspondente em [Fazer mudanças sem editar o prefixo](https://platform.claude.com/docs/pt-BR/build-with-claude/preserved-thinking#replace-prefix-edits). Em uma conta nova, ou em qualquer requisição que defina `prefix_mismatch_behavior`, a API em vez disso rejeita a requisição ou descarta os blocos com falha. As entradas são um limite inferior do que a aplicação da verificação removeria: com `"drop_block"`, um bloco com falha também leva consigo o restante dos blocos de pensamento daquele turno, e remover um bloco pode fazer o próximo falhar também. Quando a API apenas registra a verificação, ela julga cada bloco isoladamente e lista um bloco somente se esse bloco falhar.

## Fazer mudanças sem editar o prefixo

Cada edição de prefixo comum tem uma substituição que fornece ao modelo as mesmas informações e deixa os bytes anteriores inalterados, para que o pensamento posterior permaneça válido. Encontre na primeira coluna a edição que seu código faz hoje:

| Em vez de                                                                                                                              | Use                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              | Cabeçalho beta                                                                                                                                                                                                                                                     |
| -------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Reconstruir o prompt `system` de nível superior                                                                                        | Uma [mensagem do sistema no meio da conversa](https://platform.claude.com/docs/pt-BR/build-with-claude/preserved-thinking#new-instructions)                                                                                                                                                                                                                                                                                                                                                                      | Nenhum                                                                                                                                                                                                                                                             |
| Renderizar novamente o contexto na sua primeira mensagem do usuário (ambiente, data, memória, instruções do projeto) a cada requisição | Renderize-o uma vez e reenvie-o inalterado. Quando algo mudar, [coloque a nova versão no turno mais recente](https://platform.claude.com/docs/pt-BR/build-with-claude/preserved-thinking#changing-context)                                                                                                                                                                                                                                                                                                       | Nenhum                                                                                                                                                                                                                                                             |
| Limpar ou encurtar conteúdo `tool_result` antigo, ou recodificar imagens antigas, no lugar                                             | Encurte um resultado de ferramenta ou reduza uma imagem antes da primeira vez que você a enviar, não depois. Para limpar resultados antigos mais tarde, [corte o contexto no servidor](https://platform.claude.com/docs/pt-BR/build-with-claude/preserved-thinking#server-side-trimming) com `clear_tool_uses_20250919`                                                                                                                                                                                          | `context-management-2025-06-27`                                                                                                                                                                                                                                    |
| Injetar um lembrete e excluí-lo na próxima requisição                                                                                  | Uma [mensagem do sistema com escopo de turno](https://platform.claude.com/docs/pt-BR/build-with-claude/preserved-thinking#per-turn-reminders) (`clear_at: "next_user_message"`)                                                                                                                                                                                                                                                                                                                                  | `mid-conversation-system-clear-at-2026-08-21`                                                                                                                                                                                                                      |
| Adicionar ou remover entradas em `tools`                                                                                               | [Blocos `tool_addition` e `tool_removal`](https://platform.claude.com/docs/pt-BR/build-with-claude/preserved-thinking#tool-changes)                                                                                                                                                                                                                                                                                                                                                                              | `inline-tools-2026-09-15` (adicione `mcp-client-2026-09-15` quando a ferramenta vier de um servidor MCP conectado pelo conector MCP), ou o mais antigo `mid-conversation-tool-changes-2026-07-01`, que funciona na Claude API, no Amazon Bedrock e no Google Cloud |
| Alterar `output_config.effort` de nível superior (reinicia o cache, não afeta o pensamento)                                            | Um [`output_config` por mensagem](https://platform.claude.com/docs/pt-BR/build-with-claude/preserved-thinking#effort-changes)                                                                                                                                                                                                                                                                                                                                                                                    | `mid-conversation-output-config-2026-07-01`                                                                                                                                                                                                                        |
| Descartar ou resumir turnos antigos no cliente                                                                                         | [Compactação sob demanda](https://platform.claude.com/docs/pt-BR/build-with-claude/compaction-on-demand) para manter os turnos recentes com seu pensamento, outra [compactação ou edição de contexto](https://platform.claude.com/docs/pt-BR/build-with-claude/preserved-thinking#server-side-trimming) do lado do servidor, ou [compactação do lado do cliente](https://platform.claude.com/docs/pt-BR/build-with-claude/preserved-thinking#custom-compaction-on-the-client) que não mantém pensamento obsoleto | `compact-2026-09-04`                                                                                                                                                                                                                                               |
| Uma URL de imagem ou documento cujos bytes mudam entre requisições                                                                     | Um [`file_id` da Files API](https://platform.claude.com/docs/pt-BR/build-with-claude/preserved-thinking#files-by-id), ou base64                                                                                                                                                                                                                                                                                                                                                                                  | Nenhum                                                                                                                                                                                                                                                             |

Tudo isso pressupõe que você [envie os turnos do assistente de volta exatamente como retornados](https://platform.claude.com/docs/pt-BR/build-with-claude/preserved-thinking#append-assistant-turns-exactly-as-returned). Mensagens do sistema no meio da conversa, mensagens do sistema com escopo de turno e alterações de ferramentas não estão disponíveis em todos os modelos: [Mensagens de sistema e alterações de ferramentas no meio da conversa](https://platform.claude.com/docs/pt-BR/build-with-claude/mid-conversation-system-messages) lista os modelos que as aceitam. Se seu código atende vários modelos, continue editando o prompt `system` de nível superior para os modelos que não as aceitam.

Para usar vários betas em uma requisição na Claude API, combine seus nomes em um único cabeçalho `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
```

Outras plataformas que oferecem esses betas usam os mesmos nomes. Para enviá-los lá, consulte [Recursos beta em outras plataformas](https://platform.claude.com/docs/pt-BR/api/beta-headers#beta-features-on-other-platforms).

### Enviar os turnos do assistente de volta exatamente como retornados

Armazene o array `content` de cada resposta e envie-o de volta inalterado como o turno do assistente: todos os tipos de bloco, na ordem recebida, incluindo blocos `thinking` cujo campo `thinking` esteja vazio. Um serializador que descarta tipos de bloco desconhecidos, descarta campos vazios ou reordena blocos edita o prefixo para todos os turnos posteriores.

No Claude Fable 5.1, no Claude Opus 5.5, no Claude Sonnet 5.5 e no Claude Haiku 5.5, o campo `thinking` fica vazio por padrão e a `signature` carrega o raciocínio, então um serializador que ignora blocos vazios remove o pensamento. Se ele remover todos, nada falha e o modelo perde seu raciocínio anterior em todos os turnos. Se você mesmo analisa o stream, mantenha o bloco mesmo quando nenhum texto de pensamento chegar: ele abre, recebe sua `signature` em um evento `signature_delta` e fecha. Um bloco enviado de volta com uma `signature` vazia falha.

### Adicionar instruções com uma mensagem do sistema no meio da conversa

Alguns harnesses reconstroem o prompt do sistema de nível superior (`system`) a cada requisição para incluir a hora atual, um orçamento de tokens, uma flag de modo ou contexto de projeto recém-descoberto. Isso invalida todos os blocos de pensamento da conversa. Em vez disso, congele `system` no início da sessão. Quando algo mudar, acrescente uma [mensagem `role: "system"`](https://platform.claude.com/docs/pt-BR/build-with-claude/mid-conversation-system-messages) no ponto de `messages` em que a mudança passa a valer:

```json
{
  "role": "system",
  "content": "The user switched the workspace to read-only mode. Do not write files until told otherwise."
}
```

O modelo trata essa mensagem com autoridade de prompt do sistema, e tudo antes dela permanece inalterado. Em um loop de ferramentas, coloque a mensagem após a mensagem do usuário com o `tool_result`, nunca entre um `tool_use` do assistente e seu `tool_result` (consulte [Limitações](https://platform.claude.com/docs/pt-BR/build-with-claude/mid-conversation-system-messages#limitations)). Depois de enviada, a mensagem faz parte do prefixo para o pensamento posterior: mantenha-a no lugar nas requisições posteriores.

### Colocar o contexto que muda no turno mais recente

Alguns harnesses colocam um bloco de ambiente na primeira mensagem do usuário (diretório de trabalho, branch, data, memória, instruções de projeto) e o renderizam novamente a cada requisição. Quando qualquer valor muda, `messages[0]` muda, e todos os blocos de pensamento da conversa ficam inválidos. Renderize esse bloco uma vez e reenvie-o como estava. Quando um valor mudar, informe isso no turno mais recente: adicione um bloco de texto à mensagem do usuário que você está prestes a enviar, ou acrescente uma [mensagem do sistema no meio da conversa](https://platform.claude.com/docs/pt-BR/build-with-claude/preserved-thinking#new-instructions) se a mudança vier de você como operador.

```json
{
  "role": "user",
  "content": [
    {
      "type": "text",
      "text": "Environment update: the current branch is now release-2."
    },
    { "type": "text", "text": "Run the tests again." }
  ]
}
```

Depois de enviado, esse bloco de texto faz parte do prefixo para o pensamento posterior: mantenha-o no lugar nas requisições posteriores.

### Envie lembretes por turno como mensagens de sistema com escopo de turno

Uma edição de prefixo comum é o lembrete por turno: uma linha como "solicite leituras independentes em conjunto" ou "você não atualiza o usuário há algum tempo" que o seu código acrescenta após cada lote de resultados de ferramentas. Para evitar que os lembretes se acumulem, envie cada lembrete como uma [mensagem do sistema no meio da conversa](https://platform.claude.com/docs/pt-BR/build-with-claude/mid-conversation-system-messages) com `clear_at: "next_user_message"`, colocada após a mensagem do usuário com o `tool_result`. `clear_at` exige o cabeçalho beta `mid-conversation-system-clear-at-2026-08-21`. O array `messages` a seguir é a requisição após duas chamadas de ferramenta e seus resultados. `messages[3]` é o lembrete da requisição anterior, mantido no lugar, e `messages[6]` é a cópia desta requisição:

```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."
  }
]
```

Uma mensagem do usuário que contém apenas blocos `tool_result` conta como a "próxima mensagem do usuário", então `messages[3]` já está limpa. Ela não acrescenta nada ao que o modelo vê e não custa tokens de entrada, mas, como ainda está no array, o pensamento em `messages[4]` permanece válido. `messages[6]` é a cópia que o modelo vê neste turno. Nas requisições posteriores, mantenha ambas onde estão e acrescente uma nova cópia após a próxima mensagem com `tool_result`.

### Adicionar ou remover ferramentas com `tool_addition` e `tool_removal`

Editar o array `tools` no meio da sessão invalida os blocos de pensamento preservados. Deixe o array como você o enviou pela primeira vez e altere quais ferramentas o modelo pode usar anexando uma mensagem `role: "system"` que carrega blocos `tool_addition` ou `tool_removal`. Essas são [alterações de ferramentas no meio da conversa](https://platform.claude.com/docs/pt-BR/build-with-claude/mid-conversation-system-messages#mid-conversation-tool-changes) e precisam do cabeçalho beta `inline-tools-2026-09-15`, que está disponível na Claude API. O cabeçalho mais antigo `mid-conversation-tool-changes-2026-07-01` ainda funciona para alterações que nomeiam uma ferramenta por referência, na Claude API, no Amazon Bedrock e no Google Cloud.

Você tem duas maneiras de usar esses blocos:

* **Declarar todas as ferramentas antecipadamente.** Coloque todas as ferramentas de que a sessão possa precisar em `tools` na primeira requisição, com `defer_loading: true` em qualquer uma que o modelo ainda não deva ver. Depois, ative e desative ferramentas com blocos `tool_addition` e `tool_removal` que as nomeiam.
* **Começar com um snapshot e adicionar ferramentas conforme avança.** Coloque as ferramentas que você conhece em `tools` na primeira requisição. Quando surgir uma nova ferramenta, defina-a dentro de um bloco `tool_addition` em vez de editar `tools`.

De qualquer forma, `tools` nunca muda, então o pensamento anterior permanece válido e o cache de prompt continua sendo aproveitado, com a única exceção indicada mais adiante nesta seção.

Por exemplo, para retirar uma ferramenta perigosa após uma troca de modo:

```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." }
  ]
}
```

Para ativar uma ferramenta que você declarou com `defer_loading: true`, anexe um bloco `tool_addition` que a nomeia:

```json
{
  "role": "system",
  "content": [
    { "type": "tool_addition", "tool": { "type": "tool_reference", "name": "deploy" } },
    { "type": "text", "text": "Authentication succeeded. Deployment is now available." }
  ]
}
```

Às vezes você não consegue declarar uma ferramenta antecipadamente porque ainda não conhece seu schema: uma ferramenta que sua aplicação descobre em tempo de execução, ou um servidor MCP que se conecta após o primeiro turno. Defina-a dentro do bloco `tool_addition` em vez de mexer em `tools`. Com `inline-tools-2026-09-15`, o `tool` do bloco pode ser `{"type": "tool_definition", "definition": {...}}`, carregando a mesma entrada que você teria colocado em `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"]
          }
        }
      }
    }
  ]
}
```

A nova ferramenta chega em `messages`, `tools` nunca muda e o pensamento anterior continua válido. Mantenha pelo menos uma ferramenta sem `defer_loading: true` em `tools`: se todas as ferramentas ali forem adiadas, a primeira ferramenta que você definir dessa forma custa uma falha completa do cache de prompt.

Se a API se conecta ao servidor MCP por você por meio do [conector MCP](https://platform.claude.com/docs/pt-BR/agents-and-tools/mcp-connector), envie também `mcp-client-2026-09-15`. Ele cobre tudo o que `mcp-client-2025-11-20` faz, então envie-o no lugar daquele. A `definition` do bloco pode então ser um `mcp_toolset` para um servidor listado em `mcp_servers`. Quando a API precisa buscar a lista de ferramentas de um servidor, a resposta começa com um bloco `mcp_tool_listing` para esse servidor. Envie-o de volta sem alterações junto com o restante do turno do assistente e continue enviando `mcp-client-2026-09-15` em todas as requisições posteriores que o carregam. O bloco fixa o toolset a essa lista, então a API não contata o servidor novamente para obtê-la. Esses recursos do conector MCP estão disponíveis na Claude API.

Apenas com o cabeçalho mais antigo, você ainda pode anexar a `tools` uma ferramenta que descobre no meio da sessão com `defer_loading: true` e depois oferecê-la com um bloco `tool_addition`. Isso é seguro porque a verificação de prefixo ignora uma ferramenta adiada até que um bloco `tool_addition` a referencie. Adicionar uma ferramenta sem `defer_loading: true` altera o prefixo e invalida o pensamento anterior.

As mensagens `role: "system"` que carregam esses blocos passam a fazer parte do prefixo para o pensamento posterior. Mantenha-as no lugar nas requisições posteriores.

### Alterar o esforço com um `output_config` por mensagem

Alterar o `output_config.effort` de nível superior entre requisições não invalida o pensamento, porque o esforço não faz parte do prefixo. Alterar o esforço de nível superior, porém, reinicia o cache de prompt. Onde o modelo e a plataforma suportam [esforço por mensagem](https://platform.claude.com/docs/pt-BR/build-with-claude/effort#change-effort-mid-conversation-beta), use-o em vez disso: anexe uma mensagem `role: "system"` com `content` vazio e o novo nível. Isso requer o cabeçalho beta `mid-conversation-output-config-2026-07-01`. No Claude Haiku 5.5, o esforço por mensagem está disponível na Claude API e no Google Cloud e requer pensamento adaptativo.

```json
{ "role": "system", "content": [], "output_config": { "effort": "low" } }
```

Quando o novo nível entra em vigor depende de onde você coloca a mensagem. Logo após uma mensagem `user` com nova entrada, ele começa com a resposta do Claude a essa mensagem. Em qualquer outro lugar, como após uma mensagem `assistant` ou após uma mensagem `user` que contém apenas blocos `tool_result`, ele começa com a próxima mensagem `user` com nova entrada, então um loop de ferramentas já em andamento mantém o nível atual até lá. Depois de enviada, a mensagem faz parte de `messages` e, portanto, do prefixo para o pensamento posterior: deixe-a no lugar nas requisições seguintes e anexe outra para alterar o esforço novamente.

### Cortar o contexto no servidor

Outra edição de prefixo comum é o corte no lado do cliente: descartar ou resumir os turnos mais antigos e manter os recentes literalmente. Os blocos de pensamento dos turnos mantidos foram produzidos enquanto o histórico removido ainda estava presente, então eles falham na verificação. Os equivalentes no lado do servidor não contam como edições, porque a verificação compara a conversa como você a enviou:

* A [compactação sob demanda](https://platform.claude.com/docs/pt-BR/build-with-claude/compaction-on-demand) (beta) retorna o resumo a partir de uma requisição separada, que pode [ser executada em segundo plano](https://platform.claude.com/docs/pt-BR/build-with-claude/compaction-background), e você envia o bloco retornado no lugar das mensagens que ele resume. A verificação aceita essa troca, então os turnos que você mantém podem permanecer válidos com seu pensamento, sob as [condições para o pensamento mantido](https://platform.claude.com/docs/pt-BR/build-with-claude/compaction-thinking-blocks#conditions-for-kept-thinking-to-stay-valid). [Solicitar um resumo](https://platform.claude.com/docs/pt-BR/build-with-claude/compaction-on-demand#request-a-summary) mostra a requisição e indica o cabeçalho beta de que ela precisa.
* A [compactação em um limite de tokens](https://platform.claude.com/docs/pt-BR/build-with-claude/compaction-threshold) resume os turnos mais antigos em um bloco de compactação quando o contexto se aproxima de um limite que você define, e o prefixo verificado recomeça a partir desse bloco. Seu [parâmetro `instructions`](https://platform.claude.com/docs/pt-BR/build-with-claude/compaction-threshold#custom-summarization-instructions) aceita seu próprio prompt de resumo, como "preserve todos os tickers, tamanhos de posição e premissas declaradas".
* A [edição de contexto](https://platform.claude.com/docs/pt-BR/build-with-claude/context-editing) limpa resultados de ferramentas antigos ou blocos de pensamento antigos por regra, começando pelos mais antigos. As estratégias são `clear_tool_uses_20250919` e `clear_thinking_20251015`.

### Compactar no cliente

Você ainda pode compactar no cliente. Se você mesmo escrever o resumo, não envie de volta um bloco de pensamento que foi produzido antes da reescrita. Se a API o escrever com compactação sob demanda, [Condições para que o pensamento mantido permaneça válido](https://platform.claude.com/docs/pt-BR/build-with-claude/compaction-thinking-blocks#conditions-for-kept-thinking-to-stay-valid) lista quando o pensamento mantido permanece válido.

#### Compactação simples (recomendada)

Quando a conversa ficar longa demais, resuma a sessão inteira em uma única mensagem do usuário e envie apenas essa mensagem mais a próxima instrução. Nada anterior é reenviado, então não resta pensamento para falhar na verificação, e o modelo raciocina do zero a partir do resumo.

<Frame>
  ![Simple compaction (compactação simples): a requisição 4 envia o histórico completo com pensamento em cada turno do assistente; a requisição 5 envia uma mensagem do usuário contendo um resumo dos turnos 1 a 4 mais a próxima instrução, então nenhum pensamento anterior é enviado e nada é verificado](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>"
  }
]
```

Os modelos Claude são treinados em tarefas de longo horizonte com esse esquema e, para a maioria das cargas de trabalho, ele tem bom desempenho.

#### Compactação com cauda preservada

A "keep-tail compaction" (compactação com cauda preservada) resume os turnos mais antigos e mantém os turnos mais recentes literalmente, para que o modelo ainda veja as últimas trocas palavra por palavra. Se você mesmo escrever o resumo, isso quebra a regra: os turnos do assistente mantidos ainda carregam blocos de pensamento que foram produzidos quando os turnos originais, e não o resumo, vinham antes deles. Esses blocos falham.

Para manter esse pensamento, faça com que a API escreva o resumo com compactação sob demanda. [Compactação que mantém turnos recentes](https://platform.claude.com/docs/pt-BR/build-with-claude/compaction-keep-recent-turns) mostra como, e [Condições para que o pensamento mantido permaneça válido](https://platform.claude.com/docs/pt-BR/build-with-claude/compaction-thinking-blocks#conditions-for-kept-thinking-to-stay-valid) lista quando o pensamento mantido permanece válido.

O restante desta seção trata de um resumo que você mesmo escreve.

<Frame>
  ![Keep-tail compaction (compactação com cauda preservada): o histórico é substituído por um resumo dos turnos 1 e 2 seguido dos turnos 3 a 5 literalmente; o pensamento nos turnos 3 e 4 do assistente foi produzido após os turnos originais, e não após o resumo, então ele falha; a mesma requisição enviada com prefix\_mismatch\_behavior drop\_block é bem-sucedida, a API descarta esses dois blocos e os lista em input\_transformations](https://platform.claude.com/docs/images/preserved-thinking-keep-tail-compaction.svg)
</Frame>

Correção: mantenha os turnos exatamente como estão e envie `prefix_mismatch_behavior: "drop_block"`. A API descarta os blocos de pensamento obsoletos, o modelo lê os blocos `text` e `tool_use` dos turnos mantidos e a requisição é bem-sucedida.

Passe o histórico compactado como `messages` e defina `block_binding` na configuração `thinking`. No exemplo a seguir, `compacted_messages` é o array que sua etapa de compactação produziu: a mensagem de resumo seguida dos turnos mantidos exatamente como a API os retornou, incluindo os blocos `thinking`:

<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: a mensagem de resumo, seguida dos turnos mantidos conforme retornados
  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: a mensagem de resumo, seguida dos turnos mantidos conforme retornados
  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: a mensagem de resumo, seguida dos turnos mantidos conforme retornados
  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: a mensagem de resumo, seguida dos turnos mantidos conforme retornados
  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: a mensagem de resumo, seguida dos turnos mantidos conforme retornados
      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: a mensagem de resumo, seguida dos turnos mantidos conforme retornados
  $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: a mensagem de resumo, seguida dos turnos mantidos conforme retornados
  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>

A resposta traz o novo turno do assistente normalmente, mais uma entrada `input_transformations` por bloco descartado. Para o histórico do diagrama, isso corresponde ao pensamento nos turnos 3 e 4 do 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"
    }
  ]
}
```

Continue enviando `"drop_block"` nas requisições seguintes enquanto esses dois turnos permanecerem no histórico. O pensamento que o modelo produz a partir desta requisição segue o resumo e permanece válido. Se você preferir não depender do cabeçalho beta, a alternativa é remover você mesmo os blocos `thinking` e `redacted_thinking` dos turnos do assistente mantidos ao construir o histórico compactado.

#### Compactação em segundo plano (assíncrona)

A compactação em segundo plano constrói o resumo fora do caminho crítico enquanto a conversa continua e, em seguida, faz a troca algumas requisições depois. Para manter o pensamento produzido nesse meio-tempo, faça com que a API escreva o resumo com compactação sob demanda: [Compactação em segundo plano](https://platform.claude.com/docs/pt-BR/build-with-claude/compaction-background) traz as etapas, e esse pensamento permanece válido sob as mesmas [condições para o pensamento mantido](https://platform.claude.com/docs/pt-BR/build-with-claude/compaction-thinking-blocks#conditions-for-kept-thinking-to-stay-valid) que os turnos recentes mantidos.

Um resumo que você mesmo constrói quebra a regra da mesma forma que a compactação keep-tail, só que com atraso: cada turno do assistente produzido enquanto o resumo estava sendo construído carrega thinking anterior à troca, e todo ele falha no momento em que o resumo entra. Se você usar um, trate a troca como na compactação keep-tail e envie `"drop_block"` a partir da troca, ou compacte de forma síncrona.

#### Padrões que não funcionam com pensamento preservado

* **Cortar turnos do meio.** Remover turnos individuais invalida todos os blocos de thinking posteriores a eles, e nenhum esquema de compactação evita isso. Se você estava cortando um turno para alterar uma instrução, adicione uma [mensagem de sistema no meio da conversa](https://platform.claude.com/docs/pt-BR/build-with-claude/preserved-thinking#new-instructions) em vez disso. Para remover resultados de ferramentas antigos ou thinking antigo de forma seletiva, use a [edição de contexto](https://platform.claude.com/docs/pt-BR/build-with-claude/context-editing) no lado do servidor.
* **Compactar no meio de uma rodada de ferramentas.** Não compacte entre o `tool_use` de um turno do assistente e o `tool_result` que o responde. Envie esse turno do assistente de volta com seu thinking intacto para que o modelo conclua a rodada com seu raciocínio. Consulte [Preservando blocos de thinking](https://platform.claude.com/docs/pt-BR/build-with-claude/thinking#preserving-thinking-blocks).

### Referencie arquivos por ID, não por uma URL cujo conteúdo muda

Para um bloco `image` ou `document` com uma fonte `url`, a verificação abrange os bytes obtidos, não a string da URL. Uma URL cujo conteúdo muda invalida o thinking posterior: um endpoint de "captura de tela mais recente", ou um documento que alguém edita entre os turnos. Uma URL assinada rotativa para o mesmo arquivo não invalida. Para conteúdo que você referencia ao longo dos turnos, faça o upload uma vez com a [Files API](https://platform.claude.com/docs/pt-BR/build-with-claude/files) e use o `file_id`, ou envie em base64.

### Bibliotecas, proxies e gateways

Uma biblioteca, proxy ou gateway fica entre o histórico de outra pessoa e a API, então suas próprias reescritas contam como edições, e seus usuários não conseguem vê-las nem corrigi-las.

* **Repasse o que você não reconhece.** Encaminhe os valores `anthropic-beta` e `thinking.block_binding` do chamador sem alterações e retorne `input_transformations` para ele. Um schema de opções que rejeita chaves desconhecidas impede que seus usuários escolham `"drop_block"`.
* **Deixe uma mensagem `role: "system"` onde o chamador a colocou.** Movê-la para o campo `system` de nível superior altera `system` nessa requisição e invalida todos os blocos de thinking da conversa.
* **Para desativar o uso de ferramentas em uma requisição, envie `tool_choice: {"type": "none"}`.** Não remova `tools`.
* **Não oculte o 400.** Se o seu código o captura, remove o thinking e tenta novamente em nome do chamador, registre em log que fez isso: o histórico dele continua editado, e o modelo perde seu raciocínio anterior em todas as requisições seguintes.

## Perguntas frequentes

<AccordionGroup>
  <Accordion title="Preciso de uma nova conta para testar o pensamento preservado?">
    Não. Envie o cabeçalho beta `thinking-binding-controls-2026-08-01` e defina `thinking.block_binding.prefix_mismatch_behavior`. Definir o campo inclui essa requisição na aplicação da verificação, independentemente da idade da conta. `"error"` rejeita um histórico editado com o mesmo 400 que uma conta nova recebe, e `"drop_block"` deixa a requisição passar e lista o que foi descartado em `input_transformations`. Para encontrar edições de prefixo em uma conta mais antiga sem aplicar a verificação, envie o cabeçalho e deixe o campo sem definir: os blocos que falham ainda chegam ao modelo, e `input_transformations` os lista como `thinking_mismatch_allowed`. Consulte [Verificar se seu código edita o prefixo](https://platform.claude.com/docs/pt-BR/build-with-claude/preserved-thinking#how-to-tell-whether-your-integration-is-impacted).
  </Accordion>

  <Accordion title="Se qualquer coisa antes de um bloco de pensamento mudar, mesmo a descrição de uma ferramenta, a conversa fica inutilizável?">
    Não. O que falha é o pensamento já presente no histórico após o ponto que você alterou, e você escolhe o que acontece com ele. Com `prefix_mismatch_behavior: "drop_block"`, a API descarta esses blocos e a requisição é bem-sucedida: o modelo responde a esse turno sem aquele raciocínio, e o cache de prompt reinicia na edição. Com o padrão `"error"`, a API rejeita a requisição com um 400 até que você desfaça a edição ou reenvie com `"drop_block"`. Consulte [O que a API faz com um bloco inválido](https://platform.claude.com/docs/pt-BR/build-with-claude/preserved-thinking#mismatch-behavior). [O que conta como edição](https://platform.claude.com/docs/pt-BR/build-with-claude/preserved-thinking#what-counts-as-an-edit) lista quais alterações importam.
  </Accordion>

  <Accordion title="Alterar o esforço ou outras configurações de pensamento entre requisições invalida o pensamento anterior?">
    Não. `output_config.effort`, `max_tokens` e a configuração `thinking` não fazem parte do prefixo verificado, que cobre apenas `system`, `tools` e `messages`. Uma alteração de esforço de nível superior invalida a maior parte do cache de prompt. Onde o modelo e a plataforma suportam [esforço por mensagem](https://platform.claude.com/docs/pt-BR/build-with-claude/preserved-thinking#effort-changes), uma alteração de esforço por mensagem mantém o cache de prompt e é usada como o novo nível de esforço até ser alterada novamente.
  </Accordion>

  <Accordion title="Minha lista de ferramentas muda no meio da sessão. Como evito invalidar a conversa?">
    Não edite `tools`. Declare o conjunto completo no início da sessão, marque as ferramentas que ainda não estão disponíveis com `defer_loading: true` e ofereça-as ou retire-as com blocos `tool_addition` e `tool_removal`. Se você só conhecer o schema de uma ferramenta no meio da sessão, defina-a dentro do bloco `tool_addition` (`inline-tools-2026-09-15`, mais `mcp-client-2026-09-15` para um servidor que o conector MCP da API alcança) e deixe `tools` inalterado. As mensagens `role: "system"` que carregam esses blocos passam a fazer parte do prefixo para o pensamento posterior, então não as mova, reescreva ou exclua depois. Consulte [Adicionar ou remover ferramentas com `tool_addition` e `tool_removal`](https://platform.claude.com/docs/pt-BR/build-with-claude/preserved-thinking#tool-changes).
  </Accordion>

  <Accordion title="Eu compacto resumindo os turnos mais antigos e mantendo os turnos recentes literalmente. Isso ainda funciona?">
    Sim, se a API escrever o resumo. A [compactação sob demanda](https://platform.claude.com/docs/pt-BR/build-with-claude/compaction-on-demand) (cabeçalho beta `compact-2026-09-04`) resume os turnos mais antigos em um bloco assinado que você envia no lugar deles. Os turnos recentes mantêm seu pensamento sob as [condições para que o pensamento mantido permaneça válido](https://platform.claude.com/docs/pt-BR/build-with-claude/compaction-thinking-blocks#conditions-for-kept-thinking-to-stay-valid).

    Se você mesmo escrever o resumo, o pensamento dos turnos mantidos falha na verificação, porque esses blocos foram produzidos com base no histórico que você substituiu. Remova os blocos `thinking` e `redacted_thinking` dos turnos que você mantém e preserve seus blocos `text` e `tool_use`, ou envie `prefix_mismatch_behavior: "drop_block"` e deixe a API descartá-los. A compactação simples não deixa nenhum pensamento para falhar e é a abordagem recomendada: uma mensagem de resumo mais o próximo turno do usuário, sem reenviar turnos anteriores. A [compactação](https://platform.claude.com/docs/pt-BR/build-with-claude/compaction) e a [edição de contexto](https://platform.claude.com/docs/pt-BR/build-with-claude/context-editing) no lado do servidor não contam como edições. Consulte [Compactar no cliente](https://platform.claude.com/docs/pt-BR/build-with-claude/preserved-thinking#custom-compaction-on-the-client).
  </Accordion>

  <Accordion title="Como lido com arquivos de instruções como AGENTS.md ou CLAUDE.md que mudam no meio da sessão?">
    Carregue-os uma vez no início da sessão e mantenha fixos o prompt `system` de nível superior e `tools`. Quando um arquivo mudar, anexe a nova versão naquele ponto em `messages` em vez de editar o original. Use uma [mensagem do sistema no meio da conversa](https://platform.claude.com/docs/pt-BR/build-with-claude/mid-conversation-system-messages) para instruções que vêm de você como operador. Para texto de arquivo que você trata como não confiável, que não deve ter a autoridade do prompt do sistema, coloque o conteúdo no próximo turno `user` em vez disso. Consulte [Adicionar instruções com uma mensagem do sistema no meio da conversa](https://platform.claude.com/docs/pt-BR/build-with-claude/preserved-thinking#new-instructions) e [Limitações](https://platform.claude.com/docs/pt-BR/build-with-claude/mid-conversation-system-messages#limitations).
  </Accordion>

  <Accordion title="Posso retomar uma sessão salva mais tarde, após uma reinicialização ou no dia seguinte?">
    Sim. Uma sessão retomada é uma requisição de continuação comum: `system`, `tools` e as `messages` anteriores devem ter o mesmo conteúdo que você enviou por último. A formatação JSON e a ordem das chaves não importam; os valores sim. Persista exatamente o que você enviou e recebeu e reenvie isso: o prompt do sistema renderizado, as definições de ferramentas e cada turno do assistente como retornado. Não renderize novamente a partir de entradas que possam ter mudado desde então, como a data, um arquivo de instruções atualizado ou uma nova versão de ferramenta. Qualquer coisa nova vai em uma mensagem anexada. Consulte [Enviar os turnos do assistente de volta exatamente como retornados](https://platform.claude.com/docs/pt-BR/build-with-claude/preserved-thinking#append-assistant-turns-exactly-as-returned).
  </Accordion>

  <Accordion title="Uma sessão salva agora falha em todas as requisições. Como faço para ela voltar a funcionar?">
    O histórico armazenado contém uma edição, então reenviá-lo não pode ter sucesso. Envie essa sessão com `prefix_mismatch_behavior: "drop_block"` daqui em diante, ou remova seus blocos `thinking` e `redacted_thinking` uma vez e continue. No Claude Sonnet 5.5 e no Claude Haiku 5.5, `block_binding` funciona apenas com `thinking: {"type": "adaptive"}`. Com `between_tools` no Claude Sonnet 5.5, ou `thinking: {"type": "disabled"}` no Claude Haiku 5.5, mantenha o histórico somente de acréscimo, ou remova os blocos de pensamento a partir do turno editado. O pensamento que o modelo produz a partir desse ponto permanece válido desde que nada antes dele mude novamente. Depois, encontre a edição para que novas sessões não a encontrem. Consulte [Tratar o erro no código](https://platform.claude.com/docs/pt-BR/build-with-claude/preserved-thinking#handle-the-error-in-code).
  </Accordion>

  <Accordion title="Meu harness pode encaminhar um turno para um modelo que não é Claude. Esses turnos invalidam o pensamento anterior do Claude?">
    Não, desde que sejam anexados após o histórico existente e nada anterior mude: uma mensagem do assistente sem blocos de pensamento é uma mensagem anexada como qualquer outra. Envie a saída do outro modelo como conteúdo `text` e `tool_use`.
  </Accordion>

  <Accordion title="Posso levar o raciocínio de uma conversa para uma nova conversa?">
    Não para uma conversa diferente. Um bloco de pensamento só pode ser usado quando segue exatamente o `system`, as `tools` e as `messages` a partir dos quais foi produzido. Uma ramificação que reenvia esse histórico sem alterações até o ponto de bifurcação mantém seu pensamento. Uma conversa que começa a partir de qualquer outra coisa não pode usá-lo, então inicie essa conversa a partir de um resumo do estado da tarefa, como na [compactação simples](https://platform.claude.com/docs/pt-BR/build-with-claude/preserved-thinking#custom-compaction-on-the-client): o objetivo, as decisões tomadas, os arquivos e resultados até o momento e o próximo passo. Os blocos de pensamento do Claude Sonnet 5.5 e do Claude Haiku 5.5 também não podem ser reutilizados a partir de outra conta (consulte [Os blocos de pensamento permanecem com a conta que os produziu](https://platform.claude.com/docs/pt-BR/build-with-claude/preserved-thinking#account-bound-thinking)).
  </Accordion>
</AccordionGroup>

## Próximos passos

<CardGroup cols={2}>
  <Card title="Solução de problemas de pensamento" icon="hammer" href="https://platform.claude.com/docs/pt-BR/build-with-claude/thinking-troubleshooting">
    Diagnostique e corrija as falhas de pensamento mais comuns: erros 400 de configuração, blocos de pensamento vazios ou ausentes, paradas por max\_tokens e falhas de cache.
  </Card>

  <Card title="Mensagens de sistema e alterações de ferramentas no meio da conversa" icon="messages" href="https://platform.claude.com/docs/pt-BR/build-with-claude/mid-conversation-system-messages">
    Altere instruções do sistema ou a disponibilidade de ferramentas no meio de uma conversa sem invalidar o prefixo em cache que veio antes delas.
  </Card>

  <Card title="Compactação" icon="stack" href="https://platform.claude.com/docs/pt-BR/build-with-claude/compaction">
    Compactação de contexto no lado do servidor para gerenciar conversas longas que se aproximam dos limites da janela de contexto.
  </Card>

  <Card title="Cache de prompt" icon="database" href="https://platform.claude.com/docs/pt-BR/build-with-claude/prompt-caching">
    Armazene prefixos de prompt em cache com `cache_control` para reduzir custos e latência, usando cache automático ou pontos de interrupção explícitos com TTLs de 5 minutos ou 1 hora.
  </Card>
</CardGroup>
