Caching promptů
AUTOMATICKÉHostované open-weight modely automaticky cachují opakující se prefixy promptů. Pokud požadavek začíná stejným systémovým promptem, nástroji a dřívějšími zprávami jako nedávný požadavek u stejného modelu, tento sdílený prefix je přečten z cache a fakturován za 25 % vstupní ceny modelu. Není nutné nic aktivovat a zápisy do cache jsou zdarma.
Jak to funguje
- Prefix v pořadí — Prompt je čten v tomto pořadí: systémový prompt, definice nástrojů a poté zprávy. Cache shoda probíhá od začátku této sekvence až po první token, který se liší.
- Co se počítá jako hit — Požadavek, jehož prompt začíná stejným obsahem jako nedávný požadavek — typicky předchozí kolo stejné konverzace s připojenými novými zprávami. Shodující se prefix je cache vstup; vše poté je běžný vstup.
- Granularita — Cache drží prompt v blocích po 1,568 tokenech, takže prompt kratší než asi 1,500 tokenů se necachuje. Počet cachovaných tokenů v odpovědi je váš počet vstupních tokenů vynásobený cachovaným podílem promptu, zaokrouhlený dolů. Nemusí být násobkem velikosti bloku.
- Bez hitu — Požadavek, jehož začátek není v cache, se účtuje běžnou sazbou vstupu. Pro cachované prompty se nezveřejňuje žádná doba platnosti a hit není zaručen: z
usagepoznáte, co požadavek převzal z cache. - Žádný vypínač — Požadavek se do cachování nepřihlašuje a žádné pole cachování nevypne.
- Které modely — Každé hostované open-weight ID. GET /v1/models reportuje capabilities.prompt_caching: true a pricing.cached_input_per_million_usd. Modely Shannon fakturují jednu paušální sazbu.
Jak poznat cache hit v odpovědi
Odešlete dva požadavky, které začínají stejným dlouhým systémovým promptem, a vypište využití každého. První číslo je vstup požadavku, druhé je jeho část přečtená z 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 Ceník
Tokeny cache vstupu jsou fakturovány za 25 % vstupní sazby modelu, zaokrouhleno na $0.001 per 1M. Zápis do cache nestojí nic navíc a výstup je fakturován jako obvykle. Cache sazba pro každé ID je v tabulce Modely a ceny. Modely a ceny
Vstup volání se účtuje jako (vstup − cachovaný) × sazba vstupu + cachovaný × sazba cache. Počet cachovaných tokenů není nikdy větší než počet vstupních.
| Model | Vstup / 1M | Cachovaný vstup / 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 |
Záznam využití uvádí cachovaný vstup každého volání. Jeho účtované tokeny a náklady již zahrnují sazbu cache. Klíče a využití
Pole použití
| Endpoint | Cache vstup | Uvažování |
|---|---|---|
/v1/chat/completions | usage.prompt_tokens_details.cached_tokens — část prompt_tokens | usage.completion_tokens_details.reasoning_tokens — část completion_tokens |
/v1/responses | usage.input_tokens_details.cached_tokens — část input_tokens | usage.output_tokens_details.reasoning_tokens — část output_tokens |
/v1/messages | usage.cache_read_input_tokens — hlášeno samostatně: input_tokens je necachovaná část; cache_creation_input_tokens je vždy 0 | thinking je počítáno v 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
}
} Streamovaná odpověď nese stejná pole ve svém závěrečném využití. Nemusíte o ně žádat:
| Endpoint | Kde využití přichází |
|---|---|
/v1/chat/completions | usage v posledním chunku před data: [DONE]. Posílá se u každého streamu. |
/v1/responses | response.usage události response.completed. |
/v1/messages | usage události message_delta. usage v message_start obsahuje nuly. |
Jak zvýšit počet cache hitů
- Udržujte systémový prompt a definice nástrojů byte-za-bytem stabilní mezi voláními. Hodnoty specifické pro konkrétní volání, jako jsou časové značky nebo ID požadavků, umístěte na konec poslední zprávy, nikoliv do systémového promptu.
- Do historie pouze př přidávejte. Úpravy, ořezávání nebo shrnování dřívějších kol změní prefix a vše po první změně je fakturováno jako běžný vstup.
- Nezměňte pořadí nástrojů, zpráv nebo bloků obsahu mezi voláními a JSON (schémata nástrojů, argumenty a výsledky) serializujte pokaždé stejným způsobem.
- V rámci konverzace zůstaňte u jednoho id modelu a následné volání posílejte brzy po předchozím.
API drží začátek konverzace stabilní v těchto případech:
- Zpráva
systemnebodeveloperodeslaná později v konverzaci zůstane na svém místě. Nemění začátek promptu, takže předchozí kola zůstávají v cache. - Argumenty volání nástrojů v dřívějších kolech asistenta se porovnávají podle hodnoty. Na pořadí klíčů a mezerách v tomto JSON nezáleží.
- Tyto tři endpointy čtou konverzaci stejně. Konverzace pokračující na jiném endpointu si zachová společný prefix, pokud je obsah stejný.
Pole požadavku
prompt_cache_key (Chat Completions a Responses) a cache_control v blocích obsahu Messages jsou podporovány, takže stávající kód klientů běží beze změn. Žádné z nich není povinné: cachování je automatické a funguje stejně i bez nich.
| Pole | Posílá se do | Co to je |
|---|---|---|
prompt_cache_key | /v1/chat/completions, /v1/responses | Klíč pro směrování cache v OpenAI API. |
cache_control | /v1/messages | Cache breakpoint na bloku obsahu, bloku system nebo zprávě v Anthropic API. |
stream_options | /v1/chat/completions | include_usage žádá OpenAI API o využití ve streamu. Tady každý stream končí využitím. |
Počítání tokenů
Dva bezplatné endpointy, POST /v1/tokenize a POST /v1/messages/count_tokens, spočítají tokeny textu nebo celého požadavku pro hostované modely s otevřenými váhami dřív, než jej odešlete. Mají vlastní stránku: Počítání tokenů