想法簽名

思考簽章是模型內部思考過程的加密表示法。在多輪和多步驟對話中,思維簽章會保留 Gemini 的推論狀態,這在使用函式呼叫時非常實用。回覆可在任何內容部分 (例如 text、functionCall) 包含 thought_signature 欄位。

Gemini 3 模型對思考簽章的驗證比先前的 Gemini 版本更嚴格,因為這能提升函式呼叫的模型效能。為確保模型在多輪對話中維持完整脈絡,您必須在後續要求中傳回先前回覆的思維簽章,即使使用 MINIMAL 思維層級也一樣。使用 Gemini 3 模型時,如果未傳回必要的思考簽章,模型會傳回 400 錯誤。

雖然 Gemini 3 Pro Image 不會強制執行這項驗證,但為確保模型在多輪對話中能完整掌握上下文,您仍須在後續要求中傳回先前回應的思考簽章。如果系統未傳回想法簽章,Gemini 3 Pro Image 不會傳回 400 錯誤。如需使用 Gemini 3 Pro Image 進行多輪圖像編輯的程式碼範例,請參閱「使用思想特徵進行多輪圖像編輯的範例」。

如果您使用官方 Google Gen AI SDK (Python、Node.js、Go 或 Java),並使用標準對話記錄功能,或將完整模型回覆附加至記錄,系統會自動處理思考簽章。

為什麼這些原則很重要?

當思考型模型呼叫外部工具時,會暫停內部推理程序。思考簽章就像是「儲存狀態」,可讓模型在您提供函式結果後,順暢地繼續思考。如果沒有思考簽章,模型在工具執行階段會「忘記」特定的推論步驟。傳回簽名可確保:

  • 情境延續性:模型會保留並檢查呼叫工具的推論步驟。
  • 複雜推論:可執行多步驟工作,其中一項工具的輸出內容會做為下一項工具的推論依據。

保留想法

如果是 Gemini 3.5 Flash 和更新的模型,系統預設會保留先前對話的思考過程。這項服務會將對話脈絡中的思考歷程記錄傳遞給模型。

傳送對話記錄時,請與先前的對話保持一致:加入完整脈絡 (思考內容、函式呼叫和回覆),或完全省略。提供部分背景資訊可能會降低模型效能。

其他模型的想法簽名

Flash-Lite 模型無法讀取非 Flash-Lite 模型產生的想法。如果向 Flash-Lite 模型提出的要求包含非 Flash-Lite 模型生成的思考簽章,要求不會失敗。而是會從模型的脈絡中捨棄這些想法。舉例來說,如果傳送要求給 Flash-Lite 模型,但要求中包含 Gemini Flash 或 Pro 模型的記錄,就會發生這種情況。

轉彎和步數

與大型語言模型 (LLM) 進行多輪對話流程,使用函式呼叫 (FC) 和函式回應 (FR) 生成最終回覆。這項程序分為兩個回合:第一回合包含三個步驟。步驟 1:使用者提示會導向模型 FC1。步驟 2:模型收到 FR1,因此產生模型 FC2。步驟 3:模型收到 FR2,並根據該結果生成第 1 輪的最終模型文字輸出內容。第 2 輪會從新的使用者提示開始,並運用第 1 輪的完整脈絡,生成第 2 輪的最終模型文字輸出內容。
透過函式呼叫和回覆進行多輪對話。

在函式呼叫的脈絡中,請務必瞭解「回合」和「步驟」之間的差異:

  • 輪次代表完整的對話互動,從使用者提示開始,到模型針對該提示提供最終回覆 (非函式呼叫) 為止。
  • 當模型叫用函式並需要函式回應才能繼續推論程序時,就會在單一回合中發生「步驟」。如圖所示,如果模型需要依序呼叫多個函式,才能滿足使用者要求,則單一回合可能包含多個步驟。

如何使用想法簽章

