Las firmas de pensamiento son representaciones encriptadas del proceso de pensamiento interno del modelo y se usan para preservar el contexto de razonamiento en las interacciones de varios pasos.
Cuando se usan modelos de pensamiento (como las series Gemini 3 y 2.5), la API puede
mostrar un campo thoughtSignature dentro de las partes de contenido
de la respuesta (p.ej., text o functionCall partes).
Como regla general, si recibes una firma de pensamiento en una respuesta del modelo,
debes volver a pasarla exactamente como la recibiste cuando envíes el historial de conversaciones
en el siguiente turno.
Cuando uses modelos de Gemini 3, debes volver a pasar las firmas de pensamiento durante la
llamada a función. De lo contrario, recibirás un error de validación (código de estado 4xx).
Esto incluye cuando se usa la configuración de minimal
nivel de pensamiento para Gemini 3
Flash.
Cómo funciona
En el siguiente gráfico, se visualiza el significado de "turno" y "paso" en relación con la llamada a función en la API de Gemini. Un "turno" es un intercambio único y completo en una conversación entre un usuario y un modelo. Un "paso" es una acción u operación más detallada que realiza el modelo, a menudo como parte de un proceso más grande para completar un turno.

Este documento se centra en el manejo de la llamada a función para los modelos de Gemini 3. Consulta la sección sobre el comportamiento del modelo para ver las discrepancias con la versión 2.5.
Gemini 3 muestra firmas de pensamiento para todas las respuestas del modelo (respuestas de la API) con una llamada a función. Las firmas de pensamiento aparecen en los siguientes casos:
- Cuando hay llamadas a funciones paralelas, la primera parte de la llamada a función que muestra la respuesta del modelo tendrá una firma de pensamiento.
- Cuando hay llamadas a funciones secuenciales (varios pasos), cada llamada a función tendrá una firma y debes volver a pasar todas las firmas.
- Las respuestas del modelo sin una llamada a función mostrarán una firma de pensamiento dentro de la última parte que muestra el modelo.
En la siguiente tabla, se proporciona una visualización de las llamadas a funciones de varios pasos, que combina las definiciones de turnos y pasos con el concepto de firmas que se presentó anteriormente:
Turn |
Step |
User Request |
Model Response |
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
|
Ninguno |
Firmas en partes de llamadas a funciones
Cuando Gemini genera un functionCall, se basa en el thought_signature
para procesar correctamente el resultado de la herramienta en el siguiente turno.
- Comportamiento:
- Llamada a función única: La parte
functionCallcontendrá unathought_signature. - Llamadas a funciones paralelas: Si el modelo genera llamadas a funciones paralelas
en una respuesta, la
thought_signaturese adjunta solo a la primerafunctionCallparte. Las partesfunctionCallposteriores en la misma respuesta no contendrán una firma.
- Llamada a función única: La parte
- Requisito: Debes mostrar esta firma en la parte exacta en la que se recibió cuando envíes el historial de conversaciones.
- Validación: Se aplica una validación estricta para todas las llamadas a funciones dentro de
l turno actual . (Solo se requiere el turno actual; no validamos en
turnos anteriores)
- La API regresa al historial (del más reciente al más antiguo) para encontrar el mensaje
User más reciente que contenga contenido estándar (p.ej.,
text) ( que sería el inicio del turno actual). Esto no be unafunctionResponse. - Se considera que todos los turnos
functionCalldel modelo que ocurren después de ese mensaje de uso específico forman parte del turno. - La primera
functionCallparte en cada paso del turno actual debe incluir suthought_signature. - Si omites un
thought_signaturepara la primera partefunctionCallen cualquier paso del turno actual, la solicitud fallará con un error 400.
- La API regresa al historial (del más reciente al más antiguo) para encontrar el mensaje
User más reciente que contenga contenido estándar (p.ej.,
- Si no se muestran las firmas adecuadas, se producirá un error de la siguiente manera
- Modelos de Gemini 3: Si no se incluyen
firmas, se producirá un error 400. La redacción tendrá el siguiente formato:
- La llamada a función
<Function Call>en el<index of contents array>bloque de contenido no tiene unathought_signature. Por ejemplo, la llamada a funciónFC1en el bloque de contenido1.no tiene unathought_signature.
- La llamada a función
- Modelos de Gemini 3: Si no se incluyen
firmas, se producirá un error 400. La redacción tendrá el siguiente formato:
Ejemplo de llamada a función secuencial
En esta sección, se muestra un ejemplo de varias llamadas a funciones en las que el usuario hace una pregunta compleja que requiere varias tareas.
Veamos un ejemplo de llamada a función de varios turnos en el que el usuario hace
una pregunta compleja que requiere varias tareas: "Check flight status for AA100 and
book a taxi if delayed".
Turn |
Step |
User Request |
Model Response |
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 |
El siguiente código ilustra la secuencia de la tabla anterior.
Turno 1, paso 1 (solicitud del usuario)
{
"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"
]
}
}
]
}
]
}
Turno 1, paso 1 (respuesta del modelo)
{
"content": {
"role": "model",
"parts": [
{
"functionCall": {
"name": "check_flight",
"args": {
"flight": "AA100"
}
},
"thoughtSignature": "<Signature A>"
}
]
}
}
Turno 1, paso 2 (respuesta del usuario: envío de resultados de herramientas) Como este turno del usuario
solo contiene un functionResponse (sin texto nuevo), aún estamos en el turno 1. Debemos
conservar <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"
}
}
}
]
}
Turno 1, paso 2 (modelo) El modelo ahora decide reservar un taxi según el resultado de la herramienta anterior.
{
"content": {
"role": "model",
"parts": [
{
"functionCall": {
"name": "book_taxi",
"args": {
"time": "10 AM"
}
},
"thoughtSignature": "<Signature B>"
}
]
}
}
Turno 1, paso 3 (usuario: envío de resultados de herramientas) Para enviar la confirmación de la reserva de taxi, debemos incluir firmas para TODAS las llamadas a funciones en este bucle
(<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"
}
}
}
]
}
}
Ejemplo de llamada a función paralela
Veamos un ejemplo de llamada a función paralela en el que el usuario pregunta
"Check weather in Paris and London" para ver dónde el modelo realiza la validación.
Turn |
Step |
User Request |
Model Response |
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) |
Ninguno |
El siguiente código ilustra la secuencia de la tabla anterior.
Turno 1, paso 1 (solicitud del usuario)
{
"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"
]
}
}
]
}
]
}
Turno 1, paso 1 (respuesta del modelo)
{
"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
}
}
]
}
}
Turno 1, paso 2 (respuesta del usuario: envío de resultados de herramientas) Debemos conservar
<Signature_A> en la primera parte exactamente como se recibió.
[
{
"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"
}
}
}
]
}
]
Firmas en partes que no son functionCall
Gemini también puede mostrar thought_signatures en la parte final de la respuesta
en partes que no son de llamadas a funciones.
- Comportamiento: La parte final del contenido (
text, inlineData…) que muestra el modelo puede contener unathought_signature. - Recomendación: Se recomienda mostrar estas firmas para garantizar que el modelo mantenga un razonamiento de alta calidad, en especial para el seguimiento de instrucciones complejas o los flujos de trabajo de agentes simulados.
- Validación: La API no aplica la validación de forma estricta. No recibirás un error de bloqueo si los omites, aunque el rendimiento puede disminuir.
Razonamiento de texto o contextual (sin validación)
Turno 1, paso 1 (respuesta del modelo)
{
"role": "model",
"parts": [
{
"text": "I need to calculate the risk. Let me think step-by-step...",
"thought_signature": "<Signature_C>" // OPTIONAL (Recommended)
}
]
}
Turno 2, paso 1 (usuario)
[
{ "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." }] }
]
Firmas para la compatibilidad con OpenAI
En los siguientes ejemplos, se muestra cómo controlar las firmas de pensamiento para una API de finalización de chat con compatibilidad con OpenAI.
Ejemplo de llamada a función secuencial
Este es un ejemplo de varias llamadas a funciones en las que el usuario hace una pregunta compleja que requiere varias tareas.
Veamos un ejemplo de llamada a función de varios turnos en el que el usuario pregunta
Check flight status for AA100 and book a taxi if delayed y puedes ver qué
sucede cuando el usuario hace una pregunta compleja que requiere varias tareas.
Turn |
Step |
User Request |
Model Response |
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 |
El siguiente código explica la secuencia determinada.
Turno 1, paso 1 (solicitud del usuario)
{
"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"
]
}
}
}
]
}
Turno 1, paso 1 (respuesta del modelo)
{
"role": "model",
"tool_calls": [
{
"extra_content": {
"google": {
"thought_signature": "<Signature A>"
}
},
"function": {
"arguments": "{\"flight\":\"AA100\"}",
"name": "check_flight"
},
"id": "function-call-1",
"type": "function"
}
]
}
Turno 1, paso 2 (respuesta del usuario: envío de resultados de herramientas)
Como este turno del usuario solo contiene un functionResponse (sin texto nuevo), aún estamos en el turno 1 y debemos conservar <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\"}"
}
]
Turno 1, paso 2 (modelo)
El modelo ahora decide reservar un taxi según el resultado de la herramienta anterior.
{
"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"
}
]
}
Turno 1, paso 3 (usuario: envío de resultados de herramientas)
Para enviar la confirmación de la reserva de taxi, debemos incluir firmas para TODAS
las llamadas a funciones en este bucle (<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\"}"
}
]
Ejemplo de llamada a función paralela
Veamos un ejemplo de llamada a función paralela en el que el usuario pregunta
"Check weather in Paris and London" y puedes ver dónde el modelo realiza
la validación.
Turn |
Step |
User Request |
Model Response |
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 |
Este es el código para explicar la secuencia determinada.
Turno 1, paso 1 (solicitud del usuario)
{
"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"
]
}
}
]
}
]
}
Turno 1, paso 1 (respuesta del modelo)
{
"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
}
]
}
Turno 1, paso 2 (respuesta del usuario: envío de resultados de herramientas)
Debes conservar <Signature_A> en la primera parte exactamente como se recibió.
"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\"}"
}
]
Preguntas frecuentes
¿Cómo transfiero el historial de un modelo diferente a Gemini 3 con una parte de llamada a función en el turno y el paso actuales? ¿Necesito proporcionar partes de llamadas a funciones que no generó la API y, por lo tanto, no tienen una firma de pensamiento asociada?
Si bien se recomienda no insertar bloques de llamadas a funciones personalizadas en la solicitud, en los casos en que no se pueda evitar, por ejemplo, proporcionar información al modelo sobre las llamadas a funciones y las respuestas que el cliente ejecutó de forma determinista, o transferir un seguimiento de un modelo diferente que no incluya firmas de pensamiento, puedes configurar las siguientes firmas ficticias de
"context_engineering_is_the_way_to_go"o"skip_thought_signature_validator"en el campo de firma de pensamiento para omitir la validación.Devuelvo llamadas a funciones y respuestas paralelas intercaladas, y la API muestra un error 400. ¿Por qué?
Cuando la API muestra llamadas a funciones paralelas "FC1 + signature, FC2", la respuesta del usuario esperada es "FC1+ signature, FC2, FR1, FR2". Si las tienes intercaladas como "FC1 + signature, FR1, FC2, FR2", la API mostrará un error 400.
Cuando se transmite y el modelo no muestra una llamada a función, no puedo encontrar la firma de pensamiento
Durante una respuesta del modelo que no contiene una FC con una solicitud de transmisión, el modelo puede mostrar la firma de pensamiento en una parte con una parte de contenido de texto vacío parte. Se recomienda analizar toda la solicitud hasta que el
finish_reasonmuestre el modelo.
Firmas de pensamiento para diferentes modelos
Los modelos de Gemini 3 y los modelos de Gemini 2.5 se comportan de manera diferente con las firmas de pensamiento en las llamadas a funciones:
- Si hay llamadas a funciones en una respuesta,
- Gemini 3 siempre tendrá la firma en la primera parte de la llamada a función. Es obligatorio mostrar esa parte.
- Gemini 2.5 tendrá la firma en la primera parte (independientemente del tipo). Es opcional mostrar esa parte.
- Si no hay llamadas a funciones en una respuesta,
- Gemini 3 tendrá la firma en la última parte si el modelo genera un pensamiento.
- Gemini 2.5 no tendrá una firma en ninguna parte.
Consulta la página Pensamiento para obtener más detalles de comparación. Para los modelos de imágenes de Gemini 3, consulta la sección sobre el proceso de pensamiento de la guía de generación de imágenes.