Caching de prompt
AUTOMÁTICOOs modelos open-weight hospedados fazem o cache de prefixos de prompt repetidos automaticamente. Quando uma requisição começa com o mesmo prompt de sistema, ferramentas e mensagens anteriores que uma requisição recente no mesmo modelo, esse prefixo compartilhado é lido do cache e faturado a 25% do preço de entrada do modelo. Não há nada para ativar, e as gravações no cache são gratuitas.
Como funciona
- Prefixos, em ordem — O prompt é lido em ordem: prompt de sistema, definições de ferramentas e, então, as mensagens. O cache corresponde desde o início dessa sequência até o primeiro token que difere.
- O que conta como um 'hit' — Uma requisição cujo prompt começa com o mesmo conteúdo de uma requisição recente — tipicamente o turno anterior da mesma conversa com novas mensagens anexadas. O prefixo correspondente é a entrada em cache; tudo após ele é entrada regular.
- Granularidade — O cache guarda um prompt em blocos de 1,568 tokens, então um prompt menor que cerca de 1,500 tokens não é colocado em cache. A contagem em cache em uma resposta é a sua contagem de entrada multiplicada pela parte do prompt que está em cache, arredondada para baixo. Ela não é necessariamente um múltiplo do tamanho do bloco.
- Sem hit — Uma requisição cujo início não está no cache é cobrada pela taxa de entrada regular. Nenhum tempo de vida é publicado para prompts em cache e um hit não é garantido: leia
usagepara ver o que uma requisição aproveitou do cache. - Sem chave liga/desliga — Uma requisição não precisa aderir, e nenhum campo desativa o cache.
- Quais modelos — Todo ID open-weight hospedado. GET /v1/models reporta capabilities.prompt_caching: true e pricing.cached_input_per_million_usd para eles. Modelos Shannon faturam uma taxa única.
Veja um cache hit em uma resposta
Envie duas requisições que comecem com o mesmo prompt de sistema longo e imprima o uso de cada uma. O primeiro número é a entrada da requisição; o segundo é a parte dela que foi lida do cache.
from openai import OpenAI
client = OpenAI(api_key="YOUR_API_KEY", base_url="https://api.shannon-ai.com/v1")
handbook = open("handbook.txt").read() # a long text that stays the same
def ask(question):
response = client.chat.completions.create(
model="Kimi-K3-3BIT-REAP",
messages=[
{"role": "system", "content": handbook},
{"role": "user", "content": question},
],
)
usage = response.usage
print(usage.prompt_tokens, usage.prompt_tokens_details.cached_tokens)
ask("What is the refund policy?")
ask("Who approves travel?") # same start: read the second number import { readFileSync } from "node:fs";
import OpenAI from "openai";
const client = new OpenAI({ apiKey: "YOUR_API_KEY", baseURL: "https://api.shannon-ai.com/v1" });
const handbook = readFileSync("handbook.txt", "utf8"); // a long text that stays the same
async function ask(question) {
const response = await client.chat.completions.create({
model: "Kimi-K3-3BIT-REAP",
messages: [
{ role: "system", content: handbook },
{ role: "user", content: question },
],
});
const usage = response.usage;
console.log(usage.prompt_tokens, usage.prompt_tokens_details.cached_tokens);
}
await ask("What is the refund policy?");
await ask("Who approves travel?"); // same start: read the second number # handbook.txt is a long text that stays the same. jq builds the JSON body from it
# and prints the usage object of the reply. Run it twice with different questions.
jq -Rs '{
model: "Kimi-K3-3BIT-REAP",
messages: [
{role: "system", content: .},
{role: "user", content: "What is the refund policy?"}
]
}' handbook.txt \
| curl -s https://api.shannon-ai.com/v1/chat/completions \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d @- \
| jq .usage Preços
Tokens de entrada em cache são faturados a 25% da taxa de entrada do modelo, arredondados para $0.001 por 1M. Gravar no cache não custa nada extra, e a saída é faturada normalmente. A taxa de cache de cada ID está na tabela de Modelos e Preços. Modelos e preços
A entrada de uma chamada é cobrada como (entrada − cache) × taxa de entrada + cache × taxa de cache. A contagem em cache nunca é maior que a contagem de entrada.
| Modelo | Entrada / 1M | Entrada em cache / 1M |
|---|---|---|
DeepSeek-V4-Pro-0813-3BIT-REAP | $1.95 | $0.488 |
GLM-5.2-3BIT-REAP | $0.73 | $0.183 |
Kimi-K3-3BIT-REAP | $3.83 | $0.958 |
Nemotron3Ultra-3BIT-REAP | $0.75 | $0.188 |
MiniMax-M3-3BIT-REAP | $0.50 | $0.125 |
DeepSeek-V4-Flash-0731-W4A16-AUTOROUND-REAP | $0.50 | $0.125 |
Kimi-K2.6-W4A16-AUTOROUND-REAP | $0.78 | $0.195 |
Laguna-S-2.1-W4A16-AUTOROUND-REAP | $0.50 | $0.125 |
inkling-W4A16-AUTOROUND-REAP | $1.42 | $0.355 |
MiMo-V2.5-Pro-W8A16 | $0.50 | $0.125 |
MiMo-V2.5-W8A16 | $0.50 | $0.125 |
Hy3-W8A16 | $0.50 | $0.125 |
O registro de uso lista a entrada em cache de cada chamada. Seus tokens faturados e o custo já incluem a taxa de cache. Chaves e uso
Campos de uso
| Endpoint | Entrada em cache | Raciocínio |
|---|---|---|
/v1/chat/completions | usage.prompt_tokens_details.cached_tokens — parte de prompt_tokens | usage.completion_tokens_details.reasoning_tokens — parte de completion_tokens |
/v1/responses | usage.input_tokens_details.cached_tokens — parte de input_tokens | usage.output_tokens_details.reasoning_tokens — parte de output_tokens |
/v1/messages | usage.cache_read_input_tokens — reportado separadamente: input_tokens é a parte não cacheada; cache_creation_input_tokens é sempre 0 | o raciocínio é contado em output_tokens |
{
"usage": {
"prompt_tokens": 20000,
"completion_tokens": 812,
"total_tokens": 20812,
"prompt_tokens_details": {
"cached_tokens": 18000
},
"completion_tokens_details": {
"reasoning_tokens": 604
}
}
} {
"usage": {
"input_tokens": 20000,
"input_tokens_details": {
"cached_tokens": 18000
},
"output_tokens": 812,
"output_tokens_details": {
"reasoning_tokens": 604
},
"total_tokens": 20812
}
} {
"usage": {
"input_tokens": 2000,
"cache_read_input_tokens": 18000,
"cache_creation_input_tokens": 0,
"output_tokens": 812
}
} Uma resposta em streaming traz os mesmos campos no seu uso final. Você não precisa pedi-lo:
| Endpoint | Onde o uso chega |
|---|---|
/v1/chat/completions | usage no último chunk antes de data: [DONE]. Ele é enviado em todo stream. |
/v1/responses | response.usage do evento response.completed. |
/v1/messages | usage do evento message_delta. O usage de message_start contém zeros. |
Como obter mais cache hits
- Mantenha o prompt de sistema e as definições de ferramentas estáveis byte a byte entre as chamadas. Coloque valores de cada chamada, como timestamps ou IDs de requisição, ao final da última mensagem, não no prompt de sistema.
- Apenas anexe ao histórico. Editar, cortar ou resumir turnos anteriores altera o prefixo, e tudo após a primeira alteração é faturado como entrada regular.
- Não reordene ferramentas, mensagens ou blocos de conteúdo entre chamadas, e serialize JSON (schemas de ferramentas, argumentos de ferramentas e resultados) da mesma maneira sempre.
- Mantenha um único id de modelo durante uma conversa e envie a chamada seguinte logo depois da anterior.
A API mantém estável o início de uma conversa nestes casos:
- Uma mensagem
systemoudeveloperenviada mais tarde em uma conversa permanece no seu lugar. Ela não altera o início do prompt, então os turnos anteriores a ela continuam em cache. - Os argumentos de chamadas de ferramenta em turnos anteriores do assistente são comparados por valor. A ordem das chaves e o espaçamento desse JSON não importam.
- Os três endpoints leem uma conversa da mesma forma. Uma conversa continuada em outro endpoint mantém o prefixo compartilhado quando o conteúdo é o mesmo.
Campos da requisição
prompt_cache_key (Chat Completions e Responses) e cache_control em blocos de conteúdo de Messages são aceitos, permitindo que o código do cliente existente funcione sem alterações. Nenhum dos dois é obrigatório: o caching é automático e funciona da mesma forma sem eles.
| Campo | Enviado para | O que é |
|---|---|---|
prompt_cache_key | /v1/chat/completions, /v1/responses | Uma chave de roteamento de cache da API da OpenAI. |
cache_control | /v1/messages | Um breakpoint de cache em um bloco de conteúdo, em um bloco system ou em uma mensagem da API da Anthropic. |
stream_options | /v1/chat/completions | include_usage pede à API da OpenAI o uso em um stream. Aqui todo stream termina com o uso. |
Contagem de tokens
Dois endpoints gratuitos, POST /v1/tokenize e POST /v1/messages/count_tokens, contam os tokens de um texto ou de uma requisição inteira para os modelos open-weight hospedados antes de você enviá-la. Eles têm página própria: Contagem de tokens