プロンプトキャッシュ
自動ホストされたオープンウェイトモデルは、繰り返されるプロンプトプレフィックスを自動的にキャッシュします。リクエストが、同一モデルの最近のリクエストと同じシステムプロンプト、ツール、以前のメッセージで開始される場合、その共有プレフィックスはキャッシュから読み取られ、モデルの入力価格の25%で請求されます。有効化の手順は不要で、キャッシュへの書き込みは無料です。
仕組み
- プレフィックスの順序 — プロンプトは、システムプロンプト、ツール定義、そしてメッセージの順に読み取られます。キャッシュは、そのシーケンスの開始点から、最初に異なるトークンが現れるまでの一致部分を対象とします。
- ヒットの定義 — プロンプトが最近のリクエストと同じ内容で始まるリクエスト(通常は、新しいメッセージを追記した同一会話の直前のターン)。一致するプレフィックスがキャッシュ済み入力となり、それ以降が通常の入力となります。
- 粒度 — キャッシュはプロンプトを 1,568 トークンのブロック単位で保持するため、約 1,500 トークンより短いプロンプトはキャッシュされません。応答に含まれるキャッシュ済みの数は、入力数にプロンプトのキャッシュ済み割合を掛け、小数点以下を切り捨てた値です。ブロックサイズの倍数になるとは限りません。
- ヒットしない場合 — 先頭部分がキャッシュにないリクエストは、通常の入力レートで課金されます。キャッシュされたプロンプトの保持期間は公開されておらず、ヒットも保証されません。リクエストがキャッシュから何を取得したかは
usageで確認してください。 - 切り替えスイッチはありません — リクエストでオプトインする必要はなく、キャッシュを無効にするフィールドもありません。
- 対象モデル — すべてのホストされたオープンウェイトID。GET /v1/models では capabilities.prompt_caching: true および pricing.cached_input_per_million_usd が報告されます。Shannonモデルは一律料金です。
応答でキャッシュヒットを確認する
同じ長いシステムプロンプトで始まる 二つのリクエストを送信し、それぞれの使用量を出力します。最初の数値はリクエストの入力、二番目の数値はそのうちキャッシュから読み取られた部分です。
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 料金
キャッシュ済み入力トークンは、モデルの入力料金の25%で請求され、1Mあたり$0.001単位で切り捨てられます。キャッシュへの書き込みに追加費用はかからず、出力は通常通り請求されます。各IDのキャッシュ料金は「モデルと料金」テーブルに記載されています。 モデルと料金
呼び出しの入力は、(入力 − キャッシュ済み) × 入力レート + キャッシュ済み × キャッシュレートで課金されます。キャッシュ済みの数が入力の数を超えることはありません。
| モデル | 入力 / 1M | キャッシュ済み入力 / 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 |
使用量ログには、各呼び出しのキャッシュ済み入力が一覧表示されます。課金されたトークン数とコストには、キャッシュレートがすでに反映されています。 キーと使用量
使用量フィールド
| エンドポイント | キャッシュ済み入力 | 推論 |
|---|---|---|
/v1/chat/completions | usage.prompt_tokens_details.cached_tokens — prompt_tokensの一部 | usage.completion_tokens_details.reasoning_tokens — completion_tokensの一部 |
/v1/responses | usage.input_tokens_details.cached_tokens — input_tokensの一部 | usage.output_tokens_details.reasoning_tokens — output_tokensの一部 |
/v1/messages | usage.cache_read_input_tokens — 個別に報告:input_tokensは非キャッシュ部分、cache_creation_input_tokensは常に0 | 思考(thinking)は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
}
} ストリーム応答も、最後の使用量に同じフィールドを含みます。要求する必要はありません。
| エンドポイント | 使用量の届く場所 |
|---|---|
/v1/chat/completions | data: [DONE] の直前の最後のチャンクにある usage。すべてのストリームで送信されます。 |
/v1/responses | response.completed イベントの response.usage。 |
/v1/messages | message_delta イベントの usage。message_start の usage はゼロです。 |
キャッシュヒット率を高めるコツ
- システムプロンプトとツール定義を、呼び出し間でバイト単位で一致させてください。タイムスタンプやリクエストIDなどの呼び出しごとの値は、システムプロンプトではなく、最新のメッセージの末尾に配置してください。
- 履歴には「追記」のみを行ってください。以前のターンを編集、トリミング、または要約するとプレフィックスが変更され、最初の変更点以降のすべてが通常の入力として請求されます。
- 呼び出し間でツール、メッセージ、コンテンツブロックの順序を入れ替えないでください。また、JSON(ツールスキーマ、ツール引数、結果)は毎回同じ方法でシリアライズしてください。
- ひとつの会話では同じモデル ID を使い続け、後続の呼び出しは直前の呼び出しからあまり間を空けずに送信してください。
次の場合、API は会話の先頭部分を安定した状態に保ちます。
- 会話の途中で送信された
systemまたはdeveloperメッセージは、その位置に残ります。プロンプトの先頭は変わらないため、その前のターンはキャッシュされたままです。 - それ以前のアシスタントターンにあるツール呼び出しの引数は、値で比較されます。その JSON のキーの順序や空白は影響しません。
- 三つのエンドポイントは、会話を同じ方法で読み取ります。別のエンドポイントで続けた会話でも、内容が同じなら共通のプレフィックスが維持されます。
リクエストフィールド
prompt_cache_key(Chat CompletionsおよびResponses)とMessagesコンテンツブロックのcache_controlがサポートされており、既存のクライアントコードは変更せずに動作します。どちらも必須ではなく、キャッシュは自動的に機能します。
| フィールド | 送信先 | 内容 |
|---|---|---|
prompt_cache_key | /v1/chat/completions, /v1/responses | OpenAI API のキャッシュルーティングキー。 |
cache_control | /v1/messages | Anthropic API のコンテンツブロック、system ブロック、またはメッセージ上のキャッシュブレークポイント。 |
stream_options | /v1/chat/completions | include_usage は、OpenAI API でストリームの使用量を要求するものです。ここでは、すべてのストリームの最後に使用量が付きます。 |
トークンのカウント
無料の二つのエンドポイント POST /v1/tokenize と POST /v1/messages/count_tokens で、ホスト型オープンウェイトモデル向けに、テキストまたはリクエスト全体のトークン数を送信前に数えられます。 これらには専用のページがあります: トークンカウント