Firmas de pensamientos

Las firmas de pensamiento son representaciones cifradas del proceso de pensamiento interno del modelo. Las firmas de pensamiento conservan el estado de razonamiento de Gemini durante las conversaciones de varios turnos y pasos, lo que puede ser útil al usar llamadas a funciones. Las respuestas pueden incluir un campo thought_signature en cualquier parte del contenido (por ejemplo, text, functionCall).

Gemini 3 Pro aplica una validación más estricta a las firmas de pensamiento que las versiones anteriores de Gemini, ya que mejoran el rendimiento del modelo en las llamadas a funciones. Para asegurarte de que el modelo mantiene el contexto completo en varias interacciones de una conversación, debes devolver las firmas de pensamiento de las respuestas anteriores en tus solicitudes posteriores. Si no se devuelve una firma de pensamiento obligatoria al usar Gemini 3 Pro, el modelo devuelve un error 400.

Gemini 3 Pro Image no aplica esta validación. Para asegurarte de que el modelo mantiene el contexto completo en varias interacciones de una conversación, debes devolver las firmas de pensamiento de las respuestas anteriores en tus solicitudes posteriores. Gemini 3 Pro Image no devuelve un error 400 si no se devuelve una firma de pensamiento. Para ver ejemplos de código relacionados con la edición de imágenes en varias fases con Gemini 3 Pro Image, consulta Ejemplo de edición de imágenes en varias fases con firmas de pensamiento.

Si usas el SDK oficial de IA generativa de Google (Python, Node.js, Go o Java) y las funciones estándar del historial de chat o añades la respuesta completa del modelo al historial, las firmas de pensamiento se gestionan automáticamente.

¿Por qué son importantes?

Cuando un modelo de pensamiento llama a una herramienta externa, pausa su proceso de razonamiento interno. La firma de pensamiento actúa como un "estado de guardado", lo que permite al modelo reanudar su cadena de pensamiento sin problemas una vez que proporciones el resultado de la función. Sin firmas de pensamiento, el modelo "olvida" los pasos de razonamiento específicos durante la fase de ejecución de la herramienta. Al devolver la firma, se asegura lo siguiente:

  • Continuidad del contexto: el modelo conserva y puede comprobar los pasos de razonamiento que justificaron la llamada a la herramienta.
  • Razonamiento complejo: permite realizar tareas de varios pasos en las que el resultado de una herramienta influye en el razonamiento de la siguiente.

Giros y pasos

Un flujo de conversación de varias interacciones con un modelo de lenguaje extenso (LLM) que usa llamadas a funciones (FC) y respuestas de funciones (FR) para generar una respuesta final. El proceso se divide en dos turnos. El turno 1 consta de tres pasos. Paso 1: La petición del usuario lleva al modelo FC1. Paso 2: El modelo recibe FR1, lo que lleva al modelo FC2. Paso 3: El modelo recibe FR2, lo que lleva al resultado final de texto del modelo para el turno 1. El turno 2 empieza con una nueva petición del usuario, que utiliza todo el contexto del turno 1 para generar el texto final del modelo correspondiente al turno 2.
Flujo de conversación de varios turnos con llamadas de funciones y respuestas.

En el contexto de las llamadas a funciones, es importante entender la diferencia entre turnos y pasos:

  • Un turno representa un intercambio completo de una conversación, que empieza con la petición de un usuario y termina cuando el modelo proporciona una respuesta final que no es una llamada a una función a esa petición.
  • Un paso se produce en un solo turno cuando el modelo invoca una función y requiere una respuesta de la función para continuar su proceso de razonamiento. Como se muestra en el diagrama, un solo turno puede implicar varios pasos si el modelo necesita llamar a varias funciones de forma secuencial para cumplir la solicitud del usuario.

Cómo usar las firmas de pensamiento

La forma más sencilla de gestionar las firmas de pensamiento es incluir todas las Parts de todos los mensajes anteriores del historial de la conversación al enviar una nueva solicitud, exactamente como las devolvió el modelo.

Si no usas uno de los SDKs de IA generativa de Google o necesitas modificar o recortar el historial de conversaciones, debes asegurarte de que las firmas de pensamientos se conserven y se envíen de nuevo al modelo.

Si usas el SDK de IA generativa de Google (opción recomendada)

Cuando se usan las funciones del historial de chat de los SDKs o se añade el objeto content del modelo de la respuesta anterior al contents de la siguiente solicitud, las firmas se gestionan automáticamente.

En el siguiente ejemplo de Python se muestra cómo se gestiona automáticamente:

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-2.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-2.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}")

Cuando se usa REST o la gestión manual

Si interactúas directamente con la API, debes implementar la gestión de firmas según las siguientes reglas de Gemini 3 Pro:

  • Llamadas a funciones:
    • Si la respuesta del modelo contiene una o varias partes functionCall, se necesita un thought_signature para que se procese correctamente.
    • En los casos de llamadas de funciones paralelas en una sola respuesta, solo la primera parte functionCall contendrá el thought_signature.
    • En los casos de llamadas a funciones secuenciales en varios pasos de un turno, cada parte functionCall contendrá un thought_signature.
    • Regla: Cuando construyas la siguiente solicitud, debes incluir el part que contiene el functionCall y su thought_signature exactamente como lo ha devuelto el modelo. En el caso de las llamadas a funciones secuenciales (de varios pasos), la validación se realiza en todos los pasos del turno actual. Si se omite un thought_signature obligatorio para la primera parte functionCall en cualquier paso del turno actual, se produce un error 400. Un turno empieza con el mensaje de usuario más reciente que no sea un functionResponse.
    • Si el modelo devuelve llamadas de función paralelas (por ejemplo, FC1+signature y FC2), tu respuesta debe contener todas las llamadas de función seguidas de todas las respuestas de función (FC1+signature, FC2, FR1 y FR2). Si se intercalan las respuestas (FC1+signature, FR1, FC2 y FR2), se producirá un error 400.
    • En raras ocasiones, es necesario proporcionar partes de functionCall que no haya generado la API y, por lo tanto, no tengan una firma de pensamiento asociada (por ejemplo, al transferir el historial de un modelo que no incluya firmas de pensamiento). Puede definir el valor thought_signature en skip_thought_signature_validator, pero esto debería ser un último recurso, ya que afectará negativamente al rendimiento del modelo.
  • Llamadas a elementos que no son funciones:
    • Si la respuesta del modelo no contiene un functionCall, puede incluir un thought_signature en el último part de la respuesta (por ejemplo, la última parte text).
    • Regla: Se recomienda incluir esta firma en la siguiente solicitud para obtener el mejor rendimiento posible, pero si no lo hace, no se producirá ningún error. Durante la transmisión, esta firma se puede devolver en una parte con contenido de texto vacío, por lo que debes analizar todas las partes hasta que el modelo devuelva finish_reason.

Sigue estas reglas para asegurarte de que se conserva el contexto del modelo:

  • Envía siempre el thought_signature de vuelta al modelo dentro de su Part original.
  • No combines un Part que contenga una firma con uno que no la tenga. Esto rompe el contexto posicional del pensamiento.
  • No combines dos Parts que contengan firmas, ya que las cadenas de firma no se pueden combinar.

Ejemplo de llamada a funciones secuencial

En el siguiente ejemplo se muestra una llamada a función de varios pasos en la que el usuario pregunta "Consulta el estado del vuelo AA100 y pide un taxi si se retrasa", lo que requiere varias tareas.

REST

En el siguiente ejemplo se muestra cómo gestionar las firmas de pensamientos en varios pasos de un flujo de trabajo de llamadas a funciones secuenciales mediante la API REST.

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 (no hay texto nuevo), seguimos en el turno 1. Debes 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>"
          }
        ]
      },
      {
        "role": "user",
        "parts": [
          {
            "functionResponse": {
              "name": "check_flight",
              "response": {
                "status": "delayed",
                "departure_time": "12 PM"
                }
              }
            }
        ]
}
Turno 1, paso 2 (respuesta del modelo)

Ahora, el modelo decide reservar un taxi basándose en 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 (respuesta del usuario: envío de la salida de la herramienta)

Para enviar la confirmación de la reserva del taxi, debes incluir firmas para todas las llamadas a funciones de este bucle (<SIGNATURE_A> y <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"
              }
              }
            }
        ]
    }
}

Completaciones de chat

En el siguiente ejemplo se muestra cómo gestionar las firmas de pensamientos en varios pasos de un flujo de trabajo de llamadas a funciones secuenciales mediante la API Chat Completions.

Turno 1, paso 1 (solicitud del usuario)
{
  "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"
          ]
        }
      }
    }
  ]
}
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 (no hay texto nuevo), seguimos en el turno 1. Debes 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>"
              }
            },
            "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 (respuesta del modelo)

Ahora, el modelo decide reservar un taxi basándose en 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 (respuesta del usuario: envío de la salida de la herramienta)

Para enviar la confirmación de la reserva del taxi, debes incluir firmas para todas las llamadas a funciones de este bucle (<SIGNATURE_A> y <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\"}"
    }
  ]

Ejemplo de llamada a funciones en paralelo

En el siguiente ejemplo se muestra una llamada a funciones en paralelo en la que el usuario pregunta "¿Qué tiempo hace en París y Londres?".

REST

En el siguiente ejemplo se muestra cómo gestionar las firmas de pensamientos en un flujo de trabajo de llamadas a funciones paralelas mediante la API REST.

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>"
      },
      {
        "functionCall": {
          "name": "get_current_temperature",
          "args": {
            "location": "London"
          }
        }
      }
    ]
  }
}
Turno 1, paso 2 (respuesta del usuario: envío de resultados de herramientas)

Debes conservar <SIGNATURE_A> en la primera parte exactamente como se ha recibido.

[
  {
    "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": {
          "name": "get_current_temperature",
          "response": {
            "temp": "12C"
          }
        }
      }
    ]
  }
]

Completaciones de chat

En el siguiente ejemplo se muestra cómo gestionar las firmas de pensamientos en un flujo de trabajo de llamadas a funciones paralelas mediante la API Chat Completions.

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>"
              }
            },
            "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"
          }
        ]
}
Turno 1, paso 2 (respuesta del usuario: envío de resultados de herramientas)

Debes conservar <SIGNATURE_A> en la primera parte exactamente como se ha recibido.

"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\"}"
    }
  ]

Firmas en functionCall Parts

Gemini también puede devolver un thought_signature en el Part final de una respuesta, aunque no haya ninguna llamada a función.

  • Comportamiento: el contenido final Part (text, inlineData, etc.) devuelto por el modelo puede contener un thought_signature.
  • Requisito: Se recomienda devolver esta firma para asegurarse de que el modelo mantiene un razonamiento de alta calidad, especialmente en el caso de instrucciones complejas o flujos de trabajo de agentes simulados.
  • Validación: la API no aplica estrictamente la validación de las firmas en las partes que no son functionCall. No recibirás un error de bloqueo si los omites, aunque el rendimiento puede verse afectado.

Ejemplo de respuesta del modelo con firma en la parte de texto:

En los siguientes ejemplos se muestra una respuesta de modelo en la que se incluye un thought_signature en un Part que no es functionCall y cómo gestionarlo en una solicitud posterior.

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." }] }
]

Ejemplo de edición de imágenes en varias interacciones con firmas de pensamiento

En los siguientes ejemplos se muestra cómo obtener y transferir firmas de pensamiento durante la creación y edición de imágenes en varias fases con Gemini 3 Pro Image.

Turno 1: Obtener la respuesta y guardar los datos que incluyen firmas de pensamiento

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))

Turno 2: pasa los datos que incluyen firmas de pensamiento

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))

Siguientes pasos