> ## Documentation Index
> Fetch the complete documentation index at: https://docs.apimart.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Guia de uso do cache de contexto do Claude

> Armazene em cache prefixos de prompt reutilizados por meio da API Claude Messages ou da API Chat Completions compatível com a OpenAI para reduzir o custo de tokens do processamento repetido de conteúdos longos.

O cache de contexto do Claude (Context Cache) é adequado para reutilizar prefixos longos, como prompts de sistema, documentos, bases de código ou históricos de conversa. Depois que você adiciona `cache_control` a um prefixo estável, a primeira solicitação cria um cache e as solicitações seguintes podem ler esse cache enquanto ele não expirar.

Antes de começar, defina sua chave de API:

```bash theme={null}
export API_KEY="SUA_CHAVE_DE_API"
```

<Note>Os exemplos deste guia usam o `claude-sonnet-5`. Para saber se outros modelos são compatíveis com o cache de contexto, consulte a descrição dos modelos na plataforma.</Note>

## Casos de uso

Quando várias solicitações incluem repetidamente o mesmo bloco grande de conteúdo, você pode armazenar em cache um prefixo estável, por exemplo:

* Um prompt de sistema longo
* Uma base de conhecimento fixa ou documentação de produto
* Um histórico de conversa com vários turnos que permanece inalterado
* Bases de código, definições de ferramentas e instruções reutilizadas

O cache de contexto é adequado para solicitações em que o conteúdo inicial permanece igual e apenas a pergunta final muda.

## API Claude Messages

### Cache de 5 minutos

Adicione `cache_control` ao bloco de conteúdo que deve ser armazenado em cache:

```bash theme={null}
curl "https://api.apimart.ai/v1/messages" \
  -H "x-api-key: $API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-sonnet-5",
    "max_tokens": 1024,
    "system": [
      {
        "type": "text",
        "text": "Insira aqui o prefixo longo que será reutilizado…",
        "cache_control": {
          "type": "ephemeral"
        }
      }
    ],
    "messages": [
      {
        "role": "user",
        "content": "Responda à pergunta com base no conteúdo acima."
      }
    ]
  }'
```

<Warning>`system` deve ser um array de blocos de conteúdo. Não é possível adicionar `cache_control` quando `system` é uma string.</Warning>

Se `ttl` for omitido, o período de validade padrão do cache será de 5 minutos.

### Cache de 1 hora

Para usar um cache de 1 hora, adicione também o cabeçalho de solicitação `anthropic-beta` e defina `ttl` como `1h`:

```bash theme={null}
curl "https://api.apimart.ai/v1/messages" \
  -H "x-api-key: $API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "anthropic-beta: extended-cache-ttl-2025-04-11" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-sonnet-5",
    "max_tokens": 1024,
    "system": [
      {
        "type": "text",
        "text": "Insira aqui o prefixo longo que será reutilizado…",
        "cache_control": {
          "type": "ephemeral",
          "ttl": "1h"
        }
      }
    ],
    "messages": [
      {
        "role": "user",
        "content": "Responda à pergunta com base no conteúdo acima."
      }
    ]
  }'
```

TTLs compatíveis:

| TTL  | Significado                                                                              |
| ---- | ---------------------------------------------------------------------------------------- |
| `5m` | Cache por 5 minutos; esse valor é usado quando `ttl` é omitido                           |
| `1h` | Cache por 1 hora; o cabeçalho `anthropic-beta` correspondente também deve ser adicionado |

### Campos de uso na resposta

A API Claude Messages retorna separadamente os tokens de entrada comum, gravação no cache e leitura do cache em `usage`:

```json theme={null}
{
  "usage": {
    "input_tokens": 23,
    "cache_creation_input_tokens": 2619,
    "cache_read_input_tokens": 0,
    "cache_creation": {
      "ephemeral_5m_input_tokens": 2619,
      "ephemeral_1h_input_tokens": 0
    },
    "output_tokens": 24
  }
}
```

O total de tokens de entrada é calculado assim:

```text theme={null}
input_tokens
+ cache_creation_input_tokens
+ cache_read_input_tokens
```

Esses três valores não se sobrepõem. A primeira solicitação normalmente apresenta `cache_creation_input_tokens > 0`; ao enviar novamente o mesmo prefixo estável, você deverá ver `cache_read_input_tokens > 0`.

## API compatível com a OpenAI

### Exemplo de solicitação

