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

一般的な AI ワークフローでは、同じ入力トークンをモデルに何度も渡すことがあります。Gemini API には、次の 2 種類のキャッシュ メカニズムがあります。

  • 暗黙的なキャッシュ保存(Gemini 2.5 モデルで自動的に有効になります。費用削減は保証されません)
  • 明示的なキャッシュ保存(ほとんどのモデルで手動で有効にでき、コスト削減が保証される)

明示的なキャッシュは、コスト削減を保証しつつ、デベロッパーの作業を追加する場合に便利です。

暗黙的キャッシュ

暗黙的キャッシングは、すべての Gemini 2.5 モデルでデフォルトで有効になっています。リクエストがキャッシュにヒットすると、費用の削減が自動的に反映されます。これを有効にするために必要な操作はありません。2025 年 5 月 8 日より有効です。コンテキスト キャッシュ保存の最小入力トークン数は、2.5 Flash では 1,024、2.5 Pro では 2,048 です。

暗黙的なキャッシュ ヒットの確率を高めるには:

  • サイズが大きく、一般的なコンテンツをプロンプトの先頭に配置してみてください
  • 短時間に類似のプレフィックスを含むリクエストを送信しようとする

キャッシュヒットしたトークン数は、レスポンス オブジェクトの usage_metadata フィールドで確認できます。

明示的なキャッシュ保存

Gemini API の明示的なキャッシュ保存機能を使用すると、一部のコンテンツをモデルに 1 回渡し、入力トークンをキャッシュに保存してから、後続のリクエストでキャッシュに保存されたトークンを参照できます。一定のボリュームでは、キャッシュに保存されたトークンを使用する方が、同じトークン コーパスを繰り返し渡すよりも費用が少なくなります。

トークンのセットをキャッシュに保存するときに、トークンが自動的に削除されるまでのキャッシュの存続期間を選択できます。このキャッシュ保存期間は有効期間(TTL)と呼ばれます。設定しない場合、TTL はデフォルトで 1 時間になります。キャッシュに保存する費用は、入力トークンのサイズとトークンを保持する時間によって異なります。

このセクションでは、クイックスタートに記載されているように、Gemini SDK がインストールされていること(または curl がインストールされていること)と、API キーが構成されていることを前提としています。

キャッシュを使用してコンテンツを生成する

次の例は、キャッシュに保存されたシステム インストラクションと動画ファイルを使用してコンテンツを生成する方法を示しています。

動画

import os
import pathlib
import requests
import time

from google import genai
from google.genai import types

client = genai.Client()

# Download video file
url = 'https://storage.googleapis.com/generativeai-downloads/data/SherlockJr._10min.mp4'
path_to_video_file = pathlib.Path('SherlockJr._10min.mp4')
if not path_to_video_file.exists():
  with path_to_video_file.open('wb') as wf:
    response = requests.get(url, stream=True)
    for chunk in response.iter_content(chunk_size=32768):
      wf.write(chunk)

# Upload the video using the Files API
video_file = client.files.upload(file=path_to_video_file)

# Wait for the file to finish processing
while video_file.state.name == 'PROCESSING':
  print('Waiting for video to be processed.')
  time.sleep(2)
  video_file = client.files.get(name=video_file.name)

print(f'Video processing complete: {video_file.uri}')

# You must use an explicit version suffix: "-flash-001", not just "-flash".
model='models/gemini-2.0-flash-001'

# Create a cache with a 5 minute TTL
cache = client.caches.create(
    model=model,
    config=types.CreateCachedContentConfig(
      display_name='sherlock jr movie', # used to identify the cache
      system_instruction=(
          'You are an expert video analyzer, and your job is to answer '
          'the user\'s query based on the video file you have access to.'
      ),
      contents=[video_file],
      ttl="300s",
  )
)

# Construct a GenerativeModel which uses the created cache.
response = client.models.generate_content(
  model = model,
  contents= (
    'Introduce different characters in the movie by describing '
    'their personality, looks, and names. Also list the timestamps '
    'they were introduced for the first time.'),
  config=types.GenerateContentConfig(cached_content=cache.name)
)

print(response.usage_metadata)

# The output should look something like this:
#
# prompt_token_count: 696219
# cached_content_token_count: 696190
# candidates_token_count: 214
# total_token_count: 696433

print(response.text)

PDF

from google import genai
from google.genai import types
import io
import httpx

client = genai.Client()

long_context_pdf_path = "https://www.nasa.gov/wp-content/uploads/static/history/alsj/a17/A17_FlightPlan.pdf"

# Retrieve and upload the PDF using the File API
doc_io = io.BytesIO(httpx.get(long_context_pdf_path).content)

document = client.files.upload(
  file=doc_io,
  config=dict(mime_type='application/pdf')
)

model_name = "gemini-2.0-flash-001"
system_instruction = "You are an expert analyzing transcripts."

