Compactação sob demanda
Peça ao Claude para resumir uma conversa quando sua aplicação decidir e, em seguida, continue a partir do resumo.
Com a "on-demand compaction" (compactação sob demanda), sua aplicação decide quando uma conversa é resumida: você envia uma solicitação com o parâmetro compaction, e Claude retorna um resumo no lugar de uma resposta.
Como a compactação sob demanda funciona
Uma solicitação de compactação é separada dos turnos da sua conversa. Você envia a conversa como está com o parâmetro compaction, e a resposta contém um único bloco compaction. O bloco contém o resumo como texto que você pode ler, e uma assinatura. Envie-o em solicitações futuras exatamente como ele veio.
A partir daí, o bloco ocupa o lugar das mensagens que ele resume. Ele vai primeiro em messages, as mensagens resumidas são removidas, e seu próximo turno vem depois dele. Claude vê o resumo onde essas mensagens estavam.
Solicitar um resumo
Envie o cabeçalho beta compact-2026-09-04 na solicitação que pede o resumo e em todas as solicitações posteriores que carregam o bloco assinado. Para verificar se um modelo oferece suporte à compactação sob demanda, chame a Models API com o cabeçalho beta e leia o capabilities.compaction de cada modelo. Você não pode combinar compaction com context_management em uma mesma solicitação.
Envie a conversa como está com "compaction": {"type": "summarize"}. A API resume todas as mensagens da solicitação uma vez, não gera nenhuma resposta depois disso e retorna apenas o bloco com stop_reason "compaction". Envie o mesmo prompt system e as mesmas tools que você usa no restante da conversa. O sumarizador os lê e, se você mantiver turnos após o bloco em um modelo com "preserved thinking" (pensamento preservado), o pensamento nesses turnos permanece válido somente se system e tools corresponderem. A conversa neste exemplo não tem prompt system nem ferramentas, então a solicitação não envia nenhum dos dois:
from anthropic.types.beta import BetaMessageParam
client = anthropic.Anthropic()
history: list[BetaMessageParam] = [
{
"role": "user",
"content": "I am building a recipe app. Help me name the main entities in the data model.",
},
{
"role": "assistant",
"content": "Start with Recipe, Ingredient, and Step. Add a RecipeIngredient entry that holds the quantity and unit for each ingredient in a recipe.",
},
{"role": "user", "content": "Good. Now suggest field names for Recipe."},
]
response = client.beta.messages.create(
model="claude-opus-5-5",
# max_tokens limita a chamada inteira, incluindo qualquer pensamento, então reserve vários milhares de tokens.
max_tokens=4096,
betas=["compact-2026-09-04"],
messages=history,
compaction={"type": "summarize"},
)
print(f"Stop reason: {response.stop_reason}"){
"id": "msg_013Zva2CMHLNnXjNJJKqJ2EF",
"type": "message",
"role": "assistant",
"model": "claude-opus-5-5",
"content": [
{
"type": "compaction",
"content": "Summary of the conversation: the user is designing the data model for a recipe app. The entities agreed so far are Recipe, Ingredient, Step, and RecipeIngredient, which holds the quantity and unit. The user then asked for field names for Recipe.",
"signature": "EuYBCkQY..."
}
],
"stop_reason": "compaction",
"usage": {
"input_tokens": 0,
"output_tokens": 0,
"iterations": [{ "type": "compaction", "input_tokens": 144, "output_tokens": 276 }]
}
}A chamada de sumarização usa o modelo, o system, as tools, as configurações de pensamento e o max_tokens da solicitação. O sumarizador lê as definições de ferramentas, mas nunca executa uma ferramenta, e a resposta não traz nenhum pensamento. max_tokens limita a chamada inteira, incluindo qualquer pensamento que o modelo faça antes de escrever o resumo, então reserve vários milhares de tokens. Contabilizar o uso da compactação mostra como a chamada é cobrada.
Se o último turno assistant terminar em uma chamada de ferramenta ainda sem resultado, a API rejeita a solicitação. Envie primeiro os resultados de ferramentas desse turno. Também deixe de fora stop_sequences, o output_config.format de saída estruturada e um tool_choice do tipo any ou tool. Eles não teriam efeito em uma chamada de sumarização, e a API os rejeita. A conversa ainda precisa caber na "context window" (janela de contexto) do modelo, então compacte antes de ultrapassá-la, não depois.
Quando você faz streaming da resposta, o bloco chega inteiro. Você recebe um evento content_block_start carregando o bloco completo, depois content_block_stop, sem eventos content_block_delta. Eventos ping podem chegar antes ou entre eles.
Continuar a partir do resumo
No seu histórico, substitua as mensagens que você enviou pela mensagem do assistente retornada. Mantenha o bloco compaction exatamente como a API o retornou, incluindo sua signature. Quaisquer turnos realizados depois que você enviou a solicitação de compactação vêm após o bloco sem alterações, e é nisso que se baseia a Compactação em segundo plano. Envie o bloco primeiro em todas as solicitações posteriores, com o cabeçalho beta:
{
"model": "claude-opus-5-5",
"max_tokens": 2048,
"messages": [
{
"role": "assistant",
"content": [
{
"type": "compaction",
"content": "Summary of the conversation: the user is designing the data model for a recipe app. The entities agreed so far are Recipe, Ingredient, Step, and RecipeIngredient, which holds the quantity and unit. The user then asked for field names for Recipe.",
"signature": "EuYBCkQY..."
}
]
},
{
"role": "assistant",
"content": "For Recipe, use title, description, servings, prep_minutes, and cook_minutes. Add created_at and updated_at timestamps."
},
{ "role": "user", "content": "Now do the same for Ingredient." }
]
}Este exemplo dá continuidade ao exemplo de solicitação, que terminou em um turno user; o diagrama mostra o caso mais simples, em que nenhum turno é realizado enquanto o resumo é escrito. Aqui, a segunda mensagem assistant é a resposta ao último turno user resumido. Ela chegou enquanto o resumo estava sendo escrito, então não estava entre as mensagens resumidas. Duas mensagens assistant seguidas não são um problema aqui, porque o bloco ainda vem primeiro.
A API coloca o resumo onde o bloco está e passa todas as mensagens posteriores para Claude sem alterações. Siga estas regras:
- Coloque o bloco primeiro em
messages, seja como uma mensagemassistantprópria ou como o primeiro bloco de conteúdo da primeira mensagem, seja ela uma mensagemuserouassistant. - Remova as mensagens resumidas. Se alguma permanecer antes do bloco, a solicitação retorna um erro 400 (
compaction_block_misplaced). - Envie exatamente um bloco
compactionpor solicitação, em todas as solicitações posteriores.
A "threshold compaction" (compactação por limite) funciona ao contrário: seu bloco vem depois das mensagens que ele resume, e a API as descarta para você. Consulte Enviando os blocos de compactação de volta.
Em Python, use client.beta.messages, como fazem os exemplos desta página. Se você chamar client.messages e serializar os blocos por conta própria, use to_dict() ou model_dump(exclude_none=True): um model_dump() simples adiciona citations: null e text: null ao bloco, e a API o rejeita.
Se você mantiver turnos após o bloco e enviar de volta os blocos de pensamento deles, as condições que mantêm esse pensamento válido estão em Compactação e pensamento preservado.
Compactar novamente
Para compactar uma conversa que já começa com um bloco, envie compaction novamente. O novo bloco resume o resumo antigo e tudo o que vem depois dele. A partir daí, envie apenas o bloco mais recente.
Compactar em um loop
Após cada turno, o loop soma os tokens de entrada e de saída da última resposta, porque a próxima solicitação também envia a resposta. Quando esse total ultrapassa um limite e ainda há outro turno por vir, ele envia uma solicitação de compactação com o mesmo modelo e o mesmo prompt system, verifica stop_reason, substitui seu histórico pela mensagem retornada e imprime o turno antes do qual compactou. O limite de 2.500 tokens do exemplo é deliberadamente baixo, para que uma conversa curta seja compactada. Defina o seu próximo ao seu orçamento real de entrada.
from anthropic.types.beta import BetaMessageParam
client = anthropic.Anthropic()
# Defina isto perto do seu orçamento real de entrada. Aqui está baixo para que uma conversa curta seja compactada.
COMPACT_AT_TOKENS = 2500
SYSTEM = "You help design a recipe app's data model. Keep answers short."
QUESTIONS = [
"What are the main entities in the data model?",
"Which fields should Recipe have?",
"Which fields should Ingredient have?",
"Which fields should RecipeIngredient have?",
"Which fields should Step have?",
"Which indexes should these tables have?",
"Which fields should be required?",
"Which fields should have default values?",
]
history: list[BetaMessageParam] = []
for turn, question in enumerate(QUESTIONS, start=1):
history.append({"role": "user", "content": question})
response = client.beta.messages.create(
model="claude-opus-5-5",
max_tokens=8192,
system=SYSTEM,
betas=["compact-2026-09-04"],
messages=history,
)
history.append({"role": "assistant", "content": response.content})
# A próxima requisição também envia esta resposta, então conte-a.
conversation_tokens = response.usage.input_tokens + response.usage.output_tokens
if conversation_tokens > COMPACT_AT_TOKENS and turn < len(QUESTIONS):
summary = client.beta.messages.create(
model="claude-opus-5-5",
max_tokens=4096,
system=SYSTEM,
betas=["compact-2026-09-04"],
messages=history,
compaction={"type": "summarize"},
)
if summary.stop_reason == "compaction":
history = [{"role": "assistant", "content": summary.content}]
print(f"Compacted before turn {turn + 1}")A verificação de stop_reason vem antes de o código procurar o bloco; Lidar com um resumo ausente ou um erro explica por quê. O histórico é substituído, e não acrescido: a mensagem retornada substitui todas as mensagens que a solicitação carregava, conforme as regras em Continuar a partir do resumo. Quando nenhum resumo é retornado, o loop mantém seu histórico e pede novamente após o próximo turno.
O "tool runner" (executor de ferramentas) do SDK em Python, TypeScript, C#, Go e Java pode enviar a solicitação de compactação por você. Quando você decidir compactar, chame compact_before_next_turn() no runner (compactBeforeNextTurn() em TypeScript e Java, CompactBeforeNextTurn() em C# e Go). Assim que o turno atual e suas chamadas de ferramentas terminarem, o runner envia a solicitação de compactação e substitui seu histórico pela mensagem retornada. Crie o runner com o beta compact-2026-09-04, porque o runner não o adiciona. O runner monta a solicitação a partir de seus próprios parâmetros e deixa context_management de fora. Se esses parâmetros incluírem stop_sequences, um tool_choice do tipo any ou tool, ou um output_config.format de saída estruturada, a API rejeita a solicitação com um erro 400. Solicitar um resumo explica por quê. O runner se recusa a compactar enquanto seu context_management tiver uma edição de compactação, então use um único tipo de compactação em um runner.
Quando compactar
Você pode enviar uma solicitação de compactação após qualquer turno concluído, então é o seu código que decide quando.
Para estimar o tamanho da próxima solicitação, some input_tokens e output_tokens do usage da última resposta, como o loop faz. Com "prompt caching" (cache de prompt), input_tokens conta apenas os tokens após o último ponto de interrupção de cache, então some também cache_read_input_tokens e cache_creation_input_tokens. Você também pode enviar as mesmas mensagens para o endpoint de "token counting" (contagem de tokens).
Compare esse número com um limite que você escolher, abaixo da janela de contexto do modelo.
Escrever seu próprio prompt de sumarização
Sem instructions, a API usa seu próprio prompt de sumarização. Uma string instructions não vazia (de até 16.384 caracteres) substitui esse prompt por completo. Por exemplo:
{
"compaction": {
"type": "summarize",
"instructions": "Summarize this recipe app design conversation. Preserve every entity and field name agreed so far, and the user's latest open request. Do not call tools; respond with the summary text only."
}
}O sumarizador lê a conversa inteira, incluindo o pensamento anterior, com ou sem instructions. Em suas instructions, diga o que o resumo deve reter e instrua o modelo a não chamar ferramentas. A chamada de sumarização é executada sob as mesmas salvaguardas que qualquer outra solicitação.
Lidar com um resumo ausente ou um erro
Um resumo é produzido somente quando a chamada de sumarização termina normalmente com texto e sem chamada de ferramenta. Caso contrário, a resposta ainda é um 200 com content vazio, então verifique stop_reason antes de procurar o bloco. A chamada ainda é cobrada e informada em usage.iterations, com uso zero quando nenhuma chamada pôde ser feita. O stop_reason é aquele com o qual a chamada de sumarização terminou. Em todos os casos, você pode continuar sem um resumo e compactar mais tarde.
stop_reason | Causa | O que fazer |
|---|---|---|
"max_tokens" | O resumo foi cortado. | Reenvie com um max_tokens maior. |
"model_context_window_exceeded" | Não havia espaço para o prompt de sumarização. | Reenvie com instructions mais curtas ou menos mensagens. |
"tool_use" | O modelo chamou uma ferramenta em vez de escrever o resumo. | Reenvie com instructions que digam ao modelo para não chamar ferramentas. |
"refusal" | A solicitação foi recusada. | Continue sem um resumo. |
"end_turn" | A chamada não retornou nenhum texto. | Continue sem um resumo. |
A chamada de sumarização está sujeita às mesmas salvaguardas que suas outras solicitações. Após um "refusal", stop_details identifica a categoria de política por trás dele.
Erros
Uma solicitação de compactação, ou uma solicitação que carrega um bloco, também pode falhar completamente. A maioria dos erros 400 tem uma mensagem que diz o que remover ou reenviar. Alguns também trazem um error.details.error_code que começa com compaction_. Erros de parâmetro, como um campo que não pode ser combinado com compaction, trazem apenas a mensagem.
| Erro | Causa | O que fazer |
|---|---|---|
529 overloaded_error, error.details.error_code compaction_unavailable | Um problema transitório no servidor ao produzir um bloco, ou ao ler um que você enviou de volta. | Tente a solicitação novamente. |
400 compaction_block_misplaced | Mensagens resumidas permanecem antes do bloco. | Remova-as, para que o bloco venha primeiro em messages. |
400 compaction_signature_invalid ou compaction_content_mismatch | A signature ou o content do bloco foi alterado depois que a API o retornou. | Envie o bloco exatamente como retornado, incluindo sua signature. |
| 400 | A solicitação carrega mais de um bloco compaction. | Envie exatamente um, o mais recente. |
| 400 | O último turno assistant termina em uma chamada de ferramenta ainda sem resultado. | Envie os resultados de ferramentas desse turno e, em seguida, compacte. |
400 compaction_nothing_to_summarize | messages não tem conteúdo user ou assistant, por exemplo, uma lista vazia. | Envie pelo menos uma mensagem user ou assistant. |
400 na solicitação de compactação, com uma mensagem que diz que o parâmetro compaction requires anthropic-beta: compact-2026-09-04 | A solicitação de compactação deixou de fora o cabeçalho beta. | Adicione o cabeçalho beta; consulte Solicitar um resumo. |
400 em uma solicitação posterior que carrega o bloco: um erro de validação que diz que compaction não é um dos tipos de bloco de conteúdo esperados. A mensagem não menciona o cabeçalho | Essa solicitação deixou de fora o cabeçalho beta. | Adicione o cabeçalho beta a todas as solicitações que carregam o bloco; consulte Solicitar um resumo. |
Erro de validação 400, como messages.0.content.0.compaction.citations: Extra inputs are not permitted | Um bloco foi enviado de volta com campos que a API não retornou, como citations: null. | Envie o bloco exatamente como retornado; consulte Continuar a partir do resumo. |
Contabilizar o uso da compactação
A chamada de sumarização é cobrada e sujeita a "rate limits" (limites de taxa) como qualquer outra solicitação, e usage.iterations a informa como a entrada compaction. Os input_tokens e output_tokens de nível superior são zero porque nenhuma resposta foi gerada. Para contabilizar o que uma conversa consumiu, some os valores ao longo de usage.iterations, e não os campos de nível superior. Enviar um bloco de volta em solicitações posteriores não adiciona custo de compactação.
Você tem um loop funcional que compacta uma conversa e lida com um resumo ausente. Duas páginas mudam a forma como ele é executado, e você pode combiná-las: Compactação que mantém turnos recentes mantém os últimos turnos palavra por palavra, e Compactação em segundo plano permite que a conversa continue enquanto o resumo é escrito. Compactação e pensamento preservado se aplica se você enviar blocos de pensamento de volta e fizer qualquer uma das duas coisas.
Limites e interações com outros recursos
- Compactação por limite e edição de contexto. Você não pode enviar
compactionecontext_managementna mesma solicitação. A compactação por limite (compact_20260112) não pode ser executada em uma solicitação que carrega um bloco assinado. - Cache de prompt.
cache_controlno bloco coloca um ponto de interrupção após o resumo. - Mensagens de sistema no meio da conversa e alterações de ferramentas. Mensagens
role: "system"dentro do intervalo resumido também são resumidas, então suas instruções de texto deixam de se aplicar quando o bloco as substitui. Se uma instrução ainda for importante, declare-a novamente em uma mensagemrole: "system". Envie essa mensagem logo após seu próximo novo turnousere mantenha-a em seu histórico a partir de então. Para alterações de ferramentas, e para saber onde essa mensagem vai quando você mantém turnos após o bloco, consulte Alterar o prompt do sistema ou as ferramentas. - Orçamentos de tarefa. Não envie o valor
remainingde um orçamento de tarefa (output_config.task_budget.remaining) comcompactionou em solicitações que carregam o bloco. Fazer isso retorna um erro 400. - Contagem de tokens. O endpoint de contagem de tokens ignora o parâmetro
compaction. - Conteúdo que o resumo não consegue carregar. Imagens, documentos, blocos
container_uploade URLs buscadas dentro das mensagens resumidas desaparecem quando o bloco as substitui. Reafirme ou reenvie qualquer coisa de que um turno posterior ainda precise.
Compatibility
| Supported models |
|
|---|---|
| Supported platforms |
|
Was this page helpful?