Ao usar o cache por meio de `/v1/chat/completions`, a sintaxe de `cache_control` é semelhante à da API Claude Messages:

```bash theme={null}
curl "https://api.apimart.ai/v1/chat/completions" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-sonnet-5",
    "max_tokens": 1024,
    "messages": [
      {
        "role": "system",
        "content": [
          {
            "type": "text",
            "text": "Insira aqui o prefixo longo que será reutilizado…",
            "cache_control": {
              "type": "ephemeral"
            }
          }
        ]
      },
      {
        "role": "user",
        "content": "Responda à pergunta com base no conteúdo acima."
      }
    ]
  }'
```

### Cache de 1 hora

O formato compatível com a OpenAI também oferece cache de 1 hora. Basta adicionar o cabeçalho de solicitação `anthropic-beta` e definir `ttl: "1h"` em `cache_control`:

```bash theme={null}
-H "anthropic-beta: extended-cache-ttl-2025-04-11"
```

```json theme={null}
"cache_control": {
  "type": "ephemeral",
  "ttl": "1h"
}
```

### `content` deve ser um array

No formato compatível com a OpenAI, `cache_control` deve estar dentro de um bloco de conteúdo específico. Ele não pode ser anexado a uma mensagem cujo conteúdo seja uma string.

```json theme={null}
{
  "role": "system",
  "content": "Insira aqui o prefixo longo…",
  "cache_control": {
    "type": "ephemeral"
  }
}
```

A sintaxe acima não ativa o cache, mas também não causa um erro na solicitação. A sintaxe correta é:

```json theme={null}
{
  "role": "system",
  "content": [
    {
      "type": "text",
      "text": "Insira aqui o prefixo longo…",
      "cache_control": {
        "type": "ephemeral"
      }
    }
  ]
}
```

<Warning>Se `content` for uma string, o marcador de cache será ignorado e o conteúdo continuará sendo processado como entrada comum. Verifique os campos de uso do cache na resposta para confirmar se houve uma leitura do cache.</Warning>

### Armazenar em cache blocos de conteúdo `user` ou `assistant`

Você também pode colocar `cache_control` no bloco de conteúdo de uma mensagem `user` ou `assistant` para armazenar em cache um documento longo ou um prefixo de conversa com vários turnos:

```json theme={null}
{
  "role": "user",
  "content": [
    {
      "type": "text",
      "text": "Insira aqui o documento longo que será reutilizado…",
      "cache_control": {
        "type": "ephemeral"
      }
    },
    {
      "type": "text",
      "text": "Resuma os três principais pontos do documento acima."
    }
  ]
}
```

Separe o conteúdo estável e a pergunta atual em blocos de conteúdo diferentes e adicione `cache_control` somente ao bloco de conteúdo estável.

### Campos de uso na resposta

O formato compatível com a OpenAI usa campos diferentes para relatar o uso do cache:

```json theme={null}
{
  "usage": {
    "prompt_tokens": 1942,
    "completion_tokens": 22,
    "prompt_tokens_details": {
      "cached_tokens": 1921,
      "cache_write_tokens": 0
    },
    "claude_cache_creation_5_m_tokens": 0,
    "claude_cache_creation_1_h_tokens": 0
  }
}
```

Correspondência dos campos:

| Significado                         | API Claude Messages                        | API compatível com a OpenAI                                                                  |
| ----------------------------------- | ------------------------------------------ | -------------------------------------------------------------------------------------------- |
| Total de entrada                    | Soma dos três campos de entrada            | `prompt_tokens`                                                                              |
| Leitura do cache                    | `cache_read_input_tokens`                  | `prompt_tokens_details.cached_tokens`                                                        |
| Campo genérico de gravação no cache | `cache_creation_input_tokens`              | `prompt_tokens_details.cache_write_tokens` (só tem valor quando não há detalhamento por TTL) |
| Gravação no cache de 5 minutos      | `cache_creation.ephemeral_5m_input_tokens` | `claude_cache_creation_5_m_tokens`                                                           |
| Gravação no cache de 1 hora         | `cache_creation.ephemeral_1h_input_tokens` | `claude_cache_creation_1_h_tokens`                                                           |
| Saída                               | `output_tokens`                            | `completion_tokens`                                                                          |

<Note>Se `prompt_tokens_details.cache_write_tokens` for `0`, ainda será necessário verificar `claude_cache_creation_5_m_tokens` e `claude_cache_creation_1_h_tokens`. Quando houver campos detalhados por TTL, o volume gravado no cache será retornado pelo campo correspondente.</Note>

