AI NOTE — 151

Anthropic API Prompt Cachingでコスト削減

Anthropic APIのPrompt Caching(プロンプトキャッシング)は、同一のシステムプロンプトを繰り返し送信するユースケースでAPIコストを最大90%削減できる機能です。2024年後半にリリースされ、現在はすべてのアクティブなClaudeモデルで利用できます(Anthropic公式ドキュメントより)。

この記事を読んだほうが良い人

  • GWSの監査ログをAnthropicのClaude APIで定期分析していて、月次コストが予算を圧迫し始めた情シス担当者
  • 同じシステムプロンプト(分析ルール集・セキュリティポリシー)を毎回のAPI呼び出しで送信している
  • OpenAIやGemini APIと比較しながら、Prompt Cachingを導入すべきか判断したい

Claude API 監査ログ分析でコストが増える理由

GWSの監査ログをClaude APIで分析するシステムは、一般的に次の2つの部分から成ります。

  • 固定部分:分析ルール集、組織のセキュリティポリシー、アラート判定基準(例:10,000〜30,000トークン)
  • 変動部分:その日・その時間帯の監査ログデータ(例:3,000〜10,000トークン)

問題は固定部分にあります。100件のログを個別に分析するケースでは、1回のAPI呼び出しごとに同一のシステムプロンプトが送信されます。入力トークンの大半が毎回同じ内容の繰り返しになるため、コストが件数に比例してそのまま増えていく構造です。

GWS監査ログ分析のシステムプロンプトが大きくなる理由は、組織固有の情報が積み重なるからです。不審なログインの判定基準、許可するIPレンジ一覧、アラート対象のイベント種別リスト、部門・役職マッピングなど、各企業のポリシーを反映した内容が加わるたびにトークン数が増えます。100名規模の組織でも運用を継続すると、システムプロンプトが20,000トークンを超えることは珍しくありません。

さらに、分析精度を上げるためにサンプル事例(few-shot例)をシステムプロンプトに追加するケースも多く、こうした改善を重ねるほど固定部分のトークン数は膨らみ、Prompt Cachingの恩恵が大きくなります。

この固定部分をキャッシュすることで、繰り返しの入力コストを大幅に下げられます。

Prompt Cachingの仕組みとコスト構造

Prompt Cachingは、プロンプトの指定した部分をAnthropicのサーバー側にキャッシュし、後続のリクエストでその部分をキャッシュから読み出す機能です。

課金の仕組みは通常の入力トークンと異なります(Anthropic公式ドキュメントより)。

操作 料金の倍率 有効期間
キャッシュ書き込み(5分TTL) 通常入力の1.25倍 5分間
キャッシュ書き込み(1時間TTL) 通常入力の2倍 1時間
キャッシュ読み出し 通常入力の0.1倍(90%削減) 書き込みと同じ

5分TTLでは1回のキャッシュ読み出しで書き込みコストを回収でき、1時間TTLなら2回の読み出しで元が取れる計算です。

キャッシュが有効になる最小トークン数はモデルによって異なります(Anthropic公式ドキュメントより)。以下は代表的なモデル(4.5/4.6世代)の値で、最新モデルは公式ドキュメントで要確認です。

  • Claude Haiku 4.5、Claude Opus 4.5/4.6:4,096トークン以上
  • Claude Sonnet 4.5/4.6、Claude Opus 4.8:1,024トークン以上

GWS監査ログ分析のシステムプロンプトは通常これを上回るため、ほとんどのケースでキャッシュが機能します。

APIコスト試算:キャッシュ適用前後の比較

Claude Sonnet 4.5(入力$3/MTok、キャッシュ書き込み$3.75/MTok、キャッシュ読み出し$0.30/MTok、出力$15/MTok)を使った試算例を示します。

前提条件

  • システムプロンプト(固定):25,000トークン
  • ログデータ(変動):1リクエストあたり5,000トークン
  • 出力:1リクエストあたり1,500トークン
  • API呼び出し:1日100件を1バッチで処理、月30日間

以下が月次コストの比較です($1 = ¥150で換算、概算)。

項目 キャッシュなし キャッシュあり(5分TTL)
システムプロンプト入力コスト $225(¥33,750) $25(¥3,750)※
ログデータ入力コスト $45(¥6,750) $45(¥6,750)
出力コスト $67.5(¥10,125) $67.5(¥10,125)
月次合計 $337.5(¥50,625) $137.5(¥20,625)

※ キャッシュ書き込み($2.8)+キャッシュ読み出し($22.3)の合計

100件/日のバッチで1件目がキャッシュ書き込み、残り99件がキャッシュ読み出しになります。システムプロンプト部分のコストが約89%削減され、全体では約59%削減になります。

実際のコストは使用モデル・システムプロンプトの長さ・呼び出し件数によって変わります。価格の最新情報はAnthropicの公式ドキュメントで確認してください。

