1. Introduction
Vous êtes passionné de lecture, mais ne savez plus où donner de la tête parmi tous les ouvrages disponibles ? Imaginez une appli optimisée par l'IA qui non seulement vous recommande le livre parfait, mais vous en propose également un résumé concis, selon le genre de votre choix, vous donnant ainsi un aperçu des grandes lignes de l'œuvre. Au cours de cet atelier de programmation, je vous aiderai à concevoir ce type d'application avec BigQuery et Cloud Functions, avec l'aide de Gemini.
Présentation du projet
Notre cas d'utilisation s'articule autour des quatre composants clés suivants :
- Base de données de livres : le vaste ensemble de données public BigQuery composé de livres archivés sur Internet nous servira de catalogue complet de livres.
- Moteur de synthèse d'IA : Google Cloud Functions, équipé du modèle de langage Gemini-Pro, générera des résumés pertinents adaptés aux requêtes des utilisateurs.
- Intégration de BigQuery : la fonction distante de BigQuery appellera la fonction Cloud afin de fournir des thèmes et des résumés de livres à la demande.
- Interface utilisateur : application Web hébergée sur Cloud Run. Elle proposera une application Web permettant aux utilisateurs d'afficher les résultats.
L'implémentation sera répartie sur trois ateliers de programmation :
Atelier de programmation 1 : utiliser Gemini pour concevoir une fonction Cloud Java pour une application Gemini.
Atelier de programmation 2 : utiliser Gemini pour concevoir des applications d'IA générative en SQL uniquement avec BigQuery.
Atelier de programmation 3 : utiliser Gemini pour créer une application Web Spring Boot Java qui interagit avec BigQuery
2. Utiliser Gemini pour créer une application d'IA générative sans serveur sur une fonction Cloud Java
Ce que vous allez faire
Vous allez créer un
- Application Java Cloud Functions qui implémente Gemini 1.0 Pro pour prendre une invite spécifique en entrée sous la forme d'un tableau JSON et renvoyer une réponse (valeur JSON intitulée "replies").
- Vous allez effectuer les étapes de compilation et de déploiement avec l'aide de Gemini.
3. Conditions requises
Voici les conditions préalables :
Créer votre projet
- 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 Cloud. Découvrez comment vérifier si la facturation est activée sur un projet.
Activer Cloud Shell
- Vous allez utiliser Cloud Shell, un environnement de ligne de commande exécuté dans Google Cloud et fourni avec bq :
Dans la console Cloud, cliquez sur "Activer Cloud Shell" en haut à droite : 
- Une fois connecté à Cloud Shell, vous êtes en principe authentifié, et le projet est déjà défini avec votre ID de projet. Exécutez la commande suivante dans Cloud Shell pour vérifier que vous êtes authentifié :
gcloud auth list
- Exécutez la commande suivante dans Cloud Shell pour vérifier que la commande gcloud reconnaît votre projet
gcloud config list project
- Si votre projet n'est pas défini, utilisez la commande suivante pour le définir :
gcloud config set project <YOUR_PROJECT_ID>
Consultez la documentation pour connaître les commandes gcloud ainsi que leur utilisation.
4. Activer Gemini for Google Cloud et les API nécessaires
Activer Gemini
- Accédez à Gemini pour Google Cloud sur la Marketplace pour activer l'API. Vous pouvez également exécuter la commande suivante :
gcloud services enable cloudaicompanion.googleapis.com --project PROJECT_ID
- Accédez à la page Gemini, puis cliquez sur "Commencer à discuter".
Important : Suivez les étapes 1 et 2 de cet atelier de programmation pour commencer à utiliser Gemini et activer Gemini dans Cloud Shell IDE, respectivement.
Activer d'autres API nécessaires
Comment faire ? Et si on demandait à Gemini ? Mais avant cela, n'oubliez pas :
Les LLM ont un comportement non déterministe. Ainsi, lorsque vous testez ces requêtes, il se peut que la réponse que vous recevez soit différente de celles qui figurent sur ma capture d'écran.
Accédez à la console de discussion Gemini en cliquant sur l'icône "Ouvrir Gemini" en haut à droite, à côté de la barre de recherche dans la console Google Cloud.

