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

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

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

コンテキスト キャッシュは、Gemini 1.5 Pro と Gemini 1.5 Flash の両方をサポートしています。

コンテキスト キャッシュ保存を使用する状況

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

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

キャッシュ保存によって費用が削減される仕組み

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

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

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

コンテキスト キャッシュ保存を使用する方法

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

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

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

import { GoogleGenerativeAI } from '@google/generative-ai';
import {
  FileState,
  GoogleAICacheManager,
  GoogleAIFileManager,
} from '@google/generative-ai/server';

// A helper function that uploads the video to be cached.
async function uploadMp4Video(filePath, displayName) {
  const fileManager = new GoogleAIFileManager(process.env.API_KEY);
  const fileResult = await fileManager.uploadFile(filePath, {
    displayName,
    mimeType: 'video/mp4',
  });

  const { name, uri } = fileResult.file;

  // Poll getFile() on a set interval (2 seconds here) to check file state.
  let file = await fileManager.getFile(name);
  while (file.state === FileState.PROCESSING) {
    console.log('Waiting for video to be processed.');
    // Sleep for 2 seconds
    await new Promise((resolve) => setTimeout(resolve, 2_000));
    file = await fileManager.getFile(name);
  }

  console.log(`Video processing complete: ${uri}`);

  return fileResult;
}

// Download video file
// curl -O https://storage.googleapis.com/generativeai-downloads/data/Sherlock_Jr_FullMovie.mp4
const pathToVideoFile = 'Sherlock_Jr_FullMovie.mp4';

// Upload the video.
const fileResult = await uploadMp4Video(pathToVideoFile, 'Sherlock Jr. video');

// Construct a GoogleAICacheManager using your API key.
const cacheManager = new GoogleAICacheManager(process.env.API_KEY);

// Create a cache with a 5 minute TTL.
const displayName = 'sherlock jr movie';
const model = 'models/gemini-1.5-flash-001';
const systemInstruction =
  '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.";
let ttlSeconds = 300;
const cache = await cacheManager.create({
  model,
  displayName,
  systemInstruction,
  contents: [
    {
      role: 'user',
      parts: [
        {
          fileData: {
            mimeType: fileResult.file.mimeType,
            fileUri: fileResult.file.uri,
          },
        },
      ],
    },
  ],
  ttlSeconds,
});

// Get your API key from https://aistudio.google.com/app/apikey
// Access your API key as an environment variable.
const genAI = new GoogleGenerativeAI(process.env.API_KEY);

// Construct a `GenerativeModel` which uses the cache object.
const genModel = genAI.getGenerativeModelFromCachedContent(cache);

// Query the model.
const result = await genModel.generateContent({
  contents: [
    {
      role: 'user',
      parts: [
        {
          text:
            'Introduce different characters in the movie by describing ' +
            'their personality, looks, and names. Also list the ' +
            'timestamps they were introduced for the first time.',
        },
      ],
    },
  ],
});

console.log(result.response.usageMetadata);

// The output should look something like this:
//
// {
//   promptTokenCount: 696220,
//   candidatesTokenCount: 270,
//   totalTokenCount: 696490,
//   cachedContentTokenCount: 696191
// }

console.log(result.response.text());

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

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

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

const listResult = await cacheManager.list();
listResult.cachedContents.forEach((cache) => {
  console.log(cache);
});

キャッシュを更新する

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

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

const ttlSeconds = 2 * 60 * 60;
const updateParams = { cachedContent: { ttlSeconds } };
const updatedCache = await cacheManager.update(cacheName, updateParams);

キャッシュを削除する

キャッシュ サービスは、キャッシュからコンテンツを手動で削除する削除オペレーションを提供します。次の例は、GoogleAICacheManager.delete() を使用してキャッシュを削除する方法を示しています。

await cacheManager.delete(cacheName);

その他の考慮事項

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

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