Home Claude Code設計思想解説: Prompt Caching Is Everything — キャッシュファーストなエージェント設計
投稿
キャンセル

✍️ Claude Code設計思想解説: Prompt Caching Is Everything — キャッシュファーストなエージェント設計

本記事は Lessons from building Claude Code: Prompt caching is everything の解説記事です。

ブログ概要(Summary)

Anthropicのエンジニアリングチームが公開した本記事は、Claude Code(対話型AIコーディングエージェント)の設計において、プロンプトキャッシュがいかに中核的な設計原則であるかを解説している。著者のThariq氏は「cache rules everything around me」と表現し、キャッシュヒット率をシステムのアップタイムと同等の重要度で監視する運用哲学を示している。Claude Codeでは、キャッシュヒット率90%で$100相当のセッションが$19に圧縮されるという具体的コスト効果が報告されている。

この記事は Zenn記事: エージェントのプロンプトキャッシュ設計 — ツール定義と思考トークンを壊さない実装 の深掘りです。

情報源

  • 種別: 企業テックブログ
  • URL: https://claude.com/blog/lessons-from-building-claude-code-prompt-caching-is-everything
  • 組織: Anthropic(Claude Codeチーム)
  • 発表日: 2026年

技術的背景(Technical Background)

Claude Codeは長時間稼働するエージェント製品であり、1セッションあたり数十〜数百ターンの対話を処理する。各ターンでLLM APIを呼び出すため、プレフィックスの再計算コストが累積的に増大する。プロンプトキャッシュはこの問題に対する根本的解決策であり、前回のリクエストと共通するプレフィックス部分の計算をスキップすることで、レイテンシとコストの両方を削減する。

Claude Codeチームがキャッシュを「すべてに優先する設計原則」として位置づけた背景には、以下の定量的事実がある:

  • キャッシュ読み込み(cache read)のコストは通常入力の10%
  • 90%のキャッシュヒット率で、セッション全体のコストが約80%削減される
  • キャッシュヒット率の低下は直接的にレート制限の逼迫につながる

実装アーキテクチャ(Architecture)

プロンプトの安定性レイヤー設計

Claude Codeのプロンプトは、変更頻度の低い要素から高い要素へと順序付けされている。この順序がキャッシュプレフィックスの安定性を決定する。

graph TD
    A["Layer 1: ツール定義<br/>変更: ほぼなし<br/>全セッション共通"] --> B["Layer 2: システムプロンプト<br/>変更: デプロイ時のみ<br/>全セッション共通"]
    B --> C["Layer 3: プロジェクトコンテキスト<br/>変更: セッション開始時<br/>セッション固有"]
    C --> D["Layer 4: 会話履歴<br/>変更: 毎ターン末尾追加<br/>ターン固有"]

この設計により、Layer 1-2は全セッション・全ユーザーで共有キャッシュとなり、Layer 3はセッション単位、Layer 4は末尾追加のみで既存キャッシュを維持する。

キャッシュを壊さない4つの設計原則

原則1: ツール定義を会話途中で変更しない

ツール定義はキャッシュプレフィックスの最上位に位置する。ツールの追加・削除は全キャッシュを無効化するため、Claude Codeでは以下の代替パターンを採用している:

  • Plan Mode: 直感的にはツールセットを読み取り専用に切り替えたいが、それはキャッシュを破壊する。代わりにEnterPlanMode/ExitPlanModeというツール自体を使って状態遷移を実現
  • モデル切り替え: Opus→Haikuへの切り替えが必要な場合、サブエージェントとして別セッションを起動(キャッシュはモデル固有のため)
1
2
3
4
5
6
7
8
9
10
# ❌ 悪い例: ツールセットの動的変更
def enter_plan_mode(tools):
    return [t for t in tools if t["name"] in READ_ONLY_TOOLS]

# ✅ 良い例: ツール自体で状態を管理
TOOLS = [
    # ... 全ツール(常に固定)
    {"name": "EnterPlanMode", "description": "読み取り専用モードに入る"},
    {"name": "ExitPlanMode", "description": "通常モードに戻る"},
]

原則2: システムプロンプトをメッセージ途中で変更しない

情報更新が必要な場合、システムプロンプトを書き換えるのではなく、system-reminderタグとして後続メッセージに挿入する。これにより、システムプロンプトのキャッシュは維持されたまま、最新情報が反映される。

1
2
3
4
5
6
7
8
# ❌ 悪い例: システムプロンプトの更新
system_prompt = base_prompt + f"\n現在の日時: {datetime.now()}"

