> ## Documentation Index
> Fetch the complete documentation index at: https://docs.apimart.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Claude コンテキストキャッシュ利用ガイド

> Claude Messages API または OpenAI 互換の Chat Completions API を使用して、繰り返し利用するプロンプトプレフィックスをキャッシュし、長いコンテンツを繰り返し処理する際の token コストを削減します。

Claude コンテキストキャッシュ（Context Cache）は、system prompt、ドキュメント、コードベース、会話履歴などの長いプレフィックスを繰り返し利用する場合に適しています。安定したプレフィックスに `cache_control` を追加すると、最初のリクエストでキャッシュが作成され、それ以降のリクエストでは有効期限内のキャッシュを読み取ることができます。

使用前に API キーを設定してください。

```bash theme={null}
export API_KEY="あなたのAPIキー"
```

<Note>本ガイドの例では `claude-sonnet-5` を使用します。ほかのモデルがコンテキストキャッシュに対応しているかどうかは、プラットフォームのモデル説明を参照してください。</Note>

## 適したユースケース

複数のリクエストで同じ長いコンテンツを繰り返し送信する場合、次のような安定したプレフィックスをキャッシュできます。

* 長い system prompt
* 固定されたナレッジベースまたは製品ドキュメント
* マルチターン会話内で変化しない履歴メッセージ
* 繰り返し使用するコードベース、ツール定義、説明

コンテキストキャッシュは、「先頭部分は変わらず、最後の質問だけが継続的に変わる」リクエストに適しています。

## Claude Messages API

### 5 分間キャッシュ

キャッシュする content block に `cache_control` を追加します。

```bash theme={null}
curl "https://api.apimart.ai/v1/messages" \
  -H "x-api-key: $API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-sonnet-5",
    "max_tokens": 1024,
    "system": [
      {
        "type": "text",
        "text": "ここに繰り返し使用する長いプレフィックスを入力します……",
        "cache_control": {
          "type": "ephemeral"
        }
      }
    ],
    "messages": [
      {
        "role": "user",
        "content": "上記の内容に基づいて質問に回答してください。"
      }
    ]
  }'
```

<Warning>`system` は content block の配列として記述する必要があります。文字列形式の `system` には `cache_control` を追加できません。</Warning>

`ttl` を省略した場合、キャッシュの有効期間はデフォルトで 5 分です。

### 1 時間キャッシュ

1 時間キャッシュを使用するには、`anthropic-beta` リクエストヘッダーを追加し、`ttl` を `1h` に設定します。

```bash theme={null}
curl "https://api.apimart.ai/v1/messages" \
  -H "x-api-key: $API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "anthropic-beta: extended-cache-ttl-2025-04-11" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-sonnet-5",
    "max_tokens": 1024,
    "system": [
      {
        "type": "text",
        "text": "ここに繰り返し使用する長いプレフィックスを入力します……",
        "cache_control": {
          "type": "ephemeral",
          "ttl": "1h"
        }
      }
    ],
    "messages": [
      {
        "role": "user",
        "content": "上記の内容に基づいて質問に回答してください。"
      }
    ]
  }'
```

対応している TTL：

| TTL  | 意味                                           |
| ---- | -------------------------------------------- |
| `5m` | 5 分間キャッシュ。`ttl` を省略した場合はこの値を使用               |
| `1h` | 1 時間キャッシュ。対応する `anthropic-beta` リクエストヘッダーも必要 |

### レスポンスの使用量フィールド

Claude Messages API は、通常入力、キャッシュ書き込み、キャッシュ読み取りの token を `usage` で個別に返します。

```json theme={null}
{
  "usage": {
    "input_tokens": 23,
    "cache_creation_input_tokens": 2619,
    "cache_read_input_tokens": 0,
    "cache_creation": {
      "ephemeral_5m_input_tokens": 2619,
      "ephemeral_1h_input_tokens": 0
    },
    "output_tokens": 24
  }
}
```

合計入力 token は次のように計算します。

```text theme={null}
input_tokens
+ cache_creation_input_tokens
+ cache_read_input_tokens
```

この 3 項目は重複しません。通常、最初のリクエストでは `cache_creation_input_tokens > 0` になります。同じ安定したプレフィックスを再度送信すると、`cache_read_input_tokens > 0` になるはずです。

## OpenAI 互換 API

### リクエストの例

`/v1/chat/completions` でキャッシュを使用する場合、`cache_control` の形式は Claude Messages API とほぼ同じです。

