Les signatures de pensée sont des représentations chiffrées du processus de réflexion interne du modèle. Elles préservent l'état de raisonnement de Gemini lors de
conversations multitours et en plusieurs étapes, ce qui peut être utile lorsque vous utilisez
l'appel de fonction. Les réponses peuvent inclure un champ thought_signature dans n'importe quelle partie de contenu (par exemple, text, functionCall).
Les modèles Gemini 3 appliquent une validation plus stricte des signatures de pensée que les versions précédentes de Gemini, car ils améliorent les performances du modèle pour l'appel de fonction. Pour vous assurer que le modèle conserve le contexte complet sur plusieurs tours d'une conversation, vous devez renvoyer les signatures de pensée des réponses précédentes dans vos requêtes suivantes, même lorsque vous utilisez des niveaux de réflexion MINIMAL. Si une signature de pensée requise n'est pas renvoyée lorsque vous utilisez des modèles Gemini 3, le modèle renvoie une erreur 400.
Bien que Gemini 3 Pro Image n'applique pas cette validation, pour vous assurer que le modèle conserve le contexte complet sur plusieurs tours d'une conversation, vous devez toujours renvoyer les signatures de pensée des réponses précédentes dans vos requêtes suivantes. Gemini 3 Pro Image ne renvoie pas d'erreur 400 si une signature de pensée n'est pas renvoyée. Pour obtenir des exemples de code liés à la modification d'images multitour
à l'aide de Gemini 3 Pro Image, consultez
Exemple de modification d'images multitour à l'aide de signatures de pensée.
Si vous utilisez le SDK Google Gen AI officiel (Python, Node.js, Go ou Java) et que vous utilisez les fonctionnalités d'historique de chat standard ou que vous ajoutez la réponse complète du modèle à l'historique, les signatures de pensée sont gérées automatiquement.
Pourquoi sont-elles importantes ?
Lorsqu'un modèle Thinking appelle un outil externe, il met en pause son processus de raisonnement interne. La signature de pensée agit comme un "état d'enregistrement", ce qui permet au modèle de reprendre sa chaîne de pensée de manière transparente une fois que vous avez fourni le résultat de la fonction. Sans signatures de pensée, le modèle "oublie" ses étapes de raisonnement spécifiques lors de la phase d'exécution de l'outil. Le renvoi de la signature garantit les éléments suivants :
- Continuité du contexte : le modèle préserve et peut vérifier les étapes de raisonnement qui ont justifié l'appel de l'outil.
- Raisonnement complexe : permet d'effectuer des tâches en plusieurs étapes où la sortie d'un outil informe le raisonnement du suivant.
Préservation des pensées
Pour Gemini 3.5 Flash et les modèles plus récents, les pensées des tours précédents sont conservées par défaut. Le service conserve l'historique des pensées dans le contexte de la conversation avant de le transmettre au modèle.
Lorsque vous envoyez l'historique des conversations, soyez cohérent avec les tours précédents : incluez le contexte complet (pensées, appels de fonction et réponses) ou omettez-le entièrement. Fournir un contexte partiel peut dégrader les performances du modèle.
Tours et étapes
Dans le contexte de l'appel de fonction, il est important de comprendre la différence entre les tours et les étapes :
- Un tour représente un échange de conversation complet, qui commence par une requête de l'utilisateur et se termine lorsque le modèle fournit une réponse finale sans appel de fonction à cette requête.
- Une étape se produit au cours d'un seul tour lorsque le modèle appelle une fonction et nécessite une réponse de fonction pour poursuivre son processus de raisonnement. Comme le montre le schéma, un seul tour peut impliquer plusieurs étapes si le modèle doit appeler plusieurs fonctions de manière séquentielle pour répondre à la requête de l'utilisateur.
Comment utiliser les signatures de pensée
La façon la plus simple de gérer les signatures de pensée consiste à inclure tous les Part de tous les messages précédents dans l'historique des conversations lorsque vous envoyez une nouvelle requête, exactement comme ils ont été renvoyés par le modèle.
Si vous n'utilisez pas l'un des SDK Google Gen AI ou si vous devez modifier ou raccourcir l'historique des conversations, vous devez vous assurer que les signatures de pensée sont conservées et renvoyées au modèle.
Lorsque vous utilisez le SDK Google Gen AI (recommandé)
Lorsque vous utilisez les fonctionnalités d'historique de chat des SDK ou que vous ajoutez l'objet
content du modèle de la réponse précédente aux contents de la requête suivante, les signatures sont gérées automatiquement.
L'exemple Python suivant montre la gestion automatique :
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}")
Lorsque vous utilisez REST ou la gestion manuelle
Si vous interagissez directement avec l'API, vous devez implémenter la gestion des signatures en fonction des règles suivantes pour Gemini 3 Pro :
- Appel de fonction:
- Si la réponse du modèle contient une ou plusieurs parties
functionCall, unethought_signatureest requise pour un traitement correct. - Dans le cas d'appels de fonction parallèles dans une seule réponse, seule la première partie
functionCallcontient lathought_signature. - Dans le cas d'appels de fonction séquentiels sur plusieurs étapes d'un tour, chaque partie
functionCallcontient unethought_signature. - Règle : lorsque vous construisez la requête suivante, vous devez inclure la
partcontenant lefunctionCallet sathought_signatureexactement comme elle a été renvoyée par le modèle. Pour l'appel de fonction séquentiel (en plusieurs étapes), la validation est effectuée sur toutes les étapes du tour actuel. Si vous omettez unethought_signaturerequise pour la première partiefunctionCallà n'importe quelle étape du tour actuel, une erreur400est générée. Un tour commence par le message utilisateur le plus récent qui n'est pas unefunctionResponse. - Si le modèle renvoie des appels de fonction parallèles (par exemple,
FC1+signature,FC2), votre réponse doit contenir tous les appels de fonction suivis de toutes les réponses de fonction (FC1+signature,FC2,FR1,FR2). Les réponses entrelacées (FC1+signature,FR1,FC2,FR2) entraînent une erreur400. - Dans de rares cas, vous devez fournir des parties
functionCallqui n'ont pas été générées par l'API et qui ne comportent donc pas de signature de pensée associée (par exemple, lorsque vous transférez l'historique d'un modèle qui n'inclut pas de signatures de pensée). Vous pouvez définirthought_signaturesurskip_thought_signature_validator, mais cela ne doit être utilisé qu'en dernier recours, car cela aura un impact négatif sur les performances du modèle.
- Si la réponse du modèle contient une ou plusieurs parties
- Appel sans fonction:
- Si la réponse du modèle ne contient pas de
functionCall, elle peut inclure unethought_signaturedans la dernièrepartde la réponse (par exemple, la dernière partietext). - Règle : l'inclusion de cette signature dans la requête suivante est
recommandée pour des performances optimales, mais son omission n'entraînera pas d'
erreur. Lors de la diffusion en streaming, cette signature peut être renvoyée dans une partie avec un contenu textuel vide. Veillez donc à analyser toutes les parties jusqu'à ce que
finish_reasonsoit renvoyé par le modèle.
- Si la réponse du modèle ne contient pas de
Suivez ces règles pour vous assurer que le contexte du modèle est conservé :
- Renvoyez toujours la
thought_signatureau modèle dans sonPartd'origine. - Ne fusionnez pas un
Partcontenant une signature avec un autre qui n'en contient pas. Cela interrompt le contexte positionnel de la pensée. - Ne combinez pas deux
Partqui contiennent tous deux des signatures, car les chaînes de signature ne peuvent pas être fusionnées.
Exemple d'appel de fonction séquentiel
L'exemple suivant montre un exemple d'appel de fonction en plusieurs étapes où l'utilisateur demande "Vérifier le statut du vol AA100 et réserver un taxi en cas de retard", ce qui nécessite plusieurs tâches.
REST
L'exemple suivant montre comment gérer les signatures de pensée sur plusieurs étapes d'un workflow d'appel de fonction séquentiel à l'aide de l'API REST.
Tour 1, étape 1 (requête utilisateur)
{ "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" ] } } ] } ] }
Tour 1, étape 1 (réponse du modèle)
{ "content": { "role": "model", "parts": [ { "functionCall": { "name": "check_flight", "args": { "flight": "AA100" } }, "thoughtSignature": "<SIGNATURE_A>" } ] } }
Tour 1, étape 2 (réponse de l'utilisateur – envoi des sorties d'outil)
Étant donné que ce tour utilisateur ne contient qu'une functionResponse (pas de nouveau texte), nous sommes toujours au tour 1. Vous devez conserver <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" } } } ] }
Tour 1, étape 2 (réponse du modèle)
Le modèle décide maintenant de réserver un taxi en fonction de la sortie de l'outil précédent.
{ "content": { "role": "model", "parts": [ { "functionCall": { "name": "book_taxi", "args": { "time": "10 AM" } }, "thoughtSignature": "<SIGNATURE_B>" } ] } }
Tour 1, étape 3 (réponse de l'utilisateur – envoi de la sortie de l'outil)
Pour envoyer la confirmation de réservation du taxi, vous devez inclure les signatures de tous
les appels de fonction de cette boucle (<SIGNATURE_A> et <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
L'exemple suivant montre comment gérer les signatures de pensée sur plusieurs étapes d'un workflow d'appel de fonction séquentiel à l'aide de l'API Chat Completions.
Tour 1, étape 1 (requête utilisateur)
{ "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" ] } } } ] }
Tour 1, étape 1 (réponse du modèle)
{ "role": "model", "tool_calls": [ { "extra_content": { "google": { "thought_signature": "<SIGNATURE_A>" } }, "function": { "arguments": "{\"flight\":\"AA100\"}", "name": "check_flight" }, "id": "function-call-1", "type": "function" } ] }
Tour 1, étape 2 (réponse de l'utilisateur – envoi des sorties d'outil)
Étant donné que ce tour utilisateur ne contient qu'une functionResponse (pas de nouveau texte), nous sommes toujours au tour 1. Vous devez conserver <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\"}" } ]
Tour 1, étape 2 (réponse du modèle)
Le modèle décide maintenant de réserver un taxi en fonction de la sortie de l'outil précédent.
{ "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" } ] }
Tour 1, étape 3 (réponse de l'utilisateur – envoi de la sortie de l'outil)
Pour envoyer la confirmation de réservation du taxi, vous devez inclure les signatures de tous
les appels de fonction de cette boucle (<SIGNATURE_A> et <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\"}" } ]
Exemple d'appel de fonction parallèle
L'exemple suivant montre un exemple d'appel de fonction parallèle où l'utilisateur demande "Vérifier la météo à Paris et à Londres".
REST
L'exemple suivant montre comment gérer les signatures de pensée dans un workflow d'appel de fonction parallèle à l'aide de l'API REST.
Tour 1, étape 1 (requête utilisateur)
{ "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" ] } } ] } ] }
Tour 1, étape 1 (réponse du modèle)
{ "content": { "parts": [ { "functionCall": { "name": "get_current_temperature", "args": { "location": "Paris" } }, "thoughtSignature": "<SIGNATURE_A>" }, { "functionCall": { "name": "get_current_temperature", "args": { "location": "London" } } } ] } }
Tour 1, étape 2 (réponse de l'utilisateur – envoi des sorties d'outil)
Vous devez conserver <SIGNATURE_A> sur la première partie exactement comme elle a été reçue.
[ { "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
L'exemple suivant montre comment gérer les signatures de pensée dans un workflow d'appel de fonction parallèle à l'aide de l'API Chat Completions.
Tour 1, étape 1 (requête utilisateur)
{ "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" ] } } ] } ] }
Tour 1, étape 1 (réponse du modèle)
{ "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" } ] }
Tour 1, étape 2 (réponse de l'utilisateur – envoi des sorties d'outil)
Vous devez conserver <SIGNATURE_A> sur la première partie exactement comme elle a été reçue.
"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\"}" } ]
Signatures dans les Part non-functionCall
Gemini peut également renvoyer une thought_signature dans le Part final d'une réponse, même si aucun appel de fonction n'est présent.
- Comportement : le
Partde contenu final (text,inlineData, etc.) renvoyé par le modèle peut contenir unethought_signature. - Exigence : le renvoi de cette signature est recommandé pour garantir que le modèle conserve un raisonnement de haute qualité, en particulier pour les instructions complexes ou les workflows d'agent simulés.
- Validation : l'API n'applique pas strictement la validation des signatures dans les parties non-
functionCall. Vous ne recevrez pas d'erreur bloquante si vous les omettez, mais les performances peuvent se dégrader.
Exemple de réponse du modèle avec signature dans la partie texte :
Les exemples suivants montrent une réponse du modèle dans laquelle une thought_signature est incluse dans un Part non-functionCall et comment la gérer dans une requête ultérieure.
Tour 1, étape 1 (réponse du modèle)
{ "role": "model", "parts": [ { "text": "I need to calculate the risk. Let me think step-by-step...", "thought_signature": "<SIGNATURE_C>" // OPTIONAL (Recommended) } ] }
Tour 2, étape 1 (utilisateur)
[ { "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." }] } ]
Exemple de modification d'images multitour à l'aide de signatures de pensée
Les exemples suivants montrent comment récupérer et transmettre des signatures de pensée lors de la création et de la modification d'images en multitour avec Gemini 3 Pro Image.
Tour 1 : Obtenir la réponse et enregistrer les données incluant les signatures de pensée
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))
Tour 2 : transmettre les données incluant les signatures de pensée
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))
Étape suivante
Réflexion
Découvrez les capacités de réflexion de Gemini et comment configurer les niveaux de réflexion.
Guide sur la création de requêtes pour la réflexion
Découvrez les techniques de prompt engineering et les bonnes pratiques adaptées aux modèles de raisonnement Gemini.
Présentation de l'appel de fonction
Découvrez comment permettre aux modèles Gemini d'utiliser des outils externes lors de la génération de réponses à l'aide de l'appel de fonction.