CLAUDE LABEN
FORK — Claude Code 2.1.212で/forkの挙動が変わりました。会話を新しいバックグラウンドセッションへ複製し、作業を続けたまま並走できます。従来のセッション内サブエージェントは/subtaskに移りましたLIMITS — WebSearchの呼び出しがセッション単位で既定200回に制限されました。サブエージェントの起動も既定200回が上限で、暴走した検索・委譲のループを止められますMCPBG — 2分を超えるMCPツール呼び出しは自動的にバックグラウンドへ移り、セッションが固まらなくなりました。しきい値はCLAUDE_CODE_MCP_AUTO_BACKGROUND_MSで調整できますPLANFIX — プランモードがtouchやrmといったファイルを変更するBashコマンドを、許可プロンプトもcanUseToolコールバックも通さずに実行してしまう不具合が修正されましたSONNET5 — Claude Sonnet 5は導入価格として入力100万トークンあたり2ドル、出力10ドルで提供中です。8月31日を過ぎると3ドルと15ドルに戻りますIPO — Anthropicが早ければ10月の株式公開を視野に、引受銀行が投資家との面談を組み始めたと報じられていますFORK — Claude Code 2.1.212で/forkの挙動が変わりました。会話を新しいバックグラウンドセッションへ複製し、作業を続けたまま並走できます。従来のセッション内サブエージェントは/subtaskに移りましたLIMITS — WebSearchの呼び出しがセッション単位で既定200回に制限されました。サブエージェントの起動も既定200回が上限で、暴走した検索・委譲のループを止められますMCPBG — 2分を超えるMCPツール呼び出しは自動的にバックグラウンドへ移り、セッションが固まらなくなりました。しきい値はCLAUDE_CODE_MCP_AUTO_BACKGROUND_MSで調整できますPLANFIX — プランモードがtouchやrmといったファイルを変更するBashコマンドを、許可プロンプトもcanUseToolコールバックも通さずに実行してしまう不具合が修正されましたSONNET5 — Claude Sonnet 5は導入価格として入力100万トークンあたり2ドル、出力10ドルで提供中です。8月31日を過ぎると3ドルと15ドルに戻りますIPO — Anthropicが早ければ10月の株式公開を視野に、引受銀行が投資家との面談を組み始めたと報じられています
記事一覧/API & SDK
API & SDK/2026-04-26中級

Claude API のプロンプトキャッシュで月額コストを半分にした実装メモ

Claude API のプロンプトキャッシュを正しく設計すると、長文プロンプトを使う本番ワークロードは月額コストが体感で半分以下になります。実例ベースで設計のコツとつまずきどころをまとめました。

claude-api81prompt-caching12cost-optimization25production87anthropic12

Anthropic API のプロンプトキャッシュを使い始めて半年ほど経ちました。最初は半信半疑だったのですが、長文のシステムプロンプトを毎リクエスト送る本番ワークロードでは、請求額が体感で半分以下になります。一方で、設計を間違えるとほぼ何の効果もない、という落差が大きい機能でもあります。

この記事は、私が個人運営している複数のアプリケーションで実際にプロンプトキャッシュを導入して、月額コストの推移を追いながら設計を直していった記録です。公式ドキュメントには載っていない「現場で気づいた挙動」も含めて整理します。

なぜ私はプロンプトキャッシュを真剣に検討したのか

きっかけは恥ずかしい話ですが、API の請求額が想定の3倍に膨れていたことでした。チャット系のサービスでは、システムプロンプト(前提情報・ペルソナ・出力フォーマット指定)が長くなりがちで、私のケースでは6,000〜10,000トークンほど。これを毎ターン送り直していました。

20往復の会話で、システムプロンプトだけで12万トークン以上を消費している計算です。リクエスト本体のコンテキスト処理に埋もれて見えていませんでしたが、内訳を見て愕然としました。

プロンプトキャッシュは、この「同じ前提情報を毎回送る」コストを大きく下げてくれます。具体的には、キャッシュヒット時の入力トークン単価が標準の10分の1になります(書き込み時は1.25倍ですが、これは初回のみ)。

ただし、効果が出るかどうかは「プロンプトのどこに静的な部分があるか」「アクセスパターンがどうか」に強く依存します。

プロンプトキャッシュが効くプロンプト構造とは

公式の cache_control パラメータを使うと、プロンプトの特定の位置までを「キャッシュ対象」として指定できます。Python SDK だと次のようになります。

from anthropic import Anthropic
 
client = Anthropic()
 
response = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=1024,
    system=[
        {
            "type": "text",
            "text": LONG_STATIC_SYSTEM_PROMPT,  # 数千トークン
            "cache_control": {"type": "ephemeral"}
        }
    ],
    messages=[
        {"role": "user", "content": user_input}
    ]
)

