思考シグネチャ

思考シグネチャは、モデルの内部的な思考プロセスを暗号化したものです。思考シグネチャは、マルチターンとマルチステップの会話中に Gemini の推論状態を保持します。これは、関数呼び出しを使用する場合に役立ちます。レスポンスには、thought_signature フィールドを任意のコンテンツ部分(textfunctionCall)に含めることが可能です。

Gemini 3 Pro では、関数呼び出しのモデル パフォーマンスが向上するため、以前の Gemini バージョンよりも思考シグネチャの検証が厳しくなっています。モデルが会話を何度もやり取りしながらコンテキストを維持できるようにするために、その後のリクエストで以前のレスポンスの思考シグネチャを返す必要があります。Gemini 3 Pro の使用時に必要な思考シグネチャが返されない場合、モデルは 400 エラーを返します。

公式の Google Gen AI SDK(Python、Node.js、Go、Java)を使用して、標準のチャット履歴機能を使用している場合、またはモデルの完全なレスポンスを履歴に追加している場合、思考シグネチャは自動的に処理されます。

重要とされる理由

思考モデルが外部ツールを呼び出すと、内部の推論プロセスが一時停止します。思考シグネチャは「保存状態」として機能し、関数結果を提供すると、モデルは思考の連鎖をシームレスに再開できます。思考シグネチャがないと、モデルはツール実行フェーズで特定の推論ステップを「忘れて」しまいます。署名を渡すことで、次のことが保証されます。

  • コンテキストの継続性: モデルは、ツール呼び出しを正当化した推論ステップを保持し、確認できます。
  • 複雑な推論: 1 つのツールの出力が次の推論の根拠となるマルチステップ タスクを有効にします。

ターンとステップ

関数呼び出し(FC)と関数レスポンス(FR)を使用して最終レスポンスを生成する大規模言語モデル(LLM)によるマルチターンの会話フロー。このプロセスは 2 つのターンに分かれています。ターン 1 は 3 つのステップで構成されています。ステップ 1: ユーザーのプロンプトがモデル FC1 につながります。ステップ 2: モデルが FR1 を受け取り、モデル FC2 につながります。ステップ 3: モデルは FR2 を受け取り、ターン 1 の最終的なモデルテキスト出力につながります。ターン 2 は新しいユーザー プロンプトで始まり、ターン 1 のコンテキスト全体を使用して、ターン 2 の最終的なモデルテキスト出力を生成します。
関数呼び出しとレスポンスを含むマルチターン会話フロー。

関数呼び出しのコンテキストでは、ターンステップの違いを理解することが重要です。

  • ターンは、ユーザーのプロンプトで始まり、モデルがそのプロンプトに対する関数呼び出し以外の最終的なレスポンスを提供したときに終了する、完全な会話のやり取りを表します。
  • ステップは、モデルが関数を呼び出し、推論プロセスを続行するために関数レスポンスを必要とする場合に、単一のターン内で発生します。図に示すように、モデルがユーザーのリクエストを満たすために複数の関数を順番に呼び出す必要がある場合、1 つのターンに複数のステップが含まれることがあります。

思考シグネチャの使用方法

思考シグネチャを処理する最も簡単な方法は、新しいリクエストを送信するときに、会話履歴内の以前のすべてのメッセージのすべての Part を、モデルから返されたとおりに含めることです。

Google Gen AI SDK のいずれかを使用していない場合、または会話履歴の変更やトリミングが必要な場合は、思考署名が保持され、モデルに送り返されるようにする必要があります。

Google Gen AI SDK を使用する場合(推奨)

SDK のチャット履歴機能を使用する場合や、前のレスポンスのモデルの content オブジェクトを次のリクエストの contents に追加する場合は、署名が自動的に処理されます。

次の Python の例は、自動処理を示しています。

from google import genai
from google.genai.types import Content, FunctionDeclaration, GenerateContentConfig, Part, ThinkingConfig, Tool

client = genai.Client()

