Cada passo de um agente com ferramentas costuma enviar de novo as mesmas definições de tools, o mesmo system prompt e o histórico que já existia. Sem cache de prefixo, o provedor processa esse bloco como input novo. Com cache, ele reutiliza o trecho idêntico e cobra (e processa) sobretudo o que mudou: o tool result, a resposta do assistente e a próxima pergunta.

Prompt caching é o reuso de um prefixo idêntico entre requisições da API. Em um loop de agentes, isso não é um detalhe de fatura. É um contrato de layout: o que permanece igual fica no começo; o que muda a cada passo fica no final; e o harness registra se o hit realmente aconteceu.

Se você ainda está cortando tokens do harness, comece pelo orçamento de contexto em agentes de código. O orçamento decide o que entra. O caching decide quanto desse bloco estável você paga de novo em cada tool step.

Diagrama mostra prefixo estável de tools e system, cache hit, cauda nova com tool result e próximo passo do loop.

Resultado prático

  • Prefixo estável: tools + system + exemplos fixos no início.
  • Cauda dinâmica: tool results, timestamps e pedido atual no final.
  • Medição: logar tokens lidos do cache e tokens escritos no cache a cada passo.
  • Falha comum: timestamp, tool list reordenada ou system mutável no prefixo.

O que o prompt caching reutiliza no loop do agente?

Nos provedores atuais, o cache opera sobre um prefixo exato. A OpenAI descreve o comportamento como match de prefixo idêntico no início do prompt, com caching automático para prompts elegíveis a partir de cerca de 1.024 tokens, e com tools, mensagens e structured outputs podendo entrar nesse prefixo (OpenAI, "Prompt caching", consultado em 06/08/2026).

A Anthropic documenta a mesma ideia com ordem fixa de construção do prefixo: tools, depois system, depois messages, até o bloco marcado com cache_control. A documentação lista o uso agentic com várias tool calls como um dos cenários em que o cache reduz custo e latência, porque cada passo costuma ser uma nova chamada de API (Anthropic, "Prompt caching", consultado em 06/08/2026).

Em termos de sistema, o loop típico fica assim:

  1. Enviar tools + system + tarefa.
  2. Receber tool_use.
  3. Executar a ferramenta no seu runtime.
  4. Reenviar o histórico com o tool_result.
  5. Repetir até a resposta final ou o limite de passos.

O passo 4 é onde o cache importa. Se tools e system forem byte a byte iguais aos do passo anterior, o prefixo pode ser lido do cache. Se qualquer parte estável mudar, o hit some e você volta a pagar o prefixo inteiro.

Isso complementa o context engineering para agentes de código: ali você reduz o que entra; aqui você reutiliza o que precisa permanecer.

Como estruturar tools, system e histórico para acertar o hit?

Trate o prompt como duas zonas.

Zona estável (prefixo): nomes e schemas de ferramentas, system prompt, políticas, exemplos fixos, documentos de referência que não mudam a cada passo. Coloque essa zona no início e evite interpolar nela data, id de request, contador de turnos ou JSON serializado com ordem aleatória de chaves.

Zona dinâmica (cauda): a mensagem do usuário, os tool_results, o estado da tarefa e qualquer telemetria que mude. Deixe essa zona no final.

A documentação da OpenAI recomenda conteúdo estático no começo e conteúdo variável no fim, e observa que tools e imagens também precisam ser idênticos entre requisições para o prefixo bater (OpenAI, "Prompt caching", consultado em 06/08/2026). A Anthropic reforça o mesmo layout e alerta que alterar definições de tools invalida o cache de tools, system e messages (Anthropic, "Prompt caching", consultado em 06/08/2026).

// Ilustrativo: layout de prefixo estável + cauda dinâmica.
// Não é um cliente de produção completo.

type ToolDef = {
  name: string;
  description: string;
  input_schema: Record<string, unknown>;
};

type Message =
  | { role: "user" | "assistant"; content: string }
  | {
      role: "user";
      content: Array<{
        type: "tool_result";
        tool_use_id: string;
        content: string;
      }>;
    };

