AI NOTE — 191

GWS監査ログのPrompt Caching設計でコスト削減

Anthropic APIのPrompt Caching(プロンプトキャッシング)は、同一のシステムプロンプトを繰り返し送信するユースケースでAPIコストを最大90%削減できる機能で、現在はすべてのアクティブなClaudeモデルで利用できます(Anthropic公式ドキュメントより)。GWS(Google Workspace)監査ログを毎月AIで分析している情シス担当者にとって、月次フローへの組み込み方次第でAPIコストが大きく変わります。

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

  • Claude APIでGWS監査ログを月次分析していて、APIコストが月々増えてきた情シス担当者
  • 毎回同じ分析ルール集・判定基準を含む長いシステムプロンプトを送り続けている
  • Prompt Cachingをどこに組み込むべきか、処理パターン別の設計判断を知りたい

GWS監査ログのAI分析がPrompt Caching向きな理由

GWS監査ログのAI分析フローを月次単位で観察すると、送信内容が2層に分かれています。

固定層(月をまたいでもほぼ変わらない部分)

  • 分析ルール集:不審ログインの判定基準、許可IPレンジ、アラート対象イベントの種別
  • 組織固有のコンテキスト:部門・役職マッピング、例外ユーザーリスト
  • 出力フォーマット指示:レポートの構造、優先度の定義、Slack通知用のテンプレート
  • few-shot例(判定基準のサンプル事例集):過去の判定事例(「このログパターンは正常範囲」「このパターンは要調査」など)

変動層(リクエストごとに異なる部分)

  • 分析対象のログデータ:日次・時間帯別にエクスポートしたイベントデータ

問題の本質は「固定層が肥大化しやすい」点にあります。組織のセキュリティポリシーを丁寧に書き込むほど、また判断事例集(few-shot例)を追加するほど、システムプロンプトのトークン数は増えます。100名規模の組織でも運用を継続すると、固定層だけで20,000〜30,000トークンを超えることは珍しくありません。

典型的な内訳例を挙げると次のようになります。

  • 組織ポリシー文書(初期バージョン):約5,000〜8,000トークン
  • 部門・役職マッピング(全ユーザー分):約3,000〜5,000トークン
  • few-shot判定事例を10〜20件追加:約5,000〜10,000トークン
  • フォーマット指示と出力テンプレート:約2,000〜3,000トークン

運用6ヶ月で固定層が25,000トークン規模になることは、現実的な数字です。

従来の実装では、100件のログを個別分析するたびに同一のシステムプロンプトが毎回送信されます。入力コストの大半が同じ内容の繰り返しになり、件数に比例してコストが増え続ける構造です。

Prompt Cachingは「固定層を一度キャッシュし、後続リクエストでは読み出しコストだけで処理する」仕組みです。固定層が大きく、同一セッション内のリクエスト数が多いほど効果が大きくなります。GWS監査ログ分析は、この条件を構造的に満たしています。

Prompt Cachingのコスト構造:3つの数字を押さえる

Anthropic公式ドキュメントに記載されているコスト倍率は以下の通りです(通常の入力コストを1とした場合の倍率)。

操作 コスト倍率 TTL(有効期間)
キャッシュ書き込み(短期) 1.25倍 5分
キャッシュ書き込み(長期) 2.0倍 1時間
キャッシュ読み出し 0.1倍(90%削減) 書き込みと同じ

TTL(Time To Live)はキャッシュの有効期間です。5分のデフォルト設定では、書き込みコストは通常の1.25倍で済み、5分以内の後続リクエストは90%引きで処理されます。

キャッシュが機能する最小トークン数はモデルによって異なります(Anthropic公式ドキュメントより)。

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

※代表的なモデルを掲載。Claude Opus 4.7(2,048トークン)等その他モデルは公式ドキュメントで確認してください。

GWS監査ログ分析のシステムプロンプトは通常この閾値を大幅に超えるため、ほとんどの現場でキャッシュが機能する条件を満たしています。

Prompt Cachingが効きにくいケース

逆に、以下のような条件下ではコスト削減効果が限定的です。

  • 1日のリクエスト件数が5件以下:書き込みコスト(1.25倍)が読み出しの節約額を上回る
  • システムプロンプトが1,000〜2,000トークン程度で小さい:固定層の比率が低く、全体削減率が伸びない
  • リクエスト間隔が不定で1時間を超えることが多い:TTLが切れるたびに再書き込みが発生する