# 1. Define your tool
get_weather_declaration = FunctionDeclaration(
   name="get_weather",
   description="Gets the current weather temperature for a given location.",
   parameters={
       "type": "object",
       "properties": {"location": {"type": "string"}},
       "required": ["location"],
   },
)
get_weather_tool = Tool(function_declarations=[get_weather_declaration])

# 2. Send a message that triggers the tool
prompt = "What's the weather like in London?"
response = client.models.generate_content(
   model="gemini-2.5-flash",
   contents=prompt,
   config=GenerateContentConfig(
       tools=[get_weather_tool],
       thinking_config=ThinkingConfig(include_thoughts=True)
   ),
)

# 3. Handle the function call
function_call = response.function_calls[0]
location = function_call.args["location"]
print(f"Model wants to call: {function_call.name}")

# Execute your tool (for example, call an API)
# (This is a mock response for the example)
print(f"Calling external tool for: {location}")
function_response_data = {
   "location": location,
   "temperature": "30C",
}

# 4. Send the tool's result back
# Append this turn's messages to history for a final response.
# The `content` object automatically attaches the required thought_signature behind the scenes.
history = [
   Content(role="user", parts=[Part(text=prompt)]),
   response.candidates[0].content, # Signature preserved here
   Content(
     role="tool",
     parts=[
         Part.from_function_response(
             name=function_call.name,
             response=function_response_data,
         )
     ],
   )
]

response_2 = client.models.generate_content(
   model="gemini-2.5-flash",
   contents=history,
   config=GenerateContentConfig(
       tools=[get_weather_tool],
       thinking_config=ThinkingConfig(include_thoughts=True)
   ),
)

# 5. Get the final, natural-language answer
print(f"\nFinal model response: {response_2.text}")

REST または手動処理を使用する場合

API を直接操作する場合は、Gemini 3 Pro の次のルールに基づいてシグネチャ処理を実装する必要があります。

  • 関数呼び出し
    • モデルのレスポンスに 1 つ以上の functionCall 部分が含まれている場合は、正しい処理を行うために thought_signature が必要です。
    • 1 つのレスポンスで関数呼び出しが並列に行われる場合、thought_signature を含むのは最初の functionCall 部分のみです。
    • 1 つのターンの複数のステップにわたって関数が連続して呼び出される場合、各 functionCall 部分に thought_signature が含まれます。
    • ルール: 次のリクエストを作成するときは、モデルから返された functionCall とその thought_signature を含む part を正確に含める必要があります。順次(マルチステップ)関数呼び出しの場合、現在のターンのすべてのステップで検証が実行されます。現在のターンのいずれかのステップの最初の functionCall 部分で必須の thought_signature を省略すると、400 エラーが発生します。ターンは、functionResponse ではない最新のユーザー メッセージで始まります。
    • モデルが並列関数呼び出し(FC1+signatureFC2 など)を返す場合、レスポンスにはすべての関数呼び出しの後にすべての関数レスポンス(FC1+signatureFC2FR1FR2)が含まれている必要があります。レスポンスをインターリーブ(FC1+signatureFR1FC2FR2)すると、400 エラーが発生します。
    • API で生成されなかったため、関連する思考シグネチャーがない functionCall 部分を提供する必要がある場合があります(思考シグネチャーを含まないモデルから履歴を転送する場合など)。thought_signatureskip_thought_signature_validator に設定できますが、モデルのパフォーマンスに悪影響を及ぼすため、最後の手段として使用する必要があります。
  • 非関数呼び出し:
    • モデルのレスポンスに functionCall が含まれていない場合、レスポンスの最後part(たとえば、最後の text 部分)に thought_signature が含まれている可能性があります。
    • ルール: 最適なパフォーマンスを得るには、次のリクエストにこのシグネチャを含めることが推奨されますが、省略してもエラーは発生しません。ストリーミングの場合、このシグネチャはテキスト コンテンツが空の部分で返されることがあります。そのため、モデルから finish_reason が返されるまですべての部分を解析してください。