```bash theme={null}
curl "https://api.apimart.ai/v1/chat/completions" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-sonnet-5",
    "max_tokens": 1024,
    "messages": [
      {
        "role": "system",
        "content": [
          {
            "type": "text",
            "text": "ここに繰り返し使用する長いプレフィックスを入力します……",
            "cache_control": {
              "type": "ephemeral"
            }
          }
        ]
      },
      {
        "role": "user",
        "content": "上記の内容に基づいて質問に回答してください。"
      }
    ]
  }'
```

### 1 時間キャッシュ

OpenAI 互換形式も 1 時間キャッシュに対応しています。リクエストに `anthropic-beta` ヘッダーを追加し、`cache_control` で `ttl: "1h"` を設定します。

```bash theme={null}
-H "anthropic-beta: extended-cache-ttl-2025-04-11"
```

```json theme={null}
"cache_control": {
  "type": "ephemeral",
  "ttl": "1h"
}
```

### `content` は配列で指定

OpenAI 互換形式では、`cache_control` を具体的な content block 内に配置する必要があります。文字列形式のメッセージには設定できません。

```json theme={null}
{
  "role": "system",
  "content": "ここに長いプレフィックスを入力します……",
  "cache_control": {
    "type": "ephemeral"
  }
}
```

上記の形式ではキャッシュが有効にならず、リクエストもエラーになりません。正しい形式は次のとおりです。

```json theme={null}
{
  "role": "system",
  "content": [
    {
      "type": "text",
      "text": "ここに長いプレフィックスを入力します……",
      "cache_control": {
        "type": "ephemeral"
      }
    }
  ]
}
```

<Warning>`content` が文字列の場合、キャッシュマーカーは無視され、入力内容は通常入力として処理されます。レスポンスのキャッシュ使用量フィールドを確認して、キャッシュヒットの有無を判断してください。</Warning>

### user または assistant の content block をキャッシュ

`user` または `assistant` メッセージの content block に `cache_control` を追加して、長いドキュメントやマルチターン会話のプレフィックスをキャッシュすることもできます。

```json theme={null}
{
  "role": "user",
  "content": [
    {
      "type": "text",
      "text": "ここに繰り返し使用する長いドキュメントを入力します……",
      "cache_control": {
        "type": "ephemeral"
      }
    },
    {
      "type": "text",
      "text": "上記のドキュメントから 3 つの主要なポイントを要約してください。"
    }
  ]
}
```

安定したコンテンツと現在の質問を別々の content block に分け、安定した content block のみに `cache_control` を追加します。

### レスポンスの使用量フィールド

OpenAI 互換形式では、別のフィールドでキャッシュ使用量を返します。

```json theme={null}
{
  "usage": {
    "prompt_tokens": 1942,
    "completion_tokens": 22,
    "prompt_tokens_details": {
      "cached_tokens": 1921,
      "cache_write_tokens": 0
    },
    "claude_cache_creation_5_m_tokens": 0,
    "claude_cache_creation_1_h_tokens": 0
  }
}
```

フィールドの対応：

| 意味               | Claude Messages API                        | OpenAI 互換 API                                                  |
| ---------------- | ------------------------------------------ | -------------------------------------------------------------- |
| 合計入力             | 3 つの入力フィールドの合計                             | `prompt_tokens`                                                |
| キャッシュ読み取り        | `cache_read_input_tokens`                  | `prompt_tokens_details.cached_tokens`                          |
| 汎用キャッシュ書き込みフィールド | `cache_creation_input_tokens`              | `prompt_tokens_details.cache_write_tokens`（TTL の内訳がない場合のみ値を返す） |
| 5 分間キャッシュ書き込み    | `cache_creation.ephemeral_5m_input_tokens` | `claude_cache_creation_5_m_tokens`                             |
| 1 時間キャッシュ書き込み    | `cache_creation.ephemeral_1h_input_tokens` | `claude_cache_creation_1_h_tokens`                             |
| 出力               | `output_tokens`                            | `completion_tokens`                                            |

<Note>`prompt_tokens_details.cache_write_tokens` が `0` の場合も、`claude_cache_creation_5_m_tokens` と `claude_cache_creation_1_h_tokens` を確認してください。TTL ごとのフィールドが存在する場合、キャッシュ書き込み量は対応するフィールドで返されます。</Note>

<Note>`claude_cache_creation_5_m_tokens` と `claude_cache_creation_1_h_tokens` では、数字と単位の間にアンダースコアが含まれます。レスポンスで返されたフィールド名をそのまま使用してください。</Note>