月次レポート生成のような「定期的にまとめて処理」というユースケースでは恩恵が大きく、「ユーザーの問い合わせに都度応答する」チャット系ユースケースでは恩恵が小さくなります。

コスト試算:組織規模別に比較する

Claude Sonnet 4.6(入力$3/MTok(MTok = 100万トークン)、キャッシュ書き込み$3.75/MTok、キャッシュ読み出し$0.30/MTok、出力$15/MTok)を使った試算を示します。価格はAnthropicの公式モデル概要ページ(2026年6月時点)の数値を使用しています。

シナリオA:100名規模・1日100件処理

前提条件

  • システムプロンプト(固定): 25,000トークン
  • ログデータ(変動): 1リクエストあたり5,000トークン
  • 出力: 1リクエストあたり1,000トークン
  • 処理量: 1日100件を1バッチで一括処理(5分以内)、月30日間
項目 キャッシュなし キャッシュあり(5分TTL)
システムプロンプトコスト $225/月 $25/月
ログデータコスト $45/月 $45/月
出力コスト $45/月 $45/月
月次合計 $315(約¥47,000) $115(約¥17,000)
削減率 約63%

シナリオB:30名規模・1日20件処理

前提条件

  • システムプロンプト(固定): 15,000トークン
  • ログデータ(変動): 1リクエストあたり3,000トークン
  • 出力: 1リクエストあたり800トークン
  • 処理量: 1日20件を1バッチ、月30日間
項目 キャッシュなし キャッシュあり(5分TTL)
システムプロンプトコスト $27/月 $5.3/月
ログデータコスト $5.4/月 $5.4/月
出力コスト $7.2/月 $7.2/月
月次合計 $39.6(約¥5,900) $17.9(約¥2,700)
削減率 約55%

組織規模が小さくなるほど削減率はやや低下しますが、システムプロンプトが長ければ30名規模でも月50%超の削減が見込めます。

1バッチ内では1件目がキャッシュ書き込み(1.25倍コスト)、2件目以降が読み出し(0.1倍コスト)になります。システムプロンプトのトークン比率が高いほど、また1バッチのリクエスト件数が多いほど削減率は高くなります。

$1 = ¥150換算の概算です。実際のコストは最新価格をAnthropicの公式価格ページで確認してから計算してください。

キャッシュ設計の3パターンと月次フロー

GWS監査ログ分析の処理パターンは大きく3種類に分かれます。どのパターンに当てはまるかで、キャッシュ設計の方針が変わります。

月次フローの典型的な構造

[GWSログエクスポート(管理コンソールまたはAPI)]
        ↓
[前処理・バッチ分割]
        ↓
[Claude API呼び出し] ← 固定システムプロンプト(キャッシュ)
   ↑ ↑ ↑ ↑         ← 変動ログデータ(毎回送信)
  [複数リクエスト]
        ↓
[結果集計・異常判定]
        ↓
[Slackアラート / Spreadsheet記録]

このフローの「Claude API呼び出し」ブロックにPrompt Cachingを組み込みます。


パターン1:1日分を5分以内に一括バッチ処理

最もキャッシュ効果が高い構成です。5分TTL(デフォルト)を選択し、バッチの先頭1件でキャッシュを確立してから残り99件を処理します。

採用できる条件は「1バッチ内の全処理が5分以内に完了すること」です。ログ件数が増えたり、下流処理(Slack通知・Spreadsheet書き込み等)が重くなると、後半リクエストでキャッシュが切れて再書き込みが発生します。5分の壁を安定して守れるかを本番前に検証してください。

判断目安:1日のログ件数が150件以下で、純粋なAPI呼び出しが3〜4分以内に収まる構成なら採用できます。


パターン2:1時間ごとに複数件まとめて処理

リアルタイム性が必要な場合や、1日のログ件数が多くてバッチが5分に収まらない場合に適しています。1時間TTLを選択し、毎時間の先頭リクエストでキャッシュを書き込み(通常の2倍コスト)、同一時間帯の残りリクエストが読み出しで処理されます。