# ✅ 良い例: メッセージ内でsystem-reminderとして注入
messages.append({
    "role": "user",
    "content": f"<system-reminder>現在の日時: {datetime.now()}</system-reminder>"
})

原則3: defer_loadingで未使用ツールを軽量化

Claude Codeでは多数のツール(数十個)が定義されているが、1ターンで使用されるのは通常2-3個である。defer_loading: trueを設定したツールは軽量スタブとしてキャッシュされ、ToolSearchで選択された時点で完全スキーマがロードされる。

原則4: コンパクション時にプレフィックスを共有

コンテキストウィンドウが溢れた場合の要約(コンパクション)処理では、通常のリクエストと同一のtoolssystemを使用する。これにより、コンパクション用リクエスト自体もキャッシュプレフィックスを共有し、追加コストを最小化している。

パフォーマンス最適化(Performance)

キャッシュヒット率と経済性

Claude Codeチームが報告している具体的な数値:

メトリクス
目標キャッシュヒット率90%以上
cache read単価通常inputの10%
$100セッション→キャッシュ後$19
ヒット率低下時のアクションSEV(インシデント)対応

コスト計算モデル

キャッシュ有効時のセッションコスト$C$は以下で近似される:

\[C = T_{\text{total}} \cdot r_{\text{input}} \cdot (1 - h \cdot 0.9)\]

ここで、

  • $T_{\text{total}}$: セッション全体の総入力トークン数
  • $r_{\text{input}}$: 入力トークンの単価
  • $h$: キャッシュヒット率(0〜1)
  • $0.9$: cache readの割引率(通常の10%課金 = 90%割引)

ヒット率$h = 0.9$の場合:$C = T \cdot r \cdot (1 - 0.81) = 0.19 \cdot T \cdot r$(約81%削減)

TTL戦略

Claude Codeでは、レイヤーごとに異なるTTLを適用している:

  • ツール定義・システムプロンプト: 1時間TTL(デプロイ間で不変、複数セッション間で共有)
  • プロジェクトコンテキスト: 5分TTL(セッション固有、ターン間隔は通常1分以内)
  • 会話履歴: 5分TTL(自動、末尾追加でリフレッシュ)

運用での学び(Production Lessons)

キャッシュブレイクをインシデントとして扱う

Claude Codeチームは、キャッシュヒット率の有意な低下をシステム障害と同等に扱う運用体制を構築している。これは以下の理由による:

  1. コスト直結: ヒット率10%低下 = セッションコスト約2倍
  2. レート制限: 低ヒット率 = 新規トークン処理量増 = レート制限逼迫
  3. ユーザー体験: TTFT増加による応答遅延

主要な障害パターンと対策

障害パターン原因対策
デプロイ後のヒット率急落ツール定義の変更ツール定義のバージョン管理、段階的ロールアウト
特定ユーザーのみヒット率低下プロジェクトコンテキスト過大コンテキスト圧縮の自動発動
全ユーザーで間欠的ミスTTL超過(ユーザー思考時間)1時間TTLへの移行
サブエージェント呼び出し後モデル切り替えサブエージェント完了後にpre-warm

モニタリング実装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import logging
import json
import time

logger = logging.getLogger("cache_monitor")

def log_cache_metrics(response_usage: dict, session_id: str, turn: int) -> None:
    """APIレスポンスからキャッシュメトリクスを構造化ログ出力"""
    cache_read = response_usage.get("cache_read_input_tokens", 0)
    cache_write = response_usage.get("cache_creation_input_tokens", 0)
    input_tokens = response_usage.get("input_tokens", 0)
    total = cache_read + cache_write + input_tokens

    hit_ratio = cache_read / total if total > 0 else 0.0

    logger.info(json.dumps({
        "event": "llm_cache_metrics",
        "level": "info",
        "ts": time.time(),
        "session_id": session_id,
        "turn": turn,
        "cache_read_tokens": cache_read,
        "cache_write_tokens": cache_write,
        "new_input_tokens": input_tokens,
        "hit_ratio": round(hit_ratio, 3),
        "cost_savings_pct": round(hit_ratio * 90, 1),
    }))

    # 閾値アラート
    if turn >= 3 and hit_ratio < 0.5:
        logger.warning(json.dumps({
            "event": "cache_hit_rate_low",
            "level": "warning",
            "ts": time.time(),
            "session_id": session_id,
            "turn": turn,
            "hit_ratio": round(hit_ratio, 3),
            "action": "investigate_prefix_stability",
        }))

学術研究との関連(Academic Connection)