const STABLE_TOOLS: ToolDef[] = [
  {
    name: "search_orders",
    description: "Busca pedidos por customerId.",
    input_schema: {
      type: "object",
      properties: {
        customerId: { type: "string" },
      },
      required: ["customerId"],
    },
  },
];

const STABLE_SYSTEM = [
  "Você é um agente de suporte com ferramentas.",
  "Chame no máximo uma ferramenta por passo.",
  "Não invente customerId.",
].join("\n");

function buildRequest(history: Message[]) {
  return {
    model: "claude-sonnet-4-5",
    max_tokens: 1024,
    // Anthropic: marca o fim do bloco reutilizável.
    system: [
      {
        type: "text",
        text: STABLE_SYSTEM,
        cache_control: { type: "ephemeral" },
      },
    ],
    tools: STABLE_TOOLS,
    messages: history,
  };
}

Dois detalhes de implementação importam mais do que o nome do modelo:

  1. Serialização estável. Em algumas linguagens, a ordem das chaves no JSON de tools muda entre processos. A Anthropic lista ordenação instável de chaves em tool_use como causa de miss (Anthropic, "Prompt caching", consultado em 06/08/2026).
  2. Superfície de tools fixa durante o loop. Se o harness adiciona ou remove tools no meio da tarefa, o prefixo muda e o cache de tools cai. Prefira um conjunto fixo por tipo de tarefa e deixe a escolha de ferramenta para o modelo, com validação de tool calls em runtime.

Quando orquestro loops longos em Claude Code, Codex ou harness próprio, uso o RemoteCode como minha camada para empurrar o trabalho com menos desperdício de contexto. É ferramenta do autor deste blog: ela não substitui layout de prefixo, medição de cache hit nem revisão humana.

Como medir cache hit a cada tool step?

Sem métrica, "ativamos caching" vira fé. Os dois provedores expõem contadores no objeto de uso da resposta.

Na Anthropic, o recorte útil é:

  • cache_read_input_tokens: tokens lidos do cache
  • cache_creation_input_tokens: tokens escritos no cache nesta resposta
  • input_tokens: tokens depois do último breakpoint (a cauda não elegível)

A documentação define o total de input como a soma desses três campos (Anthropic, "Prompt caching", consultado em 06/08/2026).

Na OpenAI, o campo equivalente no detalhe de input é cached_tokens. Em famílias mais novas, a documentação também descreve cache_write_tokens e o parâmetro prompt_cache_key para melhorar o roteamento de requests que compartilham o mesmo prefixo (OpenAI, "Prompt caching", consultado em 06/08/2026).

// Ilustrativo: registrar hit ratio por passo do loop.

type UsageLike = {
  input_tokens?: number;
  cache_read_input_tokens?: number;
  cache_creation_input_tokens?: number;
  prompt_tokens_details?: {
    cached_tokens?: number;
    cache_write_tokens?: number;
  };
};

function summarizeCache(step: number, usage: UsageLike) {
  const read =
    usage.cache_read_input_tokens ??
    usage.prompt_tokens_details?.cached_tokens ??
    0;
  const written =
    usage.cache_creation_input_tokens ??
    usage.prompt_tokens_details?.cache_write_tokens ??
    0;
  const uncached = usage.input_tokens ?? 0;

  return {
    step,
    read,
    written,
    uncached,
    // Hit de prefixo: houve leitura de cache neste passo.
    hit: read > 0,
  };
}

Grave esses números no mesmo lugar em que você já registra tool name, latência e custo. A observabilidade de agentes de código vira o lugar natural para esse evento: sem ele, um miss de cache parece só "a API ficou cara".

Preços mudam por modelo e por política de retenção. Em 06/08/2026, a tabela da Anthropic mostra leitura de cache a 0,1× o preço de input base e escrita de cache de 5 minutos a 1,25× o input base, com opção de TTL de 1 hora a custo maior de escrita (Anthropic, "Prompt caching"). Use a tabela atual do provedor na hora de projetar economia; não fixe um percentual no código.

O que invalida o cache no meio do loop?

Os misses mais caros em agentes costumam ser autoinfligidos.

1. Timestamp ou id no system. Um Agora: 2026-08-06T12:01:03Z no início do system transforma o prefixo a cada segundo. Mova relógio e request id para a cauda, ou omita se o agente não precisar.

