すべてのプロダクト
Search
ドキュメントセンター

Alibaba Cloud Model Studio:コンテキストキャッシュ

最終更新日:Jun 27, 2026

大規模モデルに対する推論リクエストでは、マルチターン会話や同じ書籍に関する一連の質問など、入力が重複することがよくあります。コンテキストキャッシュは、これらのリクエストの共通プレフィックスをキャッシュすることで、冗長な計算を削減します。これにより、応答の品質に影響を与えることなく、応答速度を向上させ、利用料金を削減できます。

さまざまなシナリオをサポートするため、コンテキストキャッシュには 2 つのモードがあります。利便性、決定性、コストに関する要件に基づいてモードを選択してください。

  • 明示的キャッシュ:手動で有効にするモードです。特定のコンテンツに対してキャッシュを作成することで、5 分間の有効期間内に決定的なヒットを保証します。キャッシュの作成に使用されるトークンは、標準入力トークン価格の 125% で課金され、その後のキャッシュヒットは、その価格の 10% のみで課金されます。

  • 暗黙的キャッシュ:この自動モードは、追加の設定が不要で、無効にすることもできないため、利便性を重視するシナリオに最適です。システムは、リクエストの共通プレフィックス自動的に識別してキャッシュしますが、ヒット率は保証されません。キャッシュの作成に使用されるトークンは標準入力トークン価格の 100% で課金され、キャッシュから提供される入力部分にはその価格の 20% が課金されます。

項目

明示的キャッシュ

暗黙的キャッシュ

応答品質への影響

なし

なし

キャッシュ作成トークンの課金

標準入力トークン価格の 125%

標準入力トークン価格の 100%

キャッシュされた入力トークンの課金

標準入力トークン価格の 10%

標準入力トークン価格の 20%

キャッシュの最小トークン数

1024

256

キャッシュ有効期間

5 分間 (ヒット時にリセット)

不定。システムは定期的に古い未使用のキャッシュデータをクリアします。

説明

明示的キャッシュと暗黙的キャッシュは相互排他的です。

説明

Provisioned Throughput Unit (PTU) デプロイもコンテキストキャッシュをサポートします。キャッシュヒットが発生した場合、システムはキャッシュ割引係数を使用して PTU 使用量を計算します。詳細については、「Long inputs and caching for PTU」をご参照ください。

説明

OpenAI Chat Completions、DashScope、および Anthropic 互換インターフェイスでは、Responses API とセッションキャッシュを組み合わせて使用することで、推論のレイテンシーとコストを削減できます。詳細については、「セッションキャッシュ」をご参照ください。

明示的なキャッシュ

暗黙的キャッシュとは異なり、明示的キャッシュは明示的に作成する必要があり、オーバーヘッドも発生しますが、キャッシュヒット率の向上とアクセスレイテンシーの低減を実現します。

仕組み

メッセージ配列に "cache_control": {"type": "ephemeral"} マーカーを追加します。システムは、各 cache_control マーカーから後方に検索し、キャッシュヒットを見つけるために、直前の content ブロックを最大 20 個まで検査します。

1 つのリクエストは、最大 4 つのキャッシュマーカーをサポートします。
  • キャッシュミス

    キャッシュミスが発生した場合、システムはメッセージ配列の先頭から cache_control マーカーまでの content を基に、新しいキャッシュブロックを作成します。新しいキャッシュブロックの有効期間は 5 分です。

    システムは、モデルがレスポンスを生成した後にキャッシュを作成します。そのキャッシュにヒットさせる前に、作成リクエストが完了するまで待機してください。
    キャッシュブロックには、少なくとも 1,024 トークンが含まれます。
  • キャッシュヒット

    キャッシュヒットが発生した場合、システムは一致する最長のプレフィックスを選択し、該当するキャッシュブロックの有効期間を 5 分にリセットします。

次の例は、この仕組みを示しています:

  1. 最初のリクエストを送信:テキスト A (1,024 トークン超) を含むシステムメッセージを送信し、キャッシュマーカーを追加します:

    [{"role": "system", "content": [{"type": "text", "text": A, "cache_control": {"type": "ephemeral"}}]}] 

    システムは最初のキャッシュブロックを作成し、これを キャッシュブロック A と呼びます。

  2. 2 つ目のリクエストを送信:次の構造のリクエストを送信します:

    [
        {"role": "system", "content": A},
        <Other messages>
        {"role": "user","content": [{"type": "text", "text": B, "cache_control": {"type": "ephemeral"}}]}
    ]
    • "Other messages" が 20 件以下の場合、リクエストはキャッシュブロック A にヒットし、システムはその有効期間を 5 分にリセットします。また、システムは A、その他のメッセージ、および B に基づいて新しいキャッシュブロックも作成します。

    • "Other messages" が 20 件を超える場合、キャッシュブロック A ではキャッシュミスが発生します。それでもシステムは、完全なコンテキスト (A、その他のメッセージ、および B) に基づいて新しいキャッシュブロックを作成します。

Supported models

Singapore

The following models are available in the International deployment scope.

Qwen Max: qwen3.7-max, qwen3.7-max-2026-05-20, qwen3.7-max-2026-06-08, qwen3.6-max-preview, qwen3-max

Qwen Plus: qwen3.7-plus, qwen3.7-plus-2026-05-26, qwen3.6-plus, qwen3.5-plus, qwen3.5-plus-2026-04-20, qwen-plus

Qwen Flash: qwen3.6-flash, qwen3.5-flash, qwen-flash

Qwen Coder: qwen3-coder-plus, qwen3-coder-flash

Qwen VL: qwen3-vl-plus, qwen3-vl-flash

DeepSeek: deepseek-v3.2

Kimi: kimi-k2.7-code

China (Beijing)

The following models are available in the Chinese mainland deployment scope.

Qwen Max: qwen3.7-max, qwen3.7-max-2026-05-20, qwen3.7-max-2026-06-08, qwen3.6-max-preview, qwen3-max

Qwen Plus: qwen3.7-plus, qwen3.7-plus-2026-05-26, qwen3.6-plus, qwen3.5-plus, qwen3.5-plus-2026-04-20, qwen-plus

Qwen Flash: qwen3.6-flash, qwen3.5-flash, qwen-flash

Qwen Coder: qwen3-coder-plus, qwen3-coder-flash

Qwen VL: qwen3-vl-plus, qwen3-vl-flash

DeepSeek: deepseek-v3.2

Kimi: kimi-k2.6, kimi-k2.5

GLM: glm-5.1

Germany (Frankfurt)

The supported models vary depending on the service deployment scope.

  • Global scope:

    Qwen Max: qwen3.7-max, qwen3.7-max-2026-05-20, qwen3.7-max-2026-06-08, qwen3-max

    Qwen Plus: qwen3.7-plus, qwen3.7-plus-2026-05-26, qwen3.6-plus, qwen3.5-plus, qwen-plus

    Qwen Flash: qwen3.6-flash, qwen3.5-flash, qwen-flash

    Qwen VL: qwen3-vl-plus

    Qwen Coder: qwen3-coder-plus, qwen3-coder-flash

    Kimi: kimi-k2.5

  • EU scope:

    Qwen Max: qwen3-max

    Qwen Plus: qwen-plus

    Qwen Flash: qwen3.6-flash, qwen3.5-flash

    Qwen VL: qwen3-vl-plus, qwen3-vl-flash

