cd ../back to blog
$Guide//June 4, 2026//8 min read

プロンプトキャッシュ徹底解説:入力コストを最大90%削る方法

長いシステムプロンプトに全額払っていませんか。Anthropic の cache_control と OpenAI の自動キャッシュを Brievio で使い、入力コストを60〜90%削減する方法と、キャッシュを静かに壊す落とし穴、ヒット率の検証手順を解説します。

長いシステムプロンプト — RAG コンテキスト、ツールカタログ、エージェントの ルール、例 — を送っているなら、おそらく呼び出しのたびに全額の入力料金を 払っています。Anthropic のプロンプトキャッシュは、キャッシュされた部分に ついてそれを レートの 10% まで下げます。OpenAI も暗黙的に同じことを やっています。多くのチームが 30 分の作業に見合うと判断するのは、入力 コストの行を確実に 60〜90% 削れるからです。

Brievio は両方の流儀を改変せず、本物のモデルに対して素通しします。 Anthropic スタイルの cache_control は Messages API で動き、OpenAI スタイルの 自動キャッシュは Chat Completions API で動きます。この記事では両方、 キャッシュを静かに無効化する落とし穴、そしてヒット率の検証方法を順に 説明します。

ビフォー・アフター

同じ 18K トークンのシステムプロンプトを 10 回送る素朴なループ:

naive.py
# 多くの人が最初に書く形:呼び出しごとにプロンプト全体を再課金している。
import anthropic

client = anthropic.Anthropic(
    api_key="sk-brievio-...",
    base_url="https://api.brievio.com",
)

SYSTEM = open("system-prompt.md").read()        # 18,000 トークンのルール + 例

# 1 セッションでユーザーから 10 個の質問。毎回 18K トークンのシステムブロックを送る。
for question in questions:
    resp = client.messages.create(
        model="claude-sonnet-4-6",
        max_tokens=600,
        system=SYSTEM,
        messages=[{"role": "user", "content": question}],
    )

# 1 回あたりのコスト(入力のみ): 18,000 × $3 / 1M = $0.054
# 10 回: 入力だけで $0.54。

では、システムブロックをキャッシュ可能と印付けする — フィールドを 1 つ足すだけ:

cached.py
# 修正方法:静的なプレフィックスをキャッシュ可能と印付けする。最初の呼び出しの後、
# 約 5 分以内の後続呼び出しは、キャッシュされた部分について入力レートの 10% を払う。
# 同じ答え、89% 安い。
resp = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=600,
    system=[
        {
            "type": "text",
            "text": SYSTEM,
            "cache_control": {"type": "ephemeral"},  # キャッシュ可能と印付け
        }
    ],
    messages=[{"role": "user", "content": question}],
)

# 1 回目(キャッシュ書き込み):  18,000 × $3   / 1M = $0.054
# 2〜10 回目(キャッシュヒット): 18,000 × $0.30 / 1M = 各 $0.0054
# 合計: $0.054 + 9 × $0.0054 = $0.103 (以前は $0.54 — 81% 節約)

これでこのセッションの入力コストを 81% 節約しました。最初の呼び出しは 実は素朴な版よりわずかに高くつきます(キャッシュを 書き込むため入力レートの約 1.25 倍)。2〜10 回目はレートの 10% です。 損益分岐点は 2 回目 — 3 回目には先行し、10 回目には圧勝です。

OpenAI スタイル:何もする必要なし

OpenAI SDK を使っているなら、Chat Completions は 1,024 トークンを超える プロンプトのプレフィックスを自動的にキャッシュします。フラグも 設定も不要です。Brievio の背後にある同じモデルは、Anthropic ルートを 使っても OpenAI ルートを使っても割引を受けます:

openai_style.py
# OpenAI Chat Completions スタイル — 1024 トークン以上のプロンプトはキャッシュが自動。
# 設定するフラグはない。"usage" オブジェクトが何がキャッシュされたかを教えてくれる。
from openai import OpenAI

client = OpenAI(
    api_key="sk-brievio-...",
    base_url="https://api.brievio.com/v1",
)

resp = client.chat.completions.create(
    model="claude-sonnet-4-6",
    messages=[
        {"role": "system", "content": LONG_SYSTEM_PROMPT},  # >1024 トークン
        {"role": "user", "content": "Latest question…"},
    ],
)

# レスポンスの中で:
#   resp.usage.prompt_tokens_details.cached_tokens  →  17,800
#   resp.usage.prompt_tokens                        →  18,200
# 17.8K/18.2K = 入力の 98% がキャッシュ由来。請求はそれを自動で反映する。

usage.prompt_tokens_details.cached_tokens を読めば、どれだけが キャッシュから提供されたか分かります。固定プレフィックスが大きいほど 節約も大きい。経験則:システムプロンプトが可変のユーザーコンテンツより 短いなら、キャッシュの効果はあまりありません。静的な部分が大きく、 先頭に来るようにプロンプトを組み直しましょう。

多層キャッシュ — 最大 4 ブレークポイント

一部のレイヤーが他より速く変わるエージェントループでは、複数の cache_control ブレークポイントを設定します。それぞれが そこまでのすべてのスナップショットです:

breakpoints.py
# Anthropic はリクエストごとに最大 4 つのキャッシュブレークポイントをサポートする —
# 後半のレイヤーが変わってもキャッシュを温かいまま保つために使おう。
client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=600,
    system=[
        {"type": "text",
         "text": ROLE_AND_RULES,                      # 約 3,000 トークン
         "cache_control": {"type": "ephemeral"}},     # ブレークポイント 1
        {"type": "text",
         "text": LARGE_KNOWLEDGE_BASE,                # 約 15,000 トークン、めったに変わらない
         "cache_control": {"type": "ephemeral"}},     # ブレークポイント 2
    ],
    messages=[
        {"role": "user",
         "content": [
             {"type": "text",
              "text": CONVERSATION_HISTORY,           # ターンごとに増えていく
              "cache_control": {"type": "ephemeral"}}, # ブレークポイント 3
             {"type": "text", "text": new_question},
         ]},
    ],
)

# CONVERSATION_HISTORY が変わっても、ブレークポイント 1+2 はキャッシュにヒットする。
# 全額の入力レートを払うのはブレークポイント 3 + 新しい質問だけ。

キャッシュキーはプレフィックス全体です。位置 N にトークンを 1 つ足すと、 N 以降のすべてのブレークポイントが無効になります。順序が重要です: 最も安定したコンテンツを先頭に。ルールのレイヤーはめったに 変わらないはず。ナレッジベースは毎週更新され、会話はターンごとに 増えていきます。

キャッシュを静かに壊すよくあるやり方

  • プロンプトに現在の日付や request_id を入れる。 毎回が新しいプレフィックスになり、キャッシュヒット率は 0% です。 プロンプトの入力をハッシュ化し、呼び出し間で比較しましょう。
  • 非決定的なシステムプロンプトの組み立て。 システムを dict から組み立てている場合、一部の Python バージョンでは dict の 反復順序が影響します。キーを明示的にソートしましょう。
  • キャッシュの寿命は約 5 分。 まばらなトラフィック パターン(10 分に 1 回の呼び出し)ではヒットがゼロになります。 呼び出しをまとめるか、その損失を受け入れるかです。
  • 1,024 トークンの最小値。 1K トークン未満では OpenAI スタイルのキャッシュは作動しません。小さな静的フラグメントを 1 つの 長いプレフィックスにまとめましょう。
  • ツール / 関数定義はプレフィックスの一部。 カタログに新しいツールを追加すると、全員のキャッシュが無効になります。 ツールカタログを安定させ、バージョン管理しましょう。

ヒット率を検証する

見えないキャッシュはエンジニアリングではありません — ただの願望です。 呼び出しごとに usage をログに記録しましょう:

observe.py
# 必ず usage を読む。ヒットを期待したのに cached_tokens が 0 なら、
# どこかがおかしい — たいていは非決定的なプレフィックスが原因。
resp = client.messages.create(...)
u = resp.usage
print({
    "input_uncached":  u.input_tokens,
    "input_cache_read": u.cache_read_input_tokens,
    "input_cache_write": u.cache_creation_input_tokens,
    "output": u.output_tokens,
})

# よくある落とし穴:システムプロンプトに今日の日付や request_id を入れると、
# 静かにキャッシュが無効化される。入力をハッシュ化し、2 回目の同一呼び出しで
# cache_read_input_tokens が 0 でないことを検証しよう。

Brievio のダッシュボードでは、 使用状況ページがモデルごと・日ごとの キャッシュ内訳を表示します。cache_read_input_tokens が 総入力に占める割合として増えていれば、キャッシュは機能しています。 0 のまま、あるいは激しく変動するなら、上の落とし穴リストを順に 確認してください。

Brievio では実際いくらかかるのか

各モデルのキャッシュレートは 料金ページに掲載されています:

  • Anthropic モデル:キャッシュ読み取りは入力レートの 10%。キャッシュ書き込みは入力レートで課金され、上流の上乗せは ありません。
  • OpenAI / Gemini モデル:キャッシュ読み取りは入力 レートの 20%(各プロバイダーが公表している比率)です。
  • すべてのキャッシュ料金は Brievio の定価 — プロバイダーの 公式レートより約 15% 安い — を反映します。 したがって Brievio での Sonnet 4.6 のキャッシュ読み取りは $3 × 0.95 × 0.10 = $0.285 per 1M tokens です。 キャッシュなしの入力レートの約 10 分の 1 です。

キャッシュが答えではないとき

作業に見合わないケースがいくつかあります:

  • 短いプロンプト(合計 <1K トークン)。オーバーヘッドが 支配的になるので、わざわざやる必要はありません。
  • 繰り返しトラフィックのない単発タスク。 最初の 呼び出しはわずかに高くつき、キャッシュは 2 回目以降でしか元が 取れません。
  • 出力が多く入力が少ないタスク(創作、コード生成)。 入力はすでに請求のごく一部です。代わりに出力予算の上限に注力 しましょう。

それ以外のすべて — RAG チャットボット、固定ツールカタログを持つ エージェント、静的なルーブリックで動く分類器、一貫した few-shot を持つ 構造化抽出パイプライン — では、キャッシュは 1 つの午後で出荷できる 最も ROI の高い最適化です。これを コスト最適化プレイブックの他の 4 つの手法 と組み合わせれば、出力品質を一切犠牲にせず 70% のコスト削減が 現実的になります。

すでに Brievio をお使いですか? /app/usage を開いて、最大のモデルの キャッシュ列を確認してください。ゼロなら、お金をテーブルに置き去りに しています。完全ガイド: /docs/caching