Claude Platform Docs
MensagensPensamento

Pensamento preservado

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.
  • 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.

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

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).

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.

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 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 ou durante um fallback do lado do servidor. 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.

SystemToolsUserFable thinkingread againUserFable thinkingread again[change model → Opus]UserOpus thinkingdrops Fable thinking[back to Fable 5.1]UserFable thinkingall thinking readNo errors

Com o cabeçalho beta 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":

{
  "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 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 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 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: 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".

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. 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 thinking-binding-controls-2026-08-01. Definir o comportamento de incompatibilidade e ler input_transformations mostra a requisição em cada SDK.

A mensagem do 400 começa assim:

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:

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 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 é 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), 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 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:

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 [])}")
Output
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). 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).
  • 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). 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, 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, 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 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çõesBlocos de pensamento posteriores
Acrescentar mensagens no finalVálidos
Adicionar uma ferramenta com defer_loading: true que nada referenciou aindaVálidos
Remover blocos thinking do início do histórico, do final, ou todos elesVá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_controlVálidos
Uma URL assinada rotativa que retorna os mesmos bytesVálidos
A compactação ou a edição de contexto no lado do servidor remove ou substitui conteúdoVá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 já limpa, mantida no lugarVálidos
Editar, reordenar ou excluir qualquer mensagem user, assistant ou system anteriorInválidos, exceto quando o bloco assinado da compactação sob demanda substitui as mensagens que ele resume, sob as condições para o pensamento mantido
Renderizar novamente, com um valor alterado, o contexto que você colocou na primeira mensagem do usuárioInvá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 anteriorInvá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 vezInválidos
Alterar a string ou os blocos do system de nível superiorInválidos
Adicionar, remover, renomear ou editar uma ferramenta em toolsInválidos
Remover um bloco thinking do meio do histórico e manter os posterioresInválidos para todos os blocos de pensamento posteriores
Colocar de volta um bloco thinking que você removeu em uma requisição anteriorInválidos para os blocos de pensamento produzidos enquanto ele estava ausente
Uma URL de imagem ou documento que retorna bytes diferentes na requisição seguinteInválidos
A mesma mensagem com escopo de turno excluída ou reescrita em uma requisição posteriorInválidos

Verificar se seu código edita o prefixo

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

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}")
Output
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:

{
  "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.
  • 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.
  • reason: "organization_binding_mismatch": o bloco veio de outra conta. Consulte Os blocos de pensamento permanecem com a conta que os produziu.

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

{
  "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, 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:

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}")
Output
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. 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 deUseCabeçalho beta
Reconstruir o prompt system de nível superiorUma mensagem do sistema no meio da conversaNenhum
Renderizar novamente o contexto na sua primeira mensagem do usuário (ambiente, data, memória, instruções do projeto) a cada requisiçãoRenderize-o uma vez e reenvie-o inalterado. Quando algo mudar, coloque a nova versão no turno mais recenteNenhum
Limpar ou encurtar conteúdo tool_result antigo, ou recodificar imagens antigas, no lugarEncurte 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 com clear_tool_uses_20250919context-management-2025-06-27
Injetar um lembrete e excluí-lo na próxima requisiçãoUma mensagem do sistema com escopo de turno (clear_at: "next_user_message")mid-conversation-system-clear-at-2026-08-21
Adicionar ou remover entradas em toolsBlocos tool_addition e tool_removalinline-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 mensagemmid-conversation-output-config-2026-07-01
Descartar ou resumir turnos antigos no clienteCompactação sob demanda para manter os turnos recentes com seu pensamento, outra compactação ou edição de contexto do lado do servidor, ou compactação do lado do cliente que não mantém pensamento obsoletocompact-2026-09-04
Uma URL de imagem ou documento cujos bytes mudam entre requisiçõesUm file_id da Files API, ou base64Nenhum

Tudo isso pressupõe que você envie os turnos do assistente de volta exatamente como retornados. 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 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:

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.

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" no ponto de messages em que a mudança passa a valer:

{
  "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). 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 se a mudança vier de você como operador.

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

[
  { "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 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:

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

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

{
  "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, 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, 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.

{ "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 (beta) retorna o resumo a partir de uma requisição separada, que pode ser executada em segundo plano, 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. Solicitar um resumo mostra a requisição e indica o cabeçalho beta de que ela precisa.
  • A compactação em um limite de tokens 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 aceita seu próprio prompt de resumo, como "preserve todos os tickers, tamanhos de posição e premissas declaradas".
  • A edição de contexto 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 lista quando o pensamento mantido permanece válido.

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.

Request 4full historyuser 1asst 1thinkinguser 2asst 2thinkinguser 3asst 3thinkinguser 4compact on the clientRequest 5after compactionuser: summary of turns 1–4 + next instructionno earlier turns replayed, so no thinking to check
[
  {
    "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 mostra como, e Condições para que o pensamento mantido permaneça válido lista quando o pensamento mantido permanece válido.

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

Beforefull historyuser 1asst 1thinkinguser 2asst 2thinkinguser 3asst 3thinkinguser 4asst 4thinkinguser 5Keep-tail, as writtensummary + recent turns verbatimsummary of 1–2user 3asst 3thinking ✗user 4asst 4thinking ✗user 5asst 3 and asst 4 thinking was produced after user 1 … asst 2, not after the summary, so it failsKeep-tail with drop_blockAPI drops the blockssummary of 1–2user 3asst 3droppeduser 4asst 4droppeduser 5The request succeeds. The model reads asst 3 and 4 without their thinking. input_transformations lists both blocks.

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:

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)

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:

{
  "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 traz as etapas, e esse pensamento permanece válido sob as mesmas condições para o pensamento mantido 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 em vez disso. Para remover resultados de ferramentas antigos ou thinking antigo de forma seletiva, use a edição de contexto 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.

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

Próximos passos

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.

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.

Compactação de contexto no lado do servidor para gerenciar conversas longas que se aproximam dos limites da janela de contexto.

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.

Was this page helpful?