處理思考簽章最簡單的方法,是在傳送新要求時,將對話記錄中所有先前訊息的所有 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-3.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-3.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 規則,實作簽章處理:

  • 函式呼叫:
    • 如果模型回覆包含一或多個 functionCall 部分,則必須提供 thought_signature 才能正確處理。
    • 如果單一回覆中包含平行函式呼叫,則只有第一個 functionCall 部分會包含 thought_signature。
    • 如果在一輪對話中,多個步驟依序呼叫函式,則每個 functionCall 部分都會包含 thought_signature。
    • 規則:建構下一個要求時,您必須加入包含 functionCall 及其 thought_signature 的 part,且完全與模型傳回的內容相同。如果是循序 (多步驟) 函式呼叫,系統會驗證目前回合中的所有步驟,且如果省略任何步驟中第一個 functionCall 部分的必要 thought_signature,就會導致 400 錯誤。對話輪次會從最新的使用者訊息開始,但該訊息不得為 functionResponse。
    • 如果模型傳回平行函式呼叫 (例如 FC1+signature、FC2),回覆必須包含所有函式呼叫,後面接著所有函式回覆 (FC1+signature、FC2、FR1、FR2)。如果交錯回覆 (FC1+signature、FR1、FC2、FR2),會導致 400 錯誤。
    • 在極少數情況下,您可能需要提供並非由 API 生成的 functionCall 部分,因此沒有相關聯的思考簽章 (例如從不含思考簽章的模型轉移記錄)。您可以將 thought_signature 設為 skip_thought_signature_validator,但這應該是最後手段,因為這會對模型效能造成負面影響。
  • 非函式呼叫:
    • 如果模型回應不含 functionCall,則可能在最後一個回應 part 中包含 thought_signature (例如最後一個 text 部分)。
    • 規則:建議在下一個要求中加入這個簽章,以獲得最佳效能,但省略簽章不會導致錯誤。串流時,這個簽章可能會在文字內容空白的部分傳回,因此請務必剖析所有部分,直到模型傳回 finish_reason 為止。

請遵守下列規則,確保模型保留情境:

  • 請務必將 thought_signature 傳回原始 Part 內的模型。
  • 請勿將含有簽章的 Part 與不含簽章的合併。這會中斷想法的位置脈絡。
  • 請勿合併兩個都含有簽章的 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

以下範例說明如何使用 Chat Completions API,在依序呼叫函式的工作流程中,處理多個步驟的思考簽章。

第 1 回合,步驟 1 (使用者要求)
{
  "model": "google/gemini-3.1-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": {
        "functionResponse": {
          "name": "get_current_temperature",
          "response": {
            "temp": "12C"
          }
        }
      }
    ]
  }
]

Chat Completions

以下範例說明如何使用 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 也可能會在回覆的最後一個 Part 中傳回 thought_signature。

  • 行為:模型傳回的最終內容 Part (text、inlineData 等) 可能包含 thought_signature。
  • 必要條件:建議傳回這個簽章,確保模型維持高品質的推理能力,特別是針對複雜的指令遵循或模擬代理式工作流程。
  • 驗證:API「不會」嚴格強制驗證非 functionCall 部分的簽章。如果省略這些屬性,系統不會顯示封鎖錯誤,但效能可能會降低。

模型回覆範例 (文字部分包含簽名):

以下範例顯示模型回覆,其中 thought_signature 包含在非 functionCall 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." }] }
]

使用思想特徵進行多輪圖像編輯的範例

以下範例說明如何使用 Gemini 3 Pro 圖像模型,在多輪圖像建立和編輯過程中擷取及傳遞思想特徵。

第 1 輪:取得回覆並儲存包含思考簽章的資料

chat = client.chats.create(
   model="gemini-3-pro-image-preview",
   config=types.GenerateContentConfig(
       response_modalities=['TEXT', 'IMAGE']
   )
)
message = "Create an image of a clear perfume bottle sitting on a vanity."
response = chat.send_message(message)
data = b''
for part in response.candidates[0].content.parts:
   if part.text:
       display(Markdown(part.text))
   if part.inline_data:
       data = part.inline_data.data
       display(Image(data=data, width=500))

第 2 輪:傳遞包含思考簽章的資料

response = chat.send_message(
   message=[
       types.Part.from_bytes(
           data=data,
           mime_type="image/png",
       ),
       "Make the perfume bottle purple and add a vase of hydrangeas next to the bottle.",
   ],
)
for part in response.candidates[0].content.parts:
   if part.text:
       display(Markdown(part.text))
   if part.inline_data:
       display(Image(data=part.inline_data.data, width=500))

後續步驟

總覽

瞭解 Gemini 的思考能力,以及如何設定思考等級。

指南

探索專為 Gemini 思考型模型設計的提示工程技術和最佳做法。

指南

瞭解如何啟用 Gemini 模型,在回覆生成期間使用函式呼叫功能,呼叫外部工具。