Geminiにおけるコンテキストキャッシュを検討すべきタイミング

# 課題感
生成AIを使用する際に同じ入力トークン（ファイルなど）をモデルに何度も渡すことがあります。この際にインプットのトークン数が多いと、プロンプトを実行するたびに入力のトークン数の処理が必要になり利用料金が増加してしまいます。
ここでコンテキストキャッシュを利用することで入力トークンをキャッシュに保存してから、キャッシュに保存されたトークンを後続のリクエストで参照することができます。
結果的にキャッシュに保存されたトークンを使用する方が、同じトークンを繰り返し渡すよりも費用が少なくなります。

一方で入力トークンの数やプロンプトの実行する回数によって毎回入力トークンを処理すべきか、コンテキストキャッシュを検討すべきかが変わってくるのではないかと考えました。

そこで**どのような場合にコンテキストキャッシュを使用すべきかを検討しまとめたいと思います。**

# コンテキストキャッシュの概要

https://ai.google.dev/gemini-api/docs/caching?hl=ja&lang=python

ドキュメントによるとコンテキストキャッシュを使用する状況は以下とのことです。
ユースケースとしては入力に使用するトークン数が多く、それに対して何度もクエリを行う場合が考えられます。
> * 広範なシステム指示を伴う chatbot
> * 長時間の動画ファイルの繰り返し分析
> * 大規模なドキュメント セットに対する繰り返しのクエリ
> * 頻繁なコード リポジトリの分析やバグ修正

コンテキストキャッシュは無料のサービスではなく運用コストを削減するための**有料のサービス**で以下の特徴があります。
* キャッシュトークン数:通常の入力トークン数と比較して割引料金で請求
* 保存期間:キャッシュに保存されたトークンの保存時間（TTL）。キャッシュに保存されたトークン数のTTL時間に基づいて課金。TTL の最小値や最大値に制限はなし
* その他の項目:入力トークンや出力トークンがキャッシュされていない場合などは別の料金が適用

また注意点としては以下もあります。
> * コンテキスト キャッシュの最小入力トークン数は4,096で、最大数は指定されたモデルの最大数と同じです。
> * モデルは、キャッシュに保存されたトークンと通常の入力トークンを区別しません。キャッシュに保存されたコンテンツは、プロンプトの接頭辞です。
> * コンテキストキャッシュには特別なレートや使用量の上限はありません。GenerateContent の標準レートの上限が適用され、トークンの上限にはキャッシュに保存されたトークンが含まれます。
> * キャッシュに保存されているトークン数は、キャッシュ サービスの create、get、list オペレーションから usage_metadata で返されます。また、キャッシュを使用している場合は GenerateContent でも返されます。

## コンテキストキャッシュの料金体系
https://ai.google.dev/gemini-api/docs/pricing?hl=ja

コンテキストキャッシュの料金はGeminiのモデルによって異なります。
なおGemini 2.5 Flashのモデルではキャッシュの機能は未実装となります。
#### Gemini 2.5 Pro プレビュー
* インプット価格：1.25USD（プロンプトトークン数20万超：2.50USD）
* コンテキスト キャッシュ保存の料金：0.31USD（プロンプトトークン数20万超：0.625USD）
* コンテキスト キャッシュ保存（ストレージ）：4.50USD / 100万トークン / 時間

#### Gemini 2.0 Flash
* インプット価格：0.10USD（音声：0.70USD）
* コンテキスト キャッシュ保存の料金：0.025USD（音声：0.175USD）
* コンテキスト キャッシュ保存（ストレージ）：1.00USD / 100万トークン / 時間

#### Gemini 1.5 Pro
* インプット価格：1.25USD（プロンプトトークン数12.8万超：2.5USD）
* コンテキスト キャッシュ保存の料金：0.3125USD（プロンプトトークン数12.8万超：0.625USD）
* コンテキスト キャッシュ保存（ストレージ）：4.50USD / 100万トークン / 時間

#### Gemini 1.5 Flash
* インプット価格：0.075USD（プロンプトトークン数12.8万超：0.15USD）
* コンテキスト キャッシュ保存の料金：0.01875USD（プロンプトトークン数12.8万超：0.0375USD）
* コンテキスト キャッシュ保存（ストレージ）：1.00USD / 100万トークン / 時間

わかりやすいようにスプレッドシートにもまとめてみました。
![スクリーンショット 2025-05-05 10.32.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2778864/26addd5c-38b6-4376-b5eb-fbe749a81a00.png)


冒頭で記載の通りコンテンツキャッシュを利用するとインプットの料金が安くなるだけではなく、キャッシュのストレージ保存料金もかかるため細かい資産の上での検討が必要になります。

## コンテキストキャッシュの検討

コンテキストキャッシュ（以下、キャッシュ）を検討のための試算を実施するにあたって以下によって料金が変わるための考慮が必要です。
* Geminiのモデル
* 入力トークン数
* リクエスト数
* キャッシュのストレージの保存時間

上記を考慮の上で試算結果をスプレッドシートベースでまとめてみました。

スプレッドシートを参照するにあたって以下が前提条件となります。
* リクエスト数は50回、100回、200回で試算
* ストレージの保存時間は12時間、24時間、48時間で試算
* 上記の合計9パターン（3×3）で試算
* 緑塗りがキャッシュありの方が料金が安く、赤塗りがキャッシュありの方が料金が高い

### リクエスト数：50回、ストレージの保存時間：12時間
![スクリーンショット 2025-05-05 11.04.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2778864/198e1c0e-8df6-4a4c-a85e-5c1a6f3aec9a.png)

![スクリーンショット 2025-05-05 11.04.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2778864/b1e95c79-c024-4f09-86b7-c780695ea358.png)


### リクエスト数：50回、ストレージの保存時間：24時間
![スクリーンショット 2025-05-05 11.05.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2778864/05360896-5e5a-4819-88af-f16f7e1e8a51.png)

![スクリーンショット 2025-05-05 11.05.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2778864/665452f0-92d3-4657-b4e6-bf45ccffa688.png)

### リクエスト数：50回、ストレージの保存時間：36時間
![スクリーンショット 2025-05-05 11.06.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2778864/cdbb3714-70ba-430c-9b8d-b81809d7f354.png)

![スクリーンショット 2025-05-05 11.06.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2778864/d9969161-7179-441b-95a0-e451cc52a35a.png)


### リクエスト数：100回、ストレージの保存時間：12時間
![スクリーンショット 2025-05-05 11.06.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2778864/282bcb17-9abc-48aa-9dc5-68574f7a6391.png)

![スクリーンショット 2025-05-05 11.07.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2778864/b1142b79-bb74-4bf0-805a-dce1b5ec0648.png)


### リクエスト数：100回、ストレージの保存時間：24時間
![スクリーンショット 2025-05-05 11.06.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2778864/126ef31e-9021-49ea-9869-0923dfa3f8d7.png)

![スクリーンショット 2025-05-05 11.07.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2778864/27020da1-06c8-4c0d-860b-76a1514c829b.png)


### リクエスト数：100回、ストレージの保存時間：36時間
![スクリーンショット 2025-05-05 11.06.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2778864/ae221126-e805-40e8-9daa-cf206f626ebb.png)

![スクリーンショット 2025-05-05 11.07.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2778864/298850ff-3c48-42a1-b6b5-8748893bca25.png)


### リクエスト数：200回、ストレージの保存時間：12時間
![スクリーンショット 2025-05-05 11.08.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2778864/68869133-8e60-499a-960a-9f6a4439f835.png)

![スクリーンショット 2025-05-05 11.08.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2778864/818bc35c-1609-47fc-ae65-8ccb95cf3152.png)

### リクエスト数：200回、ストレージの保存時間：24時間
![スクリーンショット 2025-05-05 11.08.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2778864/9e49e868-fa98-471a-81d5-1fbdd604bb2b.png)

![スクリーンショット 2025-05-05 11.09.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2778864/09e410c0-8dc7-47f0-b81a-8e7c27711b2c.png)


### リクエスト数：200回、ストレージの保存時間：36時間
![スクリーンショット 2025-05-05 11.08.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2778864/2606f712-d926-4269-be69-0d6fd0baed3c.png)

![スクリーンショット 2025-05-05 11.09.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2778864/df2e0036-84c9-4610-bfc7-22a7b84da409.png)


## 試算結果の考察
* ストレージの保存時間が同じ場合、リクエスト数が増えれば増えるほどキャッシュ**あり**の方が安くなる傾向
* リクエスト数が同じ場合、キャッシュの保存時間が長くなるほどキャッシュ**なし**の方が安くなる傾向
* 入力トークン数によってキャッシュあり/なしで料金に大きな差はない
* 高性能なGeminiのモデルの場合キャッシュ**あり**の方が安くなる傾向
* キャッシュの保存時間が24時間でリクエスト数が50回では他の条件を考慮してもキャッシュ**なし**の方が安い

よって同じ入力トークンに対して**高性能なモデル（Geminiの場合Pro）で24時間で50回以上のリクエストがある**場合にはキャッシュの検討をし始めても良いのではないでしょうか。