Saisissez cette question dans la section "Saisissez une requête ici" :
How do I enable the cloud functions api using a gcloud command?
Vous devriez recevoir une réponse semblable à celle-ci :
gcloud services enable cloudfunctions.googleapis.com
Copiez-la (vous pouvez utiliser l'icône Copier en haut de l'extrait de commande) et exécutez-la dans le terminal Cloud Shell pour activer Cloud Functions. Faites de même pour Cloud Run, car nous avons besoin des deux pour créer et déployer les fonctions Cloud Functions :
gcloud services enable \
cloudfunctions.googleapis.com \
aiplatform.googleapis.com \
run.googleapis.com \
cloudbuild.googleapis.com
5. Préparer un modèle Cloud Functions avec Gemini
À ce stade, je suppose que vous avez déjà activé Gemini dans votre IDE Cloud Shell.
Ouvrez l'éditeur Cloud Shell en cliquant sur l'icône Ouvrir l'éditeur en haut à droite de votre terminal Cloud Shell (en général, je préfère ouvrir le terminal et l'éditeur dans des onglets séparés en parallèle afin de pouvoir rédiger du code dans l'un et compiler dans l'autre).

Une fois l'éditeur ouvert, assurez-vous que le logo Gemini situé en bas à droite de la console de l'éditeur est actif et n'a pas été supprimé. Assurez-vous également que votre projet Google Cloud, situé en bas à gauche, pointe vers le projet actif actuel sur lequel vous souhaitez travailler. S'ils sont inactifs, cliquez dessus, activez-les, puis sélectionnez le projet Google Cloud vers lequel vous souhaitez qu'il pointe et activez-les.
Lorsque ces deux éléments sont actifs, cliquez sur le nom du projet en bas à gauche. La liste pop-up "Cloud Code" s'ouvre : parcourez-la jusqu'à voir apparaître "Nouvelle application".

Dans cette liste, sélectionnez "Application Cloud Functions". Dans la liste qui s'affiche, sélectionnez Java :

Dans la liste obtenue, remplacez le nom de projet helloworld par "duetai-gemini-calling", puis cliquez sur OK.

Parfait ! Vous avez amorcé votre application Cloud Functions Java simple avec Gemini et votre intervention s'est limitée à l'activation des configurations.
Votre projet devrait être structuré de la manière suivante :

Pour le moment, vous êtes prêt à déployer la fonction. mais nous n'en sommes pas encore là. Nous allons maintenant créer l'implémentation de l'API Gemini Pro dans cette fonction Cloud à l'aide du SDK Java.
À présent, créons la fonctionnalité pour notre cas d'utilisation, qui consiste à appeler le modèle Gemini Pro dans cette fonction Cloud. Pour ce faire, vous êtes libre d'ajouter d'autres requêtes et de développer votre code de manière incrémentielle avec Gemini, ou d'écrire la logique vous-même. Je vais combiner les deux.
6. Ajouter des dépendances
Dans la console de chat Gemini (celle de l'éditeur Cloud Code dans le volet de gauche), saisissez la requête suivante :
what is the maven dependency for com.google.cloud.vertexai library
Je demande spécifiquement le package com.google.cloud.vertexai, car c'est celui que j'utilise dans mon code source pour implémenter le code d'invocation Gemini.
J'ai obtenu le résultat suivant :

<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-vertexai</artifactId>
<version>0.1.0</version>
</dependency>
Copiez-le et collez-le dans le fichier pom.xml, juste avant la balise </dependencies>. Remplacez la version par 0.1.0 (vous pouvez supprimer la balise <version> si vous utilisez le BOM Spring Cloud GCP pour gérer les numéros de version de spring-cloud-gcp).
La section des dépendances doit se présenter comme suit :

Si nécessaire, veillez à mettre à jour les numéros de version pour qu'ils correspondent à ceux ci-dessus. Vous remarquerez que j'ai également inclus une autre dépendance :
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.10</version>
</dependency>
7. Modifier le point d'entrée de la fonction et le nom de la classe
- Accédez au fichier "launch.json" dans le dossier ".vscode". Remplacez le nom de la fonction "function-hello-world" par "function-gemini-calling".
- Modifiez la valeur entryPoint de "cloudcode.helloworld.HelloWorld" en "cloudcode.bookshelf.Bookshelf".
- Accédez maintenant au fichier de classe Java "HelloWorld.java". Remplacez le nom du package par "package cloudcode.bookshelf". Dans l'erreur qui s'affiche, cliquez sur l'ampoule jaune, puis sur l'option "Move HelloWorld.java" (Déplacer HelloWorld.java) vers "package cloudcode.bookshelf".

- Remplacez le nom de la classe par "Bookshelf", puis, dans l'erreur qui s'affiche, cliquez sur la petite ampoule jaune et sélectionnez "Rename file to Bookshelf.java" (Renommer le fichier en Bookshelf.java). Sélectionnez-le.
8. Créer la méthode qui appelle Gemini Pro
Implémentons cette fonctionnalité dans la classe Bookshelf.java. Remplacez votre fichier Bookshelf.java par le code ci-dessous :
package cloudcode.bookshelf;
import java.io.BufferedWriter;
import com.google.cloud.functions.HttpFunction;
import com.google.cloud.functions.HttpRequest;
import com.google.cloud.functions.HttpResponse;
import com.google.cloud.vertexai.VertexAI;
import com.google.cloud.vertexai.api.GenerateContentResponse;
import com.google.cloud.vertexai.api.GenerationConfig;
import com.google.cloud.vertexai.generativeai.preview.GenerativeModel;
import com.google.cloud.vertexai.generativeai.preview.ResponseHandler;
import java.io.IOException;
import java.util.List;
import java.util.Arrays;
import java.util.Map;
import java.util.LinkedHashMap;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.JsonArray;
public class Bookshelf implements HttpFunction {
private static final Gson gson = new Gson();
@Override
public void service(HttpRequest request, HttpResponse response) throws Exception {
BufferedWriter writer = response.getWriter();
// Get the request body as a JSON object.
JsonObject requestJson = new Gson().fromJson(request.getReader(), JsonObject.class);
JsonArray calls_array = requestJson.getAsJsonArray("calls");
JsonArray calls = (JsonArray) calls_array.get(0);
String context = calls.get(0).toString().replace("\"", "");
//Invoke Gemini model
String raw_result = callGemini(context);
raw_result = raw_result.replace("\n","");
String trimmed = raw_result.trim();
List<String> result_list = Arrays.asList(trimmed);
Map<String, List<String>> stringMap = new LinkedHashMap<>();
stringMap.put("replies", result_list);
// Serialization
String return_value = gson.toJson(stringMap);
writer.write(return_value);
}
public String callGemini(String context) throws IOException{
String res = "";
try (VertexAI vertexAi = new VertexAI("REPLACE_WITH_YOUR_PROJECT_ID", "us-central1"); ) {
GenerationConfig generationConfig =
GenerationConfig.newBuilder()
.setMaxOutputTokens(2048)
.setTemperature(0.4F)
.setTopK(32)
.setTopP(1)
.build();
GenerativeModel model = new GenerativeModel("gemini-pro", generationConfig, vertexAi);
GenerateContentResponse response = model.generateContent(context);
res = ResponseHandler.getText(response);
}catch(Exception e){
System.out.println(e);
}
return res;
}
}
Cette classe attend une entrée dans la structure JSON ci-dessous :
{ "calls": [["YOUR_PROMPT_HERE"]] }
La réponse renvoyée est la suivante :
(Json) Map<String, List<String>> {"replies": ["response"]}
Essayez l'option de chat Gemini dans le volet de gauche de l'éditeur Cloud Shell pour expliquer le code. Vous pouvez également sélectionner tout le code, cliquer sur l'ampoule jaune en haut à gauche de la sélection, puis choisir l'option "Expliquer ceci".

9. Déployer la fonction Cloud
Maintenant que la fonction Cloud est prête, demandons à Gemini comment la déployer. Accédez au chat Gemini dans l'éditeur Cloud Code et saisissez ce qui suit :
How to deploy this Cloud Function with a gcloud command?
J'ai reçu la réponse ci-dessous :

Je voulais maintenant l'examiner plus en détail. J'ai donc demandé à Gemini de me donner la commande gcloud functions deploy complète. La réponse se présente comme suit :

Je ne peux pas vous dire si vous recevrez la même réponse, mais j'ai trouvé intéressant de constater qu'elle ajoutait quelques détails supplémentaires à ma grande surprise, comme le montre l'image ci-dessous :
Format du corps de la requête :

et
Format de la réponse :

Maintenant, déployons la fonction en exécutant la commande gcloud que Gemini nous a fournie. Pour cela, nous devons ouvrir le terminal Cloud Shell. Vous pouvez l'ouvrir dans un nouvel onglet pour https://console.cloud.google.com et vous assurer que le bon projet est sélectionné. Ouvrez le terminal Cloud Shell en cliquant sur l'icône Activer Cloud Shell en haut à droite de la console, puis assurez-vous d'être dans le bon dossier de projet en utilisant la commande ci-dessous :
cd duetai-gemini-calling
suivie de la commande ci-dessous :
gcloud functions deploy bookshelf --runtime java17 --trigger-http --entry-point cloudcode.bookshelf.Bookshelf --allow-unauthenticated
Le message "Autoriser les appels non authentifiés de la nouvelle fonction [bookshelf]?" s'affiche. Dites "y" (oui) et appuyez sur Entrée. Ensuite, vous devrez répondre à quelques questions, le cas échéant. Votre fonction Cloud sans serveur sera alors déployée avec l'URL de déploiement : https://us-central1-*******.cloudfunctions.net/bookshelf.
Appelons maintenant les fonctions Cloud déployées et testons-les.
Remarque : Si vous avez accidentellement ignoré la question "Autoriser les appels non authentifiés" ou sélectionné "N", vous ne pourrez pas accéder au résultat des fonctions Cloud et vous verrez un "message d'erreur d'autorisation" sans accorder de paramètres IAM supplémentaires. Faites donc attention à cela.
10. Appeler la fonction Cloud déployée
Et si on demandait à Gemini ? J'ai saisi la requête
How to call the deployed cloud function?
J'ai obtenu le résultat ci-dessous : (Vous n'obtiendrez peut-être pas exactement la même réponse. N'hésitez pas à tester la requête et à observer les différences dans les réponses.)

Sondez le chat avec des questions spécifiques sur d'autres façons d'appeler la fonction déployée, d'appeler à l'aide de la commande gcloud, etc. J'ai envoyé la requête ci-dessous :
how to call the deployed cloud function using gcloud
J'ai reçu la réponse ci-dessous : 
Vous pouvez utiliser cette réponse (commande "gcloud functions call") depuis le terminal en l'adaptant à notre scénario (vous pouvez également essayer de transmettre les paramètres dans le prompt lui-même et voir si vous obtenez l'appel détaillé des fonctions gcloud en réponse) :
gcloud functions call bookshelf --region=us-central1 --gen2 --data '{"calls":[["Hello! This is my test prompt."]]}'
Voici le résultat :

11. Effectuer un nettoyage
Vous pouvez supprimer les fonctions Cloud que vous avez créées précédemment en cliquant sur le bouton "SUPPRIMER" sur la page d'informations de la fonction Cloud.
12. Félicitations
Vous avez conçu, déployé et testé avec succès une fonction Cloud Functions Java permettant d'appeler Gemini 1.0 Pro à l'aide de Gemini. Cette application prend en compte la requête d'entrée liée à la recommandation de livres, ainsi que le résumé et le thème des livres.