1. Introduction
Les modèles d'IA générative sont remarquables pour comprendre le langage naturel et y répondre. Mais que faire si vous avez besoin de résultats précis et prévisibles pour des tâches critiques comme la normalisation des adresses ? Les modèles génératifs traditionnels peuvent parfois fournir des réponses différentes à des moments différents pour les mêmes requêtes, ce qui peut entraîner des incohérences. C'est là que la fonctionnalité d'appel de fonction de Gemini brille, car elle vous permet de contrôler de manière déterministe les éléments de la réponse de l'IA.
Cet atelier de programmation illustre ce concept avec le cas d'utilisation de la saisie semi-automatique et de la normalisation des adresses. Pour ce faire, nous allons créer une fonction Cloud Java qui effectue les tâches suivantes :
- Prend des coordonnées de latitude et de longitude
- Appelle l'API Google Maps Geocoding pour obtenir les adresses correspondantes
- Utilise la fonctionnalité d'appel de fonction de Gemini 1.0 Pro pour normaliser et résumer de manière déterministe ces adresses dans un format spécifique dont nous avons besoin
C'est parti !
2. Appel de fonction Gemini
L'appel de fonction Gemini se distingue à l'ère de l'IA générative, car il vous permet de combiner la flexibilité des modèles de langage génératifs avec la précision de la programmation traditionnelle.
Voici les tâches que vous devez effectuer pour implémenter l'appel de fonction Gemini :
- Définir des fonctions : décrivez clairement les fonctions. Les descriptions doivent inclure les informations suivantes :
- Le nom de la fonction, par exemple
getAddress. - Les paramètres attendus par la fonction, par exemple
latlngsous forme de chaîne. - Le type de données renvoyé par la fonction, par exemple une liste de chaînes d'adresse.
- Créer des outils pour Gemini : regroupez les descriptions de fonctions sous forme de spécification d'API dans des outils. Considérez un outil comme une boîte à outils spécialisée que Gemini peut utiliser pour comprendre la fonctionnalité de l'API.
- Orchestrer les API à l'aide de Gemini : lorsque vous envoyez une requête à Gemini, il peut analyser votre requête et reconnaître où il peut utiliser les outils que vous avez fournis. Gemini agit ensuite comme un orchestrateur intelligent en effectuant les tâches suivantes :
- Génère les paramètres d'API nécessaires pour appeler les fonctions que vous avez définies. Gemini n'appelle pas l'API en votre nom. Vous devez appeler l'API en fonction des paramètres et de la signature que l'appel de fonction Gemini a générés pour vous.
- Gemini traite les résultats en les réinjectant dans sa génération et en intégrant des informations structurées dans sa réponse finale. Vous pouvez traiter ces informations comme vous le souhaitez pour votre application.
L'image suivante montre le flux de données, les étapes d'implémentation et le propriétaire de chaque étape, tel que l'application, le LLM ou l'API :

Objectifs de l'atelier
Vous allez créer et déployer une fonction Cloud Java qui effectue les opérations suivantes :
- Prend des coordonnées de latitude et de longitude.
- Appelle l'API Google Maps Geocoding pour obtenir les adresses correspondantes.
- Utilise la fonctionnalité d'appel de fonction de Gemini 1.0 Pro pour normaliser et résumer de manière déterministe ces adresses dans un format spécifique.
3. Conditions requises
4. Avant de commencer
- Dans la console Google Cloud, sur la page du sélecteur de projet, sélectionnez ou créez un projet Google Cloud.
- Assurez-vous que la facturation est activée pour votre projet Google Cloud. Découvrez comment vérifier si la facturation est activée sur un projet.
- Activez Cloud Shell depuis la console Google Cloud. Pour en savoir plus, consultez la page Utiliser Cloud Shell.
- Si votre projet n'est pas défini, utilisez la commande suivante pour le définir :
gcloud config set project <YOUR_PROJECT_ID>
- Dans Cloud Shell, définissez les variables d'environnement suivantes :
export GCP_PROJECT=<YOUR_PROJECT_ID>
export GCP_REGION=us-central1
- Activez les API Google Cloud nécessaires en exécutant les commandes suivantes dans Cloud Shell :
gcloud services enable cloudbuild.googleapis.com cloudfunctions.googleapis.com run.googleapis.com logging.googleapis.com storage-component.googleapis.com cloudaicompanion.googleapis.com aiplatform.googleapis.com
- Ouvrez l'éditeur de code Cloud Shell, cliquez sur Extensions , puis installez l' extension Gemini + Google Cloud Code.
5. Implémenter la fonction Cloud
- Lancer l'éditeur de code Cloud Shell.
- Cliquez sur Cloud Code , puis développez la section Cloud Functions.
- Cliquez sur l'icône Créer une fonction (+).
- Dans la boîte de dialogue Créer une application, sélectionnez l'option Java : Hello World.
- Indiquez un nom pour le projet dans le chemin d'accès au projet, par exemple GeminiFunctionCalling.
- Cliquez sur Explorateur pour afficher la structure du projet, puis ouvrez le fichier pom.xml. L'image suivante montre la structure du projet :