Claude Codeの設計は、以下の学術研究と密接に関連している:

  • “Don’t Break the Cache” (2601.06007): 本ブログの運用知見を定量的に検証した論文。Claude Codeの「Exclude Dynamic」戦略が最も効果的であることを実験で確認
  • ChunkAttention (2311.04934): プレフィックス共有のサーバ内部実装。Claude Codeが利用するAnthropicのサーバ側でもtrie構造によるKVキャッシュ共有が行われている可能性が高い
  • PagedAttention (2309.06180, vLLM): メモリの非連続管理によるフラグメンテーション解消。キャッシュの効率的格納を可能にする基盤技術

Production Deployment Guide

AWS実装パターン(コスト最適化重視)

Claude Codeの設計原則を自社エージェントに適用するAWS構成を示す。

規模月間リクエスト推奨構成月額コスト主要サービス
Small~3,000Serverless$80-200Lambda + Bedrock + ElastiCache
Medium~30,000Hybrid$400-1,000ECS Fargate + Bedrock + Redis
Large300,000+Container$2,500-6,000EKS + Bedrock + Redis Cluster

キャッシュ設計のAWSマッピング:

  • Layer 1-2(全ユーザー共通): ElastiCache Redis(TTL: 1時間)でプレフィックスメタデータを管理
  • Layer 3(セッション固有): DynamoDB(TTL: 5分)でセッションコンテキストを保持
  • Layer 4(会話履歴): Bedrock API側の自動キャッシュに委譲

コスト試算の注意事項: 上記は2026年5月時点のAWS ap-northeast-1リージョン概算値です。Bedrockのプロンプトキャッシュ料金はモデル・リクエスト量により変動します。

Terraformインフラコード

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
resource "aws_elasticache_cluster" "prefix_cache" {
  cluster_id           = "agent-prefix-cache"
  engine               = "redis"
  node_type            = "cache.t4g.micro"
  num_cache_nodes      = 1
  parameter_group_name = "default.redis7"
  port                 = 6379

  tags = {
    Purpose = "prompt-prefix-metadata"
    TTL     = "3600"
  }
}

resource "aws_lambda_function" "agent_orchestrator" {
  filename      = "orchestrator.zip"
  function_name = "cache-aware-agent"
  role          = aws_iam_role.agent_role.arn
  handler       = "main.handler"
  runtime       = "python3.12"
  timeout       = 120
  memory_size   = 2048

  environment {
    variables = {
      REDIS_ENDPOINT      = aws_elasticache_cluster.prefix_cache.cache_nodes[0].address
      BEDROCK_MODEL_ID    = "anthropic.claude-sonnet-4-6-20250514-v1:0"
      CACHE_TTL_SYSTEM    = "3600"
      CACHE_TTL_SESSION   = "300"
      ENABLE_CACHE_MONITOR = "true"
    }
  }

  vpc_config {
    subnet_ids         = module.vpc.private_subnets
    security_group_ids = [aws_security_group.lambda_sg.id]
  }
}

コスト最適化チェックリスト

  • プロンプト構造をレイヤー分離(ツール→システム→コンテキスト→会話)
  • ツール定義を会話途中で変更しない設計
  • システムプロンプト更新はmessage内system-reminderで対応
  • defer_loadingで未使用ツールを軽量スタブ化
  • コンパクション時に同一tools/systemを維持
  • 1時間TTLをシステムプロンプトに適用(デプロイ間共有)
  • キャッシュヒット率60%未満でアラート発火
  • デプロイ時のツール定義差分を自動検知

まとめと実践への示唆

Claude Codeの設計思想は「キャッシュファースト」であり、全ての機能設計がキャッシュヒット率への影響を第一に考慮して決定されている。この原則は自社エージェントにも直接適用可能であり、特にツール定義の固定化、状態遷移のツール内実装、レイヤー別TTL設定の3点が即座に導入できるプラクティスである。キャッシュヒット率をSLIとして監視し、低下をインシデントとして扱う運用体制の構築が、長期的なコスト最適化の鍵となる。

参考文献

  • Blog URL: https://claude.com/blog/lessons-from-building-claude-code-prompt-caching-is-everything
  • Anthropic Prompt Caching Docs: https://platform.claude.com/docs/en/build-with-claude/prompt-caching
  • Related Paper: https://arxiv.org/abs/2601.06007
  • Related Zenn article: https://zenn.dev/0h_n0/articles/37e71fbb85e1a6
この投稿は CC BY 4.0 でライセンスされています。

論文解説: Don't Break the Cache — エージェントタスクにおけるプロンプトキャッシュ戦略の実証評価

論文解説: CachedAttention — マルチターン会話のKVキャッシュ階層管理によるコスト50%削減