Instructivo sobre llamadas a funciones

Las llamadas a funciones te permiten obtener resultados de datos estructurados de los modelos generativos con mayor facilidad. Luego, puedes usar estos resultados para llamar a otras APIs y mostrar los datos de respuesta relevantes al modelo. En otras palabras, las llamadas a función te ayudan a conectar modelos generativos a sistemas externos para que el contenido generado incluya la información más actualizada y precisa.

Puedes proporcionar descripciones de funciones a los modelos de Gemini. Estas son funciones que escribes en el lenguaje de tu app (es decir, no son Google Cloud Functions). Es posible que el modelo te solicite que llames a una función y le envíes el resultado para ayudarlo a controlar tu consulta.

Si aún no lo hiciste, consulta la Introducción a las llamadas a funciones para obtener más información. También puedes probar esta función en Google Colab o ver el código de ejemplo en el repositorio del libro de recetas de la API de Gemini.

Ejemplo de API para el control de iluminación

Imagina que tienes un sistema básico de control de iluminación con una interfaz de programación de aplicaciones (API) y quieres permitir que los usuarios controlen las luces a través de solicitudes de texto simples. Puedes usar la función Llamada a función para interpretar las solicitudes de cambio de iluminación de los usuarios y traducirlas en llamadas a la API para establecer los valores de iluminación. Este sistema hipotético de control de iluminación te permite controlar el brillo de la luz y su temperatura de color, definidos como dos parámetros independientes:

Parámetro Tipo Obligatorio Descripción
brightness número Es el nivel de luz de 0 a 100. Cero es la opción de apagado y 100 es la opción de brillo máximo.
colorTemperature string Temperatura de color de la lámpara, que puede ser daylight, cool o warm.

Para simplificar, este sistema de iluminación imaginario solo tiene una luz, por lo que el usuario no tiene que especificar una habitación o una ubicación. Este es un ejemplo de solicitud JSON que podrías enviar a la API de control de iluminación para cambiar el nivel de luz al 50% con la temperatura de color de la luz del día:

{
  "brightness": "50",
  "colorTemperature": "daylight"
}

En este instructivo, se muestra cómo configurar una llamada a función para la API de Gemini para interpretar las solicitudes de iluminación de los usuarios y asignarlas a la configuración de la API para controlar los valores de brillo y temperatura de color de una luz.

Antes de comenzar: Configura tu proyecto y clave de API

Antes de llamar a la API de Gemini, debes configurar tu proyecto y tu clave de API.

Define una función de API

Crea una función que realice una solicitud a la API. Esta función se debe definir dentro del código de tu aplicación, pero podría llamar a servicios o APIs fuera de tu aplicación. La API de Gemini no llama a esta función directamente, por lo que puedes controlar cómo y cuándo se ejecuta a través del código de tu aplicación. A modo de demostración, este instructivo define una función de API simulada que solo muestra los valores de iluminación solicitados:

def set_light_values(brightness: int, color_temp: str) -> dict[str, int | str]:
    """Set the brightness and color temperature of a room light. (mock API).

    Args:
        brightness: Light level from 0 to 100. Zero is off and 100 is full brightness
        color_temp: Color temperature of the light fixture, which can be `daylight`, `cool` or `warm`.

    Returns:
        A dictionary containing the set brightness and color temperature.
    """
    return {
        "brightness": brightness,
        "colorTemperature": color_temp
    }

Cuando creas una función que el modelo usará en una llamada a función, debes incluir tantos detalles como sea posible en las descripciones de la función y los parámetros. El modelo generativo usa esta información para determinar qué función seleccionar y cómo proporcionar valores para los parámetros en la llamada a la función.

Cómo declarar funciones durante la inicialización del modelo

Cuando quieras usar llamadas a funciones, define las funciones como herramientas en GenerateContentConfig, junto con otros parámetros de configuración relacionados con la generación (como la temperatura o los tokens de detención).

from google.genai import types

config = types.GenerateContentConfig(tools=[set_light_values])

Esto también se puede definir como un diccionario de Python.

config = {
    'tools': [set_light_values],
}

Genera una llamada a función

Una vez que hayas definido tus declaraciones de funciones, puedes pedirle al modelo que las use. Puedes generar contenido directamente o con la interfaz de chat.

from google import genai

client = genai.Client()

# Generate directly with generate_content.
response = client.models.generate_content(
    model='gemini-2.0-flash',
    config=config,
    contents='Turn the lights down to a romantic level'
)
print(response.text)

# Use the chat interface.
chat = client.chats.create(model='gemini-2.0-flash', config=config)
response = chat.send_message('Turn the lights down to a romantic level')
print(response.text)

En el SDK de Python, las funciones se llaman automáticamente. Si deseas controlar cada llamada a función o realizar alguna otra lógica entre llamadas, puedes inhabilitarla a través de la marca en la configuración de generación.

from google.genai import types

# Use strong types.
config = types.GenerateContentConfig(
    tools=[set_light_values],
    automatic_function_calling=types.AutomaticFunctionCallingConfig(disable=True)
)