TTLが長いぶん書き込みコストが高く(2倍)、1時間内のリクエスト件数が少ない時間帯では費用対効果が落ちます。1時間あたり概ね3件以上まとまるなら採算が合います。

判断目安:勤務時間帯に1時間ごと5件以上のログが発生し、翌日まで待てないアラート要件がある場合に向いています。


パターン3:1件ずつ散発的に処理(非推奨)

リクエストのたびに書き込みコストが発生し、次のリクエストが5分以内に届かなければ読み出しが発生しません。Prompt Cachingの恩恵がほぼゼロになります。このパターンでコスト削減が目的なら、バッチ設計に変更するか、モデルのダウングレードや前処理でのログ圧縮を先に検討してください。

よくある設計ミスと対策

設計を始めると、いくつかの典型的なミスが頻発します。事前に把握しておくと手戻りを避けられます。

ミス1:変動データをシステムプロンプトに混入する

最も多いパターンです。「今月の分析対象:2026年6月」「対象ユーザー:全員(2026年6月時点)」のような日時情報をシステムプロンプトに直書きすると、月が変わるたびにキャッシュがミスヒットします。ヒット率が実測でほぼゼロになり、書き込みコストが毎回発生します。

対策:システムプロンプトには「変わらないルール」だけを残し、「今回の分析対象期間」「対象ユーザーリスト(今月版)」はユーザーメッセージ側で渡します。

ミス2:並列送信でウォームアップを飛ばす

処理速度を上げようとして全リクエストを同時送信すると、キャッシュが確立される前に大量のリクエストが書き込みコストで処理されます。1件目の応答が返る前に2〜100件目が到達するため、全件が書き込みコストになることも起きます。

対策:バッチの先頭1件を同期処理で先行させてキャッシュを確立してから、残りを並列または連続で処理します。

ミス3:ヒット状況を把握せず運用する

「入れたはずなのに安くなっていない」という状況でも、原因がTTL切れなのか変動データ混入なのか分からないまま運用を続けてしまいます。問題に気づくのが月次コスト確認のタイミングになりがちです。

対策:cache_read_input_tokenscache_creation_input_tokens をバッチログとして記録します。キャッシュヒット率が90%を下回っていたら設計を見直すサインです。

ヒット率を最大化する3つの設計ポイント

設計パターンを選んだ後、以下の3点がキャッシュヒット率を決めます。

1. 固定部分と変動部分を厳密に分離する

キャッシュが機能するのは、リクエスト間でまったく同一のテキストを送った場合だけです。「本日の分析対象:2026年6月24日」のような可変情報はシステムプロンプトから切り出してユーザーメッセージ側に渡すのが基本です。few-shot例を追加する場合も、可変要素を含まない固定例題のみシステムプロンプトに含め、実際のログデータとは分離します。

2. キャッシュウォームアップを先頭に置く

並行処理でリクエストを一斉送信すると、キャッシュが確立される前に多数のリクエストが書き込みコストで処理されます。バッチ処理の冒頭で1件を先行処理してキャッシュを確立してから、残りを処理するパターンを採用してください。

3. usageフィールドでヒット状況を継続監視する

Anthropic APIのレスポンスに含まれる cache_read_input_tokens(読み出しトークン数)と cache_creation_input_tokens(書き込みトークン数)を、バッチ処理のログとして記録します。書き込みが毎回発生している場合、TTL切れや固定/変動の分離ミスが原因であることが多いため、早期に気づけます。コスト監視ダッシュボードにキャッシュヒット率を組み込んでおくと、異常を自動検出できます。

Python実装例(バッチ処理ウォームアップ付き)

記事の主眼はフロー設計ですが、実装のイメージを持てるよう構成を示します。Prompt Cachingの実装は、既存のシステムプロンプトに cache_control フィールドを付与するだけで完結します。

以下は固定のシステムプロンプトをキャッシュ対象として指定し、変動のログデータをユーザーメッセージとして渡す基本パターンに、バッチ処理のウォームアップとヒット率集計を加えた構成です。

import anthropic

client = anthropic.Anthropic()

# 固定のシステムプロンプト(分析ルール集・組織ポリシー)
# 月をまたいでも変わらない内容だけをここに集約する
SYSTEM_PROMPT = """
あなたはGoogle Workspace監査ログの分析専門AIです。
以下のルールに従って分析してください。
...
(実際は20,000〜30,000トークン相当のルール集)
...
"""

