Referencia de llamada a función

Las llamadas a función mejoran la capacidad de los LLM de proporcionar respuestas relevantes y contextuales.

Puedes proporcionar funciones personalizadas a un modelo de IA generativa con la API de llamada a función. El modelo no invoca estas funciones directamente, sino que genera un resultado de datos estructurados que especifica el nombre de la función y los argumentos sugeridos.

Este resultado permite llamar a API externas o sistemas de información como bases de datos, sistemas de administración de relaciones con clientes y repositorios de documentos. El LLM puede usar el resultado de la API para mejorar la calidad de la respuesta.

Para obtener más documentación conceptual sobre las llamadas a funciones, consulta Llamadas a funciones.

Modelos compatibles:

Modelo Versión
Gemini 1.5 Flash gemini-1.5-flash-002
gemini-1.5-flash-001
Gemini 1.5 Pro gemini-1.5-pro-002
gemini-1.5-pro-001
Gemini 1.0 Pro gemini-1.0-pro-001
gemini-1.0-pro-002

Limitaciones:

  • La cantidad máxima de declaraciones de funciones que se pueden proporcionar con la solicitud es de 128.
  • FunctionCallingConfig.Mode.ANY solo está disponible con los modelos Gemini 1.5 Pro y Gemini 1.5 Flash.

Ejemplo de sintaxis

Sintaxis para enviar una solicitud a la API de llamada a función.

curl

curl -X POST \
  -H "Authorization: Bearer $(gcloud auth print-access-token)" \
  -H "Content-Type: application/json" \

https://${LOCATION}-aiplatform.googleapis.com/v1/projects/${PROJECT_ID}/locations/${LOCATION}/publishers/google/models/${MODEL_ID}:generateContent \
-d '{
  "contents": [{
    ...
  }],
  "tools": [{
    "function_declarations": [
      {
        ...
      }
    ]
  }]
}'

Python

gemini_model = GenerativeModel(
    MODEL_ID,
    generation_config=generation_config,
    tools=[
        Tool(
            function_declarations=[
                FunctionDeclaration(
                    ...
                )
            ]
        )
    ],
)

Lista de parámetros

Consulta ejemplos para obtener detalles sobre la implementación.

FunctionDeclaration

Define una función para la que el modelo puede generar entradas JSON según las especificaciones de OpenAPI 3.0.

Parámetros

name

string

El nombre de la función a la que se llamará. Debe comenzar con una letra o un guion bajo. Debe tener caracteres de la A a la Z (mayúsculas o minúsculas), o números del 0 al 9, o contiene guiones bajos y guiones, con una longitud máxima de 64.

description

Opcional: string

La descripción y el propósito de la función El modelo utiliza esto para decidir cómo y si se debe llamar a la función. Para obtener mejores resultados, te recomendamos que incluyas una descripción.

parameters

Opcional: Schema

Describe los parámetros de la función en el formato de objeto de esquema JSON de OpenAPI: especificación de OpenAPI 3.0.

response

Opcional: Schema

Describe el resultado de la función en el formato de objeto de esquema JSON de OpenAPI: especificación de OpenAPI 3.0.

Para obtener más información, consulta Llamadas a funciones.

Schema

Define el formato de los datos de entrada y salida en una llamada a función según la especificación del esquema de OpenAPI 3.0.

Parámetros
tipo

string

Enum. Es el tipo de datos. Debe ser uno de los siguientes:

  • STRING
  • INTEGER
  • BOOLEAN
  • NUMBER
  • ARRAY
  • OBJECT
description

Opcional: string

Descripción de los datos.

enum

Opcional: string[]

Valores posibles del elemento de Type.STRING con formato de enumeración.

items

Opcional: Schema[]

Esquema de los elementos de Type.ARRAY

properties

Opcional: Schema

Esquema de las propiedades de Type.OBJECT

required

Opcional: string[]

Propiedades obligatorias de Type.OBJECT.

nullable

Opcional: bool

Indica si el valor puede ser null.

FunctionCallingConfig

FunctionCallingConfig controla el comportamiento del modelo y determina a qué tipo de función llamar.

Parámetros

mode

Opcional: enum/string[]

  • AUTO: Comportamiento predeterminado del modelo. El modelo puede realizar predicciones en un formulario de llamada a función o en un formulario de respuesta de lenguaje natural. El modelo decide qué formulario usar en función del contexto.
  • NONE: El modelo no realiza ninguna predicción en forma de llamadas a función.
  • ANY: El modelo se limita a predecir solo las llamadas a función. Este modo también se conoce como "llamada a función con generación controlada" o "llamada a función forzada".

allowed_function_names

Opcional: string[]

Son los nombres de las funciones a las que se llamará. Solo se establece cuando mode es ANY. Los nombres de las funciones deben coincidir con [FunctionDeclaration.name]. Con el modo establecido en ANY, el modelo predecirá una llamada a función del conjunto de nombres de funciones proporcionados.

Ejemplos

Envía una declaración de función

El siguiente ejemplo es un ejemplo básico de cómo enviar una consulta y una declaración de función al modelo.

REST

Antes de usar cualquiera de los datos de solicitud a continuación, realiza los siguientes reemplazos:

  • PROJECT_ID: El ID del proyecto.
  • LOCATION: La región para procesar la solicitud.
  • MODEL_ID: Es el ID del modelo que se está procesando.
  • ROLE: La identidad de la entidad que crea el mensaje.
  • TEXT: Es la instrucción que se enviará al modelo.
  • NAME: el nombre de la función a la que se llamará.
  • DESCRIPTION: la descripción y el propósito de la función.
  • Para otros campos, consulta la tabla Lista de parámetros.

Método HTTP y URL:

POST https://LOCATION-aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/publishers/google/models/MODEL_ID:generateContent

Cuerpo JSON de la solicitud:

{
  "contents": [{
    "role": "ROLE",
    "parts": [{
      "text": "TEXT"
    }]
  }],
  "tools": [{
    "function_declarations": [
      {
        "name": "NAME",
        "description": "DESCRIPTION",
        "parameters": {
          "type": "TYPE",
          "properties": {
            "location": {
              "type": "TYPE",
              "description": "DESCRIPTION"
            }
          },
          "required": [
            "location"
          ]
        }
      }
    ]
  }]
}

Para enviar tu solicitud, elige una de estas opciones:

curl

Guarda el cuerpo de la solicitud en un archivo llamado request.json y ejecuta el siguiente comando:

curl -X POST \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json; charset=utf-8" \
-d @request.json \
"https://LOCATION-aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/publishers/google/models/MODEL_ID:generateContent"

PowerShell

Guarda el cuerpo de la solicitud en un archivo llamado request.json y ejecuta el siguiente comando:

$cred = gcloud auth print-access-token
$headers = @{ "Authorization" = "Bearer $cred" }

Invoke-WebRequest `
-Method POST `
-Headers $headers `
-ContentType: "application/json; charset=utf-8" `
-InFile request.json `
-Uri "https://LOCATION-aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/publishers/google/models/MODEL_ID:generateContent" | Select-Object -Expand Content

Ejemplo del comando curl

PROJECT_ID=myproject
LOCATION=us-central1
MODEL_ID=gemini-1.0-pro-002

curl -X POST \
  -H "Authorization: Bearer $(gcloud auth print-access-token)" \
  -H "Content-Type: application/json" \
  https://${LOCATION}-aiplatform.googleapis.com/v1/projects/${PROJECT_ID}/locations/${LOCATION}/publishers/google/models/${MODEL_ID}:generateContent \
  -d '{
    "contents": [{
      "role": "user",
      "parts": [{
        "text": "What is the weather in Boston?"
      }]
    }],
    "tools": [{
      "functionDeclarations": [
        {
          "name": "get_current_weather",
          "description": "Get the current weather in a given 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"
            ]
          }
        }
      ]
    }]
  }'

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.

Node.js

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'],
        },
      },
    ],
  },
];

/**
 * TODO(developer): Update these variables before running the sample.
 */
async function functionCallingBasic(
  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.preview.getGenerativeModel({
    model: model,
  });

  const request = {
    contents: [
      {role: 'user', parts: [{text: 'What is the weather in Boston?'}]},
    ],
    tools: functionDeclarations,
  };
  const result = await generativeModel.generateContent(request);
  console.log(JSON.stringify(result.response.candidates[0].content));
}

Java

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

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

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

// functionCallsBasic opens a chat session and sends 2 messages to the model:
// - first, to convert a text into a structured function call request
// - second, to convert a structured function call response into natural language.
// Writes output of second call to w.
func functionCallsBasic(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
	params := &genai.Schema{
		Type: genai.TypeObject,
		Properties: map[string]*genai.Schema{
			"location": {
				Type:        genai.TypeString,
				Description: "location",
			},
		},
	}
	fundecl := &genai.FunctionDeclaration{
		Name:        "getCurrentWeather",
		Description: "Get the current weather in a given location",
		Parameters:  params,
	}
	model.Tools = []*genai.Tool{
		{FunctionDeclarations: []*genai.FunctionDeclaration{fundecl}},
	}

	chat := model.StartChat()

	resp, err := chat.SendMessage(ctx, genai.Text("What's the weather like in Boston?"))
	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 `getCurrentWeather`
	// with a value for the argument `location`.
	_, err = json.MarshalIndent(resp.Candidates[0].Content.Parts[0], "", "  ")
	if err != nil {
		return fmt.Errorf("json.MarshalIndent: %w", err)
	}

	// In this example, we'll use synthetic data to simulate a response payload from an external API
	weather := map[string]string{
		"location":    "Boston",
		"temperature": "38",
		"description": "Partly Cloudy",
		"icon":        "partly-cloudy",
		"humidity":    "65",
		"wind":        "{\"speed\": \"10\", \"direction\": \"NW\"}",
	}
	weather_json, _ := json.Marshal(weather)

	// Create a function call response, to simulate the result of a call to a
	// real service
	funresp := &genai.FunctionResponse{
		Name: "getCurrentWeather",
		Response: map[string]any{
			"currentWeather": weather_json,
		},
	}
	_, err = json.MarshalIndent(funresp, "", "  ")
	if err != nil {
		return fmt.Errorf("json.MarshalIndent: %w", err)
	}

	// 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.
	content, err := json.MarshalIndent(resp.Candidates[0].Content.Parts[0], "", "  ")
	if err != nil {
		return fmt.Errorf("json.MarshalIndent: %w", err)
	}

	fmt.Fprintf(w, "generated summary:\n%s\n", content)
	return nil
}

REST (OpenAI)

Puedes llamar a la API de Functions Calling con la biblioteca de OpenAI. Para obtener más información, consulta Cómo llamar a modelos de Vertex AI con la biblioteca de OpenAI.

Antes de usar cualquiera de los datos de solicitud a continuación, realiza los siguientes reemplazos:

  • PROJECT_ID: El ID del proyecto.
  • LOCATION: La región para procesar la solicitud.
  • MODEL_ID: Es el ID del modelo que se está procesando.

Método HTTP y URL:

POST https://LOCATION-aiplatform.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/endpoints/openapi/chat/completions

Cuerpo JSON de la solicitud:

{
  "model": "google/MODEL_ID",
  "messages": [
    {
      "role": "user",
      "content": "What is the weather in Boston?"
    }
  ],
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "get_current_weather",
        "description": "Get the current weather in a given 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"]
        }
      }
    }
  ]
}

Para enviar tu solicitud, elige una de estas opciones:

curl

Guarda el cuerpo de la solicitud en un archivo llamado request.json y ejecuta el siguiente comando:

curl -X POST \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json; charset=utf-8" \
-d @request.json \
"https://LOCATION-aiplatform.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/endpoints/openapi/chat/completions"

PowerShell

Guarda el cuerpo de la solicitud en un archivo llamado request.json y ejecuta el siguiente comando:

$cred = gcloud auth print-access-token
$headers = @{ "Authorization" = "Bearer $cred" }

Invoke-WebRequest `
-Method POST `
-Headers $headers `
-ContentType: "application/json; charset=utf-8" `
-InFile request.json `
-Uri "https://LOCATION-aiplatform.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/endpoints/openapi/chat/completions" | Select-Object -Expand Content

Python (OpenAI)

Puedes llamar a la API de Functions Calling con la biblioteca de OpenAI. Para obtener más información, consulta Cómo llamar a modelos de Vertex AI con la biblioteca de OpenAI.

import vertexai
import openai

from google.auth import default, transport

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

vertexai.init(project=PROJECT_ID, location=location)

# Programmatically get an access token
credentials, _ = default(scopes=["https://www.googleapis.com/auth/cloud-platform"])
auth_request = transport.requests.Request()
credentials.refresh(auth_request)

# # OpenAI Client
client = openai.OpenAI(
    base_url=f"https://{location}-aiplatform.googleapis.com/v1beta1/projects/{PROJECT_ID}/locations/{location}/endpoints/openapi",
    api_key=credentials.token,
)

tools = [
    {
        "type": "function",
        "function": {
            "name": "get_current_weather",
            "description": "Get the current weather in a given 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"],
            },
        },
    }
]

