Prompt caching
AUTOMATICOI modelli hosted open-weight memorizzano automaticamente i prefissi di prompt ripetuti. Quando una richiesta inizia con lo stesso system prompt, tool e messaggi precedenti di una richiesta recente sullo stesso modello, quel prefisso condiviso viene letto dalla cache e fatturato al 25% del prezzo di input del modello. Non c'è nulla da abilitare e la scrittura in cache è gratuita.
Come funziona
- Prefisso, in ordine — Il prompt viene letto in ordine: system prompt, definizioni dei tool, quindi i messaggi. La cache corrisponde dall'inizio di tale sequenza fino al primo token che differisce.
- Cosa costituisce un hit — Una richiesta il cui prompt inizia con lo stesso contenuto di una richiesta recente — tipicamente il turno precedente della stessa conversazione con nuovi messaggi aggiunti. Il prefisso corrispondente è input cached; tutto ciò che segue è input regolare.
- Granularità — La cache conserva un prompt in blocchi da 1,568 token, quindi un prompt più corto di circa 1,500 token non viene messo in cache. Il conteggio cached in una risposta è il tuo conteggio di input moltiplicato per la quota cached del prompt, arrotondato per difetto. Non è necessariamente un multiplo della dimensione del blocco.
- Senza hit — Una richiesta il cui inizio non è nella cache viene fatturata alla tariffa regolare dell'input. Per i prompt in cache non è pubblicata alcuna durata e un hit non è garantito: leggi
usageper vedere cosa ha preso dalla cache una richiesta. - Nessun interruttore — Una richiesta non richiede di aderire e nessun campo disattiva la cache.
- Quali modelli — Ogni ID hosted open-weight. GET /v1/models riporta capabilities.prompt_caching: true e pricing.cached_input_per_million_usd per essi. I modelli Shannon fatturano una tariffa fissa.
Vedere un cache hit in una risposta
Invia due richieste che iniziano con lo stesso system prompt lungo e stampa l'utilizzo di ciascuna. Il primo numero è l'input della richiesta, il secondo è la parte che è stata letta dalla 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 Prezzi
I token di input cached sono fatturati al 25% della tariffa di input del modello, arrotondata a $0,001 per 1M. La scrittura nella cache non ha costi aggiuntivi e l'output è fatturato come di consueto. La tariffa cached di ogni ID è nella tabella Modelli e prezzi. Modelli e prezzi
L'input di una chiamata viene addebitato come (input − cached) × tariffa input + cached × tariffa cached. Il conteggio cached non è mai maggiore del conteggio dell'input.
| Modello | Input / 1M | Input cached / 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 |
Il registro di utilizzo elenca l'input cached di ogni chiamata. I suoi token fatturati e il costo includono già la tariffa cached. Chiavi e utilizzo
Campi di utilizzo
| Endpoint | Input cached | Ragionamento |
|---|---|---|
/v1/chat/completions | usage.prompt_tokens_details.cached_tokens — parte di prompt_tokens | usage.completion_tokens_details.reasoning_tokens — parte di completion_tokens |
/v1/responses | usage.input_tokens_details.cached_tokens — parte di input_tokens | usage.output_tokens_details.reasoning_tokens — parte di output_tokens |
/v1/messages | usage.cache_read_input_tokens — riportato separatamente: input_tokens è la parte non cached; cache_creation_input_tokens è sempre 0 | il thinking è conteggiato in 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
}
} Una risposta in streaming porta gli stessi campi nel suo utilizzo finale. Non devi richiederlo:
| Endpoint | Dove arriva l'utilizzo |
|---|---|
/v1/chat/completions | usage sull'ultimo chunk prima di data: [DONE]. Viene inviato su ogni stream. |
/v1/responses | response.usage dell'evento response.completed. |
/v1/messages | usage dell'evento message_delta. L'usage di message_start contiene zeri. |
Ottenere più cache hit
- Mantieni il system prompt e le definizioni dei tool stabili byte-per-byte tra le chiamate. Inserisci i valori variabili per chiamata, come timestamp o ID richiesta, alla fine dell'ultimo messaggio, non nel system prompt.
- Aggiungi contenuti solo alla fine della cronologia. Modificare, tagliare o riassumere i turni precedenti cambia il prefisso, e tutto ciò che segue la prima modifica viene fatturato come input regolare.
- Non riordinare tool, messaggi o blocchi di contenuto tra le chiamate, e serializza JSON (schemi tool, argomenti tool e risultati) allo stesso modo ogni volta.
- Resta su un solo id di modello per una conversazione e invia la chiamata successiva poco dopo la precedente.
L'API mantiene stabile l'inizio di una conversazione in questi casi:
- Un messaggio
systemodeveloperinviato più avanti in una conversazione resta al suo posto. Non cambia l'inizio del prompt, quindi i turni che lo precedono restano in cache. - Gli argomenti delle chiamate a tool nei turni precedenti dell'assistente vengono confrontati per valore. L'ordine delle chiavi e la spaziatura di quel JSON non contano.
- I tre endpoint leggono una conversazione allo stesso modo. Una conversazione proseguita su un altro endpoint mantiene il prefisso condiviso quando il contenuto è lo stesso.
Campi della richiesta
Sono accettati prompt_cache_key (Chat Completions e Responses) e cache_control nei blocchi di contenuto dei Messages, quindi il codice client esistente funziona senza modifiche. Nessuno dei due è obbligatorio: il caching è automatico e funziona allo stesso modo senza di essi.
| Campo | Inviato a | Che cos'è |
|---|---|---|
prompt_cache_key | /v1/chat/completions, /v1/responses | Una chiave di routing della cache dell'API OpenAI. |
cache_control | /v1/messages | Un breakpoint di cache su un blocco di contenuto, un blocco system o un messaggio dell'API Anthropic. |
stream_options | /v1/chat/completions | include_usage chiede all'API OpenAI l'utilizzo in uno stream. Qui ogni stream termina con l'utilizzo. |
Conteggio dei token
Due endpoint gratuiti, POST /v1/tokenize e POST /v1/messages/count_tokens, contano i token di un testo o di un'intera richiesta per i modelli open-weight ospitati prima che tu la invii. Hanno una pagina propria: Conteggio dei token