Introducción a las llamadas a funciones

Los modelos grandes de lenguaje (LLM) son potentes para resolver muchos tipos de problemas. Sin embargo, tienen las siguientes limitaciones:

  • Se congelan después del entrenamiento, lo que lleva a un conocimiento inactivo.
  • No pueden consultar ni modificar datos externos.

La llamada a función puede abordar estas deficiencias. A veces, la llamada a función se denomina uso de herramientas porque permite que el modelo use herramientas externas como APIs y funciones.

Cuando envías una instrucción al LLM, también le proporcionas al modelo un conjunto de herramientas que puede usar para responder a la instrucción del usuario. Por ejemplo, puedes proporcionar una función get_weather que tome un parámetro de ubicación y muestre información sobre las condiciones climáticas en esa ubicación.

Mientras se procesa una instrucción, el modelo puede elegir delegar ciertas tareas de procesamiento de datos a las funciones que identificas. El modelo no llama a las funciones directamente. En su lugar, el modelo proporciona un resultado de datos estructurados que incluye la función a la que se debe llamar y los valores de los parámetros que se deben usar. Por ejemplo, para una instrucción What is the weather like in Boston?, el modelo puede delegar el procesamiento a la función get_weather y proporcionar el valor del parámetro de ubicación Boston, MA.

Puedes usar el resultado estructurado del modelo para invocar APIs externas. Por ejemplo, podrías conectarte a una API de servicio meteorológico, proporcionar la ubicación Boston, MA y recibir información sobre la temperatura, la nubosidad y las condiciones del viento.

Luego, puedes proporcionar el resultado de la API al modelo, lo que le permite completar su respuesta a la instrucción. En el ejemplo del clima, el modelo puede proporcionar la siguiente respuesta: It is currently 38 degrees Fahrenheit in Boston, MA with partly cloudy skies.

Interacción de llamada a función 

Modelos compatibles

Los siguientes modelos proporcionan compatibilidad para las llamadas a funciones:

Modelo Versión Etapa de lanzamiento de la llamada a función Compatibilidad con llamada a función paralela Compatibilidad con llamada a función forzada
Gemini 1.0 Pro all versions Disponibilidad general No No
Gemini 1.5 Flash all versions Disponibilidad general
Gemini 1.5 Pro all versions Disponibilidad general

Casos de uso de llamada a función

Puedes usar la llamada a función para las siguientes tareas:

Caso de uso Descripción de ejemplo Vínculo del ejemplo
Realiza la integración con APIs externas Cómo obtener información meteorológica con una API meteorológica Instructivo de notebook
Convierte direcciones en coordenadas de latitud/longitud Instructivo de notebook
Convierte monedas con una API de cambio de moneda Codelab
Cómo crear chatbots avanzados Responder las preguntas de los clientes sobre productos y servicios Instructivo de notebook
Crea un asistente para responder preguntas financieras y de noticias sobre empresas Instructivo de notebook
Estructura y controla las llamadas a función Extrae entidades estructuradas de datos de registro sin procesar Instructivo de notebook
Extrae uno o varios parámetros de la entrada del usuario Instructivo de notebook
Controla las listas y las estructuras de datos anidadas en las llamadas a funciones Instructivo de notebook
Controla el comportamiento de las llamadas a función Controla las llamadas y respuestas de funciones paralelas Instructivo de notebook
Administra cuándo y a qué funciones puede llamar el modelo Instructivo de notebook
Consulta bases de datos con lenguaje natural Convierte preguntas en lenguaje natural en consultas de SQL para BigQuery App de ejemplo
Llamadas a funciones multimodales Usa imágenes, videos, audio y archivos PDF como entradas para activar llamadas a funciones Instructivo de notebook

Estos son otros casos prácticos:

  • Interpretar comandos por voz: Crea funciones que correspondan a las tareas en un vehículo. Por ejemplo, puedes crear funciones que activen la radio o el aire acondicionado. Envía archivos de audio de los comandos por voz del usuario al modelo y pídele que convierta el audio en texto y que identifique la función a la que el usuario desea llamar.

  • Automatizar los flujos de trabajo según los activadores de entorno: Crea funciones que representen procesos que se pueden automatizar. Proporciónale al modelo datos de los sensores ambientales y pídele que analice y procese los datos para determinar si uno o más de los flujos de trabajo deben activarse. Por ejemplo, un modelo podría procesar datos de temperatura en un almacén y elegir activar una función de rociador.

  • Automatizar la asignación de tickets de asistencia: Proporciónale al modelo tickets de asistencia, registros y reglas contextuales. Pídele al modelo que procese toda esta información para determinar a quién se le debe asignar el ticket. Llama a una función para asignarle el ticket a la persona que sugiere el modelo.

  • Recuperar información de una base de conocimiento: Crea funciones que recuperen artículos académicos sobre un tema determinado y los resuma. Permite que el modelo responda preguntas sobre temas académicos y proporcione citas para sus respuestas.

Cómo crear una aplicación que llame a una función

Para permitir que un usuario interactúe con el modelo y use la llamada a función, debes crear un código que realice las siguientes tareas:

  1. Configura el entorno.
  2. Definir y describir un conjunto de funciones disponibles mediante declaraciones de funciones.
  3. Enviar la instrucción de un usuario y las declaraciones de la función al modelo.
  4. Invocar una función con el resultado de datos estructurados del modelo.
  5. Proporcionar la salida de la API al modelo.

Puedes crear una aplicación que administre todas estas tareas. Esta aplicación puede ser un chatbot de texto, un agente de voz, un flujo de trabajo automatizado o cualquier otro programa.

Puedes usar la llamada a función para generar una sola respuesta de texto o admitir una sesión de chat. Las respuestas de texto ad hoc son útiles para tareas empresariales específicas, como la generación de código. Las sesiones de chat son útiles en situaciones de conversación de formato libre, en las que es probable que el usuario haga preguntas de seguimiento.

Si usas la llamada a función para generar una sola respuesta, debes proporcionar al modelo el contexto completo de la interacción. Por otro lado, si usas la llamada a función en el contexto de una sesión de chat, la sesión almacenará el contexto por ti y lo incluirá en cada solicitud de modelo. En ambos casos, Vertex AI almacena el historial de la interacción en el lado del cliente.

En esta guía, se muestra cómo puedes usar las llamadas a funciones para generar una sola respuesta de texto. Para ver un ejemplo de extremo a extremo, consulta Ejemplos de texto. Si quieres aprender a usar la llamada a función para admitir una sesión de chat, consulta Ejemplos de chat.

Paso 1: Configura tu entorno

Importa los módulos requeridos y, luego, inicializa el modelo:

Python

import vertexai
from vertexai.generative_models import (
    Content,
    FunctionDeclaration,
    GenerationConfig,
    GenerativeModel,
    Part,
    Tool,
)

# Initialize Vertex AI
# TODO(developer): Update and un-comment below lines
# PROJECT_ID = 'your-project-id'
vertexai.init(project=PROJECT_ID, location="us-central1")

# Initialize Gemini model
model = GenerativeModel(model_name="gemini-1.5-flash-002")

Paso 2: Declara un conjunto de funciones

La aplicación debe declarar un conjunto de funciones que el modelo pueda usar para procesar la instrucción.

La cantidad máxima de declaraciones de funciones que se pueden proporcionar con la solicitud es de 128.

Debes proporcionar declaraciones de funciones en un formato de esquema que sea compatible con el esquema de OpenAPI. Vertex AI ofrece asistencia limitada del esquema de OpenAPI. Los siguientes atributos son compatibles: type, nullable, required, format, description, properties, items, enum. Los siguientes atributos no son compatibles: default, optional, maximum, oneOf. Para conocer las prácticas recomendadas relacionadas con las declaraciones de funciones, incluidas sugerencias de nombres y descripciones, consulta Prácticas recomendadas.

Si usas la API de REST, especifica el esquema con JSON. Si usas el SDK de Vertex AI para Python, puedes especificar el esquema de forma manual con un diccionario de Python o automáticamente con la función auxiliar from_func.

JSON

{
  "contents": ...,
  "tools": [
    {
      "function_declarations": [
        {
          "name": "find_movies",
          "description": "find movie titles currently playing in theaters based on any description, genre, title words, etc.",
          "parameters": {
            "type": "object",
            "properties": {
              "location": {
                "type": "string",
                "description": "The city and state, e.g. San Francisco, CA or a zip code e.g. 95616"
              },
              "description": {
                "type": "string",
                "description": "Any kind of description including category or genre, title words, attributes, etc."
              }
            },
            "required": [
              "description"
            ]
          }
        },
        {
          "name": "find_theaters",
          "description": "find theaters based on location and optionally movie title which are is currently playing in theaters",
          "parameters": {
            "type": "object",
            "properties": {
              "location": {
                "type": "string",
                "description": "The city and state, e.g. San Francisco, CA or a zip code e.g. 95616"
              },
              "movie": {
                "type": "string",
                "description": "Any movie title"
              }
            },
            "required": [
              "location"
            ]
          }
        },
        {
          "name": "get_showtimes",
          "description": "Find the start times for movies playing in a specific theater",
          "parameters": {
            "type": "object",
            "properties": {
              "location": {
                "type": "string",
                "description": "The city and state, e.g. San Francisco, CA or a zip code e.g. 95616"
              },
              "movie": {
                "type": "string",
                "description": "Any movie title"
              },
              "theater": {
                "type": "string",
                "description": "Name of the theater"
              },
              "date": {
                "type": "string",
                "description": "Date for requested showtime"
              }
            },
            "required": [
              "location",
              "movie",
              "theater",
              "date"
            ]
          }
        }
      ]
    }
  ]
}

Diccionario de Python

La siguiente declaración de función toma un solo parámetro string:

function_name = "get_current_weather"
get_current_weather_func = FunctionDeclaration(
    name=function_name,
    description="Get the current weather in a given location",
    # Function parameters are specified in JSON schema format
    parameters={
        "type": "object",
        "properties": {
            "location": {"type": "string", "description": "The city name of the location for which to get the weather."}
        },
    },
)

La siguiente declaración de función toma parámetros de objetos y arrays:

extract_sale_records_func = FunctionDeclaration(
  name="extract_sale_records",
  description="Extract sale records from a document.",
  parameters={
      "type": "object",
      "properties": {
          "records": {
              "type": "array",
              "description": "A list of sale records",
              "items": {
                  "description": "Data for a sale record",
                  "type": "object",
                  "properties": {
                      "id": {"type": "integer", "description": "The unique id of the sale."},
                      "date": {"type": "string", "description": "Date of the sale, in the format of MMDDYY, e.g., 031023"},
                      "total_amount": {"type": "number", "description": "The total amount of the sale."},
                      "customer_name": {"type": "string", "description": "The name of the customer, including first name and last name."},
                      "customer_contact": {"type": "string", "description": "The phone number of the customer, e.g., 650-123-4567."},
                  },
                  "required": ["id", "date", "total_amount"],
              },
          },
      },
      "required": ["records"],
  },
)

Python desde la función

En la siguiente muestra de código, se declara una función que multiplica un array de números y usa from_func para generar el esquema FunctionDeclaration.

# Define a function. Could be a local function or you can import the requests library to call an API
def multiply_numbers(numbers):
  """
  Calculates the product of all numbers in an array.

  Args:
      numbers: An array of numbers to be multiplied.

  Returns:
      The product of all the numbers. If the array is empty, returns 1.
  """

  if not numbers:  # Handle empty array
      return 1

  product = 1
  for num in numbers:
      product *= num

  return product

multiply_number_func = FunctionDeclaration.from_func(multiply_numbers)

'''
multiply_number_func contains the following schema:

name: "multiply_numbers"
description: "Calculates the product of all numbers in an array."
parameters {
  type_: OBJECT
  properties {
    key: "numbers"
    value {
      description: "An array of numbers to be multiplied."
      title: "Numbers"
    }
  }
  required: "numbers"
  description: "Calculates the product of all numbers in an array."
  title: "multiply_numbers"
}
'''

Paso 3: Envía la instrucción y las declaraciones de funciones al modelo

Cuando el usuario proporciona un mensaje, la aplicación debe proporcionarle al modelo la instrucción del usuario y las declaraciones de la función. Para configurar cómo el modelo genera resultados, la aplicación puede proporcionar una configuración de generación. Para configurar cómo el modelo usa las declaraciones de funciones, la aplicación puede proporcionarle al modelo una configuración de herramienta.

Define la instrucción para el usuario

El siguiente es un ejemplo de una instrucción de usuario: "¿Cómo está el clima en Boston?".

El siguiente es un ejemplo de cómo puedes definir la instrucción del usuario

Python

# Define the user's prompt in a Content object that we can reuse in model calls
user_prompt_content = Content(
    role="user",
    parts=[
        Part.from_text("What is the weather like in Boston?"),
    ],
)

Para obtener prácticas recomendadas relacionadas con el mensaje del usuario, consulta Prácticas recomendadas: Instrucción del usuario.

Configuración de generación

El modelo puede generar resultados diferentes para los valores de parámetros diferentes. El parámetro de temperatura controla el grado de aleatorización en esta generación. Las temperaturas más bajas son buenas para las funciones que requieren valores de parámetros determinística, mientras que las temperaturas más altas son buenas para las funciones con parámetros que aceptan valores de parámetros más diversos o creativos. Una temperatura de 0 es determinística. En este caso, las respuestas para un mensaje determinado son, en su mayoría, deterministas, pero es posible que haya una pequeña cantidad de variación. Para obtener más información, consulta API de Gemini.

Para establecer este parámetro, envía una configuración de generación (generation_config) junto con la instrucción y las declaraciones de la función. Puedes actualizar el parámetro temperature durante una conversación de chat con la API de Vertex AI y un generation_config actualizado. Para ver un ejemplo de configuración del parámetro temperature, consulta Cómo enviar la instrucción y las declaraciones de la función.

Para obtener prácticas recomendadas relacionadas con la configuración de la generación, consulta Prácticas recomendadas: configuración de la generación.

Configuración de herramientas

Puedes colocar algunas restricciones sobre cómo el modelo debe usar las declaraciones de funciones que le proporcionas. Por ejemplo, en lugar de permitir que el modelo elija entre una respuesta de lenguaje natural y una llamada a función, puedes forzarlo para que prediga solo las llamadas a funciones (“llamadas a funciones forzadas” o “llamadas a funciones con generación controlada”). También puedes optar por proporcionar al modelo un conjunto completo de declaraciones de funciones, pero restringir sus respuestas a un subconjunto de ellas.

Para colocar estas restricciones, envía una configuración de herramienta (tool_config) junto con la instrucción y las declaraciones de funciones. En la configuración, puedes especificar uno de los siguientes modos:

Modo Descripción
AUTO El comportamiento predeterminado del modelo. El modelo decide si predecir llamadas a función o una respuesta de lenguaje natural.
ANY El modelo está restringido para predecir siempre una llamada a función. Si no se proporciona allowed_function_names, el modelo elige entre todas las declaraciones de funciones disponibles. Si se proporciona allowed_function_names, el modelo elige entre el conjunto de funciones permitidas.
NONE El modelo no debe predecir llamadas a función. Este comportamiento es equivalente a una solicitud de modelo sin ninguna declaración de función asociada.

Para obtener una lista de los modelos que admiten el modo ANY ("llamada de función forzada"), consulta modelos compatibles.

Para obtener más información, consulta API de llamada a función.

Cómo enviar la instrucción y las declaraciones de funciones

El siguiente es un ejemplo de cómo puedes enviar la instrucción y las declaraciones de función al modelo, y restringir el modelo para que prediga solo las llamadas a función get_current_weather.

Python

# Define a tool that includes some of the functions that we declared earlier
tool = Tool(
    function_declarations=[get_current_weather_func, extract_sale_records_func, multiply_number_func],
)

# Send the prompt and instruct the model to generate content using the Tool object that you just created
response = model.generate_content(
    user_prompt_content,
    generation_config=GenerationConfig(temperature=0),
    tools=[tool],
    tool_config=ToolConfig(
        function_calling_config=ToolConfig.FunctionCallingConfig(
            # ANY mode forces the model to predict only function calls
            mode=ToolConfig.FunctionCallingConfig.Mode.ANY,
            # Allowed function calls to predict when the mode is ANY. If empty, any  of
            # the provided function calls will be predicted.
            allowed_function_names=["get_current_weather"],
        )
    )
)

Si el modelo determina que necesita el resultado de una función en particular, la respuesta que recibe la aplicación del modelo contiene el nombre de la función y los valores de los parámetros con los que se debe llamar a la función.

El siguiente es un ejemplo de una respuesta de modelo a la instrucción del usuario “¿Cómo está el clima en Boston?”. El modelo propone llamar a la función get_current_weather con el parámetro Boston, MA.

candidates {
  content {
    role: "model"
    parts {
      function_call {
        name: "get_current_weather"
        args {
          fields {
            key: "location"
            value {
              string_value: "Boston, MA"
            }
          }
        }
      }
    }
  }
  ...
}

Para instrucciones como “¿Obtener detalles del clima en Nueva Delhi y San Francisco?”, el modelo puede proponer varias llamadas a función paralelas. Para obtener más información, consulta Ejemplo de llamada a función paralela.

Paso 4: Invoca una API externa

Si la aplicación recibe un nombre de función y valores de parámetros del modelo, la aplicación debe conectarse a una API externa y llamar a la función.

En el siguiente ejemplo, se usan datos sintéticos para simular una carga útil de respuesta desde una API externa:

Python

# Check the function name that the model responded with, and make an API call to an external system
if (response.candidates[0].function_calls[0].name == "get_current_weather"):
    # Extract the arguments to use in your API call
    location = response.candidates[0].function_calls[0].args["location"]

    # Here you can use your preferred method to make an API request to fetch the current weather, for example:
    # api_response = requests.post(weather_api_url, data={"location": location})

    # In this example, we'll use synthetic data to simulate a response payload from an external API
    api_response = """{ "location": "Boston, MA", "temperature": 38, "description": "Partly Cloudy",
                    "icon": "partly-cloudy", "humidity": 65, "wind": { "speed": 10, "direction": "NW" } }"""

Para conocer las prácticas recomendadas relacionadas con la invocación de APIs, consulta Prácticas recomendadas: Invocación de APIs.

Paso 5: Proporciónale al modelo el resultado de la función

Después de que una aplicación recibe una respuesta de una API externa, debe proporcionar esta respuesta al modelo. A continuación, se muestra un ejemplo de cómo puedes hacerlo con Python:

Python

response = model.generate_content(
    [
        user_prompt_content,  # User prompt
        response.candidates[0].content,  # Function call response
        Content(
            parts=[
                Part.from_function_response(
                    name="get_current_weather",
                    response={
                        "content": api_response,  # Return the API response to Gemini
                    },
                )
            ],
        ),
    ],
    tools=[weather_tool],
)
# Get the model summary response
summary = response.text

Si el modelo propuso varias llamadas a funciones paralelas, la aplicación debe proporcionar todas las respuestas al modelo. Para obtener más información, consulta Ejemplo de llamada a función paralela.

El modelo puede determinar que el resultado de otra función es necesario para responder a la instrucción. En este caso, la respuesta que recibe la aplicación del modelo contiene otro nombre de función y otro conjunto de valores del parámetro.

Si el modelo determina que la respuesta de la API es suficiente para responder a la instrucción del usuario, crea una respuesta de lenguaje natural y la muestra a la aplicación. En este caso, la aplicación debe pasar la respuesta al usuario. A continuación, se muestra un ejemplo de una respuesta:

It is currently 38 degrees Fahrenheit in Boston, MA with partly cloudy skies. The humidity is 65% and the wind is blowing at 10 mph from the northwest.

Ejemplos de llamadas a función

Ejemplos de texto

Puedes usar la llamada a función para generar una sola respuesta de texto. Las respuestas de texto ad hoc son útiles para tareas empresariales específicas, como la generación de código.

Si usas la llamada a función para generar una sola respuesta, debes proporcionar al modelo el contexto completo de la interacción. Vertex AI almacena el historial de la interacción en el lado del cliente.

Python

En este ejemplo, se muestra una situación de texto con una función y una instrucción. Usa la clase GenerativeModel y sus métodos. Si deseas obtener más información sobre el uso del SDK de Vertex AI para Python con modelos multimodales de Gemini, consulta Introducción a las clases multimodales en el SDK de Vertex AI para Python.

Python

Si deseas obtener información para instalar o actualizar el SDK de Vertex AI para Python, consulta Instala el SDK de Vertex AI para Python. Si deseas obtener más información, consulta la documentación de referencia de la API de Python.

import vertexai

from vertexai.generative_models import (
    Content,
    FunctionDeclaration,
    GenerationConfig,
    GenerativeModel,
    Part,
    Tool,
)

# TODO(developer): Update & uncomment below line
# PROJECT_ID = "your-project-id"

# Initialize Vertex AI
vertexai.init(project=PROJECT_ID, location="us-central1")

# Initialize Gemini model
model = GenerativeModel("gemini-1.5-flash-002")

# Define the user's prompt in a Content object that we can reuse in model calls
user_prompt_content = Content(
    role="user",
    parts=[
        Part.from_text("What is the weather like in Boston?"),
    ],
)

# Specify a function declaration and parameters for an API request
function_name = "get_current_weather"
get_current_weather_func = FunctionDeclaration(
    name=function_name,
    description="Get the current weather in a given location",
    # Function parameters are specified in JSON schema format
    parameters={
        "type": "object",
        "properties": {"location": {"type": "string", "description": "Location"}},
    },
)

# Define a tool that includes the above get_current_weather_func
weather_tool = Tool(
    function_declarations=[get_current_weather_func],
)

# Send the prompt and instruct the model to generate content using the Tool that you just created
response = model.generate_content(
    user_prompt_content,
    generation_config=GenerationConfig(temperature=0),
    tools=[weather_tool],
)
function_call = response.candidates[0].function_calls[0]
print(function_call)

# Check the function name that the model responded with, and make an API call to an external system
if function_call.name == function_name:
    # Extract the arguments to use in your API call
    location = function_call.args["location"]  # noqa: F841

    # Here you can use your preferred method to make an API request to fetch the current weather, for example:
    # api_response = requests.post(weather_api_url, data={"location": location})

    # In this example, we'll use synthetic data to simulate a response payload from an external API
    api_response = """{ "location": "Boston, MA", "temperature": 38, "description": "Partly Cloudy",
                    "icon": "partly-cloudy", "humidity": 65, "wind": { "speed": 10, "direction": "NW" } }"""

# Return the API response to Gemini so it can generate a model response or request another function call
response = model.generate_content(
    [
        user_prompt_content,  # User prompt
        response.candidates[0].content,  # Function call response
        Content(
            parts=[
                Part.from_function_response(
                    name=function_name,
                    response={
                        "content": api_response,  # Return the API response to Gemini
                    },
                ),
            ],
        ),
    ],
    tools=[weather_tool],
)

# Get the model response
print(response.text)
# Example response:
# The weather in Boston is partly cloudy with a temperature of 38 degrees Fahrenheit.
# The humidity is 65% and the wind is blowing from the northwest at 10 mph.

C#

En este ejemplo, se muestra una situación de texto con una función y una instrucción.

C#

Antes de probar este ejemplo, sigue las instrucciones de configuración para C# incluidas en la guía de inicio rápido de Vertex AI sobre cómo usar bibliotecas cliente. Para obtener más información, consulta la documentación de referencia de la API de Vertex AI C#.

Para autenticarte en Vertex AI, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para un entorno de desarrollo local.


using Google.Cloud.AIPlatform.V1;
using System;
using System.Threading.Tasks;
using Type = Google.Cloud.AIPlatform.V1.Type;
using Value = Google.Protobuf.WellKnownTypes.Value;

public class FunctionCalling
{
    public async Task<string> GenerateFunctionCall(
        string projectId = "your-project-id",
        string location = "us-central1",
        string publisher = "google",
        string model = "gemini-1.5-flash-001")
    {
        var predictionServiceClient = new PredictionServiceClientBuilder
        {
            Endpoint = $"{location}-aiplatform.googleapis.com"
        }.Build();

        // Define the user's prompt in a Content object that we can reuse in
        // model calls
        var userPromptContent = new Content
        {
            Role = "USER",
            Parts =
            {
                new Part { Text = "What is the weather like in Boston?" }
            }
        };

        // Specify a function declaration and parameters for an API request
        var functionName = "get_current_weather";
        var getCurrentWeatherFunc = new FunctionDeclaration
        {
            Name = functionName,
            Description = "Get the current weather in a given location",
            Parameters = new OpenApiSchema
            {
                Type = Type.Object,
                Properties =
                {
                    ["location"] = new()
                    {
                        Type = Type.String,
                        Description = "Get the current weather in a given location"
                    },
                    ["unit"] = new()
                    {
                        Type = Type.String,
                        Description = "The unit of measurement for the temperature",
                        Enum = {"celsius", "fahrenheit"}
                    }
                },
                Required = { "location" }
            }
        };

        // Send the prompt and instruct the model to generate content using the tool that you just created
        var generateContentRequest = new GenerateContentRequest
        {
            Model = $"projects/{projectId}/locations/{location}/publishers/{publisher}/models/{model}",
            GenerationConfig = new GenerationConfig
            {
                Temperature = 0f
            },
            Contents =
            {
                userPromptContent
            },
            Tools =
            {
                new Tool
                {
                    FunctionDeclarations = { getCurrentWeatherFunc }
                }
            }
        };

        GenerateContentResponse response = await predictionServiceClient.GenerateContentAsync(generateContentRequest);

        var functionCall = response.Candidates[0].Content.Parts[0].FunctionCall;
        Console.WriteLine(functionCall);

        string apiResponse = "";

        // Check the function name that the model responded with, and make an API call to an external system
        if (functionCall.Name == functionName)
        {
            // Extract the arguments to use in your API call
            string locationCity = functionCall.Args.Fields["location"].StringValue;

            // Here you can use your preferred method to make an API request to
            // fetch the current weather

            // In this example, we'll use synthetic data to simulate a response
            // payload from an external API
            apiResponse = @"{ ""location"": ""Boston, MA"",
                    ""temperature"": 38, ""description"": ""Partly Cloudy""}";
        }

        // Return the API response to Gemini so it can generate a model response or request another function call
        generateContentRequest = new GenerateContentRequest
        {
            Model = $"projects/{projectId}/locations/{location}/publishers/{publisher}/models/{model}",
            Contents =
            {
                userPromptContent, // User prompt
                response.Candidates[0].Content, // Function call response,
                new Content
                {
                    Parts =
                    {
                        new Part
                        {
                            FunctionResponse = new()
                            {
                                Name = functionName,
                                Response = new()
                                {
                                    Fields =
                                    {
                                        { "content", new Value { StringValue = apiResponse } }
                                    }
                                }
                            }
                        }
                    }
                }
            },
            Tools =
            {
                new Tool
                {
                    FunctionDeclarations = { getCurrentWeatherFunc }
                }
            }
        };

        response = await predictionServiceClient.GenerateContentAsync(generateContentRequest);

        string responseText = response.Candidates[0].Content.Parts[0].Text;
        Console.WriteLine(responseText);

        return responseText;
    }
}

Node.js

En este ejemplo, se muestra una situación de texto con una función y una instrucción.

Node.js

Antes de probar este ejemplo, sigue las instrucciones de configuración para Node.js incluidas en la guía de inicio rápido de Vertex AI sobre cómo usar bibliotecas cliente. Para obtener más información, consulta la documentación de referencia de la API de Vertex AI Node.js.

Para autenticarte en Vertex AI, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para un entorno de desarrollo local.

const {
  VertexAI,
  FunctionDeclarationSchemaType,
} = require('@google-cloud/vertexai');

const functionDeclarations = [
  {
    function_declarations: [
      {
        name: 'get_current_weather',
        description: 'get weather in a given location',
        parameters: {
          type: FunctionDeclarationSchemaType.OBJECT,
          properties: {
            location: {type: FunctionDeclarationSchemaType.STRING},
            unit: {
              type: FunctionDeclarationSchemaType.STRING,
              enum: ['celsius', 'fahrenheit'],
            },
          },
          required: ['location'],
        },
      },
    ],
  },
];

const functionResponseParts = [
  {
    functionResponse: {
      name: 'get_current_weather',
      response: {name: 'get_current_weather', content: {weather: 'super nice'}},
    },
  },
];

/**
 * TODO(developer): Update these variables before running the sample.
 */
async function functionCallingStreamContent(
  projectId = 'PROJECT_ID',
  location = 'us-central1',
  model = 'gemini-1.5-flash-001'
) {
  // Initialize Vertex with your Cloud project and location
  const vertexAI = new VertexAI({project: projectId, location: location});

  // Instantiate the model
  const generativeModel = vertexAI.getGenerativeModel({
    model: model,
  });

  const request = {
    contents: [
      {role: 'user', parts: [{text: 'What is the weather in Boston?'}]},
      {
        role: 'ASSISTANT',
        parts: [
          {
            functionCall: {
              name: 'get_current_weather',
              args: {location: 'Boston'},
            },
          },
        ],
      },
      {role: 'USER', parts: functionResponseParts},
    ],
    tools: functionDeclarations,
  };
  const streamingResp = await generativeModel.generateContentStream(request);
  for await (const item of streamingResp.stream) {
    console.log(item.candidates[0].content.parts[0].text);
  }
}

REST

En este ejemplo, se muestra una situación de texto con tres funciones y una instrucción.

En este ejemplo, debes llamar al modelo de IA generativa dos veces.

  • En la primera llamada, debes proporcionar al modelo el mensaje y las declaraciones de la función.
  • En la segunda llamada, debes proporcionar al modelo la respuesta de la API.

Primera solicitud del modelo

La solicitud debe definir una instrucción en el parámetro text. En este ejemplo, se define la siguiente instrucción: “¿Qué cines de Mountain View proyectan la película Barbie?”.

La solicitud también debe definir una herramienta (tools) con un conjunto de declaraciones de función (functionDeclarations). Estas declaraciones de funciones deben especificarse en un formato que sea compatible con el esquema de OpenAPI. En este ejemplo, se definen las siguientes funciones:

  • find_movies encuentra títulos de películas que se proyectan en cines.
  • find_theatres encuentra cines en función de la ubicación.
  • get_showtimes busca las horas de inicio de las películas que se proyectan en un cine específico.

Para obtener más información sobre los parámetros de la solicitud de modelo, consulta la API de Gemini.

Reemplaza my-project por el nombre del proyecto de Google Cloud.

Primera solicitud del modelo

PROJECT_ID=my-project
MODEL_ID=gemini-1.0-pro
API=streamGenerateContent
curl -X POST -H "Authorization: Bearer $(gcloud auth print-access-token)" -H "Content-Type: application/json"  https://us-central1-aiplatform.googleapis.com/v1/projects/${PROJECT_ID}/locations/us-central1/publishers/google/models/${MODEL_ID}:${API} -d '{
"contents": {
  "role": "user",
  "parts": {
    "text": "Which theaters in Mountain View show the Barbie movie?"
  }
},
"tools": [
  {
    "function_declarations": [
      {
        "name": "find_movies",
        "description": "find movie titles currently playing in theaters based on any description, genre, title words, etc.",
        "parameters": {
          "type": "object",
          "properties": {
            "location": {
              "type": "string",
              "description": "The city and state, e.g. San Francisco, CA or a zip code e.g. 95616"
            },
            "description": {
              "type": "string",
              "description": "Any kind of description including category or genre, title words, attributes, etc."
            }
          },
          "required": [
            "description"
          ]
        }
      },
      {
        "name": "find_theaters",
        "description": "find theaters based on location and optionally movie title which are is currently playing in theaters",
        "parameters": {
          "type": "object",
          "properties": {
            "location": {
              "type": "string",
              "description": "The city and state, e.g. San Francisco, CA or a zip code e.g. 95616"
            },
            "movie": {
              "type": "string",
              "description": "Any movie title"
            }
          },
          "required": [
            "location"
          ]
        }
      },
      {
        "name": "get_showtimes",
        "description": "Find the start times for movies playing in a specific theater",
        "parameters": {
          "type": "object",
          "properties": {
            "location": {
              "type": "string",
              "description": "The city and state, e.g. San Francisco, CA or a zip code e.g. 95616"
            },
            "movie": {
              "type": "string",
              "description": "Any movie title"
            },
            "theater": {
              "type": "string",
              "description": "Name of the theater"
            },
            "date": {
              "type": "string",
              "description": "Date for requested showtime"
            }
          },
          "required": [
            "location",
            "movie",
            "theater",
            "date"
          ]
        }
      }
    ]
  }
]
}'
  

Para el mensaje “¿Qué cines de Mountain View muestran la película de Barbie?”, el modelo podría mostrar la función find_theatres con los parámetros Barbie y Mountain View, CA.

Respuesta a la primera solicitud de modelo

[{
"candidates": [
  {
    "content": {
      "parts": [
        {
          "functionCall": {
            "name": "find_theaters",
            "args": {
              "movie": "Barbie",
              "location": "Mountain View, CA"
            }
          }
        }
      ]
    },
    "finishReason": "STOP",
    "safetyRatings": [
      {
        "category": "HARM_CATEGORY_HARASSMENT",
        "probability": "NEGLIGIBLE"
      },
      {
        "category": "HARM_CATEGORY_HATE_SPEECH",
        "probability": "NEGLIGIBLE"
      },
      {
        "category": "HARM_CATEGORY_SEXUALLY_EXPLICIT",
        "probability": "NEGLIGIBLE"
      },
      {
        "category": "HARM_CATEGORY_DANGEROUS_CONTENT",
        "probability": "NEGLIGIBLE"
      }
    ]
  }
],
"usageMetadata": {
  "promptTokenCount": 9,
  "totalTokenCount": 9
}
}]
  

Segunda solicitud de modelo

En este ejemplo, se usan datos sintéticos en lugar de llamar a la API externa. Hay dos resultados, cada uno con dos parámetros (name y address):

  1. name: AMC Mountain View 16, address: 2000 W El Camino Real, Mountain View, CA 94040
  2. name: Regal Edwards 14, address: 245 Castro St, Mountain View, CA 94040

Reemplaza my-project por el nombre del proyecto de Google Cloud.

Segunda solicitud de modelo

PROJECT_ID=my-project
MODEL_ID=gemini-1.0-pro
API=streamGenerateContent
curl -X POST -H "Authorization: Bearer $(gcloud auth print-access-token)" -H "Content-Type: application/json"  https://us-central1-aiplatform.googleapis.com/v1/projects/${PROJECT_ID}/locations/us-central1/publishers/google/models/${MODEL_ID}:${API} -d '{
"contents": [{
  "role": "user",
  "parts": [{
    "text": "Which theaters in Mountain View show the Barbie movie?"
  }]
}, {
  "role": "model",
  "parts": [{
    "functionCall": {
      "name": "find_theaters",
      "args": {
        "location": "Mountain View, CA",
        "movie": "Barbie"
      }
    }
  }]
}, {
  "parts": [{
    "functionResponse": {
      "name": "find_theaters",
      "response": {
        "name": "find_theaters",
        "content": {
          "movie": "Barbie",
          "theaters": [{
            "name": "AMC Mountain View 16",
            "address": "2000 W El Camino Real, Mountain View, CA 94040"
          }, {
            "name": "Regal Edwards 14",
            "address": "245 Castro St, Mountain View, CA 94040"
          }]
        }
      }
    }
  }]
}],
"tools": [{
  "functionDeclarations": [{
    "name": "find_movies",
    "description": "find movie titles currently playing in theaters based on any description, genre, title words, etc.",
    "parameters": {
      "type": "OBJECT",
      "properties": {
        "location": {
          "type": "STRING",
          "description": "The city and state, e.g. San Francisco, CA or a zip code e.g. 95616"
        },
        "description": {
          "type": "STRING",
          "description": "Any kind of description including category or genre, title words, attributes, etc."
        }
      },
      "required": ["description"]
    }
  }, {
    "name": "find_theaters",
    "description": "find theaters based on location and optionally movie title which are is currently playing in theaters",
    "parameters": {
      "type": "OBJECT",
      "properties": {
        "location": {
          "type": "STRING",
          "description": "The city and state, e.g. San Francisco, CA or a zip code e.g. 95616"
        },
        "movie": {
          "type": "STRING",
          "description": "Any movie title"
        }
      },
      "required": ["location"]
    }
  }, {
    "name": "get_showtimes",
    "description": "Find the start times for movies playing in a specific theater",
    "parameters": {
      "type": "OBJECT",
      "properties": {
        "location": {
          "type": "STRING",
          "description": "The city and state, e.g. San Francisco, CA or a zip code e.g. 95616"
        },
        "movie": {
          "type": "STRING",
          "description": "Any movie title"
        },
        "theater": {
          "type": "STRING",
          "description": "Name of the theater"
        },
        "date": {
          "type": "STRING",
          "description": "Date for requested showtime"
        }
      },
      "required": ["location", "movie", "theater", "date"]
    }
  }]
}]
}'
  

La respuesta del modelo podría ser similar a la siguiente:

Respuesta a la segunda solicitud de modelo

{
"candidates": [
  {
    "content": {
      "parts": [
        {
          "text": " OK. Barbie is showing in two theaters in Mountain View, CA: AMC Mountain View 16 and Regal Edwards 14."
        }
      ]
    }
  }
],
"usageMetadata": {
  "promptTokenCount": 9,
  "candidatesTokenCount": 27,
  "totalTokenCount": 36
}
}
  

Ejemplos de chat

Puedes usar la llamada a función para admitir una sesión de chat. Las sesiones de chat son útiles en situaciones de conversación de formato libre, en las que es probable que el usuario haga preguntas de seguimiento.

Si usas la llamada a función en el contexto de una sesión de chat, la sesión almacena el contexto por ti y lo incluye en cada solicitud de modelo. Vertex AI almacena el historial de la interacción en el lado del cliente.

Python

En este ejemplo, se muestra una situación de chat con dos funciones y dos prompts secuenciales. Usa la clase GenerativeModel y sus métodos. Si deseas obtener más información sobre el uso del SDK de Vertex AI para Python con modelos multimodales, consulta Introducción a las clases multimodales en el SDK de Vertex AI para Python.

Si deseas obtener información para instalar o actualizar el SDK de Python, consulta Instala el SDK de Vertex AI para Python. Si deseas obtener más información, consulta la documentación de referencia de la API de Python.

import vertexai

from vertexai.generative_models import (
    FunctionDeclaration,
    GenerationConfig,
    GenerativeModel,
    Part,
    Tool,
)

# TODO(developer): Update & uncomment below line
# PROJECT_ID = "your-project-id"

# Initialize Vertex AI
vertexai.init(project=PROJECT_ID, location="us-central1")

# Specify a function declaration and parameters for an API request
get_product_sku = "get_product_sku"
get_product_sku_func = FunctionDeclaration(
    name=get_product_sku,
    description="Get the SKU for a product",
    # Function parameters are specified in OpenAPI JSON schema format
    parameters={
        "type": "object",
        "properties": {
            "product_name": {"type": "string", "description": "Product name"}
        },
    },
)

# Specify another function declaration and parameters for an API request
get_store_location_func = FunctionDeclaration(
    name="get_store_location",
    description="Get the location of the closest store",
    # Function parameters are specified in JSON schema format
    parameters={
        "type": "object",
        "properties": {"location": {"type": "string", "description": "Location"}},
    },
)

# Define a tool that includes the above functions
retail_tool = Tool(
    function_declarations=[
        get_product_sku_func,
        get_store_location_func,
    ],
)

# Initialize Gemini model
model = GenerativeModel(
    model_name="gemini-1.5-flash-001",
    generation_config=GenerationConfig(temperature=0),
    tools=[retail_tool],
)

# Start a chat session
chat = model.start_chat()

# Send a prompt for the first conversation turn that should invoke the get_product_sku function
response = chat.send_message("Do you have the Pixel 8 Pro in stock?")

function_call = response.candidates[0].function_calls[0]
print(function_call)

# Check the function name that the model responded with, and make an API call to an external system
if function_call.name == get_product_sku:
    # Extract the arguments to use in your API call
    product_name = function_call.args["product_name"]  # noqa: F841

    # Here you can use your preferred method to make an API request to retrieve the product SKU, as in:
    # api_response = requests.post(product_api_url, data={"product_name": product_name})

    # In this example, we'll use synthetic data to simulate a response payload from an external API
    api_response = {"sku": "GA04834-US", "in_stock": "Yes"}

# Return the API response to Gemini, so it can generate a model response or request another function call
response = chat.send_message(
    Part.from_function_response(
        name=get_product_sku,
        response={
            "content": api_response,
        },
    ),
)
# Extract the text from the model response
print(response.text)

# Send a prompt for the second conversation turn that should invoke the get_store_location function
response = chat.send_message(
    "Is there a store in Mountain View, CA that I can visit to try it out?"
)

function_call = response.candidates[0].function_calls[0]
print(function_call)

# Check the function name that the model responded with, and make an API call to an external system
if function_call.name == "get_store_location":
    # Extract the arguments to use in your API call
    location = function_call.args["location"]  # noqa: F841

    # Here you can use your preferred method to make an API request to retrieve store location closest to the user, as in:
    # api_response = requests.post(store_api_url, data={"location": location})

    # In this example, we'll use synthetic data to simulate a response payload from an external API
    api_response = {"store": "2000 N Shoreline Blvd, Mountain View, CA 94043, US"}

# Return the API response to Gemini, so it can generate a model response or request another function call
response = chat.send_message(
    Part.from_function_response(
        name="get_store_location",
        response={
            "content": api_response,
        },
    ),
)

# Extract the text from the model response
print(response.text)
# Example response:
# name: "get_product_sku"
# args {
#   fields { key: "product_name" value {string_value: "Pixel 8 Pro" }
#   }
# }
# Yes, we have the Pixel 8 Pro in stock.
# name: "get_store_location"
# args {
#   fields { key: "location" value { string_value: "Mountain View, CA" }
#   }
# }
# Yes, there is a store located at 2000 N Shoreline Blvd, Mountain View, CA 94043, US.

Java

Antes de probar este ejemplo, sigue las instrucciones de configuración para Java incluidas en la guía de inicio rápido de Vertex AI sobre cómo usar bibliotecas cliente. Para obtener más información, consulta la documentación de referencia de la API de Vertex AI Java.

Para autenticarte en Vertex AI, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para un entorno de desarrollo local.

import com.google.cloud.vertexai.VertexAI;
import com.google.cloud.vertexai.api.Content;
import com.google.cloud.vertexai.api.FunctionDeclaration;
import com.google.cloud.vertexai.api.GenerateContentResponse;
import com.google.cloud.vertexai.api.Schema;
import com.google.cloud.vertexai.api.Tool;
import com.google.cloud.vertexai.api.Type;
import com.google.cloud.vertexai.generativeai.ChatSession;
import com.google.cloud.vertexai.generativeai.ContentMaker;
import com.google.cloud.vertexai.generativeai.GenerativeModel;
import com.google.cloud.vertexai.generativeai.PartMaker;
import com.google.cloud.vertexai.generativeai.ResponseHandler;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;

public class FunctionCalling {
  public static void main(String[] args) throws IOException {
    // TODO(developer): Replace these variables before running the sample.
    String projectId = "your-google-cloud-project-id";
    String location = "us-central1";
    String modelName = "gemini-1.5-flash-001";

    String promptText = "What's the weather like in Paris?";

    whatsTheWeatherLike(projectId, location, modelName, promptText);
  }

  // A request involving the interaction with an external tool
  public static String whatsTheWeatherLike(String projectId, String location,
                                           String modelName, String promptText)
      throws IOException {
    // Initialize client that will be used to send requests.
    // This client only needs to be created once, and can be reused for multiple requests.
    try (VertexAI vertexAI = new VertexAI(projectId, location)) {

      FunctionDeclaration functionDeclaration = FunctionDeclaration.newBuilder()
          .setName("getCurrentWeather")
          .setDescription("Get the current weather in a given location")
          .setParameters(
              Schema.newBuilder()
                  .setType(Type.OBJECT)
                  .putProperties("location", Schema.newBuilder()
                      .setType(Type.STRING)
                      .setDescription("location")
                      .build()
                  )
                  .addRequired("location")
                  .build()
          )
          .build();

      System.out.println("Function declaration:");
      System.out.println(functionDeclaration);

      // Add the function to a "tool"
      Tool tool = Tool.newBuilder()
          .addFunctionDeclarations(functionDeclaration)
          .build();

      // Start a chat session from a model, with the use of the declared function.
      GenerativeModel model = new GenerativeModel(modelName, vertexAI)
          .withTools(Arrays.asList(tool));
      ChatSession chat = model.startChat();

      System.out.println(String.format("Ask the question: %s", promptText));
      GenerateContentResponse response = chat.sendMessage(promptText);

      // The model will most likely return a function call to the declared
      // function `getCurrentWeather` with "Paris" as the value for the
      // argument `location`.
      System.out.println("\nPrint response: ");
      System.out.println(ResponseHandler.getContent(response));

      // Provide an answer to the model so that it knows what the result
      // of a "function call" is.
      Content content =
          ContentMaker.fromMultiModalData(
              PartMaker.fromFunctionResponse(
                  "getCurrentWeather",
                  Collections.singletonMap("currentWeather", "sunny")));
      System.out.println("Provide the function response: ");
      System.out.println(content);
      response = chat.sendMessage(content);

      // See what the model replies now
      System.out.println("Print response: ");
      String finalAnswer = ResponseHandler.getText(response);
      System.out.println(finalAnswer);

      return finalAnswer;
    }
  }
}

Go

Antes de probar este ejemplo, sigue las instrucciones de configuración para Go incluidas en la guía de inicio rápido de Vertex AI sobre cómo usar bibliotecas cliente. Para obtener más información, consulta la documentación de referencia de la API de Vertex AI Go.

Para autenticarte en Vertex AI, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para un entorno de desarrollo local.

import (
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"io"

	"cloud.google.com/go/vertexai/genai"
)

// functionCallsChat opens a chat session and sends 4 messages to the model:
// - convert a first text question into a structured function call request
// - convert the first structured function call response into natural language
// - convert a second text question into a structured function call request
// - convert the second structured function call response into natural language
func functionCallsChat(w io.Writer, projectID, location, modelName string) error {
	// location := "us-central1"
	// modelName := "gemini-1.5-flash-001"
	ctx := context.Background()
	client, err := genai.NewClient(ctx, projectID, location)
	if err != nil {
		return fmt.Errorf("unable to create client: %w", err)
	}
	defer client.Close()

	model := client.GenerativeModel(modelName)

	// Build an OpenAPI schema, in memory
	paramsProduct := &genai.Schema{
		Type: genai.TypeObject,
		Properties: map[string]*genai.Schema{
			"productName": {
				Type:        genai.TypeString,
				Description: "Product name",
			},
		},
	}
	fundeclProductInfo := &genai.FunctionDeclaration{
		Name:        "getProductSku",
		Description: "Get the SKU for a product",
		Parameters:  paramsProduct,
	}
	paramsStore := &genai.Schema{
		Type: genai.TypeObject,
		Properties: map[string]*genai.Schema{
			"location": {
				Type:        genai.TypeString,
				Description: "Location",
			},
		},
	}
	fundeclStoreLocation := &genai.FunctionDeclaration{
		Name:        "getStoreLocation",
		Description: "Get the location of the closest store",
		Parameters:  paramsStore,
	}
	model.Tools = []*genai.Tool{
		{FunctionDeclarations: []*genai.FunctionDeclaration{
			fundeclProductInfo,
			fundeclStoreLocation,
		}},
	}
	model.SetTemperature(0.0)

	chat := model.StartChat()

	// Send a prompt for the first conversation turn that should invoke the getProductSku function
	prompt := "Do you have the Pixel 8 Pro in stock?"
	fmt.Fprintf(w, "Question: %s\n", prompt)
	resp, err := chat.SendMessage(ctx, genai.Text(prompt))
	if err != nil {
		return err
	}
	if len(resp.Candidates) == 0 ||
		len(resp.Candidates[0].Content.Parts) == 0 {
		return errors.New("empty response from model")
	}

	// The model has returned a function call to the declared function `getProductSku`
	// with a value for the argument `productName`.
	jsondata, err := json.MarshalIndent(resp.Candidates[0].Content.Parts[0], "\t", "  ")
	if err != nil {
		return fmt.Errorf("json.MarshalIndent: %w", err)
	}
	fmt.Fprintf(w, "function call generated by the model:\n\t%s\n", string(jsondata))

	// Create a function call response, to simulate the result of a call to a
	// real service
	funresp := &genai.FunctionResponse{
		Name: "getProductSku",
		Response: map[string]any{
			"sku":      "GA04834-US",
			"in_stock": "yes",
		},
	}
	jsondata, err = json.MarshalIndent(funresp, "\t", "  ")
	if err != nil {
		return fmt.Errorf("json.MarshalIndent: %w", err)
	}
	fmt.Fprintf(w, "function call response sent to the model:\n\t%s\n\n", string(jsondata))

	// And provide the function call response to the model
	resp, err = chat.SendMessage(ctx, funresp)
	if err != nil {
		return err
	}
	if len(resp.Candidates) == 0 ||
		len(resp.Candidates[0].Content.Parts) == 0 {
		return errors.New("empty response from model")
	}

	// The model has taken the function call response as input, and has
	// reformulated the response to the user.
	jsondata, err = json.MarshalIndent(resp.Candidates[0].Content.Parts[0], "\t", "  ")
	if err != nil {
		return fmt.Errorf("json.MarshalIndent: %w", err)
	}
	fmt.Fprintf(w, "Answer generated by the model:\n\t%s\n\n", string(jsondata))

	// Send a prompt for the second conversation turn that should invoke the getStoreLocation function
	prompt2 := "Is there a store in Mountain View, CA that I can visit to try it out?"
	fmt.Fprintf(w, "Question: %s\n", prompt)

	resp, err = chat.SendMessage(ctx, genai.Text(prompt2))
	if err != nil {
		return err
	}
	if len(resp.Candidates) == 0 ||
		len(resp.Candidates[0].Content.Parts) == 0 {
		return errors.New("empty response from model")
	}

	// The model has returned a function call to the declared function `getStoreLocation`
	// with a value for the argument `store`.
	jsondata, err = json.MarshalIndent(resp.Candidates[0].Content.Parts[0], "\t", "  ")
	if err != nil {
		return fmt.Errorf("json.MarshalIndent: %w", err)
	}
	fmt.Fprintf(w, "function call generated by the model:\n\t%s\n", string(jsondata))

	// Create a function call response, to simulate the result of a call to a
	// real service
	funresp = &genai.FunctionResponse{
		Name: "getStoreLocation",
		Response: map[string]any{
			"store": "2000 N Shoreline Blvd, Mountain View, CA 94043, US",
		},
	}
	jsondata, err = json.MarshalIndent(funresp, "\t", "  ")
	if err != nil {
		return fmt.Errorf("json.MarshalIndent: %w", err)
	}
	fmt.Fprintf(w, "function call response sent to the model:\n\t%s\n\n", string(jsondata))

	// And provide the function call response to the model
	resp, err = chat.SendMessage(ctx, funresp)
	if err != nil {
		return err
	}
	if len(resp.Candidates) == 0 ||
		len(resp.Candidates[0].Content.Parts) == 0 {
		return errors.New("empty response from model")
	}

	// The model has taken the function call response as input, and has
	// reformulated the response to the user.
	jsondata, err = json.MarshalIndent(resp.Candidates[0].Content.Parts[0], "\t", "  ")
	if err != nil {
		return fmt.Errorf("json.MarshalIndent: %w", err)
	}
	fmt.Fprintf(w, "Answer generated by the model:\n\t%s\n\n", string(jsondata))
	return nil
}

Node.js

Antes de probar este ejemplo, sigue las instrucciones de configuración para Node.js incluidas en la guía de inicio rápido de Vertex AI sobre cómo usar bibliotecas cliente. Para obtener más información, consulta la documentación de referencia de la API de Vertex AI Node.js.

Para autenticarte en Vertex AI, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para un entorno de desarrollo local.

const {
  VertexAI,
  FunctionDeclarationSchemaType,
} = require('@google-cloud/vertexai');

const functionDeclarations = [
  {
    function_declarations: [
      {
        name: 'get_current_weather',
        description: 'get weather in a given location',
        parameters: {
          type: FunctionDeclarationSchemaType.OBJECT,
          properties: {
            location: {type: FunctionDeclarationSchemaType.STRING},
            unit: {
              type: FunctionDeclarationSchemaType.STRING,
              enum: ['celsius', 'fahrenheit'],
            },
          },
          required: ['location'],
        },
      },
    ],
  },
];

const functionResponseParts = [
  {
    functionResponse: {
      name: 'get_current_weather',
      response: {name: 'get_current_weather', content: {weather: 'super nice'}},
    },
  },
];

/**
 * TODO(developer): Update these variables before running the sample.
 */
async function functionCallingStreamChat(
  projectId = 'PROJECT_ID',
  location = 'us-central1',
  model = 'gemini-1.5-flash-001'
) {
  // Initialize Vertex with your Cloud project and location
  const vertexAI = new VertexAI({project: projectId, location: location});

  // Instantiate the model
  const generativeModel = vertexAI.getGenerativeModel({
    model: model,
  });

  // Create a chat session and pass your function declarations
  const chat = generativeModel.startChat({
    tools: functionDeclarations,
  });

  const chatInput1 = 'What is the weather in Boston?';

  // This should include a functionCall response from the model
  const result1 = await chat.sendMessageStream(chatInput1);
  for await (const item of result1.stream) {
    console.log(item.candidates[0]);
  }
  await result1.response;

  // Send a follow up message with a FunctionResponse
  const result2 = await chat.sendMessageStream(functionResponseParts);
  for await (const item of result2.stream) {
    console.log(item.candidates[0]);
  }

  // This should include a text response from the model using the response content
  // provided above
  const response2 = await result2.response;
  console.log(response2.candidates[0].content.parts[0].text);
}

Ejemplo de llamada a función paralela

Para instrucciones como “¿Obtener detalles del clima en Nueva Delhi y San Francisco?”, el modelo puede proponer varias llamadas a función paralelas. Para obtener una lista de los modelos que admiten llamadas a funciones en paralelo, consulta Modelos compatibles.

REST

En este ejemplo, se muestra una situación con una función get_current_weather. La instrucción del usuario es "¿Obtener detalles del clima en Nueva Delhi y San Francisco?". El modelo propone dos llamadas a función get_current_weather paralelas: una con el parámetro New Delhi y la otra con el parámetro San Francisco.

Para obtener más información sobre los parámetros de la solicitud de modelo, consulta la API de Gemini.

{
"candidates": [
  {
    "content": {
      "role": "model",
      "parts": [
        {
          "functionCall": {
            "name": "get_current_weather",
            "args": {
              "location": "New Delhi"
            }
          }
        },
        {
          "functionCall": {
            "name": "get_current_weather",
            "args": {
              "location": "San Francisco"
            }
          }
        }
      ]
    },
    ...
  }
],
...
}

El siguiente comando demuestra cómo puedes proporcionar el resultado de la función al modelo. Reemplaza my-project por el nombre del proyecto de Google Cloud.

Solicitud de modelo