messages = []
messages.append(
    {
        "role": "system",
        "content": "Don't make assumptions about what values to plug into functions. Ask for clarification if a user request is ambiguous.",
    }
)
messages.append({"role": "user", "content": "What is the weather in Boston?"})

response = client.chat.completions.create(
    model="google/gemini-1.5-flash-001",
    messages=messages,
    tools=tools,
)

print("Function:", response.choices[0].message.tool_calls[0].id)
print("Arguments:", response.choices[0].message.tool_calls[0].function.arguments)
# Example response:
# Function: get_current_weather
# Arguments: {"location":"Boston"}

Envía una declaración de función con FunctionCallingConfig

En el siguiente ejemplo, se muestra cómo pasar un FunctionCallingConfig al modelo.

functionCallingConfig garantiza que el resultado del modelo siempre sea una llamada a función específica. Para configurar, haz lo siguiente:

  • Establece la llamada a función a mode en ANY.
  • Especifica los nombres de las funciones que deseas usar en allowed_function_names. Si allowed_function_names está vacío, se puede mostrar cualquiera de las funciones proporcionadas.

REST

PROJECT_ID=myproject
LOCATION=us-central1
MODEL_ID=gemini-1.5-pro-001

curl -X POST \
  -H "Authorization: Bearer $(gcloud auth print-access-token)" \
  -H "Content-Type: application/json" \
  https://${LOCATION}-aiplatform.googleapis.com/v1beta1/projects/${PROJECT_ID}/locations/${LOCATION}/publishers/google/models/${MODEL_ID}:generateContent \
  -d '{
    "contents": [{
      "role": "user",
      "parts": [{
        "text": "Do you have the White Pixel 8 Pro 128GB in stock in the US?"
      }]
    }],
    "tools": [{
      "functionDeclarations": [
        {
          "name": "get_product_sku",
          "description": "Get the available inventory for a Google products, e.g: Pixel phones, Pixel Watches, Google Home etc",
          "parameters": {
            "type": "object",
            "properties": {
              "product_name": {"type": "string", "description": "Product name"}
            }
          }
        },
        {
          "name": "get_store_location",
          "description": "Get the location of the closest store",
          "parameters": {
            "type": "object",
            "properties": {
              "location": {"type": "string", "description": "Location"}
            },
          }
        }
      ]
    }],
    "toolConfig": {
        "functionCallingConfig": {
            "mode":"ANY",
            "allowedFunctionNames": ["get_product_sku"]
      }
    },
    "generationConfig": {
      "temperature": 0.95,
      "topP": 1.0,
      "maxOutputTokens": 8192
    }
  }'

Python

import vertexai
from vertexai.preview.generative_models import (
    FunctionDeclaration,
    GenerativeModel,
    Tool,
    ToolConfig,
)

# 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_func = FunctionDeclaration(
    name="get_product_sku",
    description="Get the available inventory for a Google products, e.g: Pixel phones, Pixel Watches, Google Home etc",
    # Function parameters are specified in 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,
    ],
)

# Define a tool config for the above functions
retail_tool_config = ToolConfig(
    function_calling_config=ToolConfig.FunctionCallingConfig(
        # ANY mode forces the model to predict a function call
        mode=ToolConfig.FunctionCallingConfig.Mode.ANY,
        # List of functions that can be returned when the mode is ANY.
        # If the list is empty, any declared function can be returned.
        allowed_function_names=["get_product_sku"],
    )
)

model = GenerativeModel(
    model_name="gemini-1.5-flash-002",
    tools=[retail_tool],
    tool_config=retail_tool_config,
)
response = model.generate_content(
    "Do you have the Pixel 8 Pro 128GB in stock?",
)

print(response.candidates[0].function_calls)
# Example response:
# [
# name: "get_product_sku"
# args {
#   fields { key: "product_name" value { string_value: "Pixel 8 Pro 128GB" }}
#   }
# ]

Node.js

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

const functionDeclarations = [
  {
    function_declarations: [
      {
        name: 'get_product_sku',
        description:
          'Get the available inventory for a Google products, e.g: Pixel phones, Pixel Watches, Google Home etc',
        parameters: {
          type: FunctionDeclarationSchemaType.OBJECT,
          properties: {
            productName: {type: FunctionDeclarationSchemaType.STRING},
          },
        },
      },
      {
        name: 'get_store_location',
        description: 'Get the location of the closest store',
        parameters: {
          type: FunctionDeclarationSchemaType.OBJECT,
          properties: {
            location: {type: FunctionDeclarationSchemaType.STRING},
          },
        },
      },
    ],
  },
];