def analyze_log(log_data: str) -> dict:
    """1件のログを分析する(キャッシュ境界付き)"""
    response = client.messages.create(
        model="claude-sonnet-4-6",
        max_tokens=1000,
        system=[
            {
                "type": "text",
                "text": SYSTEM_PROMPT,
                "cache_control": {"type": "ephemeral"}  # キャッシュ境界を指定
            }
        ],
        messages=[
            {
                "role": "user",
                # 変動データはユーザーメッセージ側に渡す(システムプロンプトに混ぜない)
                "content": f"以下の監査ログを分析してください:\n\n{log_data}"
            }
        ]
    )
    usage = response.usage
    return {
        "result": response.content[0].text,
        "cache_hit": bool(usage.cache_read_input_tokens),
        "cache_read": usage.cache_read_input_tokens,
        "cache_write": usage.cache_creation_input_tokens,
    }

def process_batch(log_entries: list[str]) -> list[dict]:
    """バッチ処理:先頭1件でウォームアップしてから残りを処理"""
    if not log_entries:
        return []

    results = []

    # ウォームアップ:1件目を先行処理してキャッシュを確立
    first = analyze_log(log_entries[0])
    results.append(first)
    print(f"[1/{len(log_entries)}] warmup cache_write={first['cache_write']}")

    # 2件目以降:キャッシュ読み出しで処理
    for i, entry in enumerate(log_entries[1:], start=2):
        res = analyze_log(entry)
        results.append(res)
        print(f"[{i}/{len(log_entries)}] cache_hit={res['cache_hit']}")

    # ヒット率サマリ(監視ログとして記録しておく)
    hits = sum(1 for r in results if r["cache_hit"])
    print(f"Cache hit rate: {hits}/{len(results)} ({hits/len(results)*100:.1f}%)")
    return results

1時間TTLに変更する場合は cache_control 内に "ttl": "1h" を追加するだけです。それ以外のコードは変わりません。

cache_creation_input_tokens の値を最初のリクエストで確認すると、実際のシステムプロンプトのトークン数も把握できます。コード量は小さいですが、ウォームアップ処理とヒット率ログの2点が月次運用に直結します。

月次フロー組み込みの判断軸

Prompt Cachingを月次フローに組み込む前に、以下の3点を順番に確認してください。

1. システムプロンプトのトークン数

使用するモデルの最小要件を超えているか確認します(Claude Sonnet 4.6なら1,024トークン、Claude Haiku 4.5なら4,096トークン)。20,000トークン以上あればコスト削減効果が大きくなります。最初のリクエスト後に cache_creation_input_tokens の値を見れば実数を把握できます。現状のシステムプロンプトが5,000トークン以下なら、まずfew-shot例や組織コンテキストを追加して品質を上げるほうが先決です。

2. 1バッチの処理時間と件数

1日分のログを5分以内に処理しきれるか確認します。パターン1(5分TTL一括バッチ)が最もシンプルで効果的です。5分に収まらない場合はパターン2(1時間TTL)か、バッチ分割を検討します。Claude Sonnet 4.6の応答速度は入力・出力量に依存するため、100件の場合は実測での確認が必要です。

3. 固定/変動の分離状態

現在のシステムプロンプトに日時・ユーザー名・分析期間などの変動要素が混在していないか確認します。混在している場合は分離リファクタリングが先決です。変動要素を取り除いた後のトークン数も再計測してください。

3点を確認した上で、まずステージング環境で1週間試行し、cache_read_input_tokenscache_creation_input_tokens の比率を実測してから本番適用とコスト予算の見直しを行うのが堅実な進め方です。

実装後に目指す指標の目安を示します。

  • キャッシュヒット率:90%以上(1バッチ100件なら99件がヒット)
  • システムプロンプトコストの削減率:80〜90%(固定層の比率によって変動)
  • 全体のAPIコスト削減率:50〜70%(ログデータ・出力コストはキャッシュの対象外)

試算ベースで設計してから、実測で調整する流れを踏むことで、本番投入後の想定外のコスト増を避けられます。

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

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

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

CONTACT

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

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

一社ずつ、一から。