CLAUDE LABEN
APPLY — ant CLI v1.30.0 に ant apply が入りました。エージェント・環境・スキル・メモリストア・デプロイメントを、リポジトリのファイルから作成・更新できますLOCKFILE — 書き出される claude-lock.json は必ずコミットしてください。忘れると、実行のたびに同じリソースが新しく作られていきますPLAN — ant apply は適用の前に計画を表示し、承認を挟みます。CI で無人実行するなら、この承認をどう扱うかを先に決めておくことですPRICING — Claude Sonnet 5 の 3 ドル / 15 ドルへの値上げは実施されていません。導入価格の 2 ドル / 10 ドルがそのまま標準価格になりましたSOURCE — 価格と版番号は二次ニュースに誤りが混じります。platform.claude.com のリリースノートで裏を取ってから書くようにしていますBETA — Agent Skills と Skills API はベータを抜け、skills-2025-10-02 ヘッダが不要になりました。Files API はヘッダの有無でレスポンス形式が変わる点に注意ですAPPLY — ant CLI v1.30.0 に ant apply が入りました。エージェント・環境・スキル・メモリストア・デプロイメントを、リポジトリのファイルから作成・更新できますLOCKFILE — 書き出される claude-lock.json は必ずコミットしてください。忘れると、実行のたびに同じリソースが新しく作られていきますPLAN — ant apply は適用の前に計画を表示し、承認を挟みます。CI で無人実行するなら、この承認をどう扱うかを先に決めておくことですPRICING — Claude Sonnet 5 の 3 ドル / 15 ドルへの値上げは実施されていません。導入価格の 2 ドル / 10 ドルがそのまま標準価格になりましたSOURCE — 価格と版番号は二次ニュースに誤りが混じります。platform.claude.com のリリースノートで裏を取ってから書くようにしていますBETA — Agent Skills と Skills API はベータを抜け、skills-2025-10-02 ヘッダが不要になりました。Files API はヘッダの有無でレスポンス形式が変わる点に注意です
記事一覧/API & SDK
API & SDK/2026-07-19上級

プロンプトキャッシュを入れたのに請求が下がらなかったとき — cache_read を計測してヒット率の穴を塞ぐ運用メモ

cache_control を付けたのに Claude API の請求が下がらない。原因を推測で潰す前に cache_read と cache_creation を毎リクエスト記録し、ヒット率の穴を非決定プレフィックス・TTL 失効・しきい値未満の3系統に切り分ける運用メモです。

prompt-caching15cache-hit-ratecost-optimization28observability15api39

プレミアム記事

先月の請求書を開いて、少し手が止まりました。システムプロンプトに cache_control を付けたのは3週間前。ヒット率のことは気にせず「これで9割引きになるはず」と思い込んでいたのですが、入力トークンの請求はほとんど変わっていません。

キャッシュは「有効にした/していない」の二値ではないのだと、このとき初めて腹に落ちました。付けてある。けれど読まれていない。その差は請求書の数字にしか現れず、コードを眺めても見えてこない。

この記事は、個人開発で回している要約バッチのキャッシュヒット率を 3割台から9割近くまで引き上げるまでの、計測と手直しの記録です。派手な最適化テクニックの話ではありません。まず計測し、穴を名指しし、ブレークポイントを1つずつ動かす。その地味な往復のメモです。

「有効にした」と「効いている」は別の状態です

プロンプトキャッシュは、リクエストの systemtoolsmessages の先頭(プレフィックス)をサーバー側に一時保存する仕組みです。同じプレフィックスが後続のリクエストで再利用されると、その部分は通常の入力料金の約1割で処理されます。

問題は、cache_control を書いた時点では何も保証されないという点です。実際にキャッシュが読まれたかどうかは、レスポンスの usage を見るまで分かりません。ここを見ていなかったことが、私の3週間の見落としの正体でした。

usage フィールド意味課金の目安(通常入力比)
cache_creation_input_tokensキャッシュへ書き込んだトークン(=この回はミス)約 1.25 倍(5分キャッシュ)
cache_read_input_tokensキャッシュから読んだトークン(=この回はヒット)約 0.1 倍
input_tokensキャッシュ対象外の通常入力1 倍

読み方はシンプルです。cache_read_input_tokens が毎回それなりの値で返っていれば効いています。逆に、cache_creation_input_tokens ばかりが立ち続けているなら、キャッシュは「作られては捨てられ」を繰り返しています。付けたのに効かない、はほぼこの状態です。

まず計測ハーネスを1枚だけ挟みます

原因を推測で潰し始める前に、全リクエストの usage を記録する薄い層を入れました。最適化より前に、まず現在地を数字で知りたかったからです。

