Mensagens de sistema e alterações de ferramentas no meio da conversa
Altere instruções de sistema ou a disponibilidade de ferramentas no meio de uma conversa sem invalidar o prefixo em cache que veio antes delas.
As instruções de sistema normalmente ficam no campo system de nível superior, antes de todas as mensagens da conversa. Essa posição é ótima para o prompt caching (cache de prompt): o "system prompt" (prompt do sistema) faz parte do prefixo estável, então os turnos subsequentes atingem o cache. Mas é uma posição ruim para instruções cuja necessidade você só descobre no meio de uma sessão. Editar o campo system de nível superior altera o próprio início do prompt e invalida o cache de tudo o que vem depois.
As mensagens de sistema no meio da conversa resolvem esse problema. Em vez de editar o campo system de nível superior, você anexa uma mensagem {"role": "system"} no ponto da conversa em que a nova instrução se torna relevante. O prefixo em cache permanece o mesmo, então a próxima requisição ainda o lê do cache. A nova instrução continua sendo aplicada como uma instrução de sistema, e não como texto comum do usuário.
Alterações de ferramentas no meio da conversa
O array tools fica ainda mais cedo no prefixo da requisição usado no hash do que o campo system de nível superior, então editá-lo invalida o cache de prompt da conversa inteira. As alterações de ferramentas no meio da conversa são o equivalente, para ferramentas, das mensagens do sistema no meio da conversa. Em vez de fixar a lista de ferramentas durante toda a vida da conversa, você altera quais ferramentas são oferecidas ao modelo entre os turnos: declare o conjunto completo de ferramentas em tools desde o início e, em seguida, use blocos tool_addition e tool_removal para oferecer uma ferramenta ao modelo, ou retirá-la, a partir de um ponto específico da conversa em diante. O próprio array tools nunca muda, então o prefixo em cache permanece intacto. As alterações de ferramentas no meio da conversa estão em beta e usam o cabeçalho beta inline-tools-2026-09-15 na Claude API.
tool_addition e tool_removal são blocos de conteúdo no array content de uma mensagem role: "system", e podem ser combinados com blocos text na mesma mensagem. A mensagem segue as regras de posicionamento de qualquer mensagem do sistema no meio da conversa, com uma restrição extra após um turno pausado (consulte Limitações), e a alteração se aplica daquele ponto da conversa em diante. O campo tool de cada bloco referencia uma ferramenta em vez de defini-la: {"type": "tool_reference", "name": "..."} nomeia uma ferramenta declarada no array tools da requisição, e as ferramentas do conector MCP podem ser referenciadas individualmente com mcp_tool_reference (server_name e name) ou como um conjunto de ferramentas inteiro com mcp_toolset_reference (server_name). Referenciar um nome que não está declarado em tools retorna um erro 400 (na Claude API, com error.details.error_code definido como tool_reference_unresolved). Um bloco tool_addition pode, em vez disso, conter a definição completa da ferramenta, o que o cabeçalho mid-conversation-tool-changes-2026-07-01 não suporta.
Toda ferramenta declarada em tools é oferecida ao modelo desde o início da conversa, a menos que seja declarada com defer_loading: true, o que a mantém retida até que um bloco tool_addition a exponha. tool_addition também volta a oferecer uma ferramenta que um tool_removal anterior retirou.
A requisição a seguir declara get_weather em tools e, em seguida, a retira após o primeiro turno do usuário com um bloco tool_removal. A requisição envia o cabeçalho beta inline-tools-2026-09-15.
client = anthropic.Anthropic()
response = client.beta.messages.create(
model="claude-opus-5-5",
max_tokens=1024,
betas=["inline-tools-2026-09-15"],
# O conjunto completo de ferramentas é declarado de antemão e nunca muda, então o
# prefixo em cache permanece intacto.
tools=[
{
"name": "get_weather",
"description": "Get the current weather for a location.",
"input_schema": {
"type": "object",
"properties": {
"location": {"type": "string", "description": "City name"},
},
"required": ["location"],
},
},
],
messages=[
{
"role": "user",
"content": "Say OK.",
},
# Retire get_weather a partir deste ponto. O bloco referencia
# a ferramenta pelo nome em vez de editar `tools`, então os turnos anteriores ficam
# idênticos byte a byte e o cache continua sendo aproveitado.
{
"role": "system",
"content": [
{
"type": "tool_removal",
"tool": {"type": "tool_reference", "name": "get_weather"},
},
],
},
],
)
for block in response.content:
if block.type == "text":
print(block.text)Definir ferramentas em uma mensagem (beta)
Com o cabeçalho beta inline-tools-2026-09-15, um bloco tool_addition pode definir uma ferramenta por valor, contendo sua definição completa, em vez de nomeá-la por referência. Isso permite introduzir uma ferramenta que é desconhecida no início da conversa, ou cujo schema muda depois, acrescentando uma mensagem role: "system". O array tools e todas as mensagens anteriores permanecem exatamente como foram enviados, então o cache de prompt continua sendo atingido e apenas a mensagem acrescentada é processada como nova entrada. A única exceção, um array tools sem nenhuma ferramenta não adiada, é tratada nas regras abaixo. O cabeçalho também cobre a adição e a remoção de ferramentas por referência, então você não precisa enviar também mid-conversation-tool-changes-2026-07-01.
Envolva a definição em um objeto tool do tipo tool_definition. A definition é uma entrada de tools, como uma ferramenta personalizada ou uma ferramenta de cliente ou de servidor definida pela Anthropic, com sua configuração habitual, incluindo cache_control e defer_loading. Durante o beta, alguns tipos de ferramenta (entre eles a ferramenta de uso do computador) ainda não podem ser definidos em uma mensagem e retornam um erro 400 informando isso; declare-os em tools e adicione-os por referência. Por exemplo, para definir uma ferramenta personalizada no meio da conversa:
{
"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"]
}
}
}
}
]
}Dessa posição em diante, o modelo pode chamar a ferramenta da mesma forma que chama uma ferramenta declarada em tools. Enviar novamente uma definição idêntica não altera nada, então um cliente pode reenviá-la com segurança, por exemplo em uma nova tentativa.
A requisição a seguir mantém get_weather em tools e define db_query após o primeiro turno do usuário:
client = anthropic.Anthropic()
response = client.beta.messages.create(
model="claude-opus-5-5",
max_tokens=1024,
betas=["inline-tools-2026-09-15"],
# Mantenha pelo menos uma ferramenta não adiada em `tools`, para que uma ferramenta definida
# depois não altere o início do prompt renderizado.
tools=[
{
"name": "get_weather",
"description": "Get the current weather for a location.",
"input_schema": {
"type": "object",
"properties": {
"location": {"type": "string", "description": "City name"},
},
"required": ["location"],
},
},
],
messages=[
{"role": "user", "content": "How many orders shipped yesterday?"},
# Defina db_query por valor a partir daqui. `tools` e as
# mensagens anteriores ficam exatamente como enviadas, então o cache ainda é atingido.
{
"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"],
},
},
},
},
],
},
],
)
for block in response.content:
if block.type == "tool_use":
print(block.name, block.input)O content da resposta inclui um bloco tool_use para a nova ferramenta, por exemplo:
{
"type": "tool_use",
"id": "toolu_01A09q90qw90lq917835lq9",
"name": "db_query",
"input": {
"sql": "SELECT COUNT(*) FROM orders WHERE shipped_at::date = CURRENT_DATE - 1"
}
}Para alterar o schema de uma ferramenta, ou para mover uma ferramenta de servidor para uma versão mais recente, envie uma definição diferente com o mesmo nome. A nova definição substitui a anterior dessa posição em diante. Uma definição que reutiliza o nome de um tipo diferente de ferramenta retorna um erro 400 com error.details.error_code definido como tool_name_conflict. Uma versão mais recente da mesma ferramenta não conta como um tipo diferente. tool_removal continua recebendo uma referência, e uma ferramenta removida pode ser definida ou oferecida novamente mais tarde.
Algumas regras decorrem de onde a definição é renderizada:
- Declare desde o início o que você já sabe. Uma ferramenta que você conhece na primeira requisição pertence a
tools, comdefer_loading: truee uma referênciatool_additionposterior se o modelo ainda não deve vê-la. Defina por valor apenas o que é desconhecido na primeira requisição ou muda depois. - Mantenha pelo menos uma ferramenta não adiada em
tools. Uma conversa cujo arraytoolsnão tem nenhuma ferramenta não adiada é aceita, mas a primeira ferramenta que ela define por valor altera o início do prompt renderizado, o que custa uma falha completa de cache nessa requisição. Uma ferramenta de busca de ferramentas conta como não adiada. - Tipos de ferramenta com data mantêm seus próprios cabeçalhos beta. Se uma ferramenta de servidor que você define por valor exige seu próprio cabeçalho beta, envie esse cabeçalho em todas as requisições posteriores da conversa.
cache_controlvai no bloco ou na definição, não em ambos, e conta para o limite de pontos de interrupção da requisição. Uma definição adiada não pode contercache_control.
Uma requisição retorna um erro 400 com error.details.error_code definido como available_tools_limit_exceeded quando qualquer um destes limites é excedido:
- Mais de 10.000 ferramentas adiadas estão disponíveis após qualquer mensagem.
- Mais de 10.000 ferramentas definidas após a primeira mensagem do usuário estão disponíveis após qualquer mensagem.
- As definições de ferramentas enviadas após a primeira mensagem do usuário que ainda estão disponíveis após qualquer mensagem totalizam mais de 4 MB (4.194.304 bytes).
- O texto renderizado das ferramentas é maior que 4 MB (4.194.304 bytes).
Adicionar um servidor MCP no meio da conversa (beta)
Para adicionar um servidor do conector MCP no meio de uma conversa, envie o cabeçalho beta mcp-client-2026-09-15 junto com inline-tools-2026-09-15. A definition em um bloco tool_addition pode então ser um mcp_toolset, de modo que as ferramentas do servidor ficam disponíveis sem editar tools. Liste os detalhes de conexão do servidor em mcp_servers como de costume e, em seguida, acrescente o conjunto de ferramentas no ponto em que o servidor ficou disponível:
{
"role": "system",
"content": [
{
"type": "tool_addition",
"tool": {
"type": "tool_definition",
"definition": { "type": "mcp_toolset", "mcp_server_name": "calendar" }
}
}
]
}O objeto mcp_toolset é o mesmo que você colocaria em tools, incluindo default_config e configs. Um bloco tool_addition nunca contém uma URL ou um token de servidor. Esses ficam em mcp_servers.
A requisição a seguir mantém get_weather em tools, lista o servidor de calendário em mcp_servers e adiciona o conjunto de ferramentas do servidor após o primeiro turno do usuário:
client = anthropic.Anthropic()
response = client.beta.messages.create(
model="claude-opus-5-5",
max_tokens=1024,
betas=["inline-tools-2026-09-15", "mcp-client-2026-09-15"],
mcp_servers=[
{
"type": "url",
"url": "https://mcp.example.com/calendar",
"name": "calendar",
"authorization_token": "YOUR_TOKEN",
},
],
tools=[
{
"name": "get_weather",
"description": "Get the current weather for a location.",
"input_schema": {
"type": "object",
"properties": {
"location": {"type": "string", "description": "City name"},
},
"required": ["location"],
},
},
],
messages=[
{"role": "user", "content": "What's on my calendar tomorrow?"},
# Disponibiliza as ferramentas do servidor de calendário a partir deste ponto.
# O bloco nomeia o servidor; ele nunca contém uma URL ou token.
{
"role": "system",
"content": [
{
"type": "tool_addition",
"tool": {
"type": "tool_definition",
"definition": {
"type": "mcp_toolset",
"mcp_server_name": "calendar",
},
},
},
],
},
],
)
# A resposta começa com um bloco mcp_tool_listing para o servidor de calendário,
# então verifique o tipo de cada bloco em vez de ler content[0].
for block in response.content:
match block.type:
case "mcp_tool_listing":
print(block.mcp_server_name, [tool.name for tool in block.tools])
case "text":
print(block.text)Com mcp-client-2026-09-15, uma resposta para a qual a API buscou a lista de ferramentas de um servidor começa com um bloco mcp_tool_listing, um para cada servidor buscado. Se o seu código lê content[0], ignore esses blocos. Envie a mensagem do assistente de volta sem alterações, incluindo esse bloco, e continue enviando mcp-client-2026-09-15 em todas as requisições que o contêm. As requisições posteriores passam então a usar a lista registrada em vez de consultar o servidor novamente. Para fixar um conjunto de ferramentas você mesmo, copie essa lista para o campo tools do mcp_toolset, conforme descrito em Fixar a lista de ferramentas de um servidor MCP.
mcp-client-2026-09-15 inclui tudo o que mcp-client-2025-11-20 inclui, então você não precisa enviar ambos. Esses recursos estão disponíveis na Claude API. As requisições que usam o conector MCP mantêm os termos de retenção de dados do conector.
Quando usar uma mensagem de sistema no meio da conversa
O cache de prompt calcula o hash do prefixo da requisição em ordem: tools, depois system, depois messages. Um acerto de cache exige que o prefixo corresponda exatamente a uma requisição recente, byte a byte, até o ponto de interrupção do cache.
Essa ordenação significa que o campo system de nível superior fica perto do início do prefixo com hash. Qualquer alteração nele, mesmo anexar uma frase, produz um hash diferente, e a requisição perde o cache do prompt do sistema e de todas as mensagens em cache depois dele.
As mensagens de sistema no meio da conversa permitem que você adicione a instrução no final do histórico de mensagens. Tudo antes da nova instrução permanece inalterado, então a entrada de cache existente ainda corresponde, e apenas a nova mensagem é processada como entrada nova.
Algumas situações em que isso importa:
- Mudanças de política ou persona no meio da sessão. Uma longa sessão agêntica precisa de uma nova restrição ("de agora em diante, escreva todo SQL como consultas parametrizadas") após dezenas de turnos em cache. Adicioná-la ao campo
systemde nível superior reprocessaria todo o histórico. - Contexto por turno que precisa ser autoritativo. Você quer injetar uma nota de atualidade, um prazo de sessão ou uma mudança de disponibilidade de ferramentas com peso de nível de sistema, e isso muda com frequência demais para ficar no prefixo em cache.
- Lembretes por turno que não devem se acumular. Um harness dá um toque no modelo após cada lote de resultados de ferramentas ("solicite leituras independentes juntas", "o usuário não recebe notícias suas há algum tempo") e quer que o modelo veja apenas a cópia mais recente. Uma mensagem de sistema com escopo de turno é renderizada por um turno e depois não custa nada, sem excluir nada do histórico.
- Mudanças de estado que sua aplicação observa. Sua aplicação percebe algo que Claude deve tratar como um fato de nível de operador: arquivos mudaram no disco, o usuário alternou uma configuração de aprovação automática, as ferramentas disponíveis mudaram ou o orçamento de tokens restante caiu abaixo de um limite.
- Entrada do usuário que não deve interromper um loop agêntico. Um usuário digita uma mensagem de acompanhamento enquanto Claude ainda está executando ferramentas para a requisição anterior. Repassá-la como uma mensagem do sistema após o próximo resultado de ferramenta permite que Claude incorpore a nova entrada ao trabalho que já está fazendo, em vez de tratá-la como uma nova requisição para a qual mudar. No Claude Sonnet 5.5 e no Claude Haiku 5.5, em vez disso, anexe as palavras do usuário como um bloco
textapós o últimotool_resultna mesma mensagemuser. Consulte Posicionamento após resultados de ferramentas. - Mudanças de modo que concedem permissões permanentes. Um modo de nível de sessão pode usar uma mensagem de sistema no meio da conversa para conceder consentimento permanente a uma capacidade cara, como iniciar automaticamente fluxos de trabalho multiagente, com um breve lembrete a cada vários turnos e um aviso de saída quando o modo é desativado. Para um exemplo completo, consulte Construir um modo de orquestração.
Em todos esses casos, você poderia colocar a instrução em uma mensagem user comum, e Claude segue instruções que chegam em turnos de usuário. A diferença é a prioridade: uma mensagem user é tratada como vinda do usuário final, enquanto uma mensagem system é tratada como vinda de você, o operador da aplicação. Quando as duas entram em conflito, as instruções de sistema têm precedência, então use o papel system para fatos e restrições de nível de operador que devem valer mesmo que o usuário final peça algo diferente. Uma mensagem de sistema no meio da conversa mantém essa prioridade de nível de operador sem pagar o custo de perda de cache de editar o campo system de nível superior.
Como funciona
Adicione uma mensagem com "role": "system" ao array messages. Use uma string simples ou blocos de conteúdo para content, da mesma forma que em um turno user ou assistant. A instrução se aplica daquele ponto da conversa em diante. Quando as instruções entram em conflito, mensagens de sistema posteriores têm precedência sobre as anteriores, e as mensagens de sistema no meio da conversa têm precedência sobre o campo system de nível superior nos turnos que as seguem.
Você ainda pode definir o campo system de nível superior para instruções que devem se aplicar à conversa inteira. Reserve as mensagens de sistema no meio da conversa para instruções que só se tornam relevantes mais tarde, ou que você quer adicionar sem invalidar o prefixo em cache.
Uma mensagem role: "system" também pode conter output_config.effort para alterar o nível de esforço no meio de uma conversa. Isso está em beta no Claude Fable 5.1, Claude Mythos 5.1, Claude Opus 5.5, Claude Opus 5, Claude Sonnet 5.5 e Claude Haiku 5.5 na Claude API e no Google Cloud, e exige o cabeçalho beta mid-conversation-output-config-2026-07-01. No Amazon Bedrock, está em beta no Claude Fable 5.1, Claude Mythos 5.1 e Claude Opus 5.5, com o mesmo valor beta. O Claude Opus 5 não oferece suporte a isso no Amazon Bedrock. Consulte Esforço por mensagem.
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-opus-5-5",
max_tokens=1024,
# Cache de prompt automático: cada requisição armazena em cache a conversa até aqui,
# e a próxima requisição lê do cache o prefixo inalterado.
cache_control={"type": "ephemeral"},
system="You are a code review assistant. Be concise.",
messages=[
{
"role": "user",
"content": "Review process() in utils.py for performance issues.",
},
{
"role": "assistant",
"content": "The list comprehension is fine for small inputs. For large inputs, consider a generator to avoid materializing the full list.",
},
{
"role": "user",
"content": "Now review the calling code that invokes process().",
},
# O revisor percebe no meio da sessão que todas as sugestões também
# precisam passar pela política de tipagem estrita da equipe. Anexar a
# instrução aqui mantém os turnos anteriores idênticos byte a byte, então o
# prefixo armazenado em cache pela requisição anterior ainda é lido do cache.
{
"role": "system",
"content": "From now on, every suggestion must include explicit type annotations.",
},
],
)
for block in response.content:
if block.type == "text":
print(block.text)Este exemplo ativa o cache automático com o campo cache_control de nível superior. O cache de prompt é opcional: se uma requisição não tem nenhum campo cache_control (automático ou um ponto de interrupção explícito), nada é armazenado em cache e cada requisição paga o preço normal de tokens de entrada pela conversa completa. Com o cache ativado, acrescentar a mensagem de sistema deixa inalterados os turnos já em cache, então a requisição que contém a nova instrução ainda os lê do cache em vez de processá-los novamente. O cache também exige que a conversa atinja o tamanho mínimo de prompt armazenável em cache; um exemplo tão curto quanto este fica abaixo dele, então cache_creation_input_tokens e cache_read_input_tokens permanecem em 0 até que a conversa cresça.
Uma mensagem de sistema no meio da conversa que contém conteúdo (blocos text, tool_addition ou tool_removal) deve vir imediatamente após um turno user (ou um turno assistant que termina em um resultado de ferramenta de servidor) e deve ser a última entrada em messages ou ser imediatamente seguida por um turno assistant. Uma mensagem user que contém blocos tool_result conta: em um loop agêntico, você pode colocar a mensagem de sistema logo após os resultados das ferramentas, antes do próximo turno de Claude. Qualquer outra posição para uma mensagem que contém conteúdo, incluindo entre um bloco tool_use de assistant e o tool_result que o responde, retorna um erro 400. Uma mensagem com content vazio que apenas define output_config.effort é aceita em qualquer lugar de messages. Mensagens system consecutivas são avaliadas em conjunto, então uma mensagem apenas de esforço ao lado de uma que contém conteúdo segue a regra de conteúdo.
Posicionamento após resultados de ferramentas
Em um loop agêntico, a mensagem do sistema vai após a mensagem user que entrega os resultados das ferramentas. Na maioria dos modelos, este também é o lugar onde sua aplicação pode repassar a entrada que o usuário digitou enquanto Claude estava trabalhando, para que o novo contexto seja absorvido sem reiniciar o turno (para o Claude Sonnet 5.5 e o Claude Haiku 5.5, consulte o final desta seção):
[
{ "role": "user", "content": "Run the test suite and fix any failures." },
{
"role": "assistant",
"content": [{ "type": "tool_use", "id": "toolu_01", "name": "run_tests", "input": {} }]
},
{
"role": "user",
"content": [
{ "type": "tool_result", "tool_use_id": "toolu_01", "content": "12 passed, 0 failed" }
]
},
{
"role": "system",
"content": "The user sent the following message while you were working: also update the changelog before you finish."
}
]Formule o conteúdo de sistema como contexto, e não como um comando que sobrepõe o usuário. Declare o fato ("nova entrada chegou do usuário: X", "o orçamento de tokens restante agora é Y") e deixe Claude agir com base nele. Claude é treinado para resistir a instruções que parecem agir contra o usuário, e essa proteção ainda se aplica ao papel de sistema, então linguagem como "ignore o que o usuário disse" é menos eficaz do que declarar o que mudou.
Esse padrão serve para repassar entrada do próprio usuário final da conversa. Não o use para passar saída de ferramentas, documentos recuperados ou outro conteúdo de terceiros; mantenha esse conteúdo em blocos tool_result (consulte Limitações).
No Claude Sonnet 5.5 e no Claude Haiku 5.5, entregue as palavras do usuário no turno do usuário em vez disso. Esses modelos são treinados para resistir a injeção de prompt por meio de resultados de ferramentas, então podem tratar uma mensagem do sistema colocada logo após um resultado de ferramenta como texto não confiável e ignorá-la. Anexe as palavras do usuário como um bloco text após o último tool_result na mesma mensagem user. Mantenha os avisos do harness, como lembretes, em uma mensagem do sistema no meio da conversa separada após essa mensagem user, e nunca coloque um aviso e as palavras do usuário no mesmo bloco:
[
{ "role": "user", "content": "Run the test suite and fix any failures." },
{
"role": "assistant",
"content": [{ "type": "tool_use", "id": "toolu_01", "name": "run_tests", "input": {} }]
},
{
"role": "user",
"content": [
{ "type": "tool_result", "tool_use_id": "toolu_01", "content": "12 passed, 0 failed" },
{ "type": "text", "text": "Also update the changelog before you finish." }
]
}
]Para saber mais sobre esse comportamento, consulte Como escrever prompts para o Claude Sonnet 5.5 e Prompting do Claude Haiku 5.5.
Mensagens de sistema com escopo de turno
Para limitar o escopo de uma mensagem role: "system" ao turno atual, defina seu campo clear_at. Ele aceita um de dois valores:
"never"(o padrão): a mensagem é renderizada em sua posição em todas as requisições que a incluem. Omitir o campo tem o mesmo efeito."next_user_message": a mensagem tem escopo de turno. Seu texto é renderizado apenas enquanto nenhuma mensagemrole: "user"vier depois dela emmessages. Uma mensagem do usuário que contém apenas blocostool_resultconta como mensagem do usuário aqui. Assim que existe uma mensagem do usuário posterior, a mensagem é limpa: ela permanece no array, mas não renderiza nada e não custa tokens de entrada, nessa requisição e em todas as posteriores.
As mensagens de sistema com escopo de turno estão em beta. Inclua o cabeçalho beta mid-conversation-system-clear-at-2026-08-21. Sem ele, clear_at é rejeitado como campo desconhecido.
{
"role": "system",
"clear_at": "next_user_message",
"content": "First privately list what you need next; then request every item that doesn't depend on another's result in this one response."
}O uso principal é um lembrete por turno em um loop de ferramentas. Anexe o lembrete após a mensagem tool_result sempre que quiser que o modelo o veja, e deixe todas as cópias anteriores onde estão. O modelo vê apenas as cópias que vêm após a última mensagem do usuário, então o lembrete nunca se acumula. Nada anterior em messages muda, então o cache de prompt continua correspondendo. No Claude Fable 5.1, Claude Opus 5.5, Claude Sonnet 5.5 e Claude Haiku 5.5, isso também mantém os blocos de pensamento posteriores válidos: excluir um lembrete anterior alteraria a conversa antes desses blocos e faria a verificação da conversa falhar, enquanto uma mensagem limpa permanece no array e deixa essa conversa inalterada.
A requisição a seguir é uma etapa posterior de um loop de agente. messages[3] foi renderizada na requisição anterior, quando era a última mensagem do array. Assim que messages[5] (uma mensagem do usuário posterior) existe, messages[3] é limpa: a mensagem limpa permanece no array, então a conversa antes do bloco de pensamento em messages[4] fica inalterada, mas o modelo não vê mais seu texto. messages[6] e messages[7] são ambas renderizadas, em ordem.
{
"model": "claude-fable-5-1",
"max_tokens": 16000,
"messages": [
{ "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": "test_auth.py" }
}
]
},
{
"role": "user",
"content": [{ "type": "tool_result", "tool_use_id": "toolu_01", "content": "..." }]
},
{
"role": "system",
"clear_at": "next_user_message",
"content": "Request independent reads in one turn."
},
{
"role": "assistant",
"content": [
{ "type": "thinking", "thinking": "", "signature": "..." },
{
"type": "tool_use",
"id": "toolu_02",
"name": "read_file",
"input": { "path": "auth.py" }
},
{
"type": "tool_use",
"id": "toolu_03",
"name": "read_file",
"input": { "path": "tokens.py" }
}
]
},
{
"role": "user",
"content": [
{ "type": "tool_result", "tool_use_id": "toolu_02", "content": "..." },
{
"type": "tool_result",
"tool_use_id": "toolu_03",
"content": "...",
"cache_control": { "type": "ephemeral" }
}
]
},
{
"role": "system",
"clear_at": "next_user_message",
"content": "Request independent reads in one turn."
},
{
"role": "system",
"clear_at": "next_user_message",
"content": "The shell exited with status 137."
}
]
}Regras para mensagens com escopo de turno:
- Reenvie as mensagens limpas literalmente. Uma mensagem limpa ainda faz parte do histórico da conversa. Reconstruí-la a partir do estado atual (uma nova contagem de tokens, um timestamp), descartá-la como redundante ou alterar seu valor de
clear_até uma edição de uma mensagem anterior. O cache de prompt falha a partir desse ponto e, no Claude Fable 5.1, Claude Opus 5.5, Claude Sonnet 5.5 e Claude Haiku 5.5, todo bloco de pensamento produzido depois dela falha na verificação da conversa. - Somente texto.
contenté um ou mais blocostext(ou uma string). Blocostool_additionetool_removalretornam um erro 400 em uma mensagem com escopo de turno, assim comooutput_config. Para esses, use uma mensagemrole: "system"separada, semclear_at. - Sem
cache_controlem seus blocos. Uma mensagem limpa nunca faz parte de uma chave de cache, então um breakpoint nela nunca poderia corresponder. Coloque o breakpoint no último bloco do turno do usuário anterior, como faz o exemplo. O campo de cache automático de nível superior ignora mensagens com escopo de turno ao escolher um breakpoint. Na requisição que limpa uma mensagem, o prefixo em cache reutilizável termina no turno do usuário anterior a ela, então apenas o único turno do assistente entre essa mensagem e a nova mensagem do usuário é reprocessado. - As regras de posicionamento continuam valendo, limpa ou não. Uma mensagem com escopo de turno deve vir após um turno
user(ou um turnoassistantque termina em um resultado de ferramenta de servidor) e preceder um turnoassistantou encerrar o array, como qualquer mensagem do sistema no meio da conversa. Uma que encerra o array é sempre renderizada. Uma seguida diretamente por outra mensagemuseré um erro 400, e não uma mensagem limpa: coloque todos os resultados de uma rodada de ferramentas em uma única mensagem do usuário e os lembretes depois dela. - Turnos do assistente não a limpam. Um turno do assistente pré-preenchido ou pausado após a mensagem, ou um loop de ferramentas do lado do servidor, não adiciona nenhuma mensagem do usuário, então a mensagem continua sendo renderizada nessa continuação. Para manter um lembrete visível ao longo de um loop de ferramentas do lado do cliente, acrescente-o novamente após cada mensagem
tool_result. - A contagem de tokens segue o que é renderizado. Uma mensagem limpa não adiciona nada a
usage.input_tokensnem a uma contagem de tokens. - Histórico importado. Em uma transcrição que você constrói de uma só vez (exemplos few-shot, uma conversa migrada), uma mensagem com escopo de turno que já tem um turno do assistente e uma mensagem do usuário depois dela é limpa desde a primeira requisição e nunca é renderizada. Esse é o estado correto para um lembrete por turno que você está trazendo. Deixe
clear_atsem definir apenas em uma mensagem que o modelo deve ver em todas as requisições.
Os erros de validação são:
messages.3.clear_at: Extra inputs are not permitted
messages.3.clear_at: clear_at is only permitted on role 'system' messages
messages.3.clear_at: Input should be 'next_user_message' or 'never'
messages.3: a turn-scoped system message supports text blocks only (clear_at: 'next_user_message')
messages.3: output_config is not permitted on a turn-scoped system message (clear_at: 'next_user_message')
messages.3.content.0: cache_control is not permitted on a turn-scoped system message (clear_at: 'next_user_message')O primeiro é o erro retornado sem o cabeçalho beta. No Google Cloud e no Claude no Amazon Bedrock, envie o valor beta no cabeçalho anthropic-beta, como na Claude API (consulte Cabeçalhos beta). Com a InvokeModel API do Amazon Bedrock, coloque-o no array anthropic_beta do corpo da requisição.
Pelo SDK, defina clear_at na entrada role: "system" em messages e envie o cabeçalho beta. O exemplo a seguir anexa um lembrete com escopo de turno após o turno do usuário; na próxima requisição, assim que existir uma mensagem do usuário posterior, o lembrete permanece no array, mas não é mais renderizado:
client = anthropic.Anthropic()
response = client.beta.messages.create(
model="claude-fable-5-1",
max_tokens=4096,
messages=[
{
"role": "user",
"content": "Draft a short status update on the database migration for the team channel.",
},
# Lembrete com escopo de turno: é renderizado neste turno e removido quando houver uma mensagem posterior do usuário.
{
"role": "system",
"clear_at": "next_user_message",
"content": "The reader is on call: keep this reply under 50 words.",
},
],
betas=["mid-conversation-system-clear-at-2026-08-21"],
)
for block in response.content:
if block.type == "text":
print(block.text)Combinando com cache de prompt
As mensagens de sistema no meio da conversa e o cache de prompt foram projetados para serem usados em conjunto:
- Habilite o cache explicitamente. O cache só acontece quando a requisição inclui
cache_control, seja o campo de nível superior de cache automático ou um ponto de interrupção explícito em um bloco de conteúdo. Uma mensagem de sistema no meio da conversa não cria uma entrada de cache por conta própria e, sem o cache habilitado, não há economia a preservar. - Armazene em cache o prefixo estável como de costume. Coloque
cache_controlno último bloco que permanece o mesmo entre as requisições, seja o final do camposystemde nível superior, o final das suas definições de ferramentas ou um ponto estável no histórico de mensagens. - Anexe a mensagem de sistema após o ponto de interrupção. Como ela vem depois do prefixo em cache, ela não altera o hash do prefixo e o cache ainda é atingido.
- Uma mensagem de sistema no meio da conversa também pode ser armazenada em cache. Uma vez na conversa, ela passa a fazer parte do histórico estável. No próximo turno, você pode mover seu ponto de interrupção de cache para depois dela (ou contar com o cache automático para fazer isso) e a mensagem de sistema é lida do cache como qualquer outro turno.
Evite editar ou remover uma mensagem do sistema no meio da conversa que já foi enviada. Como qualquer outra alteração em mensagens anteriores, isso invalida o cache a partir desse ponto. No Claude Fable 5.1, Claude Opus 5.5, Claude Sonnet 5.5 e Claude Haiku 5.5, isso também invalida os blocos de pensamento em todos os turnos posteriores do assistente. Para orientações que devem se aplicar a apenas um turno, use uma mensagem do sistema com escopo de turno e deixe-a no lugar. Se a instrução precisar evoluir, anexe uma nova mensagem do sistema em vez de reescrever a antiga. Mensagens do sistema consecutivas são aceitas e tratadas como uma única seção de sistema, que segue a mesma regra de posicionamento como um todo.
Limitações
- Não serve para a primeira mensagem. Uma mensagem
systemque contém conteúdo não pode ser a primeira entrada emmessages. Use o camposystemde nível superior para instruções que se aplicam desde o início. - O posicionamento é restrito. Uma mensagem
systemque contém conteúdo (blocostext,tool_additionoutool_removal) deve vir imediatamente após um turnouser(incluindo um turnouserque contém blocostool_result) ou um turnoassistantque termina em um resultado de ferramenta de servidor, e deve preceder um turnoassistantou encerrar o array. Ela não pode ficar entre um blocotool_usee seutool_result. Colocá-la em outro lugar retorna um erro 400. Uma exceção: blocostool_additionetool_removalnão são aceitos imediatamente após um turnoassistantpausado (um que termina em um resultado de ferramenta de servidor), embora blocostextsejam; retome primeiro o turno pausado e, em seguida, envie a alteração de ferramenta na próxima mensagemsystem. Uma mensagem comcontentvazio que apenas defineoutput_config.effortnão renderiza nada em sua posição e é aceita em qualquer lugar demessages, inclusive como primeira entrada ou entre um turnoassistante um turnouser. Mensagenssystemconsecutivas são avaliadas em conjunto, então adicionar uma mensagem com texto ao lado de uma que define apenas o esforço faz com que o grupo inteiro siga a regra de conteúdo. - Mensagens com escopo de turno contêm apenas texto e são reenviadas literalmente. Uma mensagem
clear_at: "next_user_message"não contémtool_addition,tool_removal,output_confignemcache_controle, depois de limpa, deve permanecer emmessagesbyte a byte nas requisições posteriores. Consulte Mensagens do sistema com escopo de turno. - Não é lugar para conteúdo não confiável. O Claude trata o conteúdo do sistema como instruções do operador e as segue. Não coloque texto de fora da conversa, como saídas brutas de ferramentas, documentos recuperados ou conteúdo da web, diretamente em uma mensagem do sistema; fazer isso dá a esse texto autoridade de nível de operador. Mantenha esses dados em blocos
tool_resulte continue seguindo Mitigar jailbreaks e injeções de prompt.
Relacionado
Como o cache funciona, onde colocar pontos de interrupção e como ler os campos de uso de cache.
Descubra exatamente onde duas requisições divergiram quando um acerto de cache que você esperava não acontece.
Estrutura de mensagens, conversas de múltiplos turnos e o campo system.
Escrevendo prompts e instruções de sistema eficazes.
Como os blocos tool_use e tool_result são estruturados no array messages.
Was this page helpful?