Les signatures de réflexion sont des représentations chiffrées du processus de réflexion interne du modèle. Elles permettent de préserver le contexte de raisonnement lors d'interactions en plusieurs étapes.
Lorsque vous utilisez des modèles de réflexion (comme 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, les parties text ou functionCall).
En règle générale, si vous recevez une signature de réflexion dans une réponse de modèle, vous devez la renvoyer exactement telle qu'elle a été reçue lorsque vous envoyez l'historique de la conversation au tour suivant.
Lorsque vous utilisez des modèles Gemini 3, 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).
Cela inclut l'utilisation du minimal
paramètre de niveau de réflexion pour Gemini 3
Flash.
Fonctionnement
Le graphique ci-dessous illustre la signification des termes "tour" et "étape" tels qu'ils s'appliquent à l'appel de fonction dans l'API Gemini. Un "tour" est 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 des appels de fonction pour les modèles Gemini 3. Pour connaître les différences avec la version 2.5, consultez la section Comportement du modèle.
Gemini 3 renvoie des signatures de réflexion pour toutes les réponses de modèle (réponses de l'API) avec un appel de fonction. Les signatures de réflexion s'affichent dans les cas suivants :
- En cas d'appels de fonction parallèles, la première partie d'appel de fonction renvoyée par la réponse du modèle comporte une signature de réflexion.
- En cas d'appels de fonction séquentiels (en plusieurs étapes), chaque appel de fonction comporte une signature, et vous devez renvoyer toutes les signatures.
- Les réponses de modèle sans appel de fonction renvoient une signature de réflexion dans la dernière partie renvoyée par le modèle.
Le tableau suivant fournit une visualisation des appels de fonction en plusieurs étapes, combinant les définitions des tours et des étapes avec le concept de signatures présenté ci-dessus :
Tour |
Étape |
Requête utilisateur |
Réponse de 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
functionCallcontient 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èrefunctionCallpartie. Les partiesfunctionCallsuivantes de la même réponse ne contiennent pas de signature.
- Appel de fonction unique : la partie
- Exigence : vous devel renvoyer cette signature dans la partie exacte où elle a été reçue lors de l'envoi de l'historique de la conversation.
- Validation : une validation stricte est appliquée à tous les appels de fonction dans
le tour actuel . (Seul le tour actuel est requis. Nous ne validons pas les tours précédents.)
- L'API revient dans l'historique (du plus récent au plus ancien) pour trouver le message Utilisateur le plus récent contenant du contenu standard (par exemple,
text) ( qui correspond au début du tour actuel). Il ne s'agit be d'unfunctionResponse. - Tous les tours
functionCalldu modèle 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 échoue avec une erreur 400.
- L'API revient dans l'historique (du plus récent au plus ancien) pour trouver le message Utilisateur le plus récent contenant du contenu standard (par exemple,
- Si les signatures appropriées ne sont pas renvoyées, voici comment vous obtiendrez une erreur
- Modèles Gemini 3 : si vous n'incluez pas de signatures, vous obtiendrez une erreur 400. La formulation sera de la forme suivante :
- L'appel de fonction
<Function Call>dans le bloc de contenu<index of contents array>ne comporte pas dethought_signature. Par exemple, L'appel de fonctionFC1dans le bloc de contenu1.ne comporte pas dethought_signature.
- L'appel de fonction
- Modèles Gemini 3 : si vous n'incluez pas de signatures, vous obtiendrez une erreur 400. La formulation sera de la forme suivante :
Exemple d'appel de fonction séquentiel
Cette section présente un exemple d'appels de fonction multiples dans lesquels l'utilisateur pose une question complexe nécessitant plusieurs tâches.
Examinons un exemple d'appel de fonction multitours dans lequel l'utilisateur pose
une question complexe nécessitant plusieurs tâches : "Check flight status for AA100 and
book a taxi if delayed".
Tour |
Étape |
Requête utilisateur |
Réponse de 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 (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 de modèle)
{
"content": {
"role": "model",
"parts": [
{
"functionCall": {
"name": "check_flight",
"args": {
"flight": "AA100"
}
},
"thoughtSignature": "<Signature A>"
}
]
}
}
Tour 1, étape 2 (réponse utilisateur – envoi des sorties d'outil) Comme ce tour utilisateur ne contient qu'un functionResponse (pas de nouveau texte), nous sommes toujours au tour 1. Nous
devons 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>" //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 d'outil précédente.
{
"content": {
"role": "model",
"parts": [
{
"functionCall": {
"name": "book_taxi",
"args": {
"time": "10 AM"
}
},
"thoughtSignature": "<Signature B>"
}
]
}
}
Tour 1, étape 3 (utilisateur – envoi de la sortie d'outil) Pour envoyer la confirmation de réservation du taxi, nous devons inclure des signatures pour TOUS les appels de fonction de 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
Examinons un exemple d'appel de fonction parallèle dans lequel l'utilisateur demande
"Check weather in Paris and London" pour voir où le modèle effectue la validation.
Tour |
Étape |
Requête utilisateur |
Réponse de modèle |
FunctionResponse |
|---|---|---|---|---|
1 |
1 |
request1="Check the weather in Paris and London" |
FC1 ("Paris") + signature FC2 ("London") |
FR1 |
1 |
2 |
request 2 = request1 + FC1 ("Paris") + signature + FC2 ("London") |
text_output (no FCs) |
Aucun |
Le code suivant illustre la séquence du tableau ci-dessus.
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 de 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
}
}
]
}
}
Tour 1, étape 2 (réponse utilisateur – envoi des sorties d'outil) Nous devons conserver
<Signature_A> sur la première partie exactement telle qu'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>" // 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 non functionCall
Gemini peut également renvoyer des thought_signatures dans la dernière partie de la réponse dans les parties qui ne sont pas des appels de fonction.
- Comportement : la dernière partie de contenu (
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 d'agent simulés ou les 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.
Raisonnement textuel/contextuel (aucune validation)
Tour 1, étape 1 (réponse de 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
Les exemples suivants montrent comment gérer les signatures de réflexion pour une API de complétion de chat à l'aide de la compatibilité avec OpenAI.
Exemple d'appel de fonction séquentiel
Voici un exemple d'appels de fonction multiples dans lesquels l'utilisateur pose une question complexe nécessitant plusieurs tâches.
Examinons un exemple d'appel de fonction multitours dans lequel l'utilisateur demande Check flight status for AA100 and book a taxi if delayed. Vous pouvez voir ce qui se passe lorsque l'utilisateur pose une question complexe nécessitant plusieurs tâches.
Tour |
Étape |
Requête utilisateur |
Réponse de 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 décrit la séquence donnée.
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 de 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 utilisateur – envoi des sorties d'outil)
Comme ce tour utilisateur ne contient qu'un functionResponse (pas de 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 de la sortie d'outil précédente.
{
"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 de la sortie d'outil)
Pour envoyer la confirmation de réservation du taxi, nous devons inclure des signatures pour TOUS
les appels de fonction de 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
Examinons un exemple d'appel de fonction parallèle dans lequel l'utilisateur demande
"Check weather in Paris and London" pour voir où le modèle effectue la
validation.
Tour |
Étape |
Requête utilisateur |
Réponse de 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 (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 de 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 utilisateur – envoi des sorties d'outil)
Vous devez conserver <Signature_A> sur la première partie exactement telle qu'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>" //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 avec une partie d'appel de fonction dans le tour et l'étape actuels ? Dois-je fournir des parties d'appel de fonction qui n'ont pas été générées par l'API et qui ne comportent donc pas de signature de réflexion associée ?
Bien qu'il soit fortement déconseillé d'injecter des blocs d'appel de fonction personnalisés dans la requête, dans les cas où cela ne peut pas être évité (par exemple, fournir des informations au modèle sur les appels de fonction et les réponses qui ont été exécutés de manière déterministe par le client, ou transférer une trace d'un autre modèle qui n'inclut pas de signatures de réflexion), vous pouvez définir les signatures factices suivantes de
"context_engineering_is_the_way_to_go"ou"skip_thought_signature_validator"dans le champ de signature de réflexion pour ignorer la validation.Je renvoie des appels de fonction et des réponses 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 utilisateur attendue est "FC1+ signature, FC2, FR1, FR2". Si vous les entrelacez comme "FC1 + signature, FR1, FC2, FR2", l'API renvoie une erreur 400.
Lors de la diffusion en streaming, le modèle ne renvoie pas d'appel de fonction. Je ne trouve pas la signature de réflexion
Lors d'une réponse de modèle ne contenant pas de FC avec une requête de diffusion en streaming, le modèle peut renvoyer la signature de réflexion dans une partie avec une partie de contenu textuel vide. Il est conseillé d'analyser l'intégralité de la requête jusqu'à ce que le modèle renvoie le
finish_reason.
Signatures de réflexion pour différents modèles
Les modèles Gemini 3 et Gemini 2.5 se comportent différemment avec les signatures de réflexion dans les appels de fonction :
- S'il existe des appels de fonction dans une réponse,
- Gemini 3 comporte toujours la signature sur la première partie d'appel de fonction. Il est obligatoire de renvoyer cette partie.
- Gemini 2.5 comporte la signature dans la première partie (quel que soit le type). Il est facultatif de renvoyer cette partie.
- S'il n'y a pas d'appels de fonction dans une réponse,
- Gemini 3 comporte la signature sur la dernière partie si le modèle génère une réflexion.
- Gemini 2.5 ne comporte pas de signature dans aucune partie.
Pour plus de détails sur la comparaison, consultez la page Réflexion. Pour les modèles d'image Gemini 3, consultez la section Processus de réflexion du guide de génération d'images.