cache_controlを使ったPython実装パターン

キャッシュ対象はシステムプロンプトの固定部分です。cache_control フィールドをシステムプロンプトのブロック末尾に付与することで、Anthropic APIがそこをキャッシュ境界として扱います。

以下は、GWS監査ログ分析に適用する基本パターンです。固定ルール部分とログデータ部分を別々のブロックに分離するのがポイントです。

import anthropic

client = anthropic.Anthropic()

# 固定のシステムプロンプト(分析ルール集・組織情報)
SYSTEM_PROMPT = """
あなたはGoogle Workspace監査ログの分析専門AIです。
以下のルールに従って分析してください。

【不審なログインの検出基準】
- 通常の勤務時間外(20時〜7時)のログイン
- 通常の接続元と異なる国・地域からのアクセス
...
(中略:実際は10,000〜30,000トークン相当のルール集)
...
"""

def analyze_audit_log(log_data: str) -> str:
    response = client.messages.create(
        model="claude-sonnet-4-5",  # 本番ではバージョン固定ID(例: "claude-sonnet-4-5-20250304")の使用を推奨
        max_tokens=1500,
        system=[
            {
                "type": "text",
                "text": SYSTEM_PROMPT,
                "cache_control": {"type": "ephemeral"}  # ← ここがキャッシュ境界
            }
        ],
        messages=[
            {
                "role": "user",
                "content": f"以下の監査ログを分析してください:\n\n{log_data}"
            }
        ]
    )

    # キャッシュ使用状況を確認する
    usage = response.usage
    cache_hit = (usage.cache_read_input_tokens or 0) > 0
    print(
        f"cache_hit={cache_hit} | "
        f"read={usage.cache_read_input_tokens} | "
        f"write={usage.cache_creation_input_tokens} | "
        f"input={usage.input_tokens}"
    )

    return response.content[0].text

response.usage の各フィールドの意味は次の通りです。

  • cache_read_input_tokens:キャッシュから読み出されたトークン数(0より大きければキャッシュヒット)
  • cache_creation_input_tokens:今回新たにキャッシュに書き込まれたトークン数
  • input_tokens:キャッシュ外の通常入力トークン数(ログデータ部分など)

最初のリクエストでは cache_creation_input_tokens に書き込みトークン数が入り、2回目以降は cache_read_input_tokens に読み出しトークン数が入ります。これをログに出力しておくと、キャッシュが期待通りに機能しているか確認できます。なお、最初の書き込み時に cache_creation_input_tokens の値を見れば、システムプロンプトの実際のトークン数も確認できます。

TTLの選び方:処理パターン別の設計判断

TTL(Time To Live)の選択は処理パターンによって変わります。どちらを選ぶかがコスト構造を大きく変えます。

処理パターン 推奨TTL 理由
1日分のログを5分以内に一括バッチ処理 5分(デフォルト) 書き込みコスト最小(1.25倍)。1件目以降は全てキャッシュ読み出し
1時間おきに複数件まとめて処理 1時間 毎時1回の書き込み(2倍)より読み出し回数が多ければ採算が合う
1件ずつ散発的に処理 キャッシュ不向き ヒット率が低く、書き込みコストが無駄になる

5分TTLを選ぶ場合、100件のバッチ処理を5分以内に完了させることが前提です。ログの件数増加や下流処理の遅延で5分を超えると、後半のリクエストでキャッシュが切れて再書き込みが発生します。バッチサイズが日によって変動する場合は、1時間TTLを選ぶほうが動作が安定します。

1時間TTLに切り替える場合は cache_control"ttl": "1h" を追加するだけです。

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

並行処理でリクエストを一斉送信するケースも注意が必要です。キャッシュエントリは最初のリクエストが完了した後に利用可能になるため、大量のリクエストを同時に投げると大半が書き込みコストになります。安全なバッチパターンは次の通りです。

def analyze_batch_safe(logs: list[str]) -> list[str]:
    """先頭1件でキャッシュを確立してから残りを処理する"""
    results = []

    # 1件目を先に処理してキャッシュを確立する
    results.append(analyze_audit_log(logs[0]))

    # キャッシュ確立後に残りを処理(全て読み出しコストになる)
    for log in logs[1:]:
        results.append(analyze_audit_log(log))

    return results

この順序を守ることで、2件目以降はキャッシュ読み出し料金(通常の0.1倍)で処理できます。

GWS監査ログ分析がバッチ型か逐次型かを先に確認し、TTLを決めてから実装に入るのがよい順番です。

OpenAI・Geminiとの比較:どのAPIが得か

Prompt Cachingの採用判断には、他のAI APIとの比較も役立ちます。