Hong Kong (China)

The supported models vary depending on the service deployment scope.

  • Global scope:

    Qwen Max: qwen3.7-max, qwen3.7-max-2026-05-20, qwen3.7-max-2026-06-08, qwen3-max

    Qwen Plus: qwen3.7-plus, qwen3.7-plus-2026-05-26, qwen3.6-plus, qwen3.5-plus, qwen-plus

    Qwen Flash: qwen3.6-flash, qwen3.5-flash, qwen-flash

  • Hong Kong (China) scope:

    Qwen Max: qwen3-max

    Qwen Plus: qwen-plus

    Qwen Flash: qwen3.6-flash, qwen3.5-flash

    Qwen VL: qwen3-vl-plus

Japan (Tokyo)

The supported models vary depending on the service deployment scope.

  • Japan scope:

    Qwen Plus: qwen3.7-plus, qwen3.7-plus-2026-05-26

  • Global scope:

    Qwen Max: qwen3.7-max, qwen3.7-max-2026-05-20, qwen3.7-max-2026-06-08, qwen3-max

    Qwen Plus: qwen3.7-plus, qwen3.7-plus-2026-05-26, qwen3.6-plus, qwen3.5-plus, qwen-plus

    Qwen Flash: qwen3.6-flash, qwen3.5-flash, qwen-flash

クイックスタート

次の例では、OpenAI 互換、DashScope、および Anthropic 互換プロトコルにおけるキャッシュブロックの作成とキャッシュヒットの仕組みを説明します。

OpenAI 互換

from openai import OpenAI
import os

client = OpenAI(
    # 環境変数が設定されていない場合は、次の行を api_key="sk-xxx" に置き換えてください
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    # China (Beijing) のモデルを使用する場合は、base_url を https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/compatible-mode/v1 に置き換えてください
    base_url="https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1",
)

# コードリポジトリのコンテンツをモックします。キャッシュ可能なプロンプト長は 1,024 トークン以上です。
long_text_content = "<Your Code Here>" * 400

# リクエストを作成する関数
def get_completion(user_input):
    messages = [
        {
            "role": "system",
            "content": [
                {
                    "type": "text",
                    "text": long_text_content,
                    # ここに cache_control マーカーを配置します。これにより、メッセージ配列の先頭からここまでのすべてのコンテンツを含むキャッシュブロックが作成されます。
                    "cache_control": {"type": "ephemeral"},
                }
            ],
        },
        # ユーザーの質問はリクエストごとに異なります。
        {
            "role": "user",
            "content": user_input,
        },
    ]
    completion = client.chat.completions.create(
        # 明示的なキャッシュをサポートするモデルを選択します。
        model="qwen3.7-max",
        messages=messages,
    )
    return completion

# 最初のリクエスト
first_completion = get_completion("What is the content of this code?")
print(f"First request cache creation tokens: {first_completion.usage.prompt_tokens_details.cache_creation_input_tokens}")
print(f"First request cached tokens: {first_completion.usage.prompt_tokens_details.cached_tokens}")
print("=" * 20)
# 2 番目のリクエスト。コードの内容は同じですが、質問は異なります。
second_completion = get_completion("How can this code be optimized?")
print(f"Second request cache creation tokens: {second_completion.usage.prompt_tokens_details.cache_creation_input_tokens}")
print(f"Second request cached tokens: {second_completion.usage.prompt_tokens_details.cached_tokens}")

DashScope

import os
import dashscope
from dashscope import Generation
# 次の URL は Singapore 用です。{WorkspaceId} をお使いのワークスペース ID に置き換えてください。URL はリージョンによって異なります。
dashscope.base_http_api_url = "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1"

# コードリポジトリのコンテンツをモックします。キャッシュ可能なプロンプト長は 1,024 トークン以上です。
long_text_content = "<Your Code Here>" * 400

# リクエストを作成する関数
def get_completion(user_input):
    messages = [
        {
            "role": "system",
            "content": [
                {
                    "type": "text",
                    "text": long_text_content,
                    # ここに cache_control マーカーを配置します。これにより、メッセージ配列の先頭からここまでのすべてのコンテンツを含むキャッシュブロックが作成されます。
                    "cache_control": {"type": "ephemeral"},
                }
            ],
        },
        # ユーザーの質問はリクエストごとに異なります。
        {
            "role": "user",
            "content": user_input,
        },
    ]
    response = Generation.call(
        # 環境変数が設定されていない場合は、Model Studio API キーを直接使用します: api_key = "sk-xxx",
        api_key=os.getenv("DASHSCOPE_API_KEY"), 
        model="qwen3.7-max",
        messages=messages,
        result_format="message"
    )
    return response

# 最初のリクエスト
first_completion = get_completion("What is the content of this code?")
print(f"First request cache creation tokens: {first_completion.usage.prompt_tokens_details['cache_creation_input_tokens']}")
print(f"First request cached tokens: {first_completion.usage.prompt_tokens_details['cached_tokens']}")
print("=" * 20)
# 2 番目のリクエスト。コードの内容は同じですが、質問は異なります。
second_completion = get_completion("How can this code be optimized?")
print(f"Second request cache creation tokens: {second_completion.usage.prompt_tokens_details['cache_creation_input_tokens']}")
print(f"Second request cached tokens: {second_completion.usage.prompt_tokens_details['cached_tokens']}")
// Java SDK の最小バージョン:2.21.6
import com.alibaba.dashscope.aigc.generation.Generation;
import com.alibaba.dashscope.aigc.generation.GenerationParam;
import com.alibaba.dashscope.aigc.generation.GenerationResult;
import com.alibaba.dashscope.common.Message;
import com.alibaba.dashscope.common.MessageContentText;
import com.alibaba.dashscope.common.Role;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.NoApiKeyException;

import java.util.Arrays;
import java.util.Collections;

