8月16日、Google Cloud on MediumのTheGenAIGirl氏が「Migrating to Gemini 3.7 Flash: What Breaks, What Changed, and How to Fix Your Code」と題した記事を公開した。Gemini 3.7 Flashへの移行はモデルIDを書き換えるだけでは済まない——この記事はその思い込みを明確に否定し、既存アプリケーションが静かに壊れる3つの層と、その具体的な修正方法を示している。
Gemini 3.7 Flash(gemini-3.7-flash)は2026年8月13日にGA(General Availability=一般提供開始)となった。記事では移行時に確認すべき変更を「生成設定」「会話状態」「エージェント/ツールのプロトコル状態」の3層に整理し、それぞれの修正コードとともに解説している。
移行の心構え: Gemini 3.7 Flashをモデル差し替えとして扱わないこと。「生成設定」「会話状態」「エージェント/ツールのプロトコル状態」の3層を監査せよ。
最初に確認すべき30秒チェックリスト
記事冒頭で示される変更の全体像は以下の通りだ。
- model="gemini-3.6-flash"
+ model="gemini-3.7-flash"
- temperature=0.2
- top_p=0.95
- top_k=40
- candidate_count=1
- thinking_budget=4096
+ thinking_level="medium"
さらに会話・ツールループで確認すべき事項:
- プリフィルドモデルターン(部分的なモデル応答の先入れ)を削除する
- ステートフルなマルチターンには
previous_interaction_idを使う - 手動で会話履歴を管理している場合、thought signatures(思考署名)を必ず保持する
generateContentを使っている場合、FunctionResponseにcall_idとnameが含まれているか確認するMalformed_Function_Callが出たら、ツール呼び出し前の構造化テキストを疑う- 移行前に
google-genaiSDKをアップグレードする
最も壊れやすい変更①:thinking_budget → thinking_level
既存コードで数値の thinking_budget を使っていた場合、これが最初の地雷になる。
変更前:
config={
"thinking_budget": 4096
}
変更後:
config={
"thinking_level": "medium"
}
Gemini 3.7 Flashがサポートするthinking levelは low / medium / high の3段階で、**デフォルトは medium**だ。
ここで見落としやすい落とし穴がある。**minimal はサポートされていない。** 他のGeminiモデルで minimal を使っていたコードをそのまま持ち込むと、エラーになる。レイテンシ重視のワークロードでは minimal の代わりに low を評価すること。
また、thinking_level はサンプリング温度の言い換えではない点にも注意が必要だ。これはモデル内部の推論ステップにかけるコストを制御するパラメータであり、high にすればレイテンシとトークン消費が増える。品質・速度・コストのトレードオフを把握したうえで、ワークロードに合わせてベンチマークすることが推奨されている。
最も壊れやすい変更②:エージェントのThought Signatures
マルチステップの関数呼び出しを実装しているエンジニアには、thought signatures(思考署名)の扱いが最重要の変更点となる。
Geminiは内部の推論状態を暗号化した「thought signature」としてレスポンスに含めることがある。これはモデルが次のリクエストで参照するプロトコルメタデータであり、アプリケーションがチェーン・オブ・ソートを読むためのものではない。言い換えれば、アプリ側は内容を解釈する必要はないが、削除せずそのまま次のリクエストに含めて返す責務がある。
問題が起きるのは、アプリケーションが会話履歴を手動で再構築するときだ。
モデルレスポンス
├── function call ← 取り出す
└── thought signature ← 捨ててしまう ← これが問題
Gemini 3系の新しいモデルでは、必要なthought signatureが欠けていると警告ではなくエラーを返すと、Google Cloudのドキュメントは明記している。
generateContent で手動履歴管理をしている場合は、モデルレスポンスのpartsとthought signaturesをドキュメント通りに完全保持すること。後述するInteractions APIのサーバーサイド状態管理(previous_interaction_id)を使えば、この手動管理のリスクを大幅に減らせる。
generateContent ユーザー:FunctionResponseの紐付けを確認
generateContent APIを使い続けるアプリケーションでは、すべての FunctionResponse オブジェクトに call_id(または id)と name が含まれているかを確認する必要がある。FunctionCall と FunctionResponse を相関IDと関数名で明示的に紐付けることで、モデルはどのツール呼び出しに対する結果なのかを正しく把握できる。
FunctionCall
│
│ correlation ID + function name
▼
ツール実行
│
▼
FunctionResponse
└── 元のcallと紐付いていること
厄介なのは、紐付けが間違っていてもAPIが直接バリデーションエラーを返すとは限らない点だ。代わりにモデルが空のレスポンスを返し、finish_reason: STOP になる。
ツール実行成功
↓
明確なAPIエラーなし
↓
モデルが空の出力を返す
↓
「なぜエージェントが止まった?」
この無言の失敗はデバッグに時間を取られやすい。エージェントがツール実行後に不可解に停止するときは、ツール実装そのものだけでなく、FunctionCall → FunctionResponse のマッピングを優先的に確認することを推奨する。
サンプリングパラメータの扱い
temperature、top_p、top_k については明示的な上書きを削除するのがGoogleの推奨だ。ただし、これらが完全に廃止されたわけではなく「モデルに自動管理させる」方針への変更である。
一方、**candidate_count はGemini 3.x全体で非サポート**と明示されており、こちらは削除必須だ。
| パラメータ | 対応 |
|---|---|
temperature / top_p / top_k |
明示的な上書きを削除 |
candidate_count |
Gemini 3.xで非サポート、削除必須 |
Interactions APIとサーバーサイド状態管理
新規アプリケーションにはGoogleがInteractions APIを推奨している。Interactions APIは従来の generateContent と異なり、会話履歴をクライアント側で保持・再送する必要がなく、サーバーサイドでセッション状態を管理する設計となっている。マルチターン会話で previous_interaction_id を使えば、会話履歴全体の再送が不要になり、前述のthought signaturesの手動管理リスクも大幅に低減できる。
first = client.interactions.create(
model="gemini-3.7-flash",
input="Review this Python function for concurrency issues."
)
second = client.interactions.create(
model="gemini-3.7-flash",
input="Now rewrite it using a safer locking strategy.",
previous_interaction_id=first.id,
)
注意点が2つある。previous_interaction_id が引き継ぐのは会話コンテキストのみで、システム指示・ツール設定・生成設定は引き継がれない。次のリクエストでも必要なら再指定が必要だ。
もう1つは保存期間の問題だ。インタラクションはデフォルトで保存され、有料プランで55日、無料プランで1日の保持期間がある。store=false を指定すると保存されないが、その場合は previous_interaction_id で参照できなくなる。エンタープライズデータを扱うプロダクションエージェントでは、この設計判断を軽視しないこと。
Gemini 3.7 Flashへの移行は「モデルIDの変更」ではなく、生成設定・会話管理・エージェントプロトコルの3層にまたがる設計の見直しだ。特にthought signaturesとFunctionResponseの紐付けは、デバッグが難しい形で静かに失敗するため、移行前に重点的にテストすることを推奨する。
詳細はMigrating to Gemini 3.7 Flash: What Breaks, What Changed, and How to Fix Your Codeを参照していただきたい。