Présentation de l'appel de fonction

Les grands modèles de langage (LLM) sont capables de résoudre de nombreux types de problèmes. Ils sont toutefois restreints par les limites suivantes :

  • Ils sont figés après l'entraînement, ce qui entraîne une obsolescence.
  • Ils ne peuvent ni interroger ni modifier des données externes.

Les appels de fonction peuvent résoudre ces problèmes. L'appel de fonction est parfois appelé utilisation d'outil, car il permet au modèle d'utiliser des outils externes tels que des API et des fonctions.

Lorsque vous envoyez une requête au LLM, vous fournissez également au modèle un ensemble d'outils qu'il peut utiliser pour répondre à la requête de l'utilisateur. Par exemple, vous pouvez fournir une fonction get_weather qui utilise un paramètre de localisation et renvoie des informations sur les conditions météorologiques de ce lieu.

Lors du traitement d'une requête, le modèle peut choisir de déléguer certaines tâches de traitement de données aux fonctions que vous identifiez. Le modèle n'appelle pas directement les fonctions. Au lieu de cela, le modèle fournit une sortie de données structurées qui inclut la fonction à appeler et les valeurs de paramètres à utiliser. Par exemple, pour une requête What is the weather like in Boston?, le modèle peut déléguer le traitement à la fonction get_weather et fournir la valeur du paramètre de localisation Boston, MA.

Vous pouvez utiliser la sortie structurée du modèle pour appeler des API externes. Par exemple, vous pouvez vous connecter à une API de service météorologique, fournir la position Boston, MA et recevoir des informations sur la température, la couverture nuageuse et les conditions de vent.

Vous pouvez ensuite renvoyer le résultat de l'API au modèle, lui permettant ainsi d'apporter une réponse complète à la requête. Pour l'exemple de la météo, le modèle peut fournir la réponse suivante : It is currently 38 degrees Fahrenheit in Boston, MA with partly cloudy skies.

Interaction d'appel de fonction 

Les modèles suivants sont compatibles avec les appels de fonction :

Modèle Version Étape de lancement de l'appel de fonction Compatibilité avec les appels de fonction en parallèle Compatibilité avec les appels de fonction forcés
Gemini 1.0 Pro gemini-1.0-pro-001 Disponibilité générale Non Non
Gemini 1.0 Pro gemini-1.0-pro-002 Disponibilité générale Non Non
Gemini 1.5 Flash gemini-1.5-flash-001 Disponibilité générale Oui Oui *
Gemini 1.5 Pro gemini-1.5-pro-001 Disponibilité générale Oui Oui

* Les fonctionnalités marquées d'un astérisque sont disponibles en version preview.

Cas d'utilisation des appels de fonction

Vous pouvez utiliser les appels de fonction pour les tâches suivantes:

Cas d'utilisationExemple de descriptionExemple de lien
Extraire des entités à partir d'histoires en langage naturel Extrayez des listes de personnages, de relations, d'éléments et de lieux à partir d'une histoire, puis stockez-les dans une base de données à l'aide d'un appel de fonction. Tutoriel de notebook
Interroger et comprendre des bases de données SQL à l'aide du langage naturel Demandez au modèle de convertir des questions telles que What percentage of orders are returned? en requêtes SQL et créez des fonctions qui les envoient à BigQuery. Article de blog
Aider les clients à interagir avec les entreprises Créez des fonctions qui se connectent à l'API d'une entreprise pour permettre au modèle de fournir des réponses précises à des requêtes telles que Do you have the Pixel 8 Pro in stock? ou Is there a store in Mountain View, CA that I can visit to try it out?. Tutoriel de notebook
Exemple REST
Exemple de chat Python
Créer des applications d'IA générative en vous connectant à des API publiques Convertir des devises Créer une fonction qui se connecte à une application de change de devises pour permettre au modèle de fournir des réponses précises à des requêtes telles que What's the exchange rate for euros to dollars today?. Codelab
Obtenir la météo d'un lieu donné Créez une fonction qui se connecte à une API d'un service météorologique pour permettre au modèle de fournir des réponses précises à des requêtes telles que What's the weather like in Paris?. Article du blog
Exemples de code Python et Node.js
Exemples de chat Node.js, Java et Go
Convertissez une adresse en coordonnées de latitude et de longitude. Créez une fonction qui convertit des données de localisation structurées en coordonnées de latitude et de longitude. Demandez au modèle d'identifier l'adresse postale, la ville, l'état et le code postal dans des requêtes telles que I want to get the lat/lon coordinates for the following address: 1600 Amphitheatre Pkwy, Mountain View, CA 94043, US.. Tutoriel de notebook

Voici d'autres cas d'utilisation :

  • Interpréter des commandes vocales : créez des fonctions correspondant aux tâches effectuées dans le véhicule. Vous pouvez par exemple créer des fonctions qui allument la radio ou activent la climatisation. Envoie au modèle les fichiers audio des commandes vocales de l'utilisateur, et demandez-lui de convertir l'audio en texte et d'identifier la fonction que l'utilisateur souhaite appeler.

  • Automatisez les workflows en fonction de déclencheurs d'environnement : créez des fonctions pour représenter les processus pouvant être automatisés. Fournissez au modèle des données provenant de capteurs environnementaux et demandez-lui de les analyser et de les traiter pour déterminer si un ou plusieurs workflows doivent être activés. Par exemple, un modèle peut traiter des données de température dans un entrepôt et choisir d'activer une fonction d'arrosage.

  • Automatiser l'attribution des demandes d'assistance : fournissez au modèle des demandes d'assistance, des journaux et des règles contextuelles. Demandez au modèle de traiter toutes ces informations pour déterminer à qui la demande doit être attribuée. Appelez une fonction pour attribuer le ticket à la personne suggérée par le modèle.

  • Récupérer des informations à partir d'une base de connaissances : créez des fonctions permettant de récupérer des articles universitaires sur un sujet donné et de les résumer. Autorisez le modèle à répondre à des questions sur des sujets académiques et à fournir des citations pour ses réponses.

Créer une application d'appel de fonction

Pour permettre à un utilisateur de communiquer avec le modèle et d'utiliser des appels de fonction, vous devez créer du code qui effectue les tâches suivantes :

  1. Configurez votre environnement.
  2. Définissez et décrivez un ensemble de fonctions disponibles à l'aide de déclarations de fonctions.
  3. Envoyer la requête d'un utilisateur et les déclarations de fonctions au modèle
  4. Appelez une fonction à l'aide de la sortie des données structurées du modèle.
  5. Fournissez le résultat de la fonction au modèle.

Vous pouvez créer une application qui gère toutes ces tâches. Il peut s'agir d'un chatbot textuel, d'un agent vocal, d'un workflow automatisé ou d'un autre programme.

Vous pouvez utiliser les appels de fonction pour générer une réponse textuelle unique ou pour prendre en charge une session de chat. Les réponses textuelles ad hoc sont utiles pour des tâches métier spécifiques, y compris la génération de code. Les sessions de chat sont utiles dans des scénarios de conversation libres, où un utilisateur est susceptible de poser des questions de suivi.

Si vous utilisez les appels de fonction pour générer une seule réponse, vous devez fournir au modèle le contexte complet de l'interaction. En revanche, si vous utilisez l'appel de fonction dans le contexte d'une session de chat, celle-ci stocke le contexte à votre place et l'inclut dans chaque requête de modèle. Dans les deux cas, Vertex AI stocke l'historique de l'interaction côté client.

Ce guide explique comment utiliser les appels de fonction pour générer une réponse textuelle unique. Pour obtenir un exemple de bout en bout, consultez Exemples de texte. Pour savoir comment utiliser les appels de fonction pour prendre en charge une session de chat, consultez des exemples de chat.

Étape 1: Configurer votre environnement

Importez les modules requis et initialisez le modèle:

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 = 'PROJECT_ID'
vertexai.init(project=project_id, location="us-central1")

# Initialize Gemini model
model = GenerativeModel(model_name="gemini-1.0-pro-001")

Étape 2: Déclarer un ensemble de fonctions

L'application doit déclarer un ensemble de fonctions que le modèle peut utiliser pour traiter la requête.

Le nombre maximal de déclarations de fonction pouvant être fournies avec la requête est de 128.

Vous devez fournir des déclarations de fonction dans un format de schéma compatible avec le schéma OpenAPI. Vertex AI offre une compatibilité limitée avec le schéma OpenAPI. Les attributs suivants sont acceptés : type, nullable, required, format, description, properties, items, enum. Les attributs suivants ne sont pas acceptés : default, optional, maximum, oneOf. Pour obtenir des conseils sur les bonnes pratiques concernant les déclarations de fonction, y compris pour les noms et les descriptions, consultez la section Bonnes pratiques.

Si vous utilisez l'API REST, spécifiez le schéma à l'aide de JSON. Si vous utilisez le SDK Vertex AI pour Python, vous pouvez spécifier le schéma manuellement à l'aide d'un dictionnaire Python ou automatiquement avec la fonction d'assistance 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"
            ]
          }
        }
      ]
    }
  ]
}

Dictionnaire Python

La déclaration de fonction suivante n'accepte qu'un seul paramètre string :

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 city name of the location for which to get the weather."}
        },
    },
)

La déclaration de fonction suivante utilise des paramètres d'objet et de tableau:

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 à partir de la fonction

L'exemple de code suivant déclare une fonction qui multiplie un tableau de nombres et utilise from_func pour générer le schéma 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"
}
'''

Étape 3: Envoyer la requête et les déclarations de fonction au modèle

Lorsque l'utilisateur fournit une requête, l'application doit fournir au modèle la requête utilisateur et les déclarations de fonctions. Pour configurer la manière dont le modèle génère des résultats, l'application peut fournir au modèle une configuration de génération. Pour configurer la manière dont le modèle utilise les déclarations de fonction, l'application peut fournir au modèle une configuration d'outil. L'appel de fonction n'est pas compatible avec l'entrée multimodale.

Définir la requête utilisateur

Voici un exemple de requête utilisateur: "Quel temps fait-il à Boston ?".

Voici un exemple de définition de requête utilisateur :

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?"),
    ],
)

Pour connaître les bonnes pratiques concernant la requête utilisateur, consultez la page Bonnes pratiques – Requête utilisateur.

Configuration de génération

Le modèle peut générer différents résultats pour différentes valeurs de paramètre. Le paramètre de température contrôle le degré de hasard dans cette génération. Les températures inférieures sont idéales pour les fonctions qui nécessitent des valeurs de paramètres déterministes, tandis que les températures plus élevées sont idéales pour les fonctions avec des paramètres qui acceptent des valeurs de paramètres plus diversifiées ou créatives. Une température de 0 est déterministe. Dans ce cas, les réponses pour une requête donnée sont principalement déterministes, mais une petite quantité de variation est toujours possible. Pour en savoir plus, consultez la page API Gemini.

Pour définir ce paramètre, envoyez une configuration de génération (generation_config) avec la requête et les déclarations de fonction. Vous pouvez mettre à jour le paramètre temperature lors d'une conversation par chat à l'aide de l'API Vertex AI et d'un generation_config mis à jour. Pour obtenir un exemple de définition du paramètre temperature, consultez la section Envoyer la requête et les déclarations de fonction.

Pour connaître les bonnes pratiques liées à la configuration de génération, consultez la section Bonnes pratiques - Configuration de génération.

Configuration de l'outil

Vous pouvez appliquer certaines contraintes sur la manière dont le modèle doit utiliser les déclarations de fonction que vous lui fournissez. Par exemple, au lieu de permettre au modèle de choisir entre une réponse en langage naturel et un appel de fonction, vous pouvez l'obliger à ne prédire que les appels de fonction ("appel de fonction forcé"). Vous pouvez également choisir de fournir au modèle un ensemble complet de déclarations de fonctions, mais limiter ses réponses à un sous-ensemble de ces fonctions.

Pour placer ces contraintes, envoyez une configuration d'outil (tool_config) avec la requête et les déclarations de fonction. Dans la configuration, vous pouvez spécifier l'un des modes suivants:

Mode Description
AUTO Comportement par défaut du modèle. Le modèle décide s'il faut prédire un appel de fonction ou une réponse en langage naturel.
TOUS Le modèle ne doit prédire que les appels de fonction. Pour limiter le modèle à un sous-ensemble de fonctions, définissez les noms de fonction autorisés dans allowed_function_names.
AUCUN Le modèle ne doit pas prédire les appels de fonction. Ce comportement est équivalent à une requête de modèle sans aucune déclaration de fonction associée.

Le mode ANY de la configuration de l'outil ("appel de fonction forcée") n'est compatible qu'avec les modèles Gemini 1.5 Pro.

Pour en savoir plus, consultez la page API d'appel de fonction.

Envoyer la requête et les déclarations de fonction

Vous trouverez ci-dessous un exemple montrant comment envoyer la requête et les déclarations de fonction au modèle, et comment contraindre le modèle à ne prédire que les appels de fonction 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={"temperature": 0},
    tools=[tool],
    tool_config=ToolConfig(
        function_calling_config=ToolConfig.FunctionCallingConfig(
            # ANY mode forces the model to predict a function call
            mode=ToolConfig.FunctionCallingConfig.Mode.ANY,
            # Allowed functions to call when the mode is ANY. If empty, any one of
            # the provided functions are called.
            allowed_function_names=["get_current_weather"],
    ))
)
response_function_call_content = response.candidates[0].content

Si le modèle détermine qu'il a besoin du résultat d'une fonction particulière, la réponse que l'application reçoit du modèle contient le nom de la fonction et les valeurs des paramètres avec lesquels la fonction doit être appelée.

Voici un exemple de réponse de modèle à la requête utilisateur "Quel temps fait-il à Boston ?". Le modèle propose d'appeler la fonction get_current_weather avec le paramètre Boston, MA.

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

Pour les requêtes de type "Puis-je obtenir des informations sur la météo à New Delhi et San Francisco ?", le modèle peut proposer plusieurs appels de fonction parallèles. L'appel de fonction parallèle est une fonctionnalité en version bêta. Il est compatible avec les modèles Gemini 1.5 Pro et Gemini 1.5 Flash. Pour en savoir plus, consultez la section Exemple d'appel de fonction parallèle.

Étape 4: Appeler une API externe

Si l'application reçoit un nom de fonction et des valeurs de paramètre du modèle, elle doit se connecter à une API externe et appeler la fonction.

L'exemple suivant utilise des données synthétiques pour simuler une charge utile de réponse provenant d'une API externe:

Python

# Check the function name that the model responded with, and make an API call to an external system
if (response.candidates[0].content.parts[0].function_call.name == "get_current_weather"):
    # Extract the arguments to use in your API call
    location = (
        response.candidates[0].content.parts[0].function_call.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" } }"""

Pour connaître les bonnes pratiques relatives aux appels d'API, consultez la page Bonnes pratiques pour les appels d'API.

Étape 5 : Fournir le résultat de la fonction au modèle

Après qu'une application a reçu une réponse d'une API externe, elle doit fournir cette réponse au modèle. Vous trouverez ci-dessous un exemple de cette procédure avec Python:

Python

response = model.generate_content(
    [
        user_prompt_content,  # User prompt
        response_function_call_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.candidates[0].content.parts[0].text

Si le modèle avait proposé plusieurs appels de fonction parallèles, l'application doit fournir toutes les réponses au modèle. L'appel de fonction parallèle est une fonctionnalité en version bêta. Il est compatible avec les modèles Gemini 1.5 Pro et Gemini 1.5 Flash. Pour en savoir plus, consultez la section Exemple d'appel de fonction parallèle.

Les modèles gemini-1.0-pro-001 et gemini-1.0-pro-002 peuvent déterminer que le résultat d'une autre fonction est nécessaire pour répondre à la requête. Dans ce cas, la réponse que l'application reçoit du modèle contient un autre nom de fonction et un autre ensemble de valeurs de paramètres.

Si le modèle détermine que la réponse de l'API est suffisante pour répondre à la requête de l'utilisateur, il crée une réponse en langage naturel et la renvoie à l'application. Dans ce cas, l'application doit renvoyer la réponse à l'utilisateur. Voici un exemple de journal :

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.

Exemples d'appels de fonction

Exemples textuels

Vous pouvez utiliser les appels de fonction pour générer une réponse textuelle unique. Les réponses textuelles ad hoc sont utiles pour des tâches métier spécifiques, y compris la génération de code.

Si vous utilisez les appels de fonction pour générer une seule réponse, vous devez fournir au modèle le contexte complet de l'interaction. Vertex AI stocke l'historique de l'interaction côté client.

Python

Cet exemple illustre un scénario de texte avec une fonction et une requête. Il utilise la classe GenerativeModel et ses méthodes. Pour en savoir plus sur l'utilisation du SDK Vertex AI pour Python avec des modèles multimodaux Gemini, consultez la page Présentation des classes multimodales dans le SDK Vertex AI pour Python.

Python

Pour savoir comment installer ou mettre à jour le SDK Vertex AI pour Python, consultez la section Installer le SDK Vertex AI pour Python. Pour en savoir plus, consultez la documentation de référence de l'API Python.

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

# Initialize Vertex AI
# TODO (developer): update project_id
vertexai.init(project=PROJECT_ID, location="us-central1")

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

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

C#

Cet exemple illustre un scénario de texte avec une fonction et une requête.

C#

Avant d'essayer cet exemple, suivez les instructions de configuration pour C# décrites dans le guide de démarrage rapide de Vertex AI à l'aide des bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence de l'API Vertex AI C#.

Pour vous authentifier auprès de Vertex AI, configurez le service Identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement 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

Cet exemple illustre un scénario de texte avec une fonction et une requête.

Node.js

Avant d'essayer cet exemple, suivez les instructions de configuration pour Node.js décrites dans le guide de démarrage rapide de Vertex AI à l'aide des bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence de l'API Vertex AI Node.js.

Pour vous authentifier auprès de Vertex AI, configurez le service Identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement 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: 'model',
        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

Cet exemple illustre un scénario textuel avec trois fonctions et une requête.

Dans cet exemple, vous appelez deux fois le modèle d'IA générative.

  • Dans le premier appel, vous fournissez au modèle la requête et les déclarations de la fonction.
  • Dans le deuxième appel, vous transmettez la réponse de l'API au modèle.

Première requête de modèle

La requête doit définir une requête dans le paramètre text. Cet exemple définit la requête suivante : "Quels cinémas à Mountain View diffusent le film Barbie ?".

La requête doit également définir un outil (tools) avec un ensemble de déclarations de fonction (functionDeclarations). Ces déclarations de fonction doivent être spécifiées dans un format compatible avec le schéma OpenAPI. Cet exemple définit les fonctions suivantes :

  • find_movies trouve les titres de films diffusés au cinéma.
  • find_theatres trouve des films en fonction de leur emplacement.
  • get_showtimes recherche les heures de début des films diffusés dans un cinéma spécifique.

Pour en savoir plus sur les paramètres de la requête de modèle, consultez la page API Gemini.

Remplacez my-project par le nom de votre projet Google Cloud.

Première requête de modèle

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

Pour la requête "Quels films à Mountain View diffusent le film Barbie ?", le modèle peut renvoyer la fonction find_theatres avec les paramètres Barbie et Mountain View, CA.

Réponse à la première requête de modèle

[{
"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
}
}]
  

Deuxième requête du modèle

Cet exemple utilise des données synthétiques au lieu d'appeler l'API externe. Deux résultats s'affichent, chacun avec deux paramètres (name et 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

Remplacez my-project par le nom de votre projet Google Cloud.

Deuxième requête du modèle

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 réponse du modèle peut ressembler à ce qui suit :

Réponse à la deuxième requête du modèle

{
"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
}
}
  

Exemples de chat

Vous pouvez utiliser les appels de fonction pour prendre en charge une session de chat. Les sessions de chat sont utiles dans des scénarios de conversation libres, où un utilisateur est susceptible de poser des questions de suivi.

Si vous utilisez l'appel de fonction dans le contexte d'une session de chat, celle-ci stocke le contexte à votre place et l'inclut dans chaque requête de modèle. Vertex AI stocke l'historique de l'interaction côté client.

Python

Cet exemple présente un scénario de chat avec deux fonctions et deux requêtes séquentielles. Il utilise la classe GenerativeModel et ses méthodes. Pour en savoir plus sur l'utilisation du SDK Vertex AI pour Python avec des modèles multimodaux, consultez la page Présentation des classes multimodales dans le SDK Vertex AI pour Python.

Pour savoir comment installer ou mettre à jour Python, consultez la page Installer le SDK Vertex AI pour Python. Pour en savoir plus, consultez la documentation de référence de l'API Python.

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

# Initialize Vertex AI
# TODO (developer): update project_id
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 OpenAPI 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)

Java

Avant d'essayer cet exemple, suivez les instructions de configuration pour Java décrites dans le guide de démarrage rapide de Vertex AI à l'aide des bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence de l'API Vertex AI Java.

Pour vous authentifier auprès de Vertex AI, configurez le service Identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement 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

Avant d'essayer cet exemple, suivez les instructions de configuration pour Go décrites dans le guide de démarrage rapide de Vertex AI à l'aide des bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence de l'API Vertex AI Go.

Pour vous authentifier auprès de Vertex AI, configurez le service Identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement 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

Avant d'essayer cet exemple, suivez les instructions de configuration pour Node.js décrites dans le guide de démarrage rapide de Vertex AI à l'aide des bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence de l'API Vertex AI Node.js.

Pour vous authentifier auprès de Vertex AI, configurez le service Identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement 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);
}

Exemple d'appel de fonction parallèle

Pour les requêtes de type "Puis-je obtenir des informations sur la météo à New Delhi et San Francisco ?", le modèle peut proposer plusieurs appels de fonction parallèles. L'appel de fonction parallèle est une fonctionnalité en version bêta. Il est compatible avec les modèles Gemini 1.5 Pro et Gemini 1.5 Flash.

REST

Cet exemple illustre un scénario avec une fonction get_current_weather. La requête de l'utilisateur est "Puis-je obtenir des informations sur la météo à New Delhi et San Francisco ?". Le modèle propose deux appels de fonction get_current_weather parallèles : l'un avec le paramètre New Delhi et l'autre avec le paramètre San Francisco. L'appel de fonction parallèle est une fonctionnalité en version bêta. Elle est compatible avec les modèles Gemini 1.5 Pro et Gemini 1.5 Flash.

Pour en savoir plus sur les paramètres de la requête de modèle, consultez la page API Gemini.

candidates {
content {
  role: "model"
  parts: [
    {
      function_call {
        name: "get_current_weather"
        args {
          fields {
            key: "location"
            value {
              string_value: "New Delhi"
            }
          }
        }
      }
    },
    {
      function_call {
        name: "get_current_weather"
        args {
          fields {
            key: "location"
            value {
              string_value: "San Francisco"
            }
          }
        }
      }
    }
  ]
}
...
}

La commande suivante montre comment fournir le résultat de la fonction au modèle. Remplacez my-project par le nom de votre projet Google Cloud.

Requête de modèle

PROJECT_ID=my-project
MODEL_ID=gemini-1.5-pro-001
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 réponse en langage naturel créée par le modèle ressemble à ce qui suit :

Réponse de modèle

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

Bonnes pratiques pour les appels de fonction

Nom de la fonction

N'utilisez pas de point (.), de tiret (-) ni d'espace dans le nom de la fonction. Utilisez plutôt des traits de soulignement (_) ou d'autres caractères.

Description de la fonction

Rédigez des descriptions de fonction claires et détaillées. Par exemple, pour une fonction book_flight_ticket:

  • Voici un exemple de description de fonction appropriée :book flight tickets after confirming users' specific requirements, such as time, departure, destination, party size and preferred airline
  • Voici un exemple de description de fonction incorrecte : book flight ticket

Paramètres de fonction

Descriptions

Rédigez des descriptions de paramètres claires et détaillées, comprenant des détails tels que le format ou les valeurs que vous préférez. Par exemple, pour une fonction book_flight_ticket:

  • Voici un bon exemple de description de paramètre departure : Use the 3 char airport code to represent the airport. For example, SJC or SFO. Don't use the city name.
  • Voici un mauvais exemple de description du paramètre departure : the departure airport

Types

Si possible, utilisez des paramètres fortement typés pour réduire les hallucinations du modèle. Par exemple, si les valeurs des paramètres proviennent d'un ensemble fini, ajoutez un champ enum au lieu de placer l'ensemble de valeurs dans la description. Si la valeur du paramètre est toujours un entier, définissez le type sur integer plutôt que number.

Instructions système

Lorsque vous utilisez des fonctions avec des paramètres de date, d'heure ou d'emplacement, incluez la date, l'heure actuelle ou les informations de localisation pertinentes (par exemple, la ville et le pays) dans l'instruction système. Cela garantit que le modèle dispose du contexte nécessaire pour traiter la requête avec précision, même si la requête de l'utilisateur manque de détails.

Requête de l'utilisateur

Pour de meilleurs résultats, ajoutez les informations suivantes en préfixe à la requête utilisateur:

  • Contexte supplémentaire pour le modèle (par exemple, You are a flight API assistant to help with searching flights based on user preferences.)
  • Détails ou instructions sur quand et comment utiliser des fonctions (par exemple, Don't make assumptions on the departure or destination airports. Always use a future date for the departure or destination time.)
  • Instructions pour poser des questions de clarification si les requêtes des utilisateurs sont ambiguës (par exemple, Ask clarifying questions if not enough information is available.)

Configuration de génération

Pour le paramètre de température, utilisez 0 ou une autre valeur faible. Cela indique au modèle de générer des résultats plus fiables et de réduire les hallucinations.

Appel d'API

Si le modèle propose d'appeler une fonction qui permet d'envoyer une commande, de mettre à jour une base de données ou de provoquer des conséquences importantes, validez l'appel de fonction auprès de l'utilisateur avant de l'exécuter.

Tarifs

Les tarifs des appels de fonction sont basés sur le nombre de caractères dans les entrées et les sorties de texte. Pour en savoir plus, consultez les tarifs de Vertex AI.

Ici, la saisie de texte (requête) fait référence à la requête utilisateur pour le tour de conversation en cours, aux déclarations de fonction pour le tour de conversation en cours et à l'historique de la conversation. L'historique de la conversation inclut les requêtes, les appels de fonction et les réponses de fonction des tours de conversation précédents. Vertex AI tronque l'historique de la conversation à 32 000 caractères.

La sortie textuelle (réponse) fait référence aux appels de fonction et aux réponses textuelles pour le tour de conversation en cours.

Étape suivante