モデルのコンテキストが保持されるように、次のルールに従ってください。

  • 常に、元の Part 内のモデルに thought_signature を送り返します。
  • シグネチャを含む Part と含まないものを結合しないでください。これにより、思考の位置コンテキストが損なわれます。
  • 署名文字列はマージできないため、両方に署名が含まれている 2 つの Part を結合しないでください。

順次関数呼び出しの例

次の例では、ユーザーが「AA100 のフライト ステータスを確認し、遅延した場合はタクシーを予約して」と尋ねた場合に、複数のタスクが必要となるマルチステップの関数呼び出しの例を示します。

REST

次の例では、REST API を使用して、順次関数呼び出しワークフローの複数のステップで思考シグネチャを処理する方法を示します。

ターン 1、ステップ 1(ユーザーのリクエスト)
{
  "contents": [
    {
      "role": "user",
      "parts": [
        {
          "text": "Check flight status for AA100 and book a taxi 2 hours before if delayed."
        }
      ]
    }
  ],
  "tools": [
    {
      "functionDeclarations": [
        {
          "name": "check_flight",
          "description": "Gets the current status of a flight",
          "parameters": {
            "type": "object",
            "properties": {
              "flight": {
                "type": "string",
                "description": "The flight number to check"
              }
            },
            "required": [
              "flight"
            ]
          }
        },
        {
          "name": "book_taxi",
          "description": "Book a taxi",
          "parameters": {
            "type": "object",
            "properties": {
              "time": {
                "type": "string",
                "description": "time to book the taxi"
              }
            },
            "required": [
              "time"
            ]
          }
        }
      ]
    }
  ]
}
ターン 1、ステップ 1(モデルのレスポンス)
{
"content": {
        "role": "model",
        "parts": [
          {
            "functionCall": {
              "name": "check_flight",
              "args": {
                "flight": "AA100"
              }
            },
            "thoughtSignature": "<SIGNATURE_A>"
          }
        ]
  }
}
ターン 1、ステップ 2(ユーザーのレスポンス - ツールの出力を送信)

このユーザーのターンには functionResponse のみ(新しいテキストなし)が含まれているため、まだターン 1 です。<SIGNATURE_A> を保持する必要があります。

{
      "role": "user",
      "parts": [
        {
          "text": "Check flight status for AA100 and book a taxi 2 hours before if delayed."
        }
      ]
    },
    {
        "role": "model",
        "parts": [
          {
            "functionCall": {
              "name": "check_flight",
              "args": {
                "flight": "AA100"
              }
            },
            "thoughtSignature": "<SIGNATURE_A>"
          }
        ]
      },
      {
        "role": "user",
        "parts": [
          {
            "functionResponse": {
              "name": "check_flight",
              "response": {
                "status": "delayed",
                "departure_time": "12 PM"
                }
              }
            }
        ]
}
ターン 1、ステップ 2(モデルのレスポンス)

モデルは、前のツールの出力に基づいてタクシーを予約することにしました。

{
      "content": {
        "role": "model",
        "parts": [
          {
            "functionCall": {
              "name": "book_taxi",
              "args": {
                "time": "10 AM"
              }
            },
            "thoughtSignature": "<SIGNATURE_B>"
          }
        ]
      }
}
ターン 1、ステップ 3(ユーザーのレスポンス - ツールの出力を送信)

タクシーの予約確認を送信するには、このループ内のすべての関数呼び出し(<SIGNATURE_A><SIGNATURE_B>)の署名を含める必要があります。

{
      "role": "user",
      "parts": [
        {
          "text": "Check flight status for AA100 and book a taxi 2 hours before if delayed."
        }
      ]
    },
    {
        "role": "model",
        "parts": [
          {
            "functionCall": {
              "name": "check_flight",
              "args": {
                "flight": "AA100"
              }
            },
            "thoughtSignature": "<SIGNATURE_A>"
          }
        ]
      },
      {
        "role": "user",
        "parts": [
          {
            "functionResponse": {
              "name": "check_flight",
              "response": {
                "status": "delayed",
                "departure_time": "12 PM"
              }
              }
            }
        ]
      },
      {
        "role": "model",
        "parts": [
          {
            "functionCall": {
              "name": "book_taxi",
              "args": {
                "time": "10 AM"
              }
            },
            "thoughtSignature": "<SIGNATURE_B>"
          }
        ]
      },
      {
        "role": "user",
        "parts": [
          {
            "functionResponse": {
              "name": "book_taxi",
              "response": {
                "booking_status": "success"
              }
              }
            }
        ]
    }
}

チャットの補完

次の例では、Chat Completions API を使用して、順次関数呼び出しワークフローの複数のステップで思考シグネチャを処理する方法を示します。

ターン 1、ステップ 1(ユーザーのリクエスト)
{
  "model": "google/gemini-3-pro-preview",
  "messages": [
    {
      "role": "user",
      "content": "Check flight status for AA100 and book a taxi 2 hours before if delayed."
    }
  ],
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "check_flight",
        "description": "Gets the current status of a flight",
        "parameters": {
          "type": "object",
          "properties": {
            "flight": {
              "type": "string",
              "description": "The flight number to check."
            }
          },
          "required": [
            "flight"
          ]
        }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "book_taxi",
        "description": "Book a taxi",
        "parameters": {
          "type": "object",
          "properties": {
            "time": {
              "type": "string",
              "description": "time to book the taxi"
            }
          },
          "required": [
            "time"
          ]
        }
      }
    }
  ]
}
ターン 1、ステップ 1(モデルのレスポンス)
{
      "role": "model",
        "tool_calls": [
          {
            "extra_content": {
              "google": {
                "thought_signature": "<SIGNATURE_A>"
              }
            },
            "function": {
              "arguments": "{\"flight\":\"AA100\"}",
              "name": "check_flight"
            },
            "id": "function-call-1",
            "type": "function"
          }
        ]
    }
ターン 1、ステップ 2(ユーザーのレスポンス - ツールの出力を送信)

このユーザーのターンには functionResponse のみ(新しいテキストなし)が含まれているため、まだターン 1 です。<SIGNATURE_A> を保持する必要があります。

"messages": [
    {
      "role": "user",
      "content": "Check flight status for AA100 and book a taxi 2 hours before if delayed."
    },
    {
      "role": "model",
        "tool_calls": [
          {
            "extra_content": {
              "google": {
                "thought_signature": "<SIGNATURE_A>"
              }
            },
            "function": {
              "arguments": "{\"flight\":\"AA100\"}",
              "name": "check_flight"
            },
            "id": "function-call-1",
            "type": "function"
          }
        ]
    },
    {
      "role": "tool",
      "name": "check_flight",
      "tool_call_id": "function-call-1",
      "content": "{\"status\":\"delayed\",\"departure_time\":\"12 PM\"}"
    }
  ]
ターン 1、ステップ 2(モデルのレスポンス)

モデルは、前のツールの出力に基づいてタクシーを予約することにしました。

{
"role": "model",
"tool_calls": [
{
"extra_content": {
"google": {
"thought_signature": "<SIGNATURE_B>"
}
            },
            "function": {
              "arguments": "{\"time\":\"10 AM\"}",
              "name": "book_taxi"
            },
            "id": "function-call-2",
            "type": "function"
          }
       ]
}
ターン 1、ステップ 3(ユーザーのレスポンス - ツールの出力を送信)

タクシーの予約確認を送信するには、このループ内のすべての関数呼び出し(<SIGNATURE_A><SIGNATURE_B>)の署名を含める必要があります。

"messages": [
    {
      "role": "user",
      "content": "Check flight status for AA100 and book a taxi 2 hours before if delayed."
    },
    {
      "role": "model",
        "tool_calls": [
          {
            "extra_content": {
              "google": {
                "thought_signature": "<SIGNATURE_A>"
              }
            },
            "function": {
              "arguments": "{\"flight\":\"AA100\"}",
              "name": "check_flight"
            },
            "id": "function-call-1d6a1a61-6f4f-4029-80ce-61586bd86da5",
            "type": "function"
          }
        ]
    },
    {
      "role": "tool",
      "name": "check_flight",
      "tool_call_id": "function-call-1d6a1a61-6f4f-4029-80ce-61586bd86da5",
      "content": "{\"status\":\"delayed\",\"departure_time\":\"12 PM\"}"
    },
    {
      "role": "model",
        "tool_calls": [
          {
            "extra_content": {
              "google": {
                "thought_signature": "<SIGNATURE_B>"
              }
            },
            "function": {
              "arguments": "{\"time\":\"10 AM\"}",
              "name": "book_taxi"
            },
            "id": "function-call-65b325ba-9b40-4003-9535-8c7137b35634",
            "type": "function"
          }
        ]
    },
    {
      "role": "tool",
      "name": "book_taxi",
      "tool_call_id": "function-call-65b325ba-9b40-4003-9535-8c7137b35634",
      "content": "{\"booking_status\":\"success\"}"
    }
  ]

並列関数呼び出しの例

次の例では、ユーザーが「パリとロンドンの天気を調べて」と尋ねた場合の並列関数呼び出しの例を示します。

REST

次の例では、REST API を使用して並列関数呼び出しワークフローで思考シグネチャを処理する方法を示します。

ターン 1、ステップ 1(ユーザーのリクエスト)
{
  "contents": [
    {
      "role": "user",
      "parts": [
        {
          "text": "Check the weather in Paris and London."
        }
      ]
    }
  ],
  "tools": [
    {
      "functionDeclarations": [
        {
          "name": "get_current_temperature",
          "description": "Gets the current temperature for a given location.",
          "parameters": {
            "type": "object",
            "properties": {
              "location": {
                "type": "string",
                "description": "The city name, e.g. San Francisco"
              }
            },
            "required": [
              "location"
            ]
          }
        }
      ]
    }
  ]
}
ターン 1、ステップ 1(モデルのレスポンス)
{
  "content": {
    "parts": [
      {
        "functionCall": {
          "name": "get_current_temperature",
          "args": {
            "location": "Paris"
          }
        },
        "thoughtSignature": "<SIGNATURE_A>"
      },
      {
        "functionCall": {
          "name": "get_current_temperature",
          "args": {
            "location": "London"
          }
        }
      }
    ]
  }
}
ターン 1、ステップ 2(ユーザーのレスポンス - ツールの出力を送信)

最初の部分の <SIGNATURE_A> は、受け取ったとおりに保持する必要があります。

[
  {
    "role": "user",
    "parts": [
      {
        "text": "Check the weather in Paris and London."
      }
    ]
  },
  {
    "role": "model",
    "parts": [
      {
        "functionCall": {
          "name": "get_current_temperature",
          "args": {
            "city": "Paris"
          }
        },
        "thought_signature": "<SIGNATURE_A>"
      },
      {
        "functionCall": {
          "name": "get_current_temperature",
          "args": {
            "city": "London"
          }
        }
      }
    ]
  },
  {
    "role": "user",
    "parts": [
      {
        "functionResponse": {
          "name": "get_current_temperature",
          "response": {
            "temp": "15C"
          }
        }
      },
      {
        "functionResponse": {
          "name": "get_current_temperature",
          "response": {
            "temp": "12C"
          }
        }
      }
    ]
  }
]

チャットの補完

次の例では、Chat Completions API を使用して、並列関数呼び出しワークフローで思考シグネチャを処理する方法を示します。

ターン 1、ステップ 1(ユーザーのリクエスト)
{
  "contents": [
    {
      "role": "user",
      "parts": [
        {
          "text": "Check the weather in Paris and London."
        }
      ]
    }
  ],
  "tools": [
    {
      "functionDeclarations": [
        {
          "name": "get_current_temperature",
          "description": "Gets the current temperature for a given location.",
          "parameters": {
            "type": "object",
            "properties": {
              "location": {
                "type": "string",
                "description": "The city name, e.g. San Francisco"
              }
            },
            "required": [
              "location"
            ]
          }
        }
      ]
    }
  ]
}
ターン 1、ステップ 1(モデルのレスポンス)
{
"role": "assistant",
        "tool_calls": [
          {
            "extra_content": {
              "google": {
                "thought_signature": "<SIGNATURE_A>"
              }
            },
            "function": {
              "arguments": "{\"location\":\"Paris\"}",
              "name": "get_current_temperature"
            },
            "id": "function-call-f3b9ecb3-d55f-4076-98c8-b13e9d1c0e01",
            "type": "function"
          },
          {
            "function": {
              "arguments": "{\"location\":\"London\"}",
              "name": "get_current_temperature"
            },
            "id": "function-call-335673ad-913e-42d1-bbf5-387c8ab80f44",
            "type": "function"
          }
        ]
}
ターン 1、ステップ 2(ユーザーのレスポンス - ツールの出力を送信)

最初の部分の <SIGNATURE_A> は、受け取ったとおりに保持する必要があります。

"messages": [
    {
      "role": "user",
      "content": "Check the weather in Paris and London."
    },
    {
      "role": "assistant",
        "tool_calls": [
          {
            "extra_content": {
              "google": {
                "thought_signature": "<SIGNATURE_A>"
              }
            },
            "function": {
              "arguments": "{\"location\":\"Paris\"}",
              "name": "get_current_temperature"
            },
            "id": "function-call-f3b9ecb3-d55f-4076-98c8-b13e9d1c0e01",
            "type": "function"
          },
          {
            "function": {
              "arguments": "{\"location\":\"London\"}",
              "name": "get_current_temperature"
            },
            "id": "function-call-335673ad-913e-42d1-bbf5-387c8ab80f44",
            "type": "function"
          }
        ]
    },
    {
      "role":"tool",
      "name": "get_current_temperature",
      "tool_call_id": "function-call-f3b9ecb3-d55f-4076-98c8-b13e9d1c0e01",
      "content": "{\"temp\":\"15C\"}"
    },
    {
      "role":"tool",
      "name": "get_current_temperature",
      "tool_call_id": "function-call-335673ad-913e-42d1-bbf5-387c8ab80f44",
      "content": "{\"temp\":\"12C\"}"
    }
  ]

functionCall Part の署名

関数呼び出しがない場合でも、Gemini はレスポンスの最後の Partthought_signature を返すことがあります。

  • 動作: モデルから返される最終的なコンテンツ ParttextinlineData など)に thought_signature が含まれることがあります。
  • 要件: このシグネチャを返すことは、特に複雑な指示の実行やエージェント ワークフローのシミュレーションで、モデルが高品質の推論を維持するために推奨されます。
  • 検証: API は、functionCall 以外の部分の署名の検証を厳密に適用しません。省略してもブロッキング エラーは発生しませんが、パフォーマンスが低下する可能性があります。

テキスト部分にシグネチャを含むモデル レスポンスの例:

次の例では、thought_signaturefunctionCall 以外の Part に含まれているモデル レスポンスと、後続のリクエストでそれを処理する方法を示します。

ターン 1、ステップ 1(モデルのレスポンス)
{
  "role": "model",
  "parts": [
    {
      "text": "I need to calculate the risk. Let me think step-by-step...",
      "thought_signature": "<SIGNATURE_C>" // OPTIONAL (Recommended)
    }
  ]
}
ターン 2、ステップ 1(ユーザー)
[
  { "role": "user", "parts": [{ "text": "What is the risk?" }] },
  {
    "role": "model",
    "parts": [
      {
        "text": "I need to calculate the risk. Let me think step-by-step...",
        // If you omit <SIGNATURE_C> here, no error will occur.
      }
    ]
  },
  { "role": "user", "parts": [{ "text": "Summarize it." }] }
]

次のステップ