Prompt caching
AUTOMATICAng mga hosted open-weight model ay awtomatikong nag-ca-cache ng mga paulit-ulit na prompt prefix. Kapag ang isang request ay nagsimula sa parehong system prompt, tools at mga naunang mensahe gaya ng isang kamakailang request sa parehong model, ang shared prefix na iyon ay binabasa mula sa cache at sisingilin sa 25% ng input price ng model. Wala nang kailangang i-enable, at ang mga cache write ay libre.
Paano ito gumagana
- Prefix, ayon sa pagkakasunod — Ang prompt ay binabasa nang sunod-sunod: system prompt, tool definitions, pagkatapos ay ang mga mensahe. Ang cache ay tumutugma mula sa simula ng sequence na iyon hanggang sa unang token na magkaiba.
- Ano ang itinuturing na hit — Isang request kung saan ang prompt ay nagsisimula sa parehong content gaya ng isang kamakailang request — karaniwan ay ang naunang turn ng parehong conversation na may mga bagong mensaheng idinagdag. Ang matching prefix ay cached input; ang lahat pagkatapos nito ay regular input.
- Granularity — Hawak ng cache ang prompt sa mga block na 1,568 tokens, kaya hindi kine-cache ang prompt na mas maikli sa humigit-kumulang 1,500 tokens. Ang cached count sa isang reply ay ang iyong input count na imu-multiply sa cached na bahagi ng prompt, ibinababa sa pinakamalapit na buong numero. Hindi ito kinakailangang multiple ng laki ng block.
- Kapag walang hit — Ang request na ang simula ay wala sa cache ay sinisingil sa regular na input rate. Walang inilathalang tagal ng buhay para sa mga cached na prompt at hindi garantisado ang hit: basahin ang
usagepara makita kung ano ang kinuha ng request mula sa cache. - Walang switch — Hindi nag-o-opt in ang request, at walang field na nag-o-off ng caching.
- Aling mga model — Bawat hosted open-weight id. Ang GET /v1/models ay nag-uulat ng capabilities.prompt_caching: true at pricing.cached_input_per_million_usd para sa mga ito. Ang mga Shannon model ay sumisingil ng isang flat rate.
Tingnan ang cache hit sa isang reply
Magpadala ng dalawang request na nagsisimula sa parehong mahabang system prompt at i-print ang usage ng bawat isa. Ang unang numero ay ang input ng request, ang pangalawa ay ang bahagi nitong binasa mula sa 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 Pagpepresyo
Ang mga cached input token ay sisingilin sa 25% ng input rate ng model, rounded sa $0.001 kada 1M. Ang pagsusulat sa cache ay walang extra na gastos, at ang output ay sisingilin gaya ng dati. Ang cached rate ng bawat id ay nasa table ng Models & pricing. Mga model at presyo
Ang input ng isang call ay sinisingil bilang (input − cached) × input rate + cached × cached rate. Hindi kailanman mas malaki ang cached count kaysa sa input count.
| Model | Input / 1M | Cached input / 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 |
Inililista ng usage log ang cached input ng bawat call. Kasama na sa mga sinisingil na token at gastos nito ang cached rate. Keys & usage
Mga field ng paggamit
| Endpoint | Cached input | Reasoning |
|---|---|---|
/v1/chat/completions | usage.prompt_tokens_details.cached_tokens — bahagi ng prompt_tokens | usage.completion_tokens_details.reasoning_tokens — bahagi ng completion_tokens |
/v1/responses | usage.input_tokens_details.cached_tokens — bahagi ng input_tokens | usage.output_tokens_details.reasoning_tokens — bahagi ng output_tokens |
/v1/messages | usage.cache_read_input_tokens — iniuulat nang hiwalay: ang input_tokens ay ang uncached part; ang cache_creation_input_tokens ay laging 0 | ang thinking ay binibilang sa 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
}
} Dala ng naka-stream na reply ang parehong field sa huling usage nito. Hindi mo kailangang hilingin ito:
| Endpoint | Kung saan dumarating ang usage |
|---|---|
/v1/chat/completions | Ang usage sa huling chunk bago ang data: [DONE]. Ipinapadala ito sa bawat stream. |
/v1/responses | Ang response.usage ng response.completed event. |
/v1/messages | Ang usage ng message_delta event. Zero ang laman ng usage ng message_start. |
Pagkuha ng mas maraming cache hits
- Panatilihing byte-for-byte stable ang system prompt at tool definitions sa mga call. Ilagay ang mga per-call value gaya ng timestamps o request ids sa dulo ng pinakabagong mensahe, hindi sa system prompt.
- Mag-append lamang sa history. Ang pag-edit, pag-trim o pag-summarize ng mga naunang turn ay nagbabago ng prefix, at ang lahat pagkatapos ng unang pagbabago ay sisingilin bilang regular input.
- Huwag i-reorder ang mga tool, mensahe o content block sa pagitan ng mga call, at i-serialize ang JSON (tool schemas, tool arguments at results) sa parehong paraan sa bawat pagkakataon.
- Manatili sa isang model id para sa isang conversation, at ipadala ang kasunod na call nang malapit sa nauna.
Pinapanatiling matatag ng API ang simula ng isang conversation sa mga kasong ito:
- Ang
systemodevelopermessage na ipinadala sa mas huling bahagi ng conversation ay nananatili sa kinalalagyan nito. Hindi nito binabago ang simula ng prompt, kaya nananatiling naka-cache ang mga turn bago nito. - Ang mga argument ng tool call sa mga naunang assistant turn ay inihahambing ayon sa value. Hindi mahalaga ang pagkakasunod ng key at spacing ng JSON na iyon.
- Parehong binabasa ng tatlong endpoint ang isang conversation. Ang conversation na itinuloy sa ibang endpoint ay nananatili ang shared prefix nito kapag pareho ang content.
Mga request field
Tinatanggap ang prompt_cache_key (Chat Completions at Responses) at cache_control sa Messages content blocks, kaya ang kasalukuyang client code ay tatakbo nang walang pagbabago. Hindi kailangan ang alinman sa mga ito: ang caching ay awtomatiko at gumagana nang pareho kahit wala ang mga ito.
| Field | Ipinapadala sa | Ano ito |
|---|---|---|
prompt_cache_key | /v1/chat/completions, /v1/responses | Isang cache routing key ng OpenAI API. |
cache_control | /v1/messages | Isang cache breakpoint sa isang content block, isang system block o isang message ng Anthropic API. |
stream_options | /v1/chat/completions | Humihingi ang include_usage sa OpenAI API ng usage sa isang stream. Dito, nagtatapos ang bawat stream na may usage. |
Pagbibilang ng tokens
Dalawang libreng endpoint, POST /v1/tokenize at POST /v1/messages/count_tokens, ang nagbibilang ng tokens ng isang text o ng buong request para sa mga hosted open-weight model bago mo ito ipadala. May sarili silang pahina: Pagbibilang ng token