- Ajoutez les dépendances nécessaires dans la balise
<dependencies>... </dependencies>du fichierpom.xml. Vous pouvez accéder à l'intégralité dupom.xmlà partir du dépôt GitHub de ce projet . Copiez le fichier pom.xml à partir de là dans le fichierpom.xmlde votre projet actuel que vous êtes en train de modifier. - Copiez la classe
HelloWorld.javaà partir du lien GitHub GeminiFunctionCalling. Vous devez remplacerAPI_KEYetproject_idpar votre clé API Geocoding et votre ID de projet Google Cloud, respectivement.
6. Comprendre l'appel de fonction à l'aide de la classe HelloWorld.java
Requête d'entrée
Dans cet exemple, la requête d'entrée est la suivante : Quelle est l'adresse correspondant à la valeur latlong 40.714224,-73.961452 ?.
Voici l'extrait de code correspondant à la requête d'entrée dans le fichier :
String promptText = "What's the address for the latlong value '" + latlngString + "'?"; //40.714224,-73.961452
Spécification de l'API
L'API Reverse Geocoding est utilisée dans cet exemple. Voici la spécification de l'API :
/* Declare the function for the API to invoke (Geo coding API) */
FunctionDeclaration functionDeclaration =
FunctionDeclaration.newBuilder()
.setName("getAddress")
.setDescription("Get the address for the given latitude and longitude value.")
.setParameters(
Schema.newBuilder()
.setType(Type.OBJECT)
.putProperties(
"latlng",
Schema.newBuilder()
.setType(Type.STRING)
.setDescription("This must be a string of latitude and longitude coordinates separated by comma")
.build())
.addRequired("latlng")
.build())
.build();
Orchestrer la requête avec Gemini
La requête d'entrée et la spécification de l'API sont envoyées à Gemini :
// Add the function to a "tool"
Tool tool = Tool.newBuilder()
.addFunctionDeclarations(functionDeclaration)
.build();
// Invoke the Gemini model with the use of the tool to generate the API parameters from the prompt input.
GenerativeModel model = GenerativeModel.newBuilder()
.setModelName(modelName)
.setVertexAi(vertexAI)
.setTools(Arrays.asList(tool))
.build();
GenerateContentResponse response = model.generateContent(promptText);
Content responseJSONCnt = response.getCandidates(0).getContent();
La réponse est le JSON des paramètres orchestrés pour l'API. Voici un exemple de résultat :
role: "model"
parts {
function_call {
name: "getAddress"
args {
fields {
key: "latlng"
value {
string_value: "40.714224,-73.961452"
}
}
}
}
}
Transmettez le paramètre suivant à l'API Reverse Geocoding : "latlng=40.714224,-73.961452"
Faites correspondre le résultat orchestré au format "latlng=VALUE".
Appeler l'API
Voici la section du code qui appelle l'API :
// Create a request
String url = API_STRING + "?key=" + API_KEY + params;
java.net.http.HttpRequest request = java.net.http.HttpRequest.newBuilder()
.uri(URI.create(url))
.GET()
.build();
// Send the request and get the response
java.net.http.HttpResponse<String> httpresponse = client.send(request, java.net.http.HttpResponse.BodyHandlers.ofString());
// Save the response
String jsonResult = httpresponse.body().toString();
La chaîne jsonResult contient la réponse de l'API Reverse Geocoding. Voici une version mise en forme du résultat :
"...277 Bedford Ave, Brooklyn, NY 11211, USA; 279 Bedford Ave, Brooklyn, NY 11211, USA; 277 Bedford Ave, Brooklyn, NY 11211, USA;..."
Traiter la réponse de l'API et préparer la requête
Le code suivant traite la réponse de l'API et prépare la requête avec des instructions sur la façon de traiter la réponse :
// Provide an answer to the model so that it knows what the result
// of a "function call" is.
String promptString =
"You are an AI address standardizer for assisting with standardizing addresses accurately. Your job is to give the accurate address in the standard format as a JSON object containing the fields DOOR_NUMBER, STREET_ADDRESS, AREA, CITY, TOWN, COUNTY, STATE, COUNTRY, ZIPCODE, LANDMARK by leveraging the address string that follows in the end. Remember the response cannot be empty or null. ";
Content content =
ContentMaker.fromMultiModalData(
PartMaker.fromFunctionResponse(
"getAddress",
Collections.singletonMap("address", formattedAddress)));
String contentString = content.toString();
String address = contentString.substring(contentString.indexOf("string_value: \"") + "string_value: \"".length(), contentString.indexOf('"', contentString.indexOf("string_value: \"") + "string_value: \"".length()));
List<SafetySetting> safetySettings = Arrays.asList(
SafetySetting.newBuilder()
.setCategory(HarmCategory.HARM_CATEGORY_HATE_SPEECH)
.setThreshold(SafetySetting.HarmBlockThreshold.BLOCK_ONLY_HIGH)
.build(),
SafetySetting.newBuilder()
.setCategory(HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT)
.setThreshold(SafetySetting.HarmBlockThreshold.BLOCK_ONLY_HIGH)
.build()
);
Appeler Gemini et renvoyer l'adresse normalisée
Le code suivant transmet la sortie traitée de l'étape précédente en tant que requête à Gemini :
GenerativeModel modelForFinalResponse = GenerativeModel.newBuilder()
.setModelName(modelName)
.setVertexAi(vertexAI)
.build();
GenerateContentResponse finalResponse = modelForFinalResponse.generateContent(promptString + ": " + address, safetySettings);
System.out.println("promptString + content: " + promptString + ": " + address);
// See what the model replies now
System.out.println("Print response: ");
System.out.println(finalResponse.toString());
String finalAnswer = ResponseHandler.getText(finalResponse);
System.out.println(finalAnswer);
La variable finalAnswer contient l'adresse normalisée au format JSON. Voici un exemple de résultat :
{"replies":["{ \"DOOR_NUMBER\": null, \"STREET_ADDRESS\": \"277 Bedford Ave\", \"AREA\": \"Brooklyn\", \"CITY\": \"New York\", \"TOWN\": null, \"COUNTY\": null, \"STATE\": \"NY\", \"COUNTRY\": \"USA\", \"ZIPCODE\": \"11211\", \"LANDMARK\": null} null}"]}
Maintenant que vous avez compris comment fonctionne l'appel de fonction Gemini avec le cas d'utilisation de la normalisation des adresses, vous pouvez déployer la fonction Cloud.
7. Déployer et tester
- Si vous avez déjà créé le projet GeminiFunctionCalling et implémenté la fonction Cloud, passez à l'étape 2. Si vous n'avez pas créé le projet, accédez au terminal Cloud Shell et clonez ce dépôt :
git clonehttps://github.com/AbiramiSukumaran/GeminiFunctionCalling - Accédez au dossier du projet :
cd GeminiFunctionCalling - Exécutez l'instruction suivante pour compiler et déployer la fonction Cloud :
gcloud functions deploy gemini-fn-calling --gen2 --region=us-central1 --runtime=java11 --source=. --entry-point=cloudcode.helloworld.HelloWorld --trigger-http
Voici le format de l'URL après le déploiement : https://us-central1-YOUR_PROJECT_ID.cloudfunctions.net/gemini-fn-calling
- Testez la fonction Cloud en exécutant la commande suivante à partir du terminal :
gcloud functions call gemini-fn-calling --region=us-central1 --gen2 --data '{"calls":[["40.714224,-73.961452"]]}'
Voici une réponse pour un exemple de requête aléatoire : '{"replies":["{ "DOOR_NUMBER": "277", "STREET_ADDRESS": "Bedford Ave", "AREA": null, "CITY": "Brooklyn", "TOWN": null, "COUNTY": "Kings County", "STATE": "NY", "COUNTRY": "USA", "ZIPCODE": "11211", "LANDMARK": null}}```"]}'
8. Effectuer un nettoyage
Pour éviter que les ressources utilisées dans cet atelier soient facturées sur votre compte Google Cloud, procédez comme suit :
- Dans la console Google Cloud, accédez à la page Gérer les ressources.
- Dans la liste des projets, sélectionnez le projet que vous souhaitez supprimer, puis cliquez sur Supprimer.
- Dans la boîte de dialogue, saisissez l'ID du projet, puis cliquez sur Arrêter pour supprimer le projet.
- Si vous souhaitez conserver votre projet, ignorez les étapes ci-dessus et supprimez la fonction Cloud en accédant à Cloud Functions. Dans la liste des fonctions, cochez celle que vous souhaitez supprimer, puis cliquez sur SUPPRIMER.
9. Félicitations
Félicitations Vous avez utilisé avec succès la fonctionnalité d'appel de fonction Gemini dans une application Java et transformé une tâche d'IA générative en un processus déterministe et fiable. Pour en savoir plus sur les modèles disponibles, consultez la documentation produit Vertex AI LLM.