# Use a dictionary.
config = {
    'tools': [set_light_values],
    'automatic_function_calling': {'disable': True},
}

Llamadas a funciones en paralelo

Además de las llamadas a funciones básicas que se describieron anteriormente, también puedes llamar a varias funciones en un solo turno. En esta sección, se muestra un ejemplo de cómo puedes usar las llamadas a funciones en paralelo.

Define las herramientas.

def power_disco_ball(power: bool) -> bool:
    """Powers the spinning disco ball."""
    print(f"Disco ball is {'spinning!' if power else 'stopped.'}")
    return True


def start_music(energetic: bool, loud: bool) -> str:
    """Play some music matching the specified parameters.

    Args:
      energetic: Whether the music is energetic or not.
      loud: Whether the music is loud or not.

    Returns: The name of the song being played.
    """
    print(f"Starting music! {energetic=} {loud=}")
    return "Never gonna give you up."


def dim_lights(brightness: float) -> bool:
    """Dim the lights.

    Args:
      brightness: The brightness of the lights, 0.0 is off, 1.0 is full.
    """
    print(f"Lights are now set to {brightness:.0%}")
    return True

Ahora llama al modelo con una instrucción que pueda usar todas las herramientas especificadas. En este ejemplo, se usa un tool_config. Para obtener más información, puedes leer sobre la configuración de llamadas a función.

# Set the model up with tools.
house_fns = [power_disco_ball, start_music, dim_lights]

config = {
    # Set the available functions.
    'tools': house_fns,
    # Disable AFC so you can inspect the results first.
    'automatic_function_calling': {'disable': True},
    # Force the model to act (call 'any' function), instead of chatting.
    'tool_config': {
        'function_calling_config': {
            'mode': 'any'
        }
    }
}

# Call the API.
chat = client.chats.create(model='gemini-2.0-flash', config=config)
response = chat.send_message('Turn this place into a party!')

# Print out each of the function calls requested from this single call.
for fn in response.function_calls:
  args = ", ".join(f"{key}={val}" for key, val in fn.args.items())
  print(f"{fn.name}({args})")
power_disco_ball(power=True)
start_music(energetic=True, loud=True)
dim_lights(brightness=0.3)

Cada uno de los resultados impresos refleja una sola llamada a función que solicitó el modelo. Para enviar los resultados, incluye las respuestas en el mismo orden en que se solicitaron.

La forma más sencilla de hacerlo es dejar automatic_function_calling habilitado, de modo que el SDK controle las llamadas a función y el paso de respuestas automáticamente.

config = {
    'tools': house_fns,
}

# Call the API.
chat = client.chats.create(model='gemini-2.0-flash', config=config)
response = chat.send_message('Do everything you need to this place into party!')

print(response.text)
Disco ball is spinning!
Starting music! energetic=True loud=True
Lights are now set to 50%
Alright, I've turned on the disco ball, started playing "Never gonna give you up.", and dimmed the lights. Let's get this party started!

Asignación de tipos de datos de llamadas a función

La extracción automática de esquemas de las funciones de Python no funciona en todos los casos. Por ejemplo, no controla los casos en los que describes los campos de un objeto de diccionario anidado, pero la API sí lo admite. La API puede describir cualquiera de los siguientes tipos:

AllowedType = (int | float | bool | str | list['AllowedType'] | dict[str, AllowedType])

Para ver cómo se ve el esquema inferido, puedes convertirlo con from_callable:

from pprint import pprint

def multiply(a: float, b: float):
    """Returns a * b."""
    return a * b

fn_decl = types.FunctionDeclaration.from_callable(callable=multiply, client=client)

# to_json_dict() provides a clean JSON representation.
pprint(fn_decl.to_json_dict())
{'description': 'Returns a * b.',
 'name': 'multiply',
 'parameters': {'properties': {'a': {'type': 'NUMBER'},
                               'b': {'type': 'NUMBER'}},
                'type': 'OBJECT'}}

Estos campos JSON se asignan a los campos equivalentes del esquema de Pydantic y se pueden unir como Tool.

config = types.GenerateContentConfig(
    tools=[types.Tool(function_declarations=[fn_decl])]
)

Esta es una declaración de la misma función multiply escrita con las clases genai.types. Ten en cuenta que estas clases solo describen la función para la API, no incluyen una implementación de ella, por lo que este enfoque no funciona con las llamadas a funciones automáticas. Sin embargo, te permite definir funciones que no son funciones concretas de Python (por ejemplo, para unir una llamada HTTP remota) y te brinda más control entre las llamadas a función (por ejemplo, para cambiar function_calling_config para seguir un gráfico de estado).

tool = types.Tool(function_declarations=[
    types.FunctionDeclaration(
        name="multiply",
        description="Returns a * b.",
        parameters=types.Schema(
            properties={
                'a': types.Schema(type='NUMBER'),
                'b': types.Schema(type='NUMBER'),
            },
            type='OBJECT',
        ),
    )
])
assert tool.function_declarations[0] == fn_decl