cache_control を付けた要素までがキャッシュされます。重要なのは、キャッシュは「プロンプトの先頭からその位置まで」が完全一致した場合にのみヒットすることです。つまり、キャッシュ対象の前にユーザーごとに変わる情報が混ざっていると、ヒットしません。

私が最初にハマったのはこれでした。ユーザー名やセッション情報をシステムプロンプトの冒頭に書いていたため、キャッシュは存在するのに毎回ミスしていたのです。

正しい配置は、静的な情報を先頭に、動的な情報を後ろに置くことです。

system=[
    {
        "type": "text",
        "text": STATIC_PROMPT,        # 動かない部分(ペルソナ・ルール・例示)
        "cache_control": {"type": "ephemeral"}
    },
    {
        "type": "text",
        "text": f"User context: {user_id}, time: {now}"  # 動的部分
    }
]

キャッシュヒット率を測ることから始める

導入してすぐにやるべきは、ヒット率の計測です。レスポンスの usage には次のようなフィールドが含まれます。

print(response.usage)
# Usage(
#   input_tokens=120,
#   cache_creation_input_tokens=0,
#   cache_read_input_tokens=8500,
#   output_tokens=300
# )

cache_read_input_tokens がキャッシュヒットしたトークン数、cache_creation_input_tokens が新規にキャッシュ書き込みされたトークン数です。input_tokens は通常通り課金される入力トークン。

私は最低限、次のメトリクスを記録しています。

def log_cache_metrics(response, request_id):
    usage = response.usage
    total_input = (
        usage.input_tokens
        + usage.cache_creation_input_tokens
        + usage.cache_read_input_tokens
    )
    hit_rate = usage.cache_read_input_tokens / total_input if total_input else 0
 
    logger.info({
        "request_id": request_id,
        "cache_hit_rate": hit_rate,
        "cache_read": usage.cache_read_input_tokens,
        "cache_write": usage.cache_creation_input_tokens,
        "input_uncached": usage.input_tokens,
        "output": usage.output_tokens,
    })

ヒット率が80%を超えていれば設計は概ね正しいです。50%を切る場合は、キャッシュ境界の前に動的な情報が混ざっている可能性が高いので、プロンプトを再点検します。

TTL(Time To Live)の選び方

ephemeral キャッシュのデフォルト TTL は5分です。最後にアクセスされてから5分経つと自動的に削除されます。チャットのような連続的な対話では十分ですが、たとえば「平日の昼休みだけ集中アクセスがある社内ツール」では、休憩時間の度にキャッシュが消えて再書き込みになります。

長めの TTL(1時間)を使う場合は、cache_controlttl を指定します。

"cache_control": {"type": "ephemeral", "ttl": "1h"}

ただし、長い TTL は書き込みコストの単価が上がります(1時間 TTL は標準の2倍)。ヒット率が高ければ得ですが、低ければ損です。

私の経験則は次の通りです。ユーザーあたり1日10回以上アクセスがある定常ワークロードなら1時間 TTL が有利。深夜だけ動くバッチ処理など、再アクセスが見込めない場合は5分 TTL のままでよい。サービスの利用パターンをログから読んでから決めるのが安全です。

トークン下限を意識する

プロンプトキャッシュには「最小キャッシュ可能トークン数」があります。Claude Sonnet 系では1,024トークン、Haiku 系では2,048トークンです。これより短いプロンプトには cache_control を付けても効きません。

意外と見落としがちなのが、システムプロンプトを「動的に組み立てる」関数です。たとえばユーザー権限によってルールを増減させていると、ある日は2,000トークンでキャッシュが効き、別の日は900トークンで効かない、ということが起きます。

私は本番サービスでは、システムプロンプトを「常に1,024トークン以上になる」ようにテンプレート化しました。例示セクションを充実させて、動的部分(ユーザー固有情報)はキャッシュ境界の外に置く設計です。これで安定してヒット率を稼げます。

4ブロック上限という制約

cache_control を付けられるのは1リクエストにつき最大4ブロックまでです。長大な RAG 文書などをキャッシュしたい場合、無計画にブロックを切ると上限に引っかかります。

おすすめは、論理的に意味のある単位で4ブロック以内に分けることです。

system=[
    {"type": "text", "text": COMPANY_RULES, "cache_control": {"type": "ephemeral"}},
    {"type": "text", "text": OUTPUT_FORMAT_SPEC, "cache_control": {"type": "ephemeral"}},
    {"type": "text", "text": EXAMPLES, "cache_control": {"type": "ephemeral"}},
    {"type": "text", "text": USER_RAG_CONTEXT, "cache_control": {"type": "ephemeral"}},
]

それぞれのブロックは独立した「キャッシュ階層」を作るので、USER_RAG_CONTEXT だけが変わってもその前の3ブロックはヒットします。これは長期記憶を持つボットを作るときに強力です。

RAG ワークロードでの実装パターン

実際に私が個人開発のサポートボットで使っている設計を共有します。FAQ データを Claude にロードして応答させるシンプルな RAG です。

def build_messages(user_query: str, retrieved_docs: list[str]) -> dict:
    return {
        "system": [
            {
                "type": "text",
                "text": SYSTEM_PROMPT_BASE,  # ペルソナと出力ルール
                "cache_control": {"type": "ephemeral"}
            },
            {
                "type": "text",
                "text": FAQ_KNOWLEDGE_BASE,  # 約50KB の固定 FAQ
                "cache_control": {"type": "ephemeral"}
            },
            {
                "type": "text",
                "text": "\n".join(retrieved_docs)  # クエリごとに変わる
            }
        ],
        "messages": [
            {"role": "user", "content": user_query}
        ]
    }

このパターンで、FAQ 部分のキャッシュヒット率は95%以上を維持できています。検索結果(retrieved_docs)はキャッシュ外なので毎回新規ですが、これは仕方ありません。

トータルで見ると、月額コストは導入前の38%まで下がりました。当初の半分どころか3分の1近くです。

ヒットしないときに疑うべき5つのポイント

これは現場で何度も書いた「自分用チェックリスト」です。

第一に、cache_control を付けた要素より前に、動的な内容が混ざっていないか。私は最初これでつまずきました。

第二に、最小トークン数を満たしているか。1,024トークン未満では Sonnet ではキャッシュされません。

第三に、TTL 切れではないか。5分以上アクセスが空くと自動的に削除されます。

第四に、モデルが違っていないか。claude-sonnet-4-6claude-sonnet-4-5 でキャッシュは別になります。バージョンアップ時はキャッシュが一旦リセットされます。

第五に、空白や改行の差分はないか。文字列が1バイトでも違うとヒットしません。プロンプトを動的生成しているなら、テンプレート関数の挙動を疑います。

月額コスト推移の実例

参考までに、私のサポートボット(月間リクエスト数 約12,000)でのコスト推移を共有します。

導入前: 月額 $187 (約 ¥28,000)。プロンプトキャッシュなし、システムプロンプト約8,000トークン × 平均20往復。

導入1週間後: 月額 $142 (約 ¥21,000)。境界の置き方を間違えてヒット率が30%程度。

導入1ヶ月後: 月額 $79 (約 ¥12,000)。動的部分を後ろに移し、TTL を1時間に。ヒット率92%。

導入3ヶ月後: 月額 $71 (約 ¥10,500)。RAG 文書もキャッシュ対象に追加。

数字としては、12月比で約62%のコスト削減。プロンプト長が増えるほどキャッシュの恩恵は大きくなるので、長文プロンプトを使うサービスほど検討する価値があります。

次にやること

この記事を読んで「うちでも効きそうだ」と思った方は、まず1日分のリクエストログを取って、システムプロンプトの長さとリクエスト頻度を見てみてください。最小トークン数(1,024)を超えていて、同じ前提情報を繰り返し送っているなら、ほぼ確実に恩恵があります。

実装は「system を配列にして cache_control を付ける」だけなので、半日もあれば組めます。難しいのは設計の方で、特に「どこを境界にするか」と「どう計測するか」が肝心です。この記事のチェックリストを手元に置いて、ヒット率を見ながら境界を動かしてみてください。

最初の数日でヒット率を80%まで持っていけたら、コスト削減はほぼ確実です。

シェア

お読みいただきありがとうございます

Claude Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • コピー&ペーストで使える実装コード付き
  • 毎日新しい上級ガイドを追加
  • ¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

もしこの記事がお役に立ちましたら、チップ(¥150)で応援いただけると大変励みになります。広告なしでの運営を続けるため、皆さまのご支援が大きな力になっています。

関連記事

API & SDK2026-05-29
Claude API のプロンプトキャッシュを 5m と 1h で二段に分ける — TTL を分けるとコストは下がり運用は安定する
Anthropic API の cache_control には 5 分と 1 時間という 2 種類の TTL があります。これを「静的な前提情報は 1h、可変な few-shot は 5m」と二段に分けて運用する設計を、私の本番ワークロードで観測した数値とともに整理しました。
API & SDK2026-04-28
Claude API のプロンプトキャッシュがヒットしない時の診断手順
Claude API のプロンプトキャッシュが効いていない時、まず確認すべきは usage フィールドです。cache_read_input_tokens がゼロのまま増えない原因を、5つの典型パターンに沿って切り分けます。
API & SDK2026-07-13
Claude API の同時実行を束ねる — シングルフライトで重複推論とキャッシュ・スタンピードを防ぐ
同一プロンプトが同時に何度も Claude へ飛ぶ重複推論を、シングルフライト(request coalescing)で束ねる設計です。プロセス内・分散環境の実装、ジッター付きリトライ、負のキャッシュまで実測付きでまとめました。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →