Builder di librerie: usa Gemini per creare una funzione Cloud Functions Java per un'applicazione Gemini

1. Introduzione

Ti piace leggere libri, ma sei sopraffatto dall'enorme quantità di scelta? Immagina di avere un'app basata sull'IA che non solo consiglia la lettura perfetta, ma offre anche un riepilogo conciso in base al genere scelto, dandoti un'idea dell'essenza del libro. In questo codelab, ti guiderò attraverso la creazione di un'app di questo tipo con BigQuery e Cloud Functions basato su Gemini.

Panoramica del progetto

Il nostro caso d'uso si basa su questi quattro componenti chiave:

  • Database di libri: il vasto set di dati pubblico di BigQuery dei libri dell'archivio di internet fungerà da catalogo completo di libri.
  • Motore di sintesi dell'IA: Cloud Functions di Google, dotato del modello linguistico Gemini-Pro, genera riepiloghi utili personalizzati in base alle richieste degli utenti.
  • Integrazione di BigQuery: una funzione remota all'interno di BigQuery che chiama la nostra funzione Cloud Functions per fornire riepiloghi e temi dei libri su richiesta.
  • Interfaccia utente: un'app web ospitata su Cloud Run che offrirà un'applicazione web per consentire agli utenti di visualizzare i risultati.

Divideremo l'implementazione in 3 codelab:

Codelab 1: utilizza Gemini per creare una funzione Cloud Java per un'applicazione Gemini.

Codelab 2: utilizza Gemini per creare applicazioni di IA generativa solo SQL con BigQuery.

Codelab 3: utilizza Gemini per creare un'applicazione web Java Spring Boot che interagisce con BigQuery.

2. Utilizzare Gemini per creare un'app di IA generativa in modo serverless su Java Cloud Function

Cosa creerai

Dovrai creare un

  • Applicazione Java Cloud Functions che implementa Gemini 1.0 Pro in modo che prenda un prompt specifico come input sotto forma di array JSON e restituisce una risposta (valore JSON etichettato come "replies").
  • Eseguirai i passaggi di compilazione e di deployment con l'aiuto di Gemini

3. Requisiti

  • Un browser, ad esempio Chrome o Firefox
  • Un progetto Google Cloud con fatturazione abilitata

Di seguito sono riportati i prerequisiti:

Creare il progetto

  1. Nella console Google Cloud, nella pagina di selezione del progetto, seleziona o crea un progetto Google Cloud.
  2. Verifica che la fatturazione sia attivata per il tuo progetto Cloud. Scopri come controllare se la fatturazione è abilitata per un progetto.

Attivare Cloud Shell

  1. Utilizzerai Cloud Shell, un ambiente a riga di comando in esecuzione in Google Cloud con bq preinstallato:

Nella console Cloud, fai clic su Attiva Cloud Shell nell'angolo in alto a destra: 6757b2fb50ddcc2d.png

  1. Una volta eseguita la connessione a Cloud Shell, dovresti vedere che il tuo account è già autenticato e il progetto è già impostato sul tuo ID progetto. Esegui questo comando in Cloud Shell per verificare che l'account sia autenticato:
gcloud auth list
  1. Esegui questo comando in Cloud Shell per confermare che il comando gcloud sia a conoscenza del tuo progetto
gcloud config list project
  1. Se il progetto non è impostato, utilizza il seguente comando per impostarlo:
gcloud config set project <YOUR_PROJECT_ID>

Consulta la documentazione per i comandi e l'utilizzo di gcloud.

4. Abilitazione di Gemini per Google Cloud e le API necessarie in corso...

Abilita Gemini

  1. Vai a Gemini per Google Cloud nel Marketplace per abilitare l'API. Puoi anche utilizzare il seguente comando:
gcloud services enable cloudaicompanion.googleapis.com --project PROJECT_ID
  1. Visita la pagina di Gemini e fai clic su "Inizia a chattare".

Importante: segui i passaggi 1 e 2 di questo codelab per iniziare a utilizzare Gemini e per attivare Gemini nell'IDE Cloud Shell.

Abilita altre API necessarie

Come possiamo farlo? Chiediamo a Gemini, d'accordo? Prima, però, ricorda:

Gli LLM sono non deterministici. Pertanto, mentre provi questi prompt, la risposta che ricevi potrebbe essere diversa da quella mostrata nel mio screenshot.

Vai alla console della chat con Gemini facendo clic sull'icona "Apri Gemini" nell'angolo in alto a destra, accanto alla barra di ricerca nella console Google Cloud.

26e1491322855614.png

Digita questa domanda nella sezione "Inserisci un prompt qui":

How do I enable the cloud functions api using a gcloud command? 

Dovresti ricevere una risposta analoga a:

gcloud services enable cloudfunctions.googleapis.com

Copialo (puoi utilizzare l'icona di copia nella parte superiore dello snippet di comando) ed eseguilo nel terminale Cloud Shell per abilitare le funzioni Cloud Functions. Fai lo stesso per Cloud Run, perché abbiamo bisogno di entrambe per ottenere la creazione e il deployment di Cloud Functions:

gcloud services enable \
  cloudfunctions.googleapis.com \
  aiplatform.googleapis.com \
  run.googleapis.com \
  cloudbuild.googleapis.com

5. Preparazione del modello Cloud Functions con Gemini

A questo punto, presumo che tu abbia già attivato Gemini nel tuo IDE Cloud Shell.

Apri l'editor di Cloud Shell facendo clic sull'icona Apri editor nell'angolo in alto a destra del terminale Cloud Shell (di solito preferisco aprire il terminale e l'editor in schede separate in parallelo in modo da poter scrivere il codice in uno e creare in un altro).

edd258384bc74f1f.png

Una volta aperto l'editor, assicurati che il logo di Gemini nell'angolo in basso a destra della console dell'editor sia attivo (e non annullato). Assicurati inoltre che il progetto Google Cloud nell'angolo in basso a sinistra indirizzi al progetto attivo corrente con cui vuoi lavorare. Se sono inattivi, fai clic su di essi, autorizzali, seleziona il progetto Google Cloud a cui vuoi che puntino e attivali.

Una volta che entrambi sono attivi, fai clic sul nome del progetto nell'angolo in basso a sinistra e nell'elenco popup che si apre denominato "Cloud Code", scorri verso il basso fino a "Nuova applicazione".

ca08602b576ebd57.png

Seleziona l'applicazione Cloud Functions nell'elenco. Dall'elenco visualizzato, seleziona Java:

ac2b44245949da68.png

Nell'elenco visualizzato, digita il nome del progetto "duetai-gemini-calling" anziché helloworld e fai clic su OK.

bf9cfe86e35cdced.png

Evviva! Hai eseguito l'avvio iniziale della tua semplice applicazione Java Cloud Functions con Gemini e non hai fatto molto oltre a abilitare e attivare le configurazioni, giusto?

Questa è la struttura del progetto che dovresti vedere:

d56e410fb76f183f.png

Ora puoi eseguire il deployment della funzione. Ma non è per questo che abbiamo iniziato. Procediamo e creiamo l'implementazione dell'API Gemini Pro in questa funzione Cloud utilizzando l'SDK Java.

Ora costruiamo la funzionalità per il nostro caso d'uso, ovvero l'invocazione del modello Gemini Pro in questa funzione Cloud. Per farlo, puoi aggiungere altri prompt e sviluppare il tuo codice in modo incrementale con Gemini oppure scrivere la logica autonomamente. Userò un mix di entrambi.

6. Aggiungi dipendenze

Nella console di chat di Gemini (quella all'interno di Cloud Code Editor nel riquadro a sinistra), digita il seguente prompt:

what is the maven dependency for com.google.cloud.vertexai library

Ti chiedo il pacchetto com.google.cloud.vertexai perché è quello che utilizzo nel mio codice sorgente in cui implemento il codice di chiamata di Gemini.

Ho ottenuto questo risultato:

62c4295b9b4654e9.png

 <dependency>
      <groupId>com.google.cloud</groupId>
      <artifactId>google-cloud-vertexai</artifactId>
      <version>0.1.0</version>
    </dependency>

Copialo e incollalo nel file pom.xml, subito prima del tag </dependencies>. Sostituisci la versione con 0.1.0 (puoi rimuovere il tag <version> se utilizzi il BOM di Spring Cloud GCP per gestire i numeri di versione di spring-cloud-gcp).

La sezione delle dipendenze dovrebbe avere il seguente aspetto:

1800f10af9331210.png

Assicurati di aggiornare i numeri di versione, se necessario, in modo che corrispondano a quelli riportati sopra. Se noti, ho incluso anche un'altra dipendenza:

    <dependency>
      <groupId>com.google.code.gson</groupId>
      <artifactId>gson</artifactId>
      <version>2.10</version>
    </dependency>

7. Modifica il punto di ingresso della funzione e il nome della classe

  1. Vai al file "launch.json" nella cartella ".vscode". Modifica il nome della funzione da "function-hello-world" a "function-gemini-calling".
  2. Aggiorna il valore entryPoint da "cloudcode.helloworld.HelloWorld a cloudcode.bookmen.Book {/4}.
  3. Ora passa al file di classe Java "HelloWorld.java". Modifica il nome del pacchetto in pacchetto cloudcode.bookmen. Nell'errore che viene visualizzato, fai clic sulla lampadina gialla e seleziona l'opzione "Sposta HelloWorld.java" nel pacchetto cloudcode.bookmen;.

38d721978bddc8a8.png

  1. Aggiorna il nome della classe in Libreria e, nell'errore visualizzato, fai clic sulla piccola lampadina gialla e seleziona "Rinomina il file in Libreria.java". Selezionalo.

8. Crea il metodo che chiama Gemini Pro

Implementiamo questa funzionalità nella classe Bookmen.java. Sostituisci Bookshelf.java con il codice seguente:

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;
    }
}

Questa classe prevede un input nella struttura JSON come segue:

{ "calls": [["YOUR_PROMPT_HERE"]] }

Restituisce una risposta come la seguente:

(Json) Mappa<String, List<String>> {"replies": ["response"]}

Prova l'opzione della chat con Gemini dall'editor di Cloud Shell nel riquadro a sinistra per spiegare il codice. In alternativa, puoi selezionare tutto il codice, fare clic sulla lampadina gialla nell'angolo in alto a sinistra della selezione e scegliere l'opzione "Spiega".

66fb67507793e368.png

9. Esegui il deployment della funzione Cloud

Ora che la funzione Cloud è pronta, chiediamo a Gemini come eseguirne il deployment. Vai alla chat di Gemini nell'editor Cloud Code e inserisci quanto segue:

   How to deploy this Cloud Function with a gcloud command?

Ho ricevuto la seguente risposta:

9f9db98933841864.png

Ora volevo approfondire. Ho quindi chiesto a Gemini di darmi il comando gcloud functions deploy completo. La risposta è come mostrato di seguito:

b77701c00dc3eaf1.png

Ora non posso dirti se riceverai la stessa risposta, ma mi è molto interessante vedere che aggiunge alcuni dettagli in più per mia sorpresa, come si vede nell'immagine di seguito:

Formato del corpo della richiesta:

82bf20304143a374.png

e

Formato della risposta:

ade55b3de5d823a6.png

Ora eseguiamo il deployment della funzione eseguendo il comando gcloud che ci ha fornito Gemini. Per farlo, dobbiamo aprire il terminale Cloud Shell. Puoi aprirlo in una nuova scheda per https://console.cloud.google.com e assicurarti che sia selezionato il progetto corretto. Apri il terminale Cloud Shell facendo clic sull'icona Attiva Cloud Shell nell'angolo in alto a destra della console e assicurati di essere nella cartella di progetto corretta usando questo comando:

cd duetai-gemini-calling

Seguito dal comando seguente:

gcloud functions deploy bookshelf --runtime java17 --trigger-http --entry-point cloudcode.bookshelf.Bookshelf --allow-unauthenticated

Ti verrà chiesto "Consenti chiamate non autenticate della nuova funzione [bookshelf]?" Di' "sì" e premi Invio. Dopodiché, se applicabile, ti verranno poste alcune domande e verrà eseguito il deployment della tua funzione Cloud serverless con l'URL di deployment: https://us-central1-*******.cloudfunctions.net/bookshelf.

Ora richiamiamo le funzioni Cloud Functions di cui è stato eseguito il deployment e testiamola.

Nota: se hai ignorato per errore la domanda "Consenti chiamate non autenticate" o hai selezionato "N", non potrai accedere ai risultati delle funzioni Cloud Functions e riceveresti un "errore di autorizzazione" senza concedere impostazioni IAM aggiuntive. Fai attenzione.

10. Chiama la funzione Cloud di cui è stato eseguito il deployment

Chiediamolo a Gemini. Ho inserito il prompt

How to call the deployed cloud function?

Ho ottenuto il seguente risultato: (potresti o meno vedere la stessa risposta esatta, non esitare a provare il prompt e a vedere la differenza nelle risposte).

1d2242715571fe6f.png

Esegui la scansione della chat con domande specifiche su modi alternativi per richiamare la funzione di cui è stato eseguito il deployment, chiama utilizzando il comando gcloud e così via. Ho inviato il seguente prompt:

how to call the deployed cloud function using gcloud

Ho ricevuto la seguente risposta: e7b29b2cfb57782c.png

Puoi utilizzare questa risposta dal terminale con qualche ritocco per adattarlo al nostro scenario (in alternativa, prova a passare i parametri nel prompt stesso e controlla se riesci a ottenere la chiamata dettagliata delle funzioni gcloud in risposta):

gcloud functions call bookshelf --region=us-central1 --gen2 --data '{"calls":[["Hello! This is my test prompt."]]}'

Ecco il mio risultato:

6f396d915251db78.png

11. Esegui la pulizia

Puoi eliminare le funzioni Cloud create in precedenza facendo clic sul pulsante ELIMINA nella pagina dei dettagli delle funzioni Cloud.

12. Complimenti

Hai creato, eseguito il deployment e testato una funzione Cloud Functions Java per chiamare Gemini 1.0 Pro utilizzando Gemini. Questa applicazione prende il prompt di input relativo al consiglio di libri con il riepilogo e il tema dei libri.