Les signatures de pensée sont des représentations chiffrées du processus de réflexion interne du modèle. Elles sont utilisées pour préserver le contexte de raisonnement lors des interactions multitours.
Lorsque vous utilisez des modèles de réflexion (tels que les séries Gemini 3 et 2.5), l'API peut renvoyer un champ thoughtSignature dans les parties de contenu de la réponse (par exemple, text ou functionCall).
En règle générale, si vous recevez une signature de pensée dans la réponse d'un modèle, vous devez la renvoyer exactement telle qu'elle a été reçue lorsque vous envoyez l'historique des conversations au tour suivant. Lorsque vous utilisez Gemini 3 Pro, vous devez renvoyer les signatures de réflexion lors de l'appel de fonction, sinon vous recevrez une erreur de validation (code d'état 4xx).
Fonctionnement
Le graphique ci-dessous illustre la signification des termes "tour" et "étape" en ce qui concerne l'appel de fonction dans l'API Gemini. Un "tour" correspond à un échange unique et complet dans une conversation entre un utilisateur et un modèle. Une "étape" est une action ou une opération plus précise effectuée par le modèle, souvent dans le cadre d'un processus plus vaste pour terminer un tour.

Ce document se concentre sur la gestion de l'appel de fonction pour Gemini 3 Pro. Pour en savoir plus sur les écarts avec 2.5, consultez la section Comportement du modèle.
Gemini 3 Pro renvoie des signatures de pensée pour toutes les réponses du modèle (réponses de l'API) avec un appel de fonction. Les signatures de pensée s'affichent dans les cas suivants :
- Lorsqu'il existe des appels de fonction parallèle, la première partie d'appel de fonction renvoyée par la réponse du modèle comporte une signature de pensée.
- Lorsqu'il existe des appels de fonction séquentiels (multietapes), chaque appel de fonction aura une signature et vous devrez renvoyer toutes les signatures.
- Les réponses du modèle sans appel de fonction renvoient une signature de pensée dans la dernière partie renvoyée par le modèle.
Le tableau suivant fournit une visualisation des appels de fonction en plusieurs étapes, en combinant les définitions des tours et des étapes avec le concept de signatures présenté ci-dessus :
Tourner |
Step |
Demande de l'utilisateur |
Réponse du modèle |
FunctionResponse |
1 |
1 |
request1 = user_prompt |
FC1 + signature |
FR1 |
1 |
2 |
request2 = request1 + (FC1 + signature) + FR1 |
FC2 + signature |
FR2 |
1 |
3 |
request3 = request2 + (FC2 + signature) + FR2 |
text_output
|
Aucun |
Signatures dans les parties d'appel de fonction
Lorsque Gemini génère un functionCall, il s'appuie sur le thought_signature pour traiter correctement la sortie de l'outil au tour suivant.
- Comportement :
- Appel de fonction unique : la partie
functionCallcontiendra unthought_signature. - Appels de fonction parallèles : si le modèle génère des appels de fonction parallèles dans une réponse, le
thought_signaturen'est associé qu'à la première partiefunctionCall. Les partiesfunctionCallsuivantes de la même réponse ne contiendront pas de signature.
- Appel de fonction unique : la partie
- Exigence : Vous devez renvoyer cette signature exactement à l'endroit où elle a été reçue lorsque vous renvoyez l'historique des conversations.
- Validation : une validation stricte est appliquée à tous les appels de fonction au cours du tour actuel . (Seul le tour actuel est requis. Nous ne validons pas les tours précédents.)
- L'API remonte dans l'historique (du plus récent au plus ancien) pour trouver le message User le plus récent contenant du contenu standard (par exemple,
text) ( qui correspond au début du tour actuel). Il ne s'agira be d'unfunctionResponse. - Les tours
functionCalldu modèle Tous qui se produisent après ce message d'utilisation spécifique sont considérés comme faisant partie du tour. - La première partie
functionCallde chaque étape du tour actuel doit inclure sonthought_signature. - Si vous omettez un
thought_signaturepour la première partiefunctionCalld'une étape du tour actuel, la requête échouera et renverra une erreur 400.
- L'API remonte dans l'historique (du plus récent au plus ancien) pour trouver le message User le plus récent contenant du contenu standard (par exemple,
- Si les signatures appropriées ne sont pas renvoyées, voici comment vous recevrez une erreur
gemini-3-pro-preview: Si vous n'incluez pas de signatures, une erreur 400 s'affichera. Le libellé se présentera sous la forme suivante :- Il manque un
thought_signatureà l'appel de fonction<Function Call>dans le bloc de contenu<index of contents array>. Par exemple, l'thought_signatureest manquant dans l'FC1de l'1..
- Il manque un
Exemple d'appel de fonction séquentiel
Cette section présente un exemple d'appels de fonction multiples dans lequel l'utilisateur pose une question complexe nécessitant plusieurs tâches.
Prenons l'exemple d'un appel de fonction multitours où l'utilisateur pose une question complexe nécessitant plusieurs tâches : "Check flight status for AA100 and
book a taxi if delayed".
Tourner |
Step |
Demande de l'utilisateur |
Réponse du modèle |
FunctionResponse |
1 |
1 |
request1="Check flight status for AA100 and book a taxi 2 hours before if delayed." |
FC1 ("check_flight") + signature |
FR1 |
1 |
2 |
request2 = request1 + FC1 ("check_flight") + signature + FR1 |
FC2("book_taxi") + signature |
FR2 |
1 |
3 |
request3 = request2 + FC2 ("book_taxi") + signature + FR2 |
text_output
|
None |
Le code suivant illustre la séquence du tableau ci-dessus.
Tour 1, étape 1 (demande de l'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 résultats de l'outil) : comme ce tour d'utilisateur ne contient qu'un functionResponse (pas de nouveau texte), nous sommes toujours au tour 1. Nous devons préserver <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>" //Required and Validated
}
]
},
{
"role": "user",
"parts": [
{
"functionResponse": {
"name": "check_flight",
"response": {
"status": "delayed",
"departure_time": "12 PM"
}
}
}
]
}
Tour 1, étape 2 (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 (Utilisateur : envoi du résultat de l'outil) Pour envoyer la confirmation de la réservation de taxi, nous devons inclure des signatures pour TOUS les appels de fonction dans cette boucle (<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>" //Required and Validated
}
]
},
{
"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>" //Required and Validated
}
]
},
{
"role": "user",
"parts": [
{
"functionResponse": {
"name": "book_taxi",
"response": {
"booking_status": "success"
}
}
}
]
}
}
Exemple d'appel de fonction parallèle
Passons à un exemple d'appel de fonction parallèle où l'utilisateur demande "Check weather in Paris and London" pour voir où le modèle effectue la validation.
Tourner |
Step |
Demande de l'utilisateur |
Réponse du modèle |
FunctionResponse |
|---|---|---|---|---|
1 |
1 |
request1="Vérifie la météo à Paris et à Londres" |
FC1 ("Paris") + signature FC2 ("Londres") |
FR1 |
1 |
2 |
demande 2 = demande 1 + FC1 ("Paris") + signature + FC2 ("Londres") |
text_output (sans FC) |
Aucun |
Le code suivant illustre la séquence du tableau ci-dessus.
Tour 1, étape 1 (demande de l'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>"// INCLUDED on First FC
},
{
"functionCall": {
"name": "get_current_temperature",
"args": {
"location": "London"
}// NO signature on subsequent parallel FCs
}
}
]
}
}
Étape 2 du tour 1 (réponse de l'utilisateur : envoi des résultats de l'outil) Nous devons conserver <Signature_A> dans la première partie exactement tel qu'il a été reçu.
[
{
"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>" // MUST BE INCLUDED
},
{
"functionCall": {
"name": "get_current_temperature",
"args": {
"city": "London"
}
}
} // NO SIGNATURE FIELD
]
},
{
"role": "user",
"parts": [
{
"functionResponse": {
"name": "get_current_temperature",
"response": {
"temp": "15C"
}
}
},
{
"functionResponse": {
"name": "get_current_temperature",
"response": {
"temp": "12C"
}
}
}
]
}
]
Signatures dans les parties autres que functionCall
Gemini peut également renvoyer thought_signatures dans la dernière partie de la réponse, dans les parties qui ne sont pas des appels de fonction.
- Comportement : la partie de contenu finale (
text, inlineData…) renvoyée par le modèle peut contenir unthought_signature. - Recommandation : Il est recommandé de renvoyer ces signatures pour s'assurer que le modèle maintient un raisonnement de haute qualité, en particulier pour les workflows agentifs simulés ou le suivi d'instructions complexes.
- Validation : l'API n'applique pas strictement la validation. Vous ne recevrez pas d'erreur bloquante si vous les omettez, mais les performances peuvent se dégrader.
Texte/Raisonnement en contexte (sans validation)
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." }] }
]
Signatures pour la compatibilité avec OpenAI
L'exemple suivant montre comment gérer les signatures de pensée pour une API Chat Completions à l'aide de la compatibilité avec OpenAI.
Exemple d'appel de fonction séquentiel
Il s'agit d'un exemple d'appel de fonction multiple dans lequel l'utilisateur pose une question complexe nécessitant plusieurs tâches.
Prenons l'exemple d'un appel de fonction multitours où l'utilisateur demande Check flight status for AA100 and book a taxi if delayed. Vous verrez ce qui se passe lorsque l'utilisateur pose une question complexe nécessitant plusieurs tâches.
Tourner |
Step |
Demande de l'utilisateur |
Réponse du modèle |
FunctionResponse |
1 |
1 |
request1="Check the weather in Paris and London" |
FC1 ("Paris") + signature
|
FR1 |
1 |
2 |
request 2 = request1 + FC1 ("Paris") + signature + FC2 ("London") |
text_output
|
None |
Le code suivant parcourt la séquence donnée.
Tour 1, étape 1 (demande de l'utilisateur)
{
"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"
]
}
}
}
]
}
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 résultats de l'outil)
Étant donné que ce tour d'utilisateur ne contient qu'un functionResponse (aucun nouveau texte), nous sommes toujours au tour 1 et devons 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>" //Required and Validated
}
},
"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 (modèle)
Le modèle décide maintenant de réserver un taxi en fonction du résultat 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 (utilisateur : envoi du résultat de l'outil)
Pour envoyer la confirmation de réservation de taxi, nous devons inclure des signatures pour TOUS les appels de fonction dans cette boucle (<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>" //Required and Validated
}
},
"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>" //Required and Validated
}
},
"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
Passons à un exemple d'appel de fonction parallèle où l'utilisateur demande "Check weather in Paris and London". Vous pouvez voir où le modèle effectue la validation.
Tourner |
Step |
Demande de l'utilisateur |
Réponse du modèle |
FunctionResponse |
1 |
1 |
request1="Check the weather in Paris and London" |
FC1 ("Paris") + signature
|
FR1 |
1 |
2 |
request 2 = request1 + FC1 ("Paris") + signature + FC2 ("London") |
text_output
|
None |
Voici le code permettant de parcourir la séquence donnée.
Tour 1, étape 1 (demande de l'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>" //Signature returned
}
},
"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" // No signature on Parallel FC
}
]
}
Tour 1, étape 2 (réponse de l'utilisateur : envoi des résultats de l'outil)
Vous devez conserver <Signature_A> dans la première partie exactement tel que vous l'avez reçu.
"messages": [
{
"role": "user",
"content": "Check the weather in Paris and London."
},
{
"role": "assistant",
"tool_calls": [
{
"extra_content": {
"google": {
"thought_signature": "<Signature A>" //Required
}
},
"function": {
"arguments": "{\"location\":\"Paris\"}",
"name": "get_current_temperature"
},
"id": "function-call-f3b9ecb3-d55f-4076-98c8-b13e9d1c0e01",
"type": "function"
},
{
"function": { //No Signature
"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\"}"
}
]
Questions fréquentes
Comment transférer l'historique d'un autre modèle vers Gemini 3 Pro avec une partie d'appel de fonction dans le tour et l'étape en cours ? Je dois fournir des parties d'appel de fonction qui n'ont pas été générées par l'API et qui n'ont donc pas de signature de pensée associée.
Bien qu'il soit fortement déconseillé d'injecter des blocs d'appels de fonction personnalisés dans la requête, vous pouvez définir les signatures fictives suivantes (
"context_engineering_is_the_way_to_go"ou"skip_thought_signature_validator") dans le champ de signature de pensée pour ignorer la validation dans les cas où cela ne peut pas être évité (par exemple, pour fournir au modèle des informations sur les appels de fonction et les réponses qui ont été exécutés de manière déterministe par le client, ou pour transférer une trace à partir d'un autre modèle qui n'inclut pas de signatures de pensée).J'envoie des appels et des réponses de fonctions parallèles entrelacés, et l'API renvoie un code 400. Pourquoi ?
Lorsque l'API renvoie des appels de fonction parallèles "FC1 + signature, FC2", la réponse attendue de l'utilisateur est "FC1+ signature, FC2, FR1, FR2". Si vous les avez entrelacés comme "FC1 + signature, FR1, FC2, FR2", l'API renverra une erreur 400.
Lorsque le modèle ne renvoie pas d'appel de fonction lors du streaming, je ne trouve pas la signature de pensée.
Lorsqu'une réponse de modèle ne contient pas de FC avec une demande de streaming, le modèle peut renvoyer la signature de pensée dans une partie avec un contenu textuel vide. Il est conseillé d'analyser l'intégralité de la requête jusqu'à ce que le modèle renvoie
finish_reason.
Comportement de la signature de pensée par série de modèles
Les modèles Gemini 3 Pro et Gemini 2.5 se comportent différemment avec les signatures de pensée dans les appels de fonction :
- Si une réponse contient des appels de fonction,
- Gemini 3 Pro aura toujours la signature dans la première partie de l'appel de fonction. Il est obligatoire de renvoyer cette pièce.
- Gemini 2.5 affichera la signature dans la première partie (quel que soit le type). Le renvoi de cette partie est facultatif.
- S'il n'y a pas d'appels de fonction dans une réponse,
- Gemini 3 Pro ajoutera la signature à la fin si le modèle génère une réflexion.
- Gemini 2.5 ne comporte aucune signature.
Pour en savoir plus sur le comportement de la signature de pensée des modèles Gemini 2.5, consultez la page Réflexion.