public class Main {
    private static final String MODEL = "qwen3-coder-plus";
    // コードリポジトリのコンテンツをモックします (1,024 トークンを超えるように 400 回繰り返します)。
    private static final String LONG_TEXT_CONTENT = generateLongText(400);
    private static String generateLongText(int repeatCount) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < repeatCount; i++) {
            sb.append("<Your Code Here>");
        }
        return sb.toString();
    }
    private static GenerationResult getCompletion(String userQuestion)
            throws NoApiKeyException, ApiException, InputRequiredException {
        // 次の URL は Singapore 用です。{WorkspaceId} をお使いのワークスペース ID に置き換えてください。URL はリージョンによって異なります。
        Generation gen = new Generation("http", "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1");

        // キャッシュコントロール付きのシステムメッセージを構築します。
        MessageContentText systemContent = MessageContentText.builder()
                .type("text")
                .text(LONG_TEXT_CONTENT)
                .cacheControl(MessageContentText.CacheControl.builder()
                        .type("ephemeral") // キャッシュタイプを設定します。
                        .build())
                .build();

        Message systemMsg = Message.builder()
                .role(Role.SYSTEM.getValue())
                .contents(Collections.singletonList(systemContent))
                .build();
        Message userMsg = Message.builder()
                .role(Role.USER.getValue())
                .content(userQuestion)
                .build();

        // リクエストパラメーターを構築します。
        GenerationParam param = GenerationParam.builder()
                .model(MODEL)
                .messages(Arrays.asList(systemMsg, userMsg))
                .resultFormat(GenerationParam.ResultFormat.MESSAGE)
                .build();
        return gen.call(param);
    }

    private static void printCacheInfo(GenerationResult result, String requestLabel) {
        System.out.printf("%s cache creation tokens: %d%n", requestLabel, result.getUsage().getPromptTokensDetails().getCacheCreationInputTokens());
        System.out.printf("%s cached tokens: %d%n", requestLabel, result.getUsage().getPromptTokensDetails().getCachedTokens());
    }

    public static void main(String[] args) {
        try {
            // 最初のリクエスト
            GenerationResult firstResult = getCompletion("What is the content of this code?");
            printCacheInfo(firstResult, "First request");
            System.out.println(new String(new char[20]).replace('\0', '='));            // 2 番目のリクエスト
            GenerationResult secondResult = getCompletion("How can this code be optimized?");
            printCacheInfo(secondResult, "Second request");
        } catch (NoApiKeyException | ApiException | InputRequiredException e) {
            System.err.println("API call failed: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

Anthropic 互換

import anthropic
import os

client = anthropic.Anthropic(
    # 環境変数が設定されていない場合は、次の行を api_key="sk-xxx" に置き換えてください
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    # China (Beijing) のモデルを使用する場合は、base_url を https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/apps/anthropic に置き換えてください
    base_url="https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/apps/anthropic",
)

# コードリポジトリのコンテンツをモックします。キャッシュ可能なプロンプト長は 1,024 トークン以上です。
long_text_content = "<Your Code Here>" * 400

# リクエストを作成する関数
def get_completion(user_input):
    response = client.messages.create(
        # 明示的なキャッシュをサポートするモデルを選択します。
        model="qwen3.7-max",
        max_tokens=1024,
        system=[
            {
                "type": "text",
                "text": long_text_content,
                # ここに cache_control マーカーを配置します。これにより、システムテキストのコンテンツからキャッシュブロックが作成されます。このマーカーは `messages` にも配置できます。
                "cache_control": {"type": "ephemeral"},
            }
        ],
        messages=[
            # ユーザーの質問はリクエストごとに異なります。
            {"role": "user", "content": user_input},
        ],
    )
    return response

# 最初のリクエスト
first_completion = get_completion("What is the content of this code?")
print(f"First request cache creation tokens: {first_completion.usage.cache_creation_input_tokens}")
print(f"First request cache read input tokens: {first_completion.usage.cache_read_input_tokens}")
print("=" * 20)
# 2 番目のリクエスト。コードの内容は同じですが、質問は異なります。
second_completion = get_completion("How can this code be optimized?")
print(f"Second request cache creation tokens: {second_completion.usage.cache_creation_input_tokens}")
print(f"Second request cache read input tokens: {second_completion.usage.cache_read_input_tokens}")

cache_control マーカーを追加すると、モックコードリポジトリのコンテンツに対して明示的なキャッシュが有効になります。このコンテンツをクエリする後続のリクエストでは、システムはキャッシュブロックを再利用し、再計算を不要にします。これにより、キャッシュにヒットしたリクエストは、最初のキャッシュ作成リクエストよりも速く、安価になります。

First request cache creation tokens: 1605
First request cached tokens: 0
====================
Second request cache creation tokens: 0
Second request cached tokens: 1605

複数のキャッシュマーカーによるきめ細かい制御

複雑なシナリオでは、プロンプトは再利用頻度が異なる複数のパートで構成されることがよくあります。複数のキャッシュマーカーを使用すると、きめ細かい制御を実現できます。

例えば、インテリジェントなカスタマーサービスエージェントのプロンプトには、通常、次の要素が含まれます:

  • システムペルソナ:安定性が高く、ほとんど変更されません。

  • 外部知識:ナレッジベースやツールのクエリから取得され、1 回の会話中は変更されないことがあります。

  • 会話履歴:動的に増加します。

  • 現在の質問:リクエストごとに異なります。

プロンプト全体を 1 つの単位としてキャッシュすると、外部知識の更新などのわずかな変更でも、キャッシュミスが発生する可能性があります。

1 つのリクエストに最大 4 つのキャッシュマーカーを追加して、プロンプトのパートごとに個別のキャッシュブロックを作成できます。これにより、キャッシュヒット率が向上し、きめ細かい制御が可能になります。

課金

明示的なキャッシュは、入力トークンの課金方法にのみ影響します。ルールは以下の通りです。

  • キャッシュの作成:新しいキャッシュの作成に使用されるコンテンツには、標準入力トークン価格の 125% が課金されます。新しいキャッシュのコンテンツに既存のキャッシュがプレフィックスとして含まれている場合、キャッシュ作成分としては増分部分のみが課金されます (つまり、新しいキャッシュトークンの数から既存のキャッシュトークンの数を引いたものです)。

    例えば、既存の 1,200 トークンのキャッシュ (キャッシュA) があり、新しいリクエストを使用して 1,500 トークンのコンテンツ (コンテンツAB) をキャッシュする場合、最初の 1,200 トークンはキャッシュヒットとして標準価格の 10% で課金されます。新しい 300 トークンは、キャッシュ作成分として標準価格の 125% で課金されます。

    cache_creation_input_tokens パラメーターは、キャッシュの作成に使用されたトークンの数を指定します。
  • キャッシュヒット:標準入力トークン価格の 10% で課金されます。

    cached_tokens パラメーターは、キャッシュされたトークンの数を指定します。
  • その他のトークン:キャッシュヒットでもなく、キャッシュの作成にも使用されないトークンは、標準入力トークン価格で課金されます。

キャッシュ可能なコンテンツ

messages 配列では、以下のメッセージタイプのみがキャッシュマーカーの追加に対応しています:

  • システムメッセージ

    説明

    関数呼び出しの場合、リクエストに tools パラメーターが含まれていると、ツール定義はシステムメッセージに含まれ、キャッシュ計算の対象となります。ツール定義を単独でキャッシュすることはできません。キャッシュマーカーはメッセージのコンテンツにのみ追加できるため、ツール定義に追加されたキャッシュマーカーは無視されます。

  • ユーザーメッセージ

    qwen3-vl-plus モデルでキャッシュを作成する場合、cache_control マーカーはマルチモーダルコンテンツまたはテキストの後に配置できます。その位置は、ユーザーメッセージ全体のキャッシュ方法には影響しません。
  • アシスタントメッセージ

  • ツールメッセージ (ツールの実行結果)

例えば、システムメッセージの場合、content フィールドを配列に変更し、cache_control フィールドを追加する必要があります:

{
  "role": "system",
  "content": [
    {
      "type": "text",
      "text": "<ご指定のプロンプト>",
      "cache_control": {
        "type": "ephemeral"
      }
    }
  ]
}

この構造は、messages 配列内の他のメッセージタイプにも当てはまります。

キャッシュの制限

  • キャッシュ可能なプロンプト長の最小値は 1,024 トークンです。

  • キャッシュは後方プレフィックスマッチング戦略を使用します。一致したコンテンツと cache_control マーカーを含むメッセージの間に 20 個を超えるコンテンツブロックがある場合、キャッシュミスが発生します。

  • type に設定できる値は ephemeral のみです。これにより、有効期間が 5 分のキャッシュが作成されます。

  • 1 つのリクエストでサポートされるキャッシュマーカーは最大 4 つです。

    キャッシュマーカーが 4 つを超えて指定された場合、有効になるのは最後の 4 つのみです。

関数呼び出しのキャッシュ最適化

ツールの定義は、キャッシュ用に JSON 文字列へシリアル化されます。キャッシュの無効化を防ぐには、この定義がすべてのリクエストで同一である必要があります。次の点にご注意ください。

  • 一貫したツールの順序tools 配列内のツールの順序は、すべてのリクエストで一貫している必要があります。

  • 一貫したフィールドの順序: 同じツール内の JSON フィールドの順序は、すべてのリクエストで一貫している必要があります。

  • 一貫したフィールド構造: フィールドが空または任意であっても、省略したり追加したりしないでください。

使用例

長文テキストのクエリ

from openai import OpenAI
import os

client = OpenAI(
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    # これは Singapore リージョンの base_url です。呼び出し時には、{WorkspaceId} を実際の WorkspaceId に置き換えてください。URL はリージョンによって異なります。
    base_url="https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1",
)

# コードリポジトリのコンテンツをモックします
long_text_content = "<Your Code Here>" * 400

# リクエストを送信する関数
def get_completion(user_input):
    messages = [
        {
            "role": "system",
            "content": [
                {
                    "type": "text",
                    "text": long_text_content,
                    # cache_control マーカーをここに配置して、プロンプトの先頭からこの content オブジェクト (モックされたコードリポジトリのコンテンツ) の末尾までのキャッシュを作成します。
                    "cache_control": {"type": "ephemeral"},
                }
            ],
        },
        {
            "role": "user",
            "content": user_input,
        },
    ]
    completion = client.chat.completions.create(
        # 明示的なキャッシュをサポートするモデルを選択します
        model="qwen3.7-max",
        messages=messages,
    )
    return completion

# 1 回目のリクエスト
first_completion = get_completion("What is the content of this code?")
created_cache_tokens = first_completion.usage.prompt_tokens_details.cache_creation_input_tokens
print(f"First request - Cache creation tokens: {created_cache_tokens}")
hit_cached_tokens = first_completion.usage.prompt_tokens_details.cached_tokens
print(f"First request - Cache hit tokens: {hit_cached_tokens}")
print(f"First request - Uncached tokens: {first_completion.usage.prompt_tokens-created_cache_tokens-hit_cached_tokens}")
print("=" * 20)
# 2 回目のリクエスト:同じコードコンテンツで異なる質問をします
second_completion = get_completion("What are some possible optimizations for this code?")
created_cache_tokens = second_completion.usage.prompt_tokens_details.cache_creation_input_tokens
print(f"Second request - Cache creation tokens: {created_cache_tokens}")
hit_cached_tokens = second_completion.usage.prompt_tokens_details.cached_tokens
print(f"Second request - Cache hit tokens: {hit_cached_tokens}")
print(f"Second request - Uncached tokens: {second_completion.usage.prompt_tokens-created_cache_tokens-hit_cached_tokens}")

この例では、コードリポジトリのコンテンツをプレフィックスとしてキャッシュします。後続のリクエストでは、同じリポジトリについて異なる質問をします。

First request - Cache creation tokens: 1605
First request - Cache hit tokens: 0
First request - Uncached tokens: 13
====================
Second request - Cache creation tokens: 0
Second request - Cache hit tokens: 1605
Second request - Uncached tokens: 15
モデルのパフォーマンスを確保するため、システムはいくつかの内部トークンを追加します。これらのトークンは標準入力料金で課金されます。詳細については、「よくある質問」をご参照ください。

関数呼び出しにおけるツールのキャッシュ

ファンクションコーリングのシステムメッセージをキャッシュする場合、tools パラメーターがシステムメッセージの一部としてキャッシュされるため、すべてのリクエストでツール定義 (ツールの順序、フィールドの順序、フィールドの構造を含む) を同一にし、messages 内の最後の contentcache_control フラグを追加する必要があります。

以下に完全なフローを示します。最初のリクエストでキャッシュが作成され、2 回目のリクエストでキャッシュがヒットします。

from openai import OpenAI
import os

client = OpenAI(
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    base_url="https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1",
)

# コードリポジトリのコンテンツをモックし、明示的なキャッシュの最小しきい値である 1,024 トークンを超えるようにします。
long_text_content = "<Your Code Here>" * 400

# ツール定義:すべてのリクエストで同一 (ツールの順序、フィールドの順序、フィールド構造) にしてください。
tools = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "Get the current weather information for a specified city.",
            "parameters": {
                "type": "object",
                "properties": {
                    "city": {
                        "type": "string",
                        "description": "The city name, e.g., Beijing, Shanghai, or New York."
                    },
                    "unit": {
                        "type": "string",
                        "description": "The temperature unit, 'celsius' or 'fahrenheit'. Defaults to 'celsius'.",
                        "enum": ["celsius", "fahrenheit"]
                    }
                },
                "required": ["city"],
                "additionalProperties": False
            },
            "strict": True
        }
    },
    {
        "type": "function",
        "function": {
            "name": "get_current_time",
            "description": "Get the current date and time for a specified time zone.",
            "parameters": {
                "type": "object",
                "properties": {
                    "timezone": {
                        "type": "string",
                        "description": "IANA time zone name, e.g., 'Asia/Shanghai' or 'America/New_York'. Defaults to 'Asia/Shanghai'."
                    }
                },
                "required": [],
                "additionalProperties": False
            },
            "strict": True
        }
    },
    {
        "type": "function",
        "function": {
            "name": "convert_currency",
            "description": "Convert currency amounts based on real-time exchange rates.",
            "parameters": {
                "type": "object",
                "properties": {
                    "from_currency": {
                        "type": "string",
                        "description": "The ISO 4217 code of the source currency, e.g., CNY, USD, or EUR."
                    },
                    "to_currency": {
                        "type": "string",
                        "description": "The ISO 4217 code of the target currency."
                    },
                    "amount": {
                        "type": "number",
                        "description": "The amount to be converted."
                    }
                },
                "required": ["from_currency", "to_currency", "amount"],
                "additionalProperties": False
            },
            "strict": True
        }
    }
]

def get_completion(user_input, messages=None):
    if messages is None:
        messages = [
            {
                "role": "system",
                "content": [
                    {
                        "type": "text",
                        "text": long_text_content,
                        # cache_control マーカーをここに配置します。これにより、messages 配列の先頭から現在の content オブジェクトまでのすべてのコンテンツを含むキャッシュブロックが作成されます。
                        # cache_control マーカーは、メッセージの 'content' に配置する必要があり、'tools' には配置できません。
                        "cache_control": {"type": "ephemeral"},
                    }
                ],
            }
        ]

    messages.append({"role": "user", "content": user_input})

    completion = client.chat.completions.create(
        # 明示的なキャッシュをサポートするモデルを選択します
        model="qwen3.7-plus",
        messages=messages,
        tools=tools,
        # 思考モードを無効化します
        extra_body={"enable_thinking": False},
    )
    return completion

# 1 回目のリクエスト:キャッシュを作成
print("=== First request (Create cache) ===")
first_completion = get_completion("What's the weather like in Beijing now?")
usage = first_completion.usage
print(f"Prompt Tokens: {usage.prompt_tokens}")
print(f"Cache creation tokens: {usage.prompt_tokens_details.cache_creation_input_tokens}")
print(f"Cache hit tokens: {usage.prompt_tokens_details.cached_tokens}")
print(f"Model selected tool(s): {[t.function.name for t in first_completion.choices[0].message.tool_calls or []]}")
print()

# 2 回目のリクエスト:同じシステムメッセージで異なる質問をしてキャッシュヒット
print("=== Second request (Cache hit) ===")
messages = [
    {
        "role": "system",
        "content": [
            {
                "type": "text",
                "text": long_text_content,
                "cache_control": {"type": "ephemeral"},
            }
        ],
    }
]
second_completion = get_completion("What's the weather like in Shanghai now?", messages=messages)
usage = second_completion.usage
print(f"Prompt Tokens: {usage.prompt_tokens}")
print(f"Cache creation tokens: {usage.prompt_tokens_details.cache_creation_input_tokens}")
print(f"Cache hit tokens: {usage.prompt_tokens_details.cached_tokens}")
print(f"Model selected tool(s): {[t.function.name for t in second_completion.choices[0].message.tool_calls or []]}")

コードを実行すると、次のような出力が生成されます。

=== First request (Create cache) ===
 Prompt Tokens: 2174
 Cache creation tokens: 2156
 Cache hit tokens: 0
 Model selected tool(s): ['get_weather']

 === Second request (Cache hit) ===
 Prompt Tokens: 2174
 Cache creation tokens: 0
 Cache hit tokens: 2156
 Model selected tool(s): ['get_weather']

継続的なマルチターン対話

典型的なマルチターン対話シナリオでは、各リクエストで messages 配列の最後の content オブジェクトにキャッシュ マーカーを追加します。2 ターン目以降、各リクエストは前のターンのキャッシュにヒットして更新し、現在のターンの新しいキャッシュブロックを作成します。

from openai import OpenAI
import os
  
client = OpenAI(
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    # これは Singapore リージョンの base_url です。呼び出し時には、{WorkspaceId} を実際の WorkspaceId に置き換えてください。URL はリージョンによって異なります。
    base_url="https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1",
)

system_prompt = "You are a witty person." * 400
messages = [{"role": "system", "content": system_prompt}]

def get_completion(messages):
    completion = client.chat.completions.create(
        model="qwen3.7-max",
        messages=messages,
    )
    return completion

while True:
    user_input = input("User: ")
    messages.append({"role": "user", "content": [{"type": "text", "text": user_input, "cache_control": {"type": "ephemeral"}}]})
    completion = get_completion(messages)
    print(f"[AI Response] {completion.choices[0].message.content}")
    messages.append(completion.choices[0].message)
    created_cache_tokens = completion.usage.prompt_tokens_details.cache_creation_input_tokens
    hit_cached_tokens = completion.usage.prompt_tokens_details.cached_tokens
    uncached_tokens = completion.usage.prompt_tokens - created_cache_tokens - hit_cached_tokens
    print(f"[Cache Info] Cache creation tokens: {created_cache_tokens}")
    print(f"[Cache Info] Cache hit tokens: {hit_cached_tokens}")
    print(f"[Cache Info] Uncached tokens: {uncached_tokens}")

コードを実行して、大規模言語モデルとの対話を開始します。後続の各質問は、前のターンで作成されたキャッシュにヒットします。

暗黙的なキャッシュ

サポートされているモデル

China (Beijing)

以下のモデルは、中国本土のデプロイメントスコープでサポートされます。
  • テキスト生成モデル

    • Qwen Max: qwen3.7-max, qwen3.7-max-2026-05-20, qwen3.7-max-2026-06-08, qwen3-max, qwen3-max-preview, qwen-max

    • Qwen Plus: qwen3.7-plus, qwen3.7-plus-2026-05-26, qwen-plus

    • Qwen Flash: qwen-flash

    • Qwen Turbo: qwen-turbo

    • Qwen Coder: qwen3-coder-plus, qwen3-coder-flash

    • DeepSeek: deepseek-v4-pro, deepseek-v4-flash, deepseek-v3.2, deepseek-v3.1, deepseek-v3, deepseek-r1

    • Kimi: kimi-k2.6, kimi-k2.5, kimi-k2-thinking, Moonshot-Kimi-K2-Instruct

    • GLM: glm-5.2, glm-5.1, glm-5, glm-4.7, glm-4.6

    • MiniMax: MiniMax-M2.5

  • 視覚理解モデル

    • Qwen VL: qwen3-vl-plus, qwen3-vl-flash, qwen-vl-max, qwen-vl-plus

Singapore

以下のモデルは、国際デプロイメントスコープでサポートされます。
  • テキスト生成モデル

    • Qwen Max: qwen3.7-max, qwen3.7-max-2026-05-20, qwen3.7-max-2026-06-08, qwen3-max, qwen3-max-preview, qwen-max

    • Qwen Plus: qwen3.7-plus, qwen3.7-plus-2026-05-26, qwen-plus

    • Qwen Flash: qwen-flash

    • Qwen Turbo: qwen-turbo

    • Qwen Coder: qwen3-coder-plus, qwen3-coder-flash

    • DeepSeek: deepseek-v4-pro, deepseek-v4-flash, deepseek-v3.2

    • GLM (Alibaba Cloud Model Studio にデプロイ済み): glm-5.1

  • 視覚理解モデル

    • Qwen VL: qwen3-vl-plus, qwen3-vl-flash, qwen-vl-max, qwen-vl-plus

US (Virginia)

サポートされるモデルは、サービスデプロイメントスコープによって異なります。

  • グローバルサービスデプロイメントスコープ:

    • テキスト生成モデル

      • Qwen Max: qwen3.7-max, qwen3.7-max-2026-05-20, qwen3.7-max-2026-06-08, qwen3-max

      • Qwen Plus: qwen3.7-plus, qwen3.7-plus-2026-05-26, qwen-plus

      • Qwen Flash: qwen-flash

      • Qwen Coder: qwen3-coder-plus, qwen3-coder-flash

      • DeepSeek: deepseek-v4-pro, deepseek-v4-flash

      • Kimi (Alibaba Cloud Model Studio にデプロイ済み): kimi-k2.5

      • GLM (Alibaba Cloud Model Studio にデプロイ済み): glm-5.2, glm-5.1

    • 視覚理解モデル

      • Qwen VL: qwen3-vl-plus, qwen3-vl-flash

  • 米国サービスデプロイメントスコープ:

    • テキスト生成モデル

      • Qwen Max: qwen3.7-max-us

      • Qwen Plus: qwen3.7-plus-us, qwen-plus-us

      • Qwen Flash: qwen-flash-us

    • 視覚理解モデル

      • Qwen VL: qwen3-vl-flash-us

Germany (Frankfurt)

サポートされるモデルは、サービスデプロイメントスコープによって異なります。

  • グローバルサービスデプロイメントスコープ:

    • テキスト生成モデル

      • Qwen Max: qwen3.7-max, qwen3.7-max-2026-05-20, qwen3.7-max-2026-06-08, qwen3-max

      • Qwen Plus: qwen3.7-plus, qwen3.7-plus-2026-05-26, qwen-plus

      • Qwen Flash: qwen-flash

      • Qwen Coder: qwen3-coder-plus, qwen3-coder-flash

      • DeepSeek: deepseek-v4-pro, deepseek-v4-flash

      • Kimi (Alibaba Cloud Model Studio にデプロイ済み): kimi-k2.5

      • GLM (Alibaba Cloud Model Studio にデプロイ済み): glm-5.2, glm-5.1

    • 視覚理解モデル

      • Qwen VL: qwen3-vl-plus, qwen3-vl-flash

  • EU サービスデプロイメントスコープ:

    • テキスト生成モデル

      • Qwen Max: qwen3-max

      • Qwen Plus: qwen-plus

      視覚理解モデル

      • Qwen VL: qwen3-vl-plus, qwen3-vl-flash

China (Hong Kong)

サポートされるモデルは、サービスデプロイメントスコープによって異なります。

  • グローバルサービスデプロイメントスコープ:

    • テキスト生成モデル

    • Qwen Plus:qwen3.7-plus、qwen3.7-plus-2026-05-26

    • GLM (Alibaba Cloud Model Studio にてデプロイ): glm-5.2

  • China (Hong Kong) サービスデプロイメントスコープ:

    • テキスト生成モデル

      • Qwen Max: qwen3-max

      • Qwen Plus: qwen-plus

    • 視覚理解モデル

      • Qwen VL: qwen3-vl-plus

Japan (Tokyo)

サポートされるモデルは、サービスデプロイメントスコープによって異なります。

  • 日本サービスデプロイメントスコープ:

    • テキスト生成モデル

      • Qwen Plus: qwen3.7-plus, qwen3.7-plus-2026-05-26

      • DeepSeek (Alibaba Cloud Model Studio にデプロイ済み): deepseek-v4-pro, deepseek-v4-flash

  • グローバルサービスデプロイメントスコープ:

    • テキスト生成モデル

      • Qwen Max: qwen3.7-max, qwen3.7-max-2026-05-20, qwen3.7-max-2026-06-08, qwen3-max

      • Qwen Plus: qwen3.7-plus, qwen3.7-plus-2026-05-26, qwen-plus

      • DeepSeek (Alibaba Cloud Model Studio にデプロイ済み): deepseek-v4-pro, deepseek-v4-flash

      • GLM (Alibaba Cloud Model Studio にデプロイ済み): glm-5.2, glm-5.1

      • Kimi (Alibaba Cloud Model Studio でデプロイ済み): kimi-k2.5

仕組み

暗黙的キャッシュ機能は、サポート対象のモデルにリクエストを送信すると自動的に有効になります。システムの動作は次のとおりです:

  1. 検索:リクエストを受信すると、システムは 前方一致 を使用して、リクエストの messages 配列内のコンテンツの共通プレフィックスがキャッシュに存在するかどうかを確認します。

  2. 判定

    • キャッシュヒットした場合、システムは残りの推論処理にキャッシュされた結果を使用します。

    • キャッシュミスした場合、システムはリクエストを通常どおり処理し、将来のリクエストに備えてプロンプトのプレフィックスをキャッシュに保存します。

システムは、長期間使用されていないキャッシュデータを定期的にクリアします。コンテキストキャッシュのヒット率は 100% ではありません。リクエストのコンテキストが同一であっても、キャッシュミスが発生する場合があります。具体的なヒット率はシステムが決定します。
説明

暗黙的キャッシュのトリガーに必要なトークンの最小数は、qwen3.7-max シリーズでは約 1000、それ以外のモデルでは 256 です。

キャッシュヒット確率の向上

暗黙的キャッシュヒットは、異なるリクエストの プレフィックス に重複するコンテンツがある場合に発生します。ヒット確率を高めるには、重複するコンテンツをプロンプトの先頭に配置し、固有のコンテンツを末尾に配置してください。

  • テキストモデル :例えば、システムが 「ABCD」 をキャッシュしているとします。「ABE」 のリクエストは 「AB」 の部分でヒットする可能性がありますが、 「BCD」 のリクエストはヒットしません。

  • 視覚理解モデル

    • 同じ画像または動画 について複数の質問をする場合は、画像または動画をテキストの前に配置してください。

    • 異なる画像または動画 について同じ質問をする場合は、テキストを画像または動画の前に配置してください。

課金

暗黙的なキャッシュモードを有効にしても、追加料金は発生しません。

リクエストがキャッシュヒットした場合、キャッシュヒットした入力トークンは cached_token として課金されます。これらのトークンの割引率は、モデルによって異なります。キャッシュヒットしなかった入力トークンは、標準の input_token として課金されます。出力トークンは、元の価格で課金されます。

  • deepseek-v4-pro 以外のモデルの場合: cached_token の単価は、input_token の単価の 20% です。

  • deepseek-v4-pro : cached_token の単価は、input_token の単価の 20% ではありません。具体的な価格については、Model Studio コンソールをご参照ください。

例:リクエストに 10,000 の入力トークンが含まれ、そのうち 5,000 がキャッシュヒットした場合、コストは次のように計算されます。

  • キャッシュヒットしなかったトークン (5,000) :単価の 100% で課金されます。

  • キャッシュヒットしたトークン (5,000) :単価の 20% で課金されます。

合計入力コストは、非キャッシュモードの場合のコストの 60% になります: (50% × 100%) + (50% × 20%) = 60%。

image.png

キャッシュヒットしたトークンの数は、レスポンス 内の cached_tokens 属性から取得できます。

OpenAI 互換 - バッチ (ファイル入力) メソッドを使用した呼び出しは、キャッシュ割引の対象外です。

キャッシュヒットの例

テキスト生成モデル

OpenAI 互換

OpenAI 互換の方法でモデルを呼び出し、暗黙的なキャッシュをトリガーすると、レスポンスの usage.prompt_tokens_details.cached_tokens フィールドにキャッシュにヒットしたトークン数が示されます。この値は usage.prompt_tokens の一部です。

{
    "choices": [
        {
            "message": {
                "role": "assistant",
                "content": "I am a large-scale language model developed by Alibaba Cloud. My name is Qwen."
            },
            "finish_reason": "stop",
            "index": 0,
            "logprobs": null
        }
    ],
    "object": "chat.completion",
    "usage": {
        "prompt_tokens": 3019,
        "completion_tokens": 104,
        "total_tokens": 3123,
        "prompt_tokens_details": {
            "cached_tokens": 2048
        }
    },
    "created": 1735120033,
    "system_fingerprint": null,
    "model": "qwen-plus",
    "id": "chatcmpl-6ada9ed2-7f33-9de2-8bb0-78bd4035025a"
}

DashScope

DashScope の Python SDK または HTTP リクエストを使用してモデルを呼び出し、暗黙的なキャッシュをトリガーすると、レスポンスの usage.prompt_tokens_details.cached_tokens フィールドにキャッシュにヒットしたトークン数が含まれます。この値は usage.input_tokens の一部です。

{
    "status_code": 200,
    "request_id": "f3acaa33-e248-97bb-96d5-cbeed34699e1",
    "code": "",
    "message": "",
    "output": {
        "text": null,
        "finish_reason": null,
        "choices": [
            {
                "finish_reason": "stop",
                "message": {
                    "role": "assistant",
                    "content": "I am a large language model from Alibaba Cloud. My name is Qwen. I can generate various types of text, such as articles, stories, and poems, and can adapt them based on different scenarios and requirements. Additionally, I can answer various questions and provide help and solutions. If you have any questions or need assistance, feel free to ask, and I will do my best to provide support. Please note that repeating the same content may not yield a more detailed response. We recommend providing more specific information or varying your questions so I can better understand your needs."
                }
            }
        ]
    },
    "usage": {
        "input_tokens": 3019,
        "output_tokens": 101,
        "prompt_tokens_details": {
            "cached_tokens": 2048
        },
        "total_tokens": 3120
    }
}

Anthropic 互換

Anthropic 互換の方法でモデルを呼び出し、暗黙的なキャッシュがトリガーされると、usage.cache_read_input_tokens でキャッシュにヒットしたトークン数を確認できます (この値は usage.input_tokens には含まれず、別途報告されます)。

{
    "id": "msg_01XFDUDYJgAACzvnptvVoYEL",
    "type": "message",
    "role": "assistant",
    "content": [
        {
            "type": "text",
            "text": "This content is repeated placeholder text."
        }
    ],
    "model": "qwen3.7-max",
    "stop_reason": "end_turn",
    "usage": {
        "input_tokens": 82,
        "cache_creation_input_tokens": 0,
        "cache_read_input_tokens": 1536,
        "output_tokens": 14
    }
}

視覚理解モデル

OpenAI 互換

OpenAI 互換の方法でモデルを呼び出し、暗黙的なキャッシュがトリガーされると、レスポンスの usage.prompt_tokens_details.cached_tokens フィールドにキャッシュにヒットしたトークン数が示されます。このトークン数は usage.prompt_tokens の一部です。

{
  "id": "chatcmpl-3f3bf7d0-b168-9637-a245-dd0f946c700f",
  "choices": [
    {
      "finish_reason": "stop",
      "index": 0,
      "logprobs": null,
      "message": {
        "content": "This image shows a heartwarming scene of a woman and a dog interacting on a beach. The woman, wearing a plaid shirt, is sitting on the sand and smiling as she interacts with the dog. The dog is a large, light-colored breed wearing a colorful collar, with its front paw raised as if to shake hands or give a high-five to the woman. The background is a vast ocean and sky, with sunlight shining from the right side of the frame, adding a warm and serene atmosphere to the entire scene.",
        "refusal": null,
        "role": "assistant",
        "audio": null,
        "function_call": null,
        "tool_calls": null
      }
    }
  ],
  "created": 1744956927,
  "model": "qwen-vl-max",
  "object": "chat.completion",
  "service_tier": null,
  "system_fingerprint": null,
  "usage": {
    "completion_tokens": 93,
    "prompt_tokens": 1316,
    "total_tokens": 1409,
    "completion_tokens_details": null,
    "prompt_tokens_details": {
      "audio_tokens": null,
      "cached_tokens": 1152
    }
  }
}

DashScope

DashScope の Python SDK または HTTP リクエストを使用してモデルを呼び出し、暗黙的なキャッシュヒットが発生した場合、キャッシュされたトークン数は合計入力トークン (usage.input_tokens) とは別に報告されます。この数を確認できる特定のフィールドは、リージョンとモデルによって異なります :

  • China (Beijing) :

    • qwen-vl-maxqwen-vl-plususage.prompt_tokens_details.cached_tokens に表示されます

    • qwen3-vl-plusqwen3-vl-flashusage.prompt_tokens_details.cached_tokens に表示されます

  • シンガポールリージョン : すべてのモデルについて、usage.cached_tokens を参照してください

シンガポールリージョンのモデルは現在 usage.cached_tokens を使用しており、将来的に usage.prompt_tokens_details.cached_tokens にアップグレードされる予定です。
{
  "status_code": 200,
  "request_id": "06a8f3bb-d871-9db4-857d-2c6eeac819bc",
  "code": "",
  "message": "",
  "output": {
    "text": null,
    "finish_reason": null,
    "choices": [
      {
        "finish_reason": "stop",
        "message": {
          "role": "assistant",
          "content": [
            {
              "text": "This image shows a heartwarming scene of a woman and a dog interacting on a beach. The woman, wearing a plaid shirt, is sitting on the sand and smiling as she interacts with the dog. The dog is a large breed wearing a colorful collar, with its front paw raised as if to shake hands or give a high-five to the woman. The background is a vast ocean and sky, with sunlight shining from the right side of the frame, adding a warm and serene atmosphere to the entire scene."
            }
          ]
        }
      }
    ]
  },
  "usage": {
    "input_tokens": 1292,
    "output_tokens": 87,
    "input_tokens_details": {
      "text_tokens": 43,
      "image_tokens": 1249
    },
    "total_tokens": 1379,
    "output_tokens_details": {
      "text_tokens": 87
    },
    "image_tokens": 1249,
    "cached_tokens": 1152
  }
}

Anthropic 互換

Anthropic 互換の方法で視覚理解モデルを呼び出し、暗黙的なキャッシュがトリガーされると、キャッシュヒットによるトークン数は usage.cache_read_input_tokens フィールドに反映されます (テキスト生成モデルと同じです)。

{
  "id": "msg_01XFDUDYJgAACzvnptvVoYEL",
  "type": "message",
  "role": "assistant",
  "content": [
    {
      "type": "text",
      "text": "This image shows a heartwarming scene of a woman and a dog interacting on a beach."
    }
  ],
  "model": "qwen-vl-max",
  "stop_reason": "end_turn",
  "usage": {
    "input_tokens": 369,
    "cache_creation_input_tokens": 0,
    "cache_read_input_tokens": 896,
    "output_tokens": 28
  }
}

ユースケース

リクエストに共通プレフィックスが含まれる場合、コンテキストキャッシュは推論速度を大幅に向上させ、推論コストを削減し、初回パケットレイテンシーを短縮できます。この機能は、特に次のユースケースで役立ちます :

  1. 長文質問応答

    小説、教科書、法的文書など、同じ長文について複数のリクエストを送信する場合にこのパターンを使用します。

    最初のリクエストの messages

    messages = [{"role": "system","content": "You are a language teacher who can help students with reading comprehension."},
              {"role": "user","content": "

    後続のリクエストの messages 配列

    messages = [{"role": "system","content": "You are a language teacher who can help students with reading comprehension."},
              {"role": "user","content": "<Article content> Please analyze the third paragraph of this text."}]

    質問は異なりますが、すべて同じ記事に基づいています。同じシステムプロンプトと記事の内容は、大量の反復的なプレフィックス情報を構成するため、キャッシュヒットの可能性が高くなります。

  2. コード自動補完

    コード自動補完シナリオでは、モデルは周囲のコードをコンテキストとして使用して後続のコードを生成します。コードを記述する際、コードファイルの先頭は同じままです。コンテキストキャッシュはこのプレフィックスを保存して、コード補完を高速化できます。

  3. 複数ターンの会話

    複数ターンの会話では、各ターンを messages 配列に追加します。これにより、各新しいリクエストが前のターンと共通プレフィックスを共有することが保証され、キャッシュヒットの可能性が高まります。

    最初のターンの messages

    messages=[{"role": "system","content": "You are a helpful assistant."},
              {"role": "user","content": "Who are you?"}]

    2ターン目の messages

    messages=[{"role": "system","content": "You are a helpful assistant."},
              {"role": "user","content": "Who are you?"},
              {"role": "assistant","content": "I am Qwen, developed by Alibaba Cloud."},
              {"role": "user","content": "What can you do?"}]

    会話が長くなるにつれて、キャッシュによる推論速度とコストのメリットはより顕著になります。

  4. ロールプレイングまたはフューショット学習

    ロールプレイングまたはフューショット学習のシナリオでは、モデルの出力形式をガイドするために、プロンプトに広範な指示を含めることがよくあります。これにより、複数のリクエストにわたって大きな共有プレフィックスが作成されます。

    たとえば、モデルにマーケティングの専門家として行動するように指示する場合、システムプロンプトには広範なテキストが含まれます。以下に2つのリクエスト例を示します :

    system_prompt = """You are an experienced marketing expert. Provide detailed marketing suggestions for different products in the following format:
    
    1. Target audience: xxx
    
    2. Main selling points: xxx
    
    3. Marketing channels: xxx
    ...
    12. Long-term development strategy: xxx
    
    Ensure your suggestions are specific, actionable, and highly relevant to the product features."""
    
    # 最初のリクエストのユーザーメッセージはスマートウォッチについて尋ねています。
    messages_1=[
      {"role": "system", "content": system_prompt},
      {"role": "user", "content": "Provide marketing suggestions for a newly launched smartwatch."}
    ]
    
    # 2番目のリクエストのユーザーメッセージはラップトップについて尋ねています。 system_prompt が同じであるため、キャッシュヒットの可能性が非常に高くなります。
    messages_2=[
      {"role": "system", "content": system_prompt},
      {"role": "user", "content": "Provide marketing suggestions for a newly launched laptop."}
    ]

    コンテキストキャッシュを使用すると、リクエスト内の製品を頻繁に変更した場合 (たとえば、スマートウォッチからラップトップへ) でも、長いシステムプロンプトがキャッシュされるため、システムはより速く応答できます。

  5. 動画理解

    動画理解のシナリオでは、同じ動画について複数の質問をする場合は videotext の前に配置すると、キャッシュヒットの確率が高まります。異なる動画について同じ質問をする場合は textvideo の前に配置すると、キャッシュヒットの確率が高まります。次の例は、同じ動画に対する2つのリクエストを示しています :

    # 最初のリクエストのユーザーメッセージは、この動画の内容について尋ねています。
    messages1 = [
        {"role":"system","content":[{"text": "You are a helpful assistant."}]},
        {"role": "user",
            "content": [
                {"video": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20250328/eepdcq/phase_change_480p.mov"},
                {"text": "What is the content of this video?"}
            ]
        }
    ]
    
    # 同じ動画に関する2番目のリクエストでは、動画をテキストの前に配置すると、キャッシュヒットの可能性が高まります。
    messages2 = [
        {"role":"system","content":[{"text": "You are a helpful assistant."}]},
        {"role": "user",
            "content": [
                {"video": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20250328/eepdcq/phase_change_480p.mov"},
                {"text": "Describe the series of events in the video. Output the start time (start_time), end time (end_time), and event (event) in JSON format. Do not include the ```json``` code block."}
            ]
        }
    ]

よくある質問

Q:暗黙的キャッシュを無効にするにはどうすればよいですか?

A:無効にすることはできません。暗黙的キャッシュは応答品質に影響しないため、適用可能なすべてのモデルリクエストで有効になります。キャッシュヒットが発生すると、コストを削減し、応答速度が向上します。

Q:明示的キャッシュでキャッシュミスが発生したのはなぜですか?

A:キャッシュミスは、次の理由で発生する場合があります:

  • 5 分の有効期間内にキャッシュヒットしない場合、システムはキャッシュブロックをクリアします。

  • 最後の content と既存のキャッシュブロックとの間隔が 20 content ブロックを超える場合、キャッシュヒットは発生しません。 新しいキャッシュブロックを作成することをお勧めします。

Q:キャッシュヒットによって有効期間はリセットされますか?

A:はい。ヒットのたびに、キャッシュブロックの有効期間が 5 分にリセットされます。

Q:明示的キャッシュはアカウント間で共有されますか?

A:いいえ。暗黙的キャッシュと明示的キャッシュのデータは、どちらもアカウントレベルで分離されています。

Q:明示的キャッシュはモデル間で共有されますか?

A:いいえ。キャッシュデータはモデル間で分離されています。

Q: なぜ input_tokensusage における値は、cache_creation_input_tokenscached_tokens の合計と等しくないのですか?

A: モデルの出力品質を確保するため、バックエンドサービスがお客様のプロンプトに少数のトークン (通常は 10 以下) を追加します。これらのトークンは cache_control マーカーの後に配置されるため、キャッシュの作成または読み取りではカウントされませんが、合計 input_tokens には含まれます。