# Create a cached content object
cache = client.caches.create(
    model=model_name,
    config=types.CreateCachedContentConfig(
      system_instruction=system_instruction,
      contents=[document],
    )
)

# Display the cache details
print(f'{cache=}')

# Generate content using the cached prompt and document
response = client.models.generate_content(
  model=model_name,
  contents="Please summarize this transcript",
  config=types.GenerateContentConfig(
    cached_content=cache.name
  ))

# (Optional) Print usage metadata for insights into the API call
print(f'{response.usage_metadata=}')

# Print the generated text
print('\n\n', response.text)

キャッシュのリストを表示する

キャッシュに保存されたコンテンツを取得または表示することはできませんが、キャッシュ メタデータ(namemodeldisplay_nameusage_metadatacreate_timeupdate_timeexpire_time)を取得できます。

アップロードされたすべてのキャッシュのメタデータを一覧表示するには、CachedContent.list() を使用します。

for cache in client.caches.list():
  print(cache)

1 つのキャッシュ オブジェクトのメタデータを取得するには、その名前がわかっている場合は get を使用します。

client.caches.get(name=name)

キャッシュを更新する

キャッシュに新しい ttl または expire_time を設定できます。キャッシュのその他の変更はサポートされていません。

次の例は、client.caches.update() を使用してキャッシュの ttl を更新する方法を示しています。

from google import genai
from google.genai import types

client.caches.update(
  name = cache.name,
  config  = types.UpdateCachedContentConfig(
      ttl='300s'
  )
)

有効期限を設定するには、datetime オブジェクトまたは ISO 形式の日時文字列(dt.isoformat()2025-01-27T16:02:36.473528+00:00 など)を指定します。時刻にはタイムゾーンを含める必要があります(datetime.utcnow() はタイムゾーンを付加しませんが、datetime.now(datetime.timezone.utc) はタイムゾーンを付加します)。

from google import genai
from google.genai import types
import datetime

# You must use a time zone-aware time.
in10min = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(minutes=10)

client.caches.update(
  name = cache.name,
  config  = types.UpdateCachedContentConfig(
      expire_time=in10min
  )
)

キャッシュを削除する

キャッシュ サービスには、キャッシュからコンテンツを手動で削除するための削除オペレーションが用意されています。次の例は、キャッシュを削除する方法を示しています。

client.caches.delete(cache.name)

OpenAI ライブラリを使用した明示的なキャッシュ

OpenAI ライブラリを使用している場合は、extra_bodycached_content プロパティを使用して明示的なキャッシュを有効にできます。

明示的なキャッシュ保存を使用する場合

コンテキスト キャッシュ保存は、初期コンテキストの実体部分が、短いリクエストで繰り返し参照されるシナリオに特に適しています。次のようなユースケースでは、コンテキスト キャッシュ保存の使用を検討してください。

  • 広範なシステム指示を伴う chatbot
  • 長時間の動画ファイルの繰り返し分析
  • 大規模なドキュメント セットに対する繰り返しのクエリ
  • 頻繁なコード リポジトリの分析やバグ修正

明示的なキャッシュ保存による費用削減

コンテキスト キャッシュ保存は、全体的な運用コストを削減するために設計された有料の機能です。ご請求は次の項目に基づいて行われます。

  1. キャッシュ トークン数: キャッシュに保存された入力トークンの数。後続のプロンプトに含まれる場合は、割引料金で請求されます。
  2. 保存期間: キャッシュに保存されたトークンの保存時間(TTL)。キャッシュに保存されたトークン数の TTL 時間に基づいて課金されます。TTL の最小値や最大値はありません。
  3. その他の項目: 入力トークンや出力トークンがキャッシュされていない場合などは、別の料金が適用されます。

最新の料金の詳細については、Gemini API の料金ページをご覧ください。トークンをカウントする方法については、トークン ガイドをご覧ください。

その他の考慮事項

コンテキスト キャッシュを使用する場合は、次の点に注意してください。

  • コンテキスト キャッシュ保存の入力トークンの最小数は、2.5 Flash では 1,024、2.5 Pro では 2,048 です。最大値は、指定されたモデルの最大値と同じです。(トークンのカウントについて詳しくは、トークンのガイドをご覧ください)。
  • モデルは、キャッシュに保存されたトークンと通常の入力トークンを区別しません。キャッシュに保存されたコンテンツは、プロンプトの接頭辞です。
  • コンテキスト キャッシュには特別なレートや使用量の上限はありません。GenerateContent の標準レートの上限が適用され、トークンの上限にはキャッシュに保存されたトークンが含まれます。
  • キャッシュに保存されているトークン数は、キャッシュ サービスの create、get、list オペレーションから usage_metadata で返されます。また、キャッシュを使用している場合は GenerateContent でも返されます。