Geminiのツール呼び出し後に「missing thought_signature」が出る場合の対処

Geminiのthought signatureを関数呼び出しや並列処理、SDK変換で保持する方法を解説します。ネイティブREST、Python、互換APIの違いも確認します。

オリーブグレーの背景に明るい紙を配置し、天秤の線画、幾何学模様、英語タイトル「Gemini Thought Signatures」を添えた表紙。

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 generateContentthoughtSignatureを含む、model contentとparts全体
Google Python SDKthought_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の文書に従ってください。