<Note>Em `claude_cache_creation_5_m_tokens` e `claude_cache_creation_1_h_tokens`, há sublinhados entre o número e a unidade. Use exatamente os nomes dos campos retornados na resposta.</Note>

<Warning>A API compatível com a OpenAI pode retornar uma resposta de streaming SSE mesmo sem o envio explícito de `stream: true`. O cliente deve ser capaz de analisar `chat.completion.chunk`. O uso aparece no último bloco de dados que contém `usage`.</Warning>

## Condições para uma leitura do cache

### O prefixo atinge o tamanho mínimo

O prefixo de cache do modelo usado nos exemplos normalmente precisa ter pelo menos cerca de 1024 tokens. Se o prefixo for muito curto, o marcador de cache poderá ser ignorado sem gerar um erro.

### O prefixo permanece idêntico byte a byte

O texto, os espaços, as quebras de linha e a ordem dos blocos de conteúdo no prefixo de cache devem permanecer inalterados. Não adicione conteúdo dinâmico, como carimbos de data e hora, IDs aleatórios ou contadores de solicitações, ao prefixo estável.

### A solicitação não acionou uma recusa do modelo

Se a solicitação acionar uma recusa do modelo, a resposta ainda poderá relatar tokens de criação do cache, mas esse cache não será lido na solicitação seguinte. Ao investigar por que não houve uma leitura do cache, verifique também se `stop_reason` é `refusal`.

### O cache ainda está válido

O período de validade do cache é de 5 minutos ou 1 hora e é calculado a partir do último acesso. Uma leitura do cache renova o período de validade.

## Uso para cobrança

O uso relacionado ao cache é dividido em três categorias:

| Uso               | Quando é gerado                                   |
| ----------------- | ------------------------------------------------- |
| Gravação no cache | Na criação inicial do cache                       |
| Leitura do cache  | Quando uma solicitação posterior encontra o cache |
| Entrada comum     | Para entradas fora do prefixo de cache            |

As três categorias de uso não se sobrepõem. A gravação no cache normalmente custa mais do que a entrada comum, enquanto a leitura do cache normalmente custa menos. Por isso, o cache de contexto é mais adequado para prefixos estáveis que serão reutilizados dentro do TTL.

## Exemplo mínimo reproduzível

O script abaixo primeiro gera um prefixo estável suficientemente longo e depois envia duas vezes a mesma solicitação. A segunda resposta deverá apresentar `cache_read_input_tokens > 0`.

```bash theme={null}
python3 - <<'PY' > /tmp/claude-cache-request.json
import json

paragraph = (
    "Prompt caching stores a prefix of the request so that later requests "
    "can reuse the same byte-identical prefix without processing it again. "
)

system_text = (
    "You are a documentation assistant. Reference material follows.\n\n"
    + paragraph * 40
)

print(json.dumps({
    "model": "claude-sonnet-5",
    "max_tokens": 32,
    "system": [{
        "type": "text",
        "text": system_text,
        "cache_control": {"type": "ephemeral"}
    }],
    "messages": [{
        "role": "user",
        "content": "In one sentence, what must remain unchanged?"
    }]
}))
PY

for request_number in 1 2; do
  echo "Solicitação ${request_number}"
  curl -s "https://api.apimart.ai/v1/messages" \
    -H "x-api-key: $API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "Content-Type: application/json" \
    --data @/tmp/claude-cache-request.json \
  | python3 -c "import json, sys; print(json.load(sys.stdin)['usage'])"
done
```

Resultado esperado:

```text theme={null}
Solicitação 1: cache_creation_input_tokens > 0, cache_read_input_tokens = 0
Solicitação 2: cache_creation_input_tokens = 0, cache_read_input_tokens > 0
```

## Lista de verificação para solução de problemas

Se não houver uma leitura do cache, verifique os itens abaixo na ordem indicada:

* `stop_reason` é `refusal`?
* O prefixo de cache atinge o número mínimo de tokens exigido pelo modelo?
* Os prefixos estáveis das duas solicitações são idênticos byte a byte?
* No formato compatível com a OpenAI, `content` é um array?
* `cache_control` está dentro de um bloco de conteúdo específico?
* Para o cache de 1 hora, `ttl: "1h"` e o cabeçalho `anthropic-beta` correspondente foram definidos?
* O cache já ultrapassou o TTL?
* Você está lendo os campos de uso do cache correspondentes à API atual?