<Warning>OpenAI 互換インターフェースは、`stream: true` を明示的に指定していない場合でも SSE ストリーミングレスポンスを返すことがあります。クライアントは `chat.completion.chunk` の解析に対応する必要があります。使用量は、`usage` を含む最後のデータブロックに格納されます。</Warning>

## キャッシュヒットの条件

### プレフィックスが最小長を満たしている

本ガイドで使用するモデルでは、通常、キャッシュプレフィックスに少なくとも約 1024 token が必要です。プレフィックスが短すぎる場合、エラーを返さずにキャッシュマーカーが無視されることがあります。

### プレフィックスがバイト単位で一致している

キャッシュプレフィックス内のテキスト、スペース、改行、content block の順序をすべて同一にする必要があります。安定したプレフィックスにタイムスタンプ、ランダム ID、リクエスト数などの動的コンテンツを追加しないでください。

### リクエストがモデルによる拒否を引き起こしていない

リクエストがモデルによる拒否を引き起こした場合、レスポンスにキャッシュ作成 token が報告されても、そのキャッシュは次のリクエストで読み取られません。キャッシュミスを調査する際は、`stop_reason` が `refusal` かどうかも確認してください。

### キャッシュが有効期限内である

キャッシュの有効期間は 5 分または 1 時間で、最後にアクセスした時点から計算されます。キャッシュヒットすると有効期間が更新されます。

## 課金対象の使用量

キャッシュ関連の使用量は、次の 3 種類に分かれます。

| 使用量       | 発生するタイミング               |
| --------- | ----------------------- |
| キャッシュ書き込み | 最初にキャッシュを作成したとき         |
| キャッシュ読み取り | それ以降のリクエストでキャッシュヒットしたとき |
| 通常入力      | キャッシュプレフィックス以外の入力       |

この 3 種類は重複しません。通常、キャッシュ書き込みのコストは通常入力より高く、キャッシュ読み取りのコストは通常入力より低くなります。そのため、コンテキストキャッシュは TTL 内に繰り返し使用する安定したプレフィックスに適しています。

## 最小再現例

次のスクリプトでは、十分に長い安定したプレフィックスを生成し、同じリクエストを 2 回連続で送信します。2 回目のレスポンスでは `cache_read_input_tokens > 0` になるはずです。

```bash theme={null}
python3 - <<'PY' > /tmp/claude-cache-request.json
import json

paragraph = (
    "プロンプトキャッシュはリクエストのプレフィックスを保存するため、後続のリクエストで "
    "バイト単位で同一のプレフィックスを再処理せずに利用できます。 "
)

system_text = (
    "あなたはドキュメント作成アシスタントです。参考資料を以下に示します。\n\n"
    + paragraph * 40
)

print(json.dumps({
    "model": "claude-sonnet-5",
    "max_tokens": 32,
    "system": [{
        "type": "text",
        "text": system_text,
        "cache_control": {"type": "ephemeral"}
    }],
    "messages": [{
        "role": "user",
        "content": "変更せずに維持する必要があるものを 1 文で答えてください。"
    }]
}))
PY

for request_number in 1 2; do
  echo "${request_number} 回目のリクエスト"
  curl -s "https://api.apimart.ai/v1/messages" \
    -H "x-api-key: $API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "Content-Type: application/json" \
    --data @/tmp/claude-cache-request.json \
  | python3 -c "import json, sys; print(json.load(sys.stdin)['usage'])"
done
```

期待される結果：

```text theme={null}
1 回目のリクエスト：cache_creation_input_tokens > 0、cache_read_input_tokens = 0
2 回目のリクエスト：cache_creation_input_tokens = 0、cache_read_input_tokens > 0
```

## トラブルシューティングチェックリスト

キャッシュヒットしない場合は、次の項目を順番に確認してください。

* `stop_reason` が `refusal` かどうか
* キャッシュプレフィックスがモデルの最小 token 数を満たしているか
* 2 回のリクエストで安定したプレフィックスがバイト単位で一致しているか
* OpenAI 互換形式の `content` が配列になっているか
* `cache_control` が具体的な content block 内に配置されているか
* 1 時間キャッシュで `ttl: "1h"` と対応する `anthropic-beta` リクエストヘッダーの両方を設定しているか
* キャッシュが TTL を超えていないか
* 使用中のインターフェースに対応するキャッシュ使用量フィールドを読み取っているか
