|

Claudeプロンプトキャッシュがヒットしない?5つの原因調査と最低トークンしきい値のクイックチェック

Claude API を使用して長大なコンテキストを呼び出す際、多くの開発者が同じ疑問に直面します。「cache_control フィールドでキャッシュを宣言したはずなのに、レスポンス内の cache_creation_input_tokenscache_read_input_tokens が 0 のままで、請求書にもキャッシュの割引が反映されていない」というものです。本記事では、Claude プロンプトキャッシュがヒットしない 5 つの主な原因を体系的に分解し、最も見落とされがちな「最低キャッシュ可能トークンしきい値」と「サイレント失敗」のメカニズムについて詳しく解説します。

核心的価値: 本記事を読めば、Anthropic 各モデルの最低キャッシュしきい値を理解し、短いプロンプトに cache_control を付けてもエラーにならずキャッシュもされない理由を把握でき、さらに 4 行のコードでキャッシュがヒットしたかどうかを判断できるようになります。

claude-prompt-caching-not-hit-minimum-token-troubleshooting-ja 图示

Claude プロンプトキャッシュの核心ポイント

Claude プロンプトキャッシュは、Anthropic が提供するプロンプトキャッシュ機能です。繰り返し使用されるシステムプロンプト、長大なドキュメント、ツール定義を一時キャッシュに保存し、次回ヒット時に読み取り料金で課金される仕組みで、通常の入力料金より約 90% 安価になります。その重要な特徴は「プレフィックス一致 + 明示的宣言 + サイレント失敗」の 3 点であり、これらがトラブルシューティングの方向性を決定づけます。

ポイント 説明 排出価値
明示的宣言 systemmessages、または tools 内に cache_control ブロックを挿入する必要がある 記述漏れや位置が誤っているとキャッシュされない
プレフィックス一致 キャッシュブロックより前のすべての内容がバイト単位で一致する必要がある わずか 1 つのスペースの違いでも無効になる
サイレント失敗 条件を満たさないリクエストはエラーにならず正常に返される usage フィールドを能動的に検証する必要がある
TTL 制限 デフォルト 5 分、最大 1 時間 長い間隔での呼び出しは自然に期限切れになる

「サイレント失敗」は、この仕組みの中で最も躓きやすい部分です。Anthropic のドキュメントでは、リクエストがキャッシュ条件(長さ不足やプレフィックスの変更など)を満たさない場合、API は通常の回答を返しますが、キャッシュの作成や読み取りは行われず、エラーもスローされないと明記されています。つまり、呼び出しコード上では何の異常も見当たらず、レスポンス内の usage オブジェクトを通じて能動的に確認するしかありません。

APIYI (apiyi.com) プラットフォームを通じて Claude の Sonnet、Opus、Haiku シリーズモデルを呼び出している場合、キャッシュロジックは Anthropic の公式インターフェースと完全に一致しています。本番環境に実装する前に、一度 usage フィールドを出力して、キャッシュが確実に有効であることを確認してから運用を開始することをお勧めします。

Claudeプロンプトキャッシング:各モデルの最低トークン閾値クイックリファレンス

プロンプトキャッシングがヒットしない原因として最も見落とされがちなのが、プロンプトの長さがAnthropicによって各モデルに設定された「最小キャッシュ可能トークン」の閾値に達していないことです。この長さを下回ると、cache_controlを指定していても通常のプロンプトとして処理されてしまいます。モデルごとに閾値は大きく異なるため、2026年5月現在の公式データをまとめた以下の表をぜひ保存して活用してください。

claude-prompt-caching-not-hit-minimum-token-troubleshooting-ja 图示

モデル 最低キャッシュ可能トークン 備考
Claude Opus 4.7 / 4.6 / 4.5 4096 最新のフラッグシップ、閾値が最大
Claude Sonnet 4.6 2048 現在の主力Sonnet、閾値が倍増
Claude Sonnet 4.5 / Sonnet 4 / Sonnet 3.7 1024 従来の定番Sonnetシリーズ
Claude Opus 4.1 / Opus 4 1024 旧世代Opus
Claude Haiku 4.5 4096 Sonnetよりも高い閾値
Claude Haiku 3.5 2048 長期安定の高速モデル

初めてこの表を見ると、「なぜHaiku 4.5のような『軽量モデル』の閾値がOpus 4.7と同じくらい高いのか?」と疑問に思うかもしれません。理由は、新世代のHaikuがより長いアテンションウィンドウを採用しているためです。キャッシュヒットによるエンジニアリング上のメリットは、より長いプレフィックス(接頭辞)があって初めて顕著になるため、Anthropicは製品戦略として閾値を引き上げています。

実務で最も多い誤判断は、旧版Sonnet 3.7の「1024トークン」という感覚でプロンプトを設計し、Sonnet 4.6に切り替えた途端にキャッシュが効かなくなり、コードのミスを疑うケースです。APIYI (apiyi.com) を通じて複数のClaudeモデルを呼び出している場合は、この表を参考に、モデル名に応じて閾値を動的に判定する仕組みを組み込むことを強く推奨します。

Claudeプロンプトキャッシングがヒットしない5つの原因

「最低トークン閾値」と「サイレント失敗」の仕組みを理解すれば、ヒットしない問題を体系的に調査できます。以下に、発生頻度が高い順に5つの原因を挙げました。特に最初の2つは、日常的なデバッグで遭遇するケースの大半を占めます。

claude-prompt-caching-not-hit-minimum-token-troubleshooting-ja 图示

原因1:プロンプト長が最低閾値を下回っている

これが最大の原因です。例えばSonnet 4.6でキャッシュを宣言しても、実際のシステムプロンプトが1500トークンしかなければ、キャッシュは作成されません。診断方法は簡単です。ローカルのトークナイザーで「システムプロンプト+ツール定義+キャッシュ済みメッセージ」の合計トークン数を概算し、表の閾値と比較してください。

より見つけにくいのが「複数のcache_controlブロックの重ね合わせ」です。Anthropicの仕様では「各キャッシュポイントよりも前の累積内容がモデルの閾値に達している必要がある」ため、達していない場合はそのポイントが無効になります。初心者はまず1つのcache_controlブロックのみを使用し、仕組みに慣れてから階層化することをお勧めします。

原因2:キャッシュプレフィックスのバイトレベルの不一致

プロンプトキャッシングは厳密なプレフィックスマッチングです。システムプロンプト、ツール定義、メッセージ履歴のいずれか1文字でも異なれば、キャッシュは無効とみなされ、再書き込みが発生します。よくある「偽の変化」には以下が含まれます。

  • システムプロンプトにタイムスタンプなどのレンダリングロジックが含まれており、リクエストごとに内容が変わる
  • Pythonの辞書型を使用しており、ツール定義のシリアライズ順序が実行ごとに漂流する
  • 履歴メッセージに対してトリミングや重複排除処理を行い、同一の会話でも微妙な差異が生じている

この問題を特定する最も直接的な方法は、2回のリクエストの完全なペイロードをdiffで比較することです。APIYI (apiyi.com) を経由して中継している場合は、ゲートウェイログでリクエストボディをハッシュ化し、不一致があればプレフィックスのズレを特定できます。

原因3:TTLの期限切れ

デフォルトのTTLは5分です。この間隔を超えると古いキャッシュエントリは解放され、次のリクエストで再書き込みがトリガーされます。1時間のTTL書き込み価格は基本入力価格の2倍となるため、呼び出し頻度に応じてコストに見合うか検討が必要です。

TTL期限切れの兆候は、本来キャッシュが効くはずのタイミングでcache_creation_input_tokensが突然ゼロ以外の値になることです。この場合はリクエスト間隔を短縮するか、"ttl": "1h"を指定してください。

原因4:cache_controlの位置エラー

cache_controlsystemmessages、またはtools配列内の具体的なコンテンツブロックに付与する必要があり、typeは必ずephemeralである必要があります。よくある誤用は以下の通りです。

  • messages.create()のトップレベルパラメータに記述している(正しくはコンテンツブロック内)
  • messages配列のuserメッセージに記述しているが、実際にはsystemプロンプトをキャッシュしたい
  • 同一メッセージ内に複数のcache_controlを記述しているが、いずれも2048トークンの閾値に達していない

正しい方法は、キャッシュしたい「ここまで」というブロックの内部に直接cache_controlを埋め込むことです。これでプロンプトの先頭からそのブロックの末尾までがロックされます。

原因5:ワークスペースやモデルの跨ぎによるキャッシュの非共有

2026年2月5日以降、Anthropicはプロンプトキャッシュの分離境界を「ワークスペース単位」に変更しました。つまり、異なるワークスペース間ではキャッシュは共有されません。APIキーやワークスペースが異なれば、キャッシュは再利用できません。

モデルレベルでも同様です。Sonnet 4.6でキャッシュしたプロンプトをSonnet 4.5で呼び出してもヒットしません。マルチモデルで運用する場合は、モデルごとにキャッシュのウォーミングアップスクリプトを維持するか、APIYI (apiyi.com) のような統合プラットフォームを使用して上流のワークスペースを統一し、キャッシュの断片化を防ぐのが賢明です。

Claude プロンプトキャッシングのヒット確認コードと判定ロジック

ヒットしない問題を調査する際の第一歩は、常に「usage フィールドを出力すること」です。Anthropic の messages.create のレスポンスには毎回 usage オブジェクトが含まれており、ここにある4つの重要なフィールドが、キャッシュ状態を判断するための唯一の信頼できる根拠となります。

最低限の確認コード

import anthropic

client = anthropic.Anthropic(
    api_key="YOUR_APIYI_KEY",
    base_url="https://api.apiyi.com"
)

response = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=1024,
    system=[{
        "type": "text",
        "text": LONG_SYSTEM_PROMPT,   # 2048トークン以上である必要があります
        "cache_control": {"type": "ephemeral"}
    }],
    messages=[{"role": "user", "content": "your question"}]
)

u = response.usage
print(f"キャッシュ書き込み: {u.cache_creation_input_tokens}")
print(f"キャッシュ読み取り: {u.cache_read_input_tokens}")
print(f"キャッシュなし入力: {u.input_tokens}")

このコードを調査用テンプレートとして活用してください。キャッシュが効いていないと疑われる場合は、すぐにこのコードを実行し、返されたフィールドを確認することで問題の切り分けが可能です。

完全な実装版を確認する
import anthropic
import logging

MIN_TOKENS = {
    "claude-opus-4-7": 4096,
    "claude-opus-4-6": 4096,
    "claude-opus-4-5": 4096,
    "claude-sonnet-4-6": 2048,
    "claude-sonnet-4-5": 1024,
    "claude-haiku-4-5": 4096,
    "claude-haiku-3-5": 2048,
}

def call_with_cache_check(model: str, system_text: str, user_msg: str):
    client = anthropic.Anthropic(
        api_key="YOUR_APIYI_KEY",
        base_url="https://api.apiyi.com"
    )
    response = client.messages.create(
        model=model,
        max_tokens=1024,
        system=[{
            "type": "text",
            "text": system_text,
            "cache_control": {"type": "ephemeral"}
        }],
        messages=[{"role": "user", "content": user_msg}]
    )
    u = response.usage
    if u.cache_creation_input_tokens == 0 and u.cache_read_input_tokens == 0:
        logging.warning(
            f"キャッシュが有効ではありません。{MIN_TOKENS.get(model)} トークンのしきい値を下回っている可能性があります"
        )
    return response

ヒット状態判定表

cache_creation_input_tokens cache_read_input_tokens 判定結果
> 0 = 0 キャッシュへの初回書き込み(正常)
= 0 > 0 キャッシュヒット(理想的)
> 0 > 0 部分ヒット、追加分が書き込まれました
= 0 = 0 キャッシュなし、原因の調査が必要

最後の行が問題発生時の兆候です。この状態であれば、直ちに原因調査を開始し、5つのチェックポイントと照らし合わせてください。チームでAPIの安定性を重視する場合は、この判定ロジックをミドルウェアとしてAPIYI (apiyi.com) の呼び出しチェーンに組み込み、異常検知時に即座に通知を受け取れるようにすることをお勧めします。

最低トークンしきい値をクリアする4つの実用テクニック

「長さ不足」が原因でヒットしないと確認できた場合、次はキャッシュプレフィックスを基準値まで引き上げる必要があります。以下に推奨順で4つのテクニックを紹介します。最初の3つは副作用がほとんどありません。

claude-prompt-caching-not-hit-minimum-token-troubleshooting-ja 图示

技巧 適用シーン トークン増加目安 注意事項
完全な知識ベース システムプロンプトが薄い +2000~4000 毎回必ず使用される内容であること
ツール定義の集中管理 マルチツールアプリ +500~2000 toolsフィールドもキャッシュ可能
よく使う few-shot 例 タスク特化型プロンプト +1000~3000 汎用的な価値がある例であること
無関係なテキストの埋め込み 緊急時 任意 推奨しません。出力品質に影響します

1つ目の「完全な知識ベース」は最も堅実な方法です。FAQ、スタイルガイド、SOPなど、アプリケーションが本来持っている知識を system ブロックの先頭に配置し cache_control を設定すれば、簡単に4096トークンを超え、すべてのモデルのしきい値を満たせます。

2つ目の「ツール定義」は見落とされがちです。Anthropic の tools フィールドもキャッシュに対応しており、マルチツール Agent アプリには非常に有効です。標準的なツール定義と JSON Schema を組み合わせれば、容易に2048トークンを突破できます。

3つ目の「few-shot 例」は複雑なタスクに適しています。3〜5個の標準的な事例を system の末尾に配置することで、出力の安定性を高めつつ、トークン数を1500から2500〜3500まで引き上げ、Sonnet 4.6 のしきい値をクリアできます。

4つ目の「無関係なテキストの埋め込み」はあくまで緊急手段です。モデルがそのテキストを読み込むため、出力スタイルに影響が出る可能性があります。どうしても長さが足りない場合は、APIYI (apiyi.com) プラットフォームを通じて、しきい値の低い Sonnet 4.5 や Sonnet 3.7 に切り替え、既存のプロンプトを1024トークンの範囲内に収めることを検討してください。

よくある質問

Q1: cache_control を追加したのにキャッシュされません。APIのバグでしょうか?

バグである可能性は低く、サイレント失敗(静かな失敗)のメカニズムがトリガーされている可能性が高いです。まずは model フィールドに対応する最小トークンしきい値を確認し、次に usage オブジェクトを出力してみてください。99%のケースで、トークン長が足りないか、プレフィックスが変更されていることが原因です。

Q2: cache_creation_input_tokens の料金は高いですか?

5分間のTTL書き込みは基本入力価格の1.25倍、1時間のTTLは2倍です。読み取り価格は0.1倍となります。一般的に、5分キャッシュは1回読み出せば元が取れ、1時間キャッシュは2回読み出せば元が取れます。再利用回数が多いほど、コスト効率は高まります。

Q3: 旧ドキュメントでは Sonnet の最小値は 1024 でしたが、新版では 2048 になっています。なぜですか?

これは Sonnet 4.6 から適用された新しいしきい値です。Sonnet 4.5 以前のバージョンは引き続き 1024 です。コード内で「モデル → しきい値」のマップテーブルを保持し、呼び出すモデルに応じて動的に判断することをお勧めします。APIYI (apiyi.com) を経由して呼び出す場合、model フィールドの命名は Anthropic 公式と完全に一致しているため、同じマッピングロジックをそのまま流用可能です。

Q4: 複数の cache_control ブロックを安全に使うには?

cache_control は、プレフィックスの累積がしきい値に達している必要があります。達していない場合、そのブレークポイントは無効になります。初心者の方には、ブレークポイントを1つだけ設定し、system ブロック全体をキャッシュすることをお勧めします。どうしても階層化したい場合は、「ほとんど変化しない知識ベース」を第1層に、「たまに変化するツール定義」を第2層に配置してください。

Q5: 国内の API 中継サービスで prompt caching をテストできますか?

はい、可能です。APIYI (apiyi.com) などの集約中継プラットフォームの Claude シリーズ API は、Anthropic 公式と完全に互換性があり、cache_controlttlusage フィールドもサポートしています。開発者は中継プラットフォーム上でデバッグや負荷テストを行うことができ、キャッシュロジックや課金ルールも一貫しています。

まとめ

Claude の prompt caching は cache_control フィールドを追加するだけの単純なものに見えますが、実際に運用すると「サイレント失敗」「最小トークンしきい値」「プレフィックスの厳密な一致」という3つの落とし穴にはまりがちです。本記事で紹介した5つのトラブルシューティングリストとヒット判定表を活用すれば、キャッシュが効かない問題の90%を5分以内に特定できるはずです。

実運用のヒントとして、検証コードをデフォルトのミドルウェアに組み込むこと、モデルのしきい値テーブルを定数として管理すること、キャッシュのウォームアップを専用スクリプト化することをお勧めします。もし複数のモデルを頻繁に切り替えて運用している場合は、APIYI (apiyi.com) プラットフォームを通じて Claude の呼び出しを一元管理することで、キャッシュ戦略や監視ロジックを共通化し、環境ごとのキャッシュの断片化やしきい値の不一致による隠れたコストを回避できます。


著者: APIYI 技術チーム
連絡先: APIYI (apiyi.com) にて Claude 全モデルおよび prompt caching の完全なデバッグサポートを提供中
更新日: 2026年5月12日

類似投稿