PROJECT_ID=my-project
MODEL_ID=gemini-1.5-pro-002
VERSION="v1"
LOCATION="us-central1"
ENDPOINT=${LOCATION}-aiplatform.googleapis.com
API="generateContent"
curl -X POST -H "Authorization: Bearer $(gcloud auth print-access-token)" -H "Content-Type: application/json"  https://${ENDPOINT}/${VERSION}/projects/${PROJECT_ID}/locations/${LOCATION}/publishers/google/models/${MODEL_ID}:${API} -d '{
"contents": [
    {
        "role": "user",
        "parts": {
            "text": "What is difference in temperature in New Delhi and San Francisco?"
        }
    },
    {
        "role": "model",
        "parts": [
            {
                "functionCall": {
                    "name": "get_current_weather",
                    "args": {
                        "location": "New Delhi"
                    }
                }
            },
            {
                "functionCall": {
                    "name": "get_current_weather",
                    "args": {
                        "location": "San Francisco"
                    }
                }
            }
        ]
    },
    {
        "role": "user",
        "parts": [
            {
                "functionResponse": {
                    "name": "get_current_weather",
                    "response": {
                        "temperature": 30.5,
                        "unit": "C"
                    }
                }
            },
            {
                "functionResponse": {
                    "name": "get_current_weather",
                    "response": {
                        "temperature": 20,
                        "unit": "C"
                    }
                }
            }
        ]
    }
],
"tools": [
    {
        "function_declarations": [
            {
                "name": "get_current_weather",
                "description": "Get the current weather in a specific location",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "location": {
                            "type": "string",
                            "description": "The city and state, e.g. San Francisco, CA or a zip code e.g. 95616"
                        }
                    },
                    "required": [
                        "location"
                    ]
                }
            }
        ]
    }
]
}'
  

La respuesta de lenguaje natural que crea el modelo es similar a la siguiente:

Respuesta del modelo

[
{
    "candidates": [
        {
            "content": {
                "parts": [
                    {
                        "text": "The temperature in New Delhi is 30.5C and the temperature in San Francisco is 20C. The difference is 10.5C. \n"
                    }
                ]
            },
            "finishReason": "STOP",
            ...
        }
    ]
    ...
}
]
  

Python

import vertexai

from vertexai.generative_models import (
    FunctionDeclaration,
    GenerativeModel,
    Part,
    Tool,
)

# TODO(developer): Update & uncomment below line
# PROJECT_ID = "your-project-id"

# Initialize Vertex AI
vertexai.init(project=PROJECT_ID, location="us-central1")

# Specify a function declaration and parameters for an API request
function_name = "get_current_weather"
get_current_weather_func = FunctionDeclaration(
    name=function_name,
    description="Get the current weather in a given location",
    parameters={
        "type": "object",
        "properties": {
            "location": {
                "type": "string",
                "description": "The location for which to get the weather. \
                  It can be a city name, a city name and state, or a zip code. \
                  Examples: 'San Francisco', 'San Francisco, CA', '95616', etc.",
            },
        },
    },
)

# In this example, we'll use synthetic data to simulate a response payload from an external API
def mock_weather_api_service(location: str) -> str:
    temperature = 25 if location == "San Francisco" else 35
    return f"""{{ "location": "{location}", "temperature": {temperature}, "unit": "C" }}"""

# Define a tool that includes the above function
tools = Tool(
    function_declarations=[get_current_weather_func],
)

# Initialize Gemini model
model = GenerativeModel(
    model_name="gemini-1.5-pro-002",
    tools=[tools],
)

# Start a chat session
chat_session = model.start_chat()
response = chat_session.send_message(
    "Get weather details in New Delhi and San Francisco?"
)

function_calls = response.candidates[0].function_calls
print("Suggested finction calls:\n", function_calls)

if function_calls:
    api_responses = []
    for func in function_calls:
        if func.name == function_name:
            api_responses.append(
                {
                    "content": mock_weather_api_service(
                        location=func.args["location"]
                    )
                }
            )

    # Return the API response to Gemini
    response = chat_session.send_message(
        [
            Part.from_function_response(
                name="get_current_weather",
                response=api_responses[0],
            ),
            Part.from_function_response(
                name="get_current_weather",
                response=api_responses[1],
            ),
        ],
    )

    print(response.text)
    # Example response:
    # The current weather in New Delhi is 35°C. The current weather in San Francisco is 25°C.

Prácticas recomendadas para las llamadas a función

Nombre de la función

El nombre de la función debe comenzar con una letra o un guion bajo y solo debe contener caracteres de la a a la z, de la A a la Z, del 0 al 9, guiones bajos, puntos o guiones, con una longitud máxima de 64.

Descripción de función

Escribe descripciones de funciones de forma clara y detallada. Por ejemplo, para una función book_flight_ticket, usa lo siguiente:

  • A continuación, se muestra un ejemplo de una buena descripción de función: book flight tickets after confirming users' specific requirements, such as time, departure, destination, party size and preferred airline
  • A continuación, se muestra un ejemplo de la descripción de una función incorrecta: book flight ticket

Parámetros de las funciones

Los nombres de atributos anidados y de parámetros de función deben comenzar con una letra o un guion bajo, y solo deben contener caracteres a-z, A-Z, 0-9 o guiones bajos, con una longitud máxima de 64. No uses caracteres de punto (.), guiones (-) ni espacios en los nombres de los parámetros de la función ni en los atributos anidados. En su lugar, usa caracteres de guion bajo (_) o cualquier otro carácter.

Descripciones

Escribe descripciones de parámetros claras y detalladas, incluidos detalles como tu formato o valores preferidos. Por ejemplo, para una función book_flight_ticket:

  • El siguiente es un buen ejemplo de la descripción de un parámetro departure: Use the 3 char airport code to represent the airport. For example, SJC or SFO. Don't use the city name.
  • El siguiente es un mal ejemplo de la descripción de un parámetro departure: the departure airport

Tipos

Si es posible, usa parámetros de tipos estrictos para reducir las alucinaciones del modelo. Por ejemplo, si los valores de los parámetros son de un conjunto finito, agrega un campo enum en lugar de colocar el conjunto de valores en la descripción. Si el valor del parámetro es siempre un número entero, establece el tipo en integer en lugar de number.

Instrucciones del sistema

Cuando uses funciones con parámetros de fecha, hora o ubicación, incluye la fecha, la hora o la información de ubicación actual que sea pertinente (por ejemplo, ciudad y país) en la instrucción del sistema. Esto garantiza que el modelo tenga el contexto necesario para procesar la solicitud con precisión, incluso si la instrucción del usuario carece de detalles.

Instrucción del usuario

Para obtener mejores resultados, antepone los siguientes detalles a la instrucción del usuario:

  • Contexto adicional para el modelo, por ejemplo, You are a flight API assistant to help with searching flights based on user preferences.
  • Detalles o instrucciones sobre cómo y cuándo usar las funciones; por ejemplo, Don't make assumptions on the departure or destination airports. Always use a future date for the departure or destination time.
  • Instrucciones para hacer preguntas aclaratorias si las búsquedas de los usuarios son ambiguas, por ejemplo, Ask clarifying questions if not enough information is available.

Configuración de generación

Para el parámetro de temperatura, usa 0 o algún otro valor bajo. Esto le indica al modelo que genere resultados más seguros y reduzca las alucinaciones.

Invocación a la API

Si el modelo propone la invocación de una función que enviaría un pedido, actualizaría una base de datos o tendría consecuencias significativas, valida la llamada a función con el usuario antes de ejecutarla.

Precios

El precio de la llamada a función se basa en la cantidad de caracteres dentro de las entradas y resultados de texto. Para obtener más información, consulta Certificaciones de Vertex AI.

Aquí, la entrada de texto (instrucción) se refiere a la instrucción del usuario para el turno de conversación actual, las declaraciones de función para el turno de conversación actual y el historial de la conversación. El historial de la conversación incluye las consultas, las llamadas a función y las respuestas de función de turnos de conversación anteriores. Vertex AI trunca el historial de la conversación en 32,000 caracteres.

El resultado de texto (respuesta) se refiere a las llamadas a función y las respuestas de texto para el turno de la conversación actual.

¿Qué sigue?