2. Tools regeneradas a cada passo. Gerar o array de tools a partir de um Map sem ordenação, ou injetar descrições com dados da sessão, quebra o match. Materialize a lista uma vez por tipo de tarefa.

3. System prompt montado com estado da tarefa. "Cliente atual: ACME" no system parece conveniente e destrói o reuso entre tenants e entre passos. Prefira mensagem de usuário ou bloco depois do breakpoint.

4. TTL estourado. O cache efêmero da Anthropic tem vida útil padrão de 5 minutos, renovada a cada hit; há TTL de 1 hora com escrita mais cara (Anthropic, "Prompt caching", consultado em 06/08/2026). Se o agente espera aprovação humana por 20 minutos e você depende do TTL de 5 minutos, o próximo passo reescreve o prefixo.

5. Esperar que o cache mude a resposta. Ambos os provedores afirmam que o caching não altera a geração de tokens de saída; ele reutiliza o processamento do prefixo (OpenAI, "Prompt caching"; Anthropic, "Prompt caching", consultados em 06/08/2026). Se a saída ficou diferente, a causa está em sampling, tools, histórico ou modelo, não em "o cache alucinou".

Checklist de verificação no harness

Use esta sequência antes de declarar vitória:

  1. Rode dois passos consecutivos do mesmo agente com o mesmo conjunto de tools.
  2. Confira no segundo passo cache_read_input_tokens ou cached_tokens > 0.
  3. Introduza de propósito um timestamp no system e confirme o miss.
  4. Remova o timestamp e confirme o retorno do hit.
  5. Mantenha o conjunto de tools estável durante o loop; valide argumentos na borda.
  6. Registre read/write/uncached por step no artefato de CI ou log estruturado.
  7. Se o volume for multi-tenant na OpenAI, use prompt_cache_key estável por prefixo compartilhado, conforme a documentação atual.

Limites do que este artigo cobre

O texto não promete um percentual fixo de economia: isso depende do tamanho do prefixo, do número de passos, do TTL, do modelo e da taxa de invalidação. Também não substitui redução de contexto. Um prefixo de 40 mil tokens com 90% de hit ainda é um prefixo grande; o orçamento continua necessário.

Não cobre storage de respostas semânticas (cache de saída por similaridade). Prompt caching é reuso de prefixo no provedor, não um Redis de respostas. Não cobre política de retenção de dados da sua organização: leia o guia de dados do provedor quando ZDR ou residência importarem.

Por fim, o exemplo TypeScript é ilustrativo. Os nomes de modelos e os campos de usage mudam; trate a documentação oficial como fonte de verdade na data do deploy.

Perguntas frequentes sobre prompt caching em agentes

Prompt caching muda a resposta do modelo?

Não. A OpenAI e a Anthropic descrevem o recurso como reuso do processamento do prefixo. A geração de tokens de saída continua sendo uma computação nova a partir desse prefixo. Não use cache como se fosse memoização da resposta final.

Preciso marcar cache_control em todo provedor?

Não. A OpenAI documenta caching automático para requests elegíveis e, em famílias mais novas, breakpoints explícitos e prompt_cache_key. A Anthropic oferece caching automático no topo da request e breakpoints explícitos por bloco. O layout estável importa nos dois casos; a API de marcação muda.

Qual o tamanho mínimo do prefixo?

Depende do modelo e da plataforma. A OpenAI indica cerca de 1.024 tokens como referência para prefixes cacheáveis. A Anthropic publica mínimos por modelo (por exemplo 1.024 tokens em vários Sonnet/Opus recentes, com outros mínimos maiores em modelos específicos). Se read e creation vierem zerados, o prefixo provavelmente ficou abaixo do mínimo ou o breakpoint ficou no bloco errado.

Vale a pena cachear um agente de um único passo?

Só se o mesmo prefixo se repete entre usuários ou entre jobs próximos no tempo. Em um loop de várias tool calls, o benefício costuma aparecer a partir do segundo passo. Em um one-shot com system curto, o ganho pode ser zero e a escrita de cache ainda custa nos planos que cobram write.

Fontes consultadas