観点 Anthropic Prompt Caching OpenAI Prompt Caching Gemini Context Caching
設定方法 cache_control を明示指定 自動(コード変更不要) 明示的なキャッシュ作成が必要
最小トークン数 1,024〜4,096(モデルによる) 1,024 公式ドキュメントを要確認
キャッシュ読み出しの割引 90%削減(通常の0.1倍) 50〜75%削減(GPT-4o / GPT-4.1系は50%。最新モデルは要確認) モデルによる
TTL制御 5分 / 1時間を選択可 自動管理 カスタム設定可

OpenAIは設定不要の自動適用が魅力ですが、キャッシュ読み出しの割引率はGPT-4o / GPT-4.1系で50%とAnthropicの90%削減に比べると小さくなります(2026年現在、OpenAIの新世代モデルでは割引率が変化しているため、最新情報は公式ドキュメントで要確認です)。

割引率の差が設計判断に直接影響します。100件/日のバッチ処理で25,000トークンのシステムプロンプトを持つ構成では、Anthropicの90%割引が大きく効きます。一方、呼び出し頻度が低い(月50件以下)ケースでは、コード変更不要のOpenAI自動キャッシュで十分なケースもあります。

すでにOpenAI GPTシリーズを別システムで利用していてAPI管理を統一したい場合は、OpenAI自動キャッシュで始めるのが現実的な判断です。逆に、高頻度バッチ処理でコスト削減を最大化したい場合、かつモデルの応答品質でClaudeが要件を満たすなら、Anthropicに切り替えるメリットは明確です。

GWS監査ログ分析のように「固定ルール集が数万トークン規模」「1日に多数の類似リクエスト」というユースケースでは、Anthropicの費用対効果が最も高い選択肢になります。

キャッシュが機能しないケースと注意点

実装にあたり、よくある落とし穴を確認しておきます。

変動するコンテンツをキャッシュ対象にしてしまう

# NG:タイムスタンプが変わるためキャッシュが毎回ミスヒット
SYSTEM_PROMPT = f"分析日時: {datetime.now()}\n\n【分析ルール】..."

cache_control を付与するブロックは、リクエストごとに内容が変わらない部分に限定します。日時・ログID・ユーザー名などの変動要素は、固定部分とは別のブロック(またはメッセージのuser部分)に分離します。

並行処理でのキャッシュ競合

前述の通り、大量リクエストの一斉送信はキャッシュ確立前に書き込みコストが重複発生します。本番環境では逐次送信か、先頭1件のウォームアップを挟む設計にします。

モデルの最小トークン要件の確認

Claude Haiku 4.5を使用する場合、最小4,096トークン未満のシステムプロンプトではキャッシュが機能しません。エラーは返されず、通常入力として処理されます。実装後は usage.cache_creation_input_tokens の値で動作を確認してください。

TTL切れの無言失敗

キャッシュの有効期限が切れても、APIはエラーを返さずに自動で書き込みコストに切り替わります。コスト監視をしていないと気づかないまま費用が戻ることがあります。usage.cache_creation_input_tokens が定常的に0以外の値を示している場合、キャッシュが期待通りに機能していないサインです。Slackアラートや監視ダッシュボードにキャッシュヒット率を組み込むと、異常を早期に検出できます。

まとめ:どこから始めるか

Prompt Cachingの実装でかかる変更は、既存のコードに cache_control フィールドを追加する数行だけです。ただし、効果の大きさは「固定システムプロンプトの割合」と「1日のリクエスト件数」に依存します。

月に50件未満のAPI呼び出しでは、キャッシュの恩恵は限定的です。一方、100件/日を超えるバッチ処理があるなら、コスト試算の通り月次費用が半分以下になる可能性があります。

実装の順序として、次の3ステップを推奨します。

  1. トークン数の確認:既存のシステムプロンプトを最初のリクエストで送信し、cache_creation_input_tokens の値で実際のトークン数を把握する。最小要件(Claude Sonnet 4.5なら1,024トークン)を満たしているかここで確認する。
  2. 処理パターンの確認:1日のリクエスト件数と処理が集中する時間帯を確認し、5分TTLと1時間TTLのどちらが適切かを判断する。
  3. ステージング環境で1週間計測するusage.cache_read_input_tokens を毎日集計して実際のキャッシュヒット率を確認してから、本番適用とコスト予算の見直しを行う。

数字が出てから設計を調整するのが、現場での近道です。

GWS監査ログのAI分析パイプライン全体の設計——ログの収集・前処理・Prompt Cachingの適用・アラート連携まで含めたシステム構成——については、DRASENAS 公式サイトからご相談いただけます。

コーポレートITのご相談はお気軽に

この記事で書いたような業務改善・自動化の設計から実装まで、DRASENASではコーポレートITの現場に寄り添った支援を行っています。 「まず相談だけ」でも大歓迎です。DRASENAS 公式サイトからお気軽にどうぞ。

CONTACT

御社の IT 部門、ここにあります。

「ITのことはあまりわからない」── そのような状態からで、まったく問題ございません。まずはお気軽にご相談ください。

一社ずつ、一から。