import time
import logging
from dataclasses import dataclass, field
 
logger = logging.getLogger("cache")
 
@dataclass
class CacheProbe:
    """cache_read / cache_creation を毎リクエスト記録する最小ハーネス"""
    requests: int = 0
    hits: int = 0            # cache_read > 0 の回数
    rewrites: int = 0        # cache_creation > 0 の回数
    read_tokens: int = 0
    write_tokens: int = 0
    # 直近のミスを原因分類するための痕跡
    last_prefix_fingerprint: str | None = field(default=None)
 
    def record(self, usage) -> None:
        self.requests += 1
        read = getattr(usage, "cache_read_input_tokens", 0) or 0
        write = getattr(usage, "cache_creation_input_tokens", 0) or 0
        self.read_tokens += read
        self.write_tokens += write
        if read > 0:
            self.hits += 1
        if write > 0:
            self.rewrites += 1
 
    @property
    def hit_rate(self) -> float:
        # 「書き込みが発生しなかった」= ヒットとみなす
        return (self.hits / self.requests * 100) if self.requests else 0.0
 
    @property
    def rewrite_rate(self) -> float:
        return (self.rewrites / self.requests * 100) if self.requests else 0.0
 
    def snapshot(self) -> str:
        return (
            f"req={self.requests} hit={self.hit_rate:.1f}% "
            f"rewrite={self.rewrite_rate:.1f}% "
            f"read_tok={self.read_tokens:,} write_tok={self.write_tokens:,}"
        )

record() を呼ぶだけの層です。ここで見たかったのは1点だけ。書き込み率(rewrite_rate)が高止まりしていないかです。要約バッチで実測したところ、ヒット率は 34.8%、書き込み率は 61.2% でした。半分以上のリクエストがキャッシュを作り直している。これで請求が下がらない理由が、ようやく数字になりました。

なぜ「書き込み率」を主役にするかというと、ヒット率だけを見ていると原因が見えないからです。ヒットしていない = ミス、までは分かっても、ミスが「プレフィックスがずれた」のか「時間切れで消えた」のかを区別できません。書き込みが何回、どの間隔で起きているかを見ると、この切り分けが一気に進みます。

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

この記事の続きを読む

この先には、実装コードやベンチマーク結果など、実務でお役に立てる内容をご用意しています。このサイトは広告を掲載しておらず、サーバーや開発にかかる費用はメンバーの皆様のご支援で成り立っています。もしお役に立てていましたら、ご支援いただけますと大変ありがたいです。

この記事で得られること
usage から cache_read と cache_creation を取り出し、ヒット率とキャッシュ書き直し回数を毎リクエスト記録する最小ハーネス
ヒット率が伸びない原因を「非決定プレフィックス・TTL 失効・しきい値未満」の3系統に計測で切り分ける手順
cache_creation が繰り返し出続けるときにブレークポイントを1つずつ後ろへ動かして安定プレフィックスを探す実測の進め方
Stripe による安全な決済 · いつでもキャンセル可能

この記事を購入する

この先の内容をすべてお読みいただけます。一度のご購入で、いつでも何度でもアクセスできます。このサイトは広告を掲載しておらず、皆さまのご支援がサーバー費用などの運営を支えています。

または
メンバーシップなら全記事が読み放題 →
シェア

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

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

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

関連記事

API & SDK2026-06-23
Claude API のプロンプトキャッシュが本番で静かにヒットしなくなるとき — TTLと節約額の実測メモ
プロンプトキャッシュは導入直後だけ効いて、本番では知らぬ間にヒットしなくなることがあります。完全一致プレフィックスを静かに壊す5つの要因、5分と1時間TTLの選び方、節約額を推測でなく実測に変える計装、変更頻度の階段で置くブレークポイント設計までを運用目線でまとめました。
API & SDK2026-03-26
Claude API コスト最適化プロダクションガイド — Batch API・Prompt Caching・Adaptive Thinking を組み合わせて最大90%削減する実装パターン
Claude APIの利用コストを最大90%削減する実践的な実装パターンを解説。Batch API、Prompt Caching、Adaptive Thinkingの組み合わせ戦略から、本番環境での監視・予算管理まで網羅した上級者向けガイド。
API & SDK2026-09-07
キャッシュ読み取りが 75% 安くなっても、請求の下がり方は構成しだいで 10 倍違います
Fable 5.1 と Mythos 5.1 でキャッシュ読み取りの倍率が 0.1 から 0.025 へ変わりました。自分のトークン内訳から削減幅を先に見積もる手順と、倍率を定数で持つコードの直し方をまとめます。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます