Geminiのツール呼び出し後に「missing thought_signature」が出る場合の対処
Geminiのthought signatureを関数呼び出しや並列処理、SDK変換で保持する方法を解説します。ネイティブREST、Python、互換APIの違いも確認します。
Geminiの最初のリクエストは成功するのに、関数呼び出し後にthought_signatureがないというエラーが出る場合は、リクエスト間に保存したmodel contentを確認します。関数の結果を追加する前に、元の関数呼び出しpartを署名ごと履歴に戻してください。関数名と引数だけを保存すると、次のターンに必要な状態が失われることがあります。
本記事はツール呼び出し後の継続処理を対象とし、2026年9月14日に確認したGoogleのthought signature文書に基づきます。要件はモデルの世代とAPIによって異なります。署名がなければ、どのGeminiモデルも同じHTTP 400を返すと考えないでください。
利用中のインターフェースでフィールドの位置を確認する
エラーではsnake_case、ネイティブRESTのペイロードではcamelCaseが使われることがあります。ネイティブgenerateContentのJSONでは、thoughtSignatureはpart内でfunctionCallと同じ階層に置かれます。Python SDKのオブジェクトでは通常thought_signatureです。互換エンドポイントでは、プロバイダー固有の拡張フィールドにメタデータを格納する場合があります。
| インターフェース | 保持するもの |
|---|---|
| ネイティブREST generateContent | thoughtSignatureを含む、model contentとparts全体 |
| Google Python SDK | thought_signatureを含む、返されたcontentオブジェクト全体 |
| OpenAI互換エンドポイント | 返されたメッセージやツール呼び出しにある、文書で定められたプロバイダーメタデータ |
| Interactionsなどの別API | そのAPI独自の継続処理と状態管理のルール |
エラー中の表記が違うという理由だけで、推測した位置へフィールドを移動してはいけません。初回の成功が示すのは、初回リクエストが受理されたことだけです。テキストのみを保存する履歴ストアやアダプターの問題は、継続時に表面化することがあります。
ツール結果の前に、元のmodelターンを保持する
実際の関数結果を含むuser contentより前に、モデルが返したcontent全体を履歴に入れます。ターンの構成はGoogleの関数呼び出しガイドを参照してください。チャット画面から再構成せず、partsを元の順序で保持します。
継続処理の概念的な順序は次のとおりです。
user: original task
model: original returned content, including functionCall and signature-bearing part
user: functionResponse containing the real result
model: next response
これは説明用のメッセージ列であり、実行できるリクエストや実APIテストのログではありません。実際の呼び出しには、そのタスクで受け取った応答を使います。署名をランダムな文字列や、他人の会話からコピーした例に置き換えてはいけません。
並列呼び出しの各partに署名が必要とは限らない
現在の文書にあるGemini 3のツール処理では、各ステップの最初のfunction-call partに必要な署名が付きます。並列呼び出しの応答でも、その最初のpartが署名を持ち、後続のpartすべてに個別の署名が必要なわけではありません。並列の各partに署名を要求するバリデーターは、正しい応答を拒否する可能性があります。
たとえば署名付きの呼び出し1、その後の呼び出し2という元のまとまりを保持し、対応する関数結果を返します。二つの呼び出しが同じ並列modelターンから来た場合、履歴を「呼び出し1、結果1、呼び出し2、結果2」に並べ替えないでください。逐次ステップは別であり、新しいmodelステップごとに、そのステップで返された状態を保持します。
この区別は、すべてのツールを個別メッセージへ正規化するミドルウェアで重要です。扱いやすい共通形式に変換すると、元のまとまりが失われることがあります。呼び出すエンドポイントのネイティブなメッセージ列を再現できる情報を残してください。
SDKが保持できるのは、アプリ側で残した情報まで
公式SDKのチャット処理は、完全な応答と履歴を保持している場合に署名を管理できます。アプリケーションが応答をテキストへ変換したり、関数の引数だけを抽出したり、省略したJSONスキーマで保存したりする場合、その動作はアプリ全体を保証するものではありません。
プロバイダーから受け取った応答、アプリが保存した履歴、次に実際にシリアライズされたリクエストの三つを比較します。署名付きpartが最初に消える、または変わる境界を探してください。データベースのスキーマ、メッセージフィルター、コールバック、API形式を変換するアダプターなどが確認箇所です。
最小再現には、固定のローカル値を返す無害な関数を使います。外部への副作用を持たせないでください。目的は関数呼び出しの1ラウンドを通すことであり、シリアライザーの調査中に決済やデプロイを再実行することではありません。本記事は特定のサードパーティークライアントのバージョンが修正済みだと主張するものではありません。
thinkingを下げるだけで回避できるとは限らない
thinkingを最小にすれば、ツール処理の署名要件もなくなるとは考えないでください。使用するモデルとインターフェースに対応したthinkingの文書に従います。生成設定を変えることと、すでに破棄した状態を復元することは別です。
Googleは、インポートした一部の会話履歴に対する特別な扱いを文書化しています。ただし、特別な検証回避用マーカーは、自分のモデル応答を失うアプリの通常の修正方法ではありません。まず履歴の保存処理を直します。そうしないと、検証エラーの一つを隠しながら、有用なメタデータを落とし続ける可能性があります。
署名不足と、不正な関数結果も区別してください。結果の名前の誤り、呼び出しとの対応漏れ、無効なツールスキーマは別のエラーを起こす場合があります。単にHTTP 400というだけで誤った原因を調べないよう、ステータスとエラー本文をすべて記録します。
検証した範囲に合わせて、修正を確認する
シリアライズを直したら、失敗したものと同じ経路、同じSDKバージョンで、小さな関数処理を再実行します。継続リクエストが受理され、関数結果が回答に反映されることを確認してください。並列関数を使うなら、並列用の別ケースも追加します。単一呼び出しの成功では、その処理経路まで検証したことにはなりません。
ローカルのスキーマ検証か、実際のAPI呼び出しかを記録します。構文チェックだけでは、プロバイダーが受理することは証明できません。ゲートウェイを使う場合も、動作をテストし仕組みを説明できない限り、失われたクライアント状態を修復すると主張しないでください。
モデルの料金や接続についてはGemini 3.8 APIガイドを参照できます。別プロバイダーの似た名称のエラーはClaude署名ガイドで扱います。Claudeのネイティブフィールドを、そのままGeminiメッセージへコピーすることはできません。
よくある質問
並列の関数呼び出しは、すべて署名が必要ですか?
いいえ。文書にあるGemini 3の並列処理では、そのステップの最初のfunction-call partに必要な署名が付きます。返されたまとまりを変更せずに保持してください。
エラーはsnake_caseなのに、RESTではcamelCaseなのはなぜですか?
エラー内の用語やSDKプロパティ名は、ネイティブRESTのフィールド名と異なる場合があります。実際にリクエストを受けるインターフェースのスキーマを使ってください。
プロバイダーを変えれば直りますか?
必ずしも直りません。送信前にクライアントが必要な状態を落としているなら、送信先を変えても復元されません。先にリクエストの処理経路を調べてください。
よくある質問
- ネイティブRESTではthoughtSignatureはどこにありますか?
- functionCallと同じpartにあります。返されたmodel content全体を保持してください。
- 並列呼び出しのすべてに署名が必要ですか?
- いいえ。モデル固有のルールに従います。文書にあるGemini 3の処理では、そのステップの最初のfunction-call partに署名が付きます。
- thinkingを下げれば署名は不要になりますか?
- そうとは限りません。必要な状態を保持し、選択したモデルとAPIの文書に従ってください。