const toolConfig = {
  function_calling_config: {
    mode: 'ANY',
    allowed_function_names: ['get_product_sku'],
  },
};

const generationConfig = {
  temperature: 0.95,
  topP: 1.0,
  maxOutputTokens: 8192,
};

/**
 * TODO(developer): Update these variables before running the sample.
 */
async function functionCallingAdvanced(
  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.preview.getGenerativeModel({
    model: model,
  });

  const request = {
    contents: [
      {
        role: 'user',
        parts: [
          {text: 'Do you have the White Pixel 8 Pro 128GB in stock in the US?'},
        ],
      },
    ],
    tools: functionDeclarations,
    tool_config: toolConfig,
    generation_config: generationConfig,
  };
  const result = await generativeModel.generateContent(request);
  console.log(JSON.stringify(result.response.candidates[0].content));
}

Go

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
}

REST (OpenAI)

Puedes llamar a la API de Functions Calling con la biblioteca de OpenAI. Para obtener más información, consulta Cómo llamar a modelos de Vertex AI con la biblioteca de OpenAI.

Antes de usar cualquiera de los datos de solicitud a continuación, realiza los siguientes reemplazos:

  • PROJECT_ID: El ID del proyecto.
  • LOCATION: La región para procesar la solicitud.
  • MODEL_ID: Es el ID del modelo que se está procesando.

Método HTTP y URL:

POST https://LOCATION-aiplatform.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/endpoints/openapi/chat/completions

Cuerpo JSON de la solicitud:

{
  "model": "google/MODEL_ID",
  "messages": [
  {
    "role": "user",
    "content": "What is the weather in Boston?"
  }
],
"tools": [
  {
    "type": "function",
    "function": {
      "name": "get_current_weather",
      "description": "Get the current weather in a given 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"]
      }
    }
  }
],
"tool_choice": "auto"
}

Para enviar tu solicitud, elige una de estas opciones:

curl

Guarda el cuerpo de la solicitud en un archivo llamado request.json y ejecuta el siguiente comando:

curl -X POST \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json; charset=utf-8" \
-d @request.json \
"https://LOCATION-aiplatform.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/endpoints/openapi/chat/completions"

PowerShell

Guarda el cuerpo de la solicitud en un archivo llamado request.json y ejecuta el siguiente comando:

$cred = gcloud auth print-access-token
$headers = @{ "Authorization" = "Bearer $cred" }

Invoke-WebRequest `
-Method POST `
-Headers $headers `
-ContentType: "application/json; charset=utf-8" `
-InFile request.json `
-Uri "https://LOCATION-aiplatform.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/endpoints/openapi/chat/completions" | Select-Object -Expand Content

Python (OpenAI)

Puedes llamar a la API de Functions Calling con la biblioteca de OpenAI. Para obtener más información, consulta Cómo llamar a modelos de Vertex AI con la biblioteca de OpenAI.

import vertexai
import openai

from google.auth import default, transport

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

vertexai.init(project=PROJECT_ID, location=location)

# Programmatically get an access token
credentials, _ = default(scopes=["https://www.googleapis.com/auth/cloud-platform"])
auth_request = transport.requests.Request()
credentials.refresh(auth_request)

# OpenAI Client
client = openai.OpenAI(
    base_url=f"https://{location}-aiplatform.googleapis.com/v1beta1/projects/{PROJECT_ID}/locations/{location}/endpoints/openapi",
    api_key=credentials.token,
)

tools = [
    {
        "type": "function",
        "function": {
            "name": "get_current_weather",
            "description": "Get the current weather in a given 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"],
            },
        },
    }
]

messages = []
messages.append(
    {
        "role": "system",
        "content": "Don't make assumptions about what values to plug into functions. Ask for clarification if a user request is ambiguous.",
    }
)
messages.append({"role": "user", "content": "What is the weather in Boston, MA?"})

response = client.chat.completions.create(
    model="google/gemini-1.5-flash-002",
    messages=messages,
    tools=tools,
    tool_choice="auto",
)

print("Function:", response.choices[0].message.tool_calls[0].id)
print("Arguments:", response.choices[0].message.tool_calls[0].function.arguments)
# Example response:
# Function: get_current_weather
# Arguments: {"location":"Boston"}

¿Qué sigue?

Para obtener documentación detallada, consulta lo siguiente: