Firebase AI Logic のコンテキスト キャッシュ保存

AI 機能では、同じ入力トークン(コンテンツ)をモデルに何度も渡すことがあります。このようなユースケースでは、代わりにこのコンテンツをキャッシュに保存できます。つまり、コンテンツをモデルに 1 回渡して保存し、後続のリクエストで参照できます。

コンテキスト キャッシュ保存を使用すると、大量のテキスト、音声ファイル、動画ファイルなど、大量のコンテンツを含む反復タスクのレイテンシと費用を大幅に削減できます。キャッシュに保存されたコンテンツの一般的なユースケースには、詳細なペルソナ ドキュメント、コードベース、マニュアルなどがあります。

Gemini モデルには、次の 2 つのキャッシュ保存メカニズムが用意されています。

明示的なキャッシュは、デベロッパーの作業を増やすことで、費用を削減する可能性を高める場合に役立ちます。

暗黙的なキャッシュ保存と明示的なキャッシュ保存の両方で、レスポンスのメタデータの cachedContentTokenCount フィールドは、入力のキャッシュに保存された部分のトークン数を示します。明示的なキャッシュ保存については、このページの下部にある料金情報をご覧ください。

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

次のモデルを使用する場合、キャッシュ保存がサポートされます。

  • gemini-4-argon(暗黙的なキャッシュ保存のみ。明示的なキャッシュ保存はサポートされていません)
  • gemini-3.8-flash
  • gemini-3.5-flash-lite(および以前の gemini-3.1-flash-lite)

古い一般用途の Gemini 3.x Flash モデルはこの機能をサポートしていますが、今後のシャットダウン日や新しいモデルへの自動ルーティングのため、使用はおすすめしません。

メディア生成モデル(gemini-nano-banana-2.1 などの Gemini Nano Banana モデルなど)は、コンテキスト キャッシュ保存をサポートしていません。

キャッシュに保存されたコンテンツのサイズの上限

各モデルには、キャッシュに保存されたコンテンツの最小トークン数の要件があります。最大値はモデルのコンテキスト ウィンドウによって決まります。

  • Gemini 4 Argon: 4,096 トークン以上(Gemini Developer API)または 6,144 トークン以上(Agent Platform Gemini API (formerly Vertex AI))
  • Gemini Pro モデル: 4,096 トークン以上
  • Gemini Flash モデル: 1,024 トークン以上

また、blob またはテキストを使用してキャッシュに保存できるコンテンツの最大サイズは 10 MB です。



暗黙的なキャッシュ保存

暗黙的なキャッシュ保存はデフォルトで有効になっており、ほとんどの Gemini モデルで使用できます。

リクエストがキャッシュに保存されたコンテンツにヒットした場合、Google は自動的にコスト削減を適用します。リクエストで暗黙的なキャッシュが使用される可能性を高める方法は次のとおりです。

  • 大規模で一般的なコンテンツは、プロンプトの先頭に配置してみてください。
  • 類似した接頭辞を含むリクエストを短時間で送信します。

入力のキャッシュに保存された部分のトークン数は、レスポンスのメタデータの cachedContentTokenCount フィールドに表示されます。



明示的なキャッシュ保存

明示的なキャッシュ保存はデフォルトでは有効になっていません。これは Gemini モデルのオプション機能です。

gemini-4-argon モデルは、明示的なキャッシュ保存をサポートしていません。

明示的なコンテンツ キャッシュを設定して操作する方法は次のとおりです。

明示的なコンテンツ キャッシュは暗黙的なキャッシュと連携するため、明示的にキャッシュに保存されたコンテンツ以外のキャッシュが追加される可能性があります。キャッシュ データの保持を防ぐには、暗黙的なキャッシュ保存を無効にし、明示的なキャッシュを作成しないようにします。詳細については、キャッシュ保存を有効または無効にするをご覧ください。



明示的なキャッシュを作成して使用する

明示的なコンテキスト キャッシュを作成して使用するには、次のものが必要です。

  1. 明示的なキャッシュを作成する。

  2. サーバー プロンプト テンプレートでキャッシュを参照する。

  3. アプリからのプロンプト リクエストでサーバー プロンプト テンプレートを参照します。

明示的なキャッシュの作成と使用に関する重要な情報

キャッシュは、アプリのプロンプト リクエストとサーバーのプロンプト テンプレートに合わせる必要があります。

  • キャッシュは Gemini API プロバイダに固有です。アプリのプロンプト リクエストでは、同じプロバイダを使用する必要があります。
    Firebase AI Logic の場合、明示的なコンテンツ キャッシュは Agent Platform Gemini API (formerly Vertex AI) でのみ使用することを強くおすすめします。このページの情報と例はすべて、その Gemini API プロバイダに固有のものです。

  • キャッシュは Gemini モデルに固有です。アプリのプロンプト リクエストでは、同じモデルを使用する必要があります。

  • Agent Platform Gemini API (formerly Vertex AI) を使用する場合、キャッシュはロケーションに固有です。
    明示的なキャッシュのロケーションは、アプリのプロンプト リクエストのサーバー プロンプト テンプレートのロケーションとモデルにアクセスするロケーションと一致する必要があります。

また、明示的なキャッシュ保存に関する次の制限事項と要件にも注意してください。

  • 明示的なキャッシュを作成すると、TTL または有効期限以外のキャッシュに関する変更はできません。

  • サポートされている入力ファイルの MIME タイプや、キャッシュ作成リクエスト内で提供されるテキストをキャッシュに保存できます。

  • キャッシュにファイルを含める場合は、ファイルを Cloud Storage URI として指定する必要があります。ブラウザの URL や YouTube の URL は使用できません。

    また、ファイルへのアクセス制限はキャッシュ作成時にチェックされ、ユーザー リクエスト時にアクセス制限は再チェックされません。このため、明示的なキャッシュに含まれるデータが、そのキャッシュを含むリクエストを行うユーザーに適していることを確認してください。

  • システム指示やツール(コード実行、URL コンテキスト、Google Search によるグラウンディング、Google Maps によるグラウンディングなど)を使用する場合は、キャッシュ自体にそれらの構成が含まれている必要があります。サーバー プロンプト テンプレートやアプリのプロンプト リクエストで構成することはできません。サーバー プロンプト テンプレートは、関数呼び出し(またはチャット)をまだサポートしていません。キャッシュでシステム指示とツールを構成する方法については、Agent Platform Gemini API (formerly Vertex AI) の REST API をご覧ください。

ステップ 1: キャッシュを作成する

Agent Platform Gemini API (formerly Vertex AI) の REST API を直接使用してキャッシュを作成します。

次の例では、PDF ファイルの明示的なキャッシュをコンテンツとして作成します。

構文:

PROJECT_ID="PROJECT_ID"
MODEL_ID="GEMINI_MODEL"  # for example, gemini-3.8-flash
LOCATION="LOCATION"  # location for both the cache and the model
MIME_TYPE="MIME_TYPE"
CACHED_CONTENT_URI="CLOUD_STORAGE_FILE_URI"  # must be a Cloud Storage URI
CACHE_DISPLAY_NAME="CACHE_DISPLAY_NAME"  # optional
TTL="CACHE_TIME_TO_LIVE"  # optional (if not specified, defaults to 3600s)

curl \
-X POST \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
https://${LOCATION}-aiplatform.googleapis.com/v1beta1/projects/${PROJECT_ID}/locations/${LOCATION}/cachedContents \
-d @- <<EOF
{
  "model":"projects/${PROJECT_ID}/locations/${LOCATION}/publishers/google/models/${MODEL_ID}",
  "contents": [
    {
      "role": "user",
      "parts": [
        {
          "fileData": {
            "mimeType": "${MIME_TYPE}",
            "fileUri": "${CACHED_CONTENT_URI}"
          }
        }
      ]
    }
  ],
  "displayName": "${CACHE_DISPLAY_NAME}",
  "ttl": "${TTL}"
}
EOF

リクエストの例:

PROJECT_ID="my-amazing-app"
MODEL_ID="gemini-3.8-flash"
LOCATION="global"
MIME_TYPE="application/pdf"
CACHED_CONTENT_URI="gs://cloud-samples-data/generative-ai/pdf/2312.11805v3.pdf"
CACHE_DISPLAY_NAME="Gemini - A Family of Highly Capable Multimodal Model (PDF)"
TTL="7200s"

curl \
-X POST \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
https://${LOCATION}-aiplatform.googleapis.com/v1beta1/projects/${PROJECT_ID}/locations/${LOCATION}/cachedContents \
-d @- <<EOF
{
  "model":"projects/${PROJECT_ID}/locations/${LOCATION}/publishers/google/models/${MODEL_ID}",
  "contents": [
    {
      "role": "user",
      "parts": [
        {
          "fileData": {
            "mimeType": "${MIME_TYPE}",
            "fileUri": "${CACHED_CONTENT_URI}"
          }
        }
      ]
    }
  ],
  "displayName": "${CACHE_DISPLAY_NAME}",
  "ttl": "${TTL}"
}
EOF

返信の例:

レスポンスには、キャッシュに対してグローバルに一意の完全修飾リソース name が含まれます(最後のセグメントはキャッシュ ID です)。この name 値全体をワークフローの次のステップで使用します。

{
  "name": "projects/861083271981/locations/global/cachedContents/4545031458888089601",
  "model": "projects/my-amazing-app/locations/global/publishers/google/models/gemini-3.8-flash",
  "createTime": "2024-06-04T01:11:50.808236Z",
  "updateTime": "2024-06-04T01:11:50.808236Z",
  "expireTime": "2024-06-04T02:11:50.794542Z"
}

ステップ 2: サーバー プロンプト テンプレートでキャッシュを参照する

キャッシュを作成したら、サーバー プロンプト テンプレートの cachedContent プロパティ内で name を使用してキャッシュを参照します。

サーバー プロンプト テンプレートを作成する際は、次の要件を満たしていることを確認してください。

  • キャッシュの作成時にレスポンスから取得した完全修飾リソース name を使用します。これは、リクエストで指定したオプションの表示名ではありません。

  • サーバー プロンプト テンプレートのロケーションは、キャッシュのロケーションと一致している必要があります。

  • システム指示やツールを使用するには、サーバー プロンプト テンプレートの一部としてではなく、キャッシュの一部として構成する必要があります。

構文:

{{cachedContent name="YOUR_CACHE_RESOURCE_NAME"}}

{{role "user"}}
{{userPrompt}}

例:

{{cachedContent name="projects/861083271981/locations/global/cachedContents/4545031458888089601"}}

{{role "user"}}
{{userPrompt}}

または、サーバー プロンプト テンプレートの name パラメータの値を動的入力変数にすることもできます。たとえば、{{cachedContent name=someVariable}} を使用すると、キャッシュの name をアプリからのリクエストの入力として含めることができます。

ステップ 3: アプリからのリクエストでサーバー プロンプト テンプレートを参照する

リクエストを作成する際は、次の点に十分注意してください。

  • キャッシュがその Gemini API プロバイダで作成されたため、Agent Platform Gemini API (formerly Vertex AI) を使用します。

  • アプリのプロンプト リクエストでモデルにアクセスするロケーションは、サーバー プロンプト テンプレートとキャッシュのロケーションと一致している必要があります。

Swift

// ...

// Initialize the Agent Platform Gemini API backend service (formerly Vertex AI).
// Create a `TemplateGenerativeModel` instance.
// Make sure to specify the same location as the server prompt template and the cache.
let model = FirebaseAI.firebaseAI(backend: .agentPlatform(location: "LOCATION"))
                                  .templateGenerativeModel()

do {
    let response = try await model.generateContent(
        // Specify your template ID.
        templateID: "TEMPLATE_ID"
    )
    if let text = response.text {
        print("Response Text: \(text)")
    }
} catch {
    print("An error occurred: \(error)")
}
print("\n")

Kotlin

// ...

// Initialize the Agent Platform Gemini API backend service (formerly Vertex AI).
// Create a `TemplateGenerativeModel` instance.
// Make sure to specify the same location as the server prompt template and the cache.
val model = Firebase.ai(backend = GenerativeBackend.agentPlatform(location = "LOCATION"))
                        .templateGenerativeModel()

val response = model.generateContent(
    // Specify your template ID.
    "TEMPLATE_ID",
)

val text = response.text
println(text)

Java

// ...

// Initialize the Agent Platform Gemini API backend service (formerly Vertex AI).
// Create a `TemplateGenerativeModel` instance.
// Make sure to specify the same location as the server prompt template and the cache.
TemplateGenerativeModel generativeModel = FirebaseAI.getInstance(GenerativeBackend.agentPlatform("LOCATION"))
      .templateGenerativeModel();

TemplateGenerativeModelFutures model = TemplateGenerativeModelFutures.from(generativeModel);

Future<GenerateContentResponse> response = model.generateContent(
    // Specify your template ID.
    "TEMPLATE_ID"
);
addCallback(response,
      new FutureCallback<GenerateContentResponse>() {
          public void onSuccess(GenerateContentResponse result) {
            System.out.println(result.getText());
          }
          public void onFailure(Throwable t) {
            reportError(t);
          }
    }
executor);

Web

// ...

// Initialize the Agent Platform Gemini API backend service (formerly Vertex AI).
// Make sure to specify the same location as the server prompt template and the cache.
const ai = getAI(app, { backend: new AgentPlatformBackend('LOCATION') });

// Create a `TemplateGenerativeModel` instance
const model = getTemplateGenerativeModel(ai);

const result = await model.generateContent({
  // Specify your template ID.
  templateId: 'TEMPLATE_ID',
  templateVariables: {},
});

const response = result.response;
const text = response.text();

Dart

// ...

// Initialize the Agent Platform Gemini API backend service (formerly Vertex AI).
// Create a `TemplateGenerativeModel` instance.
// Make sure to specify the same location as the server prompt template and the cache.
var _model = FirebaseAI.agentPlatform(location: 'LOCATION').templateGenerativeModel();

var response = await _model.generateContent(
        // Specify your template ID.
        'TEMPLATE_ID',
        inputs: {},
      );

var text = response?.text;
print(text);

Unity

// ...

// Initialize the Agent Platform Gemini API backend service (formerly Vertex AI).
// Make sure to specify the same location as the server prompt template and the cache.
var firebaseAI = FirebaseAI.GetInstance(FirebaseAI.Backend.AgentPlatform(location: "LOCATION"));

// Create a `TemplateGenerativeModel` instance.
var model = firebaseAI.GetTemplateGenerativeModel();

try
{
  var response = await model.GenerateContentAsync(
      // Specify your template ID.
      "TEMPLATE_ID",
      new Dictionary<string, object>()
  );
  Debug.Log($"Response Text: {response.Text}");
}
catch (Exception e) {
  Debug.LogError($"An error occurred: {e.Message}");
}



明示的なキャッシュを管理する

このセクションでは、すべてのキャッシュを一覧表示する、キャッシュに関するメタデータを取得する、キャッシュの TTL または有効期限を更新する、キャッシュを削除するなど、明示的なコンテンツ キャッシュの管理について説明します。

明示的なキャッシュは、Agent Platform Gemini API (formerly Vertex AI) の REST API を使用して管理します。

明示的なコンテンツ キャッシュを作成すると、TTL または有効期限以外のキャッシュに関する変更はできません。

すべてのキャッシュを一覧表示する

プロジェクトで使用可能なすべての明示的なキャッシュを一覧表示できます。このコマンドは、指定されたロケーションのキャッシュのみを返します。

PROJECT_ID="PROJECT_ID"
LOCATION="LOCATION"

curl \
-X GET \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
https://${LOCATION}-aiplatform.googleapis.com/v1beta1/projects/${PROJECT_ID}/locations/${LOCATION}/cachedContents

キャッシュに関するメタデータを取得する

キャッシュに保存された実際のコンテンツを取得または表示することはできません。ただし、明示的なキャッシュに関するメタデータ(name、model、display_name、usage_metadata、create_time、update_time、expire_time など)は取得できます。

CACHE_ID を指定する必要があります。これは、キャッシュの完全修飾リソース name の最後のセグメントです。

PROJECT_ID="PROJECT_ID"
LOCATION="LOCATION"
CACHE_ID="CACHE_ID"  # the final segment in the `name` of the cache

curl \
-X GET \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
https://${LOCATION}-aiplatform.googleapis.com/v1beta1/projects/${PROJECT_ID}/locations/${LOCATION}/cachedContents/${CACHE_ID}

キャッシュの TTL または有効期限を更新する

明示的なキャッシュを作成するときに、必要に応じて ttl または expire_time を設定できます。

  • ttl: キャッシュの TTL(有効期間)。具体的には、キャッシュの作成、または ttl の更新からキャッシュが期限切れになるまでの時間を秒単位およびナノ秒単位で指定します。ttl を設定すると、キャッシュの expireTime が自動的に更新されます。

  • expire_time: キャッシュが期限切れになる絶対日時を指定する Timestamp(2024-06-30T09:00:00.000000Z など)。

これらの値のいずれも設定しない場合、デフォルトの TTL は 1 時間です。TTL には最小値または最大値の制限はありません。

既存の明示的なキャッシュの場合は、ttl または expire_time を追加または更新できます。CACHE_ID を指定する必要があります。これは、キャッシュの完全修飾リソース name の最後のセグメントです。

ttl を更新

PROJECT_ID="PROJECT_ID"
LOCATION="LOCATION"
CACHE_ID="CACHE_ID"  # the final segment in the `name` of the cache
TTL="CACHE_TIME_TO_LIVE"

curl \
-X PATCH \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json; charset=utf-8" \
https://${LOCATION}-aiplatform.googleapis.com/v1beta1/projects/${PROJECT_ID}/locations/${LOCATION}/cachedContents/${CACHE_ID} -d \
'{
  "ttl": "'$TTL'"
}'

expire_time を更新

PROJECT_ID="PROJECT_ID"
LOCATION="LOCATION"
CACHE_ID="CACHE_ID"  # the final segment in the `name` of the cache
EXPIRE_TIME="ABSOLUTE_TIME_CACHE_EXPIRES"

curl \
-X PATCH \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json; charset=utf-8" \
https://${LOCATION}-aiplatform.googleapis.com/v1beta1/projects/${PROJECT_ID}/locations/${LOCATION}/cachedContents/${CACHE_ID} -d \
'{
  "expire_time": "'$EXPIRE_TIME'"
}'

キャッシュを削除する

明示的なキャッシュが不要になった場合は、削除できます。

CACHE_ID を指定する必要があります。これは、キャッシュの完全修飾リソース name の最後のセグメントです。

PROJECT_ID="PROJECT_ID"
LOCATION="LOCATION"
CACHE_ID="CACHE_ID"  # the final segment in the `name` of the cache

curl \
-X DELETE \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
https://${LOCATION}-aiplatform.googleapis.com/v1beta1/projects/${PROJECT_ID}/locations/${LOCATION}/cachedContents/${CACHE_ID}



明示的なキャッシュ保存の料金

明示的なキャッシュ保存は、費用を削減するために設計された有料の機能です。料金は次の要素に基づきます。

  • キャッシュ作成用の入力トークン: 暗黙的なキャッシュ保存と明示的なキャッシュ保存の両方で、キャッシュの作成に使用された入力トークンに対して、標準の入力トークン料金で請求されます。

  • キャッシュの保存: 明示的なキャッシュ保存の場合も、キャッシュの保存期間に基づいてストレージ費用が発生します。暗黙的なキャッシュ保存にはストレージ費用がかかりません。詳細については、Agent Platform Gemini API (formerly Vertex AI) の料金をご覧ください。

  • キャッシュに保存されたコンテンツの使用: 明示的なキャッシュ保存では、明示的なキャッシュが参照された場合に割引が適用されます。つまり、入力トークンが既存のキャッシュを参照すると、割引が適用されます。Gemini 2.5 以降のモデルの場合、この割引は 90% です。

入力のキャッシュに保存された部分のトークン数は、レスポンスのメタデータの cachedContentTokenCount フィールドに表示されます。