Bookshelf-Builder: Mit Gemini eine Java-Cloud Functions-Funktion für eine Gemini-Anwendung erstellen

1. Einführung

Lesen Sie gern, sind aber von der schieren Menge an Auswahlmöglichkeiten überfordert? Stellen Sie sich vor, Sie hätten eine KI-basierte App, die Ihnen nicht nur das perfekte Buch empfiehlt, sondern auch eine kurze Zusammenfassung basierend auf Ihrem bevorzugten Genre bietet, damit Sie einen Einblick in das Buch erhalten. In diesem Codelab zeige ich Ihnen, wie Sie eine solche App mit BigQuery und Cloud Functions auf Basis von Gemini erstellen.

Projektübersicht

Unser Anwendungsfall konzentriert sich auf diese vier Hauptkomponenten:

  • Buchdatenbank: Das umfangreiche öffentliche BigQuery-Dataset mit Büchern aus dem Internet Archive dient als umfassender Buchkatalog.
  • AI Summarization Engine: Google Cloud Functions, ausgestattet mit dem Gemini Pro-Sprachmodell, generiert aussagekräftige Zusammenfassungen, die auf Nutzeranfragen zugeschnitten sind.
  • BigQuery-Integration: Eine Remote-Funktion in BigQuery, die unsere Cloud Functions-Funktion aufruft, um On-Demand-Zusammenfassungen und ‑Themen für Bücher zu liefern.
  • Benutzeroberfläche: Eine in Cloud Run gehostete Webanwendung, die Nutzern eine Webanwendung zum Ansehen der Ergebnisse bietet.

Wir teilen die Implementierung in drei Codelabs auf:

Codelab 1: Mit Gemini eine Java-Cloud-Funktion für eine Gemini-Anwendung erstellen.

Codelab 2: Mit Gemini nur mit SQL generative KI-Anwendungen mit BigQuery erstellen.

Codelab 3: Mit Gemini eine Java Spring Boot-Webanwendung erstellen, die mit BigQuery interagiert.

2. Mit Gemini eine serverlose generative KI-App in einer Java Cloud-Funktion erstellen

Aufgaben

Sie erstellen

  • Java Cloud Functions-Anwendung, die Gemini 1.0 Pro implementiert, um einen bestimmten Prompt als Eingabe in Form eines JSON-Arrays zu verwenden und eine Antwort (JSON-Wert mit dem Label „replies“) zurückzugeben.
  • Sie führen die Build- und Bereitstellungsschritte mithilfe von Gemini aus.

3. Voraussetzungen

  • Ein Browser, z. B. Chrome oder Firefox
  • Ein Google Cloud-Projekt mit aktivierter Abrechnung

Es gelten die folgenden Voraussetzungen:

Projekt erstellen

  1. Wählen Sie in der Google Cloud Console auf der Seite zur Projektauswahl ein Google Cloud-Projekt aus oder erstellen Sie eines.
  2. Die Abrechnung für das Cloud-Projekt muss aktiviert sein. So prüfen Sie, ob die Abrechnung für ein Projekt aktiviert ist.

Cloud Shell aktivieren

  1. Sie verwenden Cloud Shell, eine Befehlszeilenumgebung, die in Google Cloud ausgeführt wird und in der bq vorinstalliert ist:

Klicken Sie in der Cloud Console rechts oben auf „Cloud Shell aktivieren“: 6757b2fb50ddcc2d.png

  1. Sobald die Verbindung mit der Cloud Shell hergestellt ist, sehen Sie, dass Sie bereits authentifiziert sind und für das Projekt schon Ihre Projekt-ID eingestellt ist. Führen Sie in der Cloud Shell den folgenden Befehl aus, um zu prüfen, ob Sie authentifiziert sind:
gcloud auth list
  1. Führen Sie den folgenden Befehl in Cloud Shell aus, um zu bestätigen, dass der gcloud-Befehl Ihr Projekt kennt.
gcloud config list project
  1. Wenn Ihr Projekt nicht festgelegt ist, verwenden Sie den folgenden Befehl, um es festzulegen:
gcloud config set project <YOUR_PROJECT_ID>

Informationen zu gcloud-Befehlen und deren Verwendung finden Sie in der Dokumentation.

4. Gemini for Google Cloud und erforderliche APIs aktivieren

Gemini aktivieren

  1. Rufen Sie Gemini for Google Cloud im Marketplace auf, um die API zu aktivieren. Sie können auch den folgenden Befehl verwenden:
gcloud services enable cloudaicompanion.googleapis.com --project PROJECT_ID
  1. Rufen Sie die Gemini-Seite auf und klicken Sie auf „Chat starten“.

Wichtig: Folgen Sie den Schritten 1 und 2 in diesem Codelab, um mit Gemini zu beginnen und Gemini in der Cloud Shell-IDE zu aktivieren.

Andere erforderliche APIs aktivieren

Wie würden wir das tun? Fragen wir Gemini. Denken Sie aber daran:

LLMs sind nicht deterministisch. Daher kann die Antwort, die Sie erhalten, anders aussehen als die in meinem Screenshot.

Rufen Sie die Gemini-Chatkonsole auf, indem Sie in der Google Cloud Console rechts oben neben der Suchleiste auf das Symbol „Gemini öffnen“ klicken.

26e1491322855614.png

Geben Sie diese Frage in den Bereich „Geben Sie hier einen Prompt ein“ ein:

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

Sie sollten eine Antwort ähnlich der folgenden erhalten:

gcloud services enable cloudfunctions.googleapis.com

Kopieren Sie den Befehl (Sie können das Kopiersymbol oben im Befehls-Snippet verwenden) und führen Sie ihn im Cloud Shell-Terminal aus, um Cloud Functions zu aktivieren. Wiederholen Sie den Vorgang für Cloud Run, da wir beide benötigen, um die Cloud Functions-Funktionen zu erstellen und bereitzustellen:

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

5. Cloud Functions-Vorlage mit Gemini vorbereiten

An dieser Stelle gehe ich davon aus, dass Sie Gemini bereits in Ihrer Cloud Shell-IDE aktiviert haben.

Öffnen Sie den Cloud Shell-Editor, indem Sie rechts oben im Cloud Shell-Terminal auf das Symbol „Editor öffnen“ klicken. Ich öffne das Terminal und den Editor normalerweise parallel auf separaten Tabs, damit ich in einem Code schreiben und im anderen erstellen kann.

edd258384bc74f1f.png

Wenn Sie den Editor geöffnet haben, muss das Gemini-Logo unten rechts in der Editorkonsole aktiv sein (und nicht durchgestrichen). Achten Sie außerdem darauf, dass Ihr Google Cloud-Projekt in der unteren linken Ecke auf das aktuelle aktive Projekt verweist, mit dem Sie arbeiten möchten. Wenn sie inaktiv sind, klicken Sie darauf, autorisieren Sie sie, wählen Sie das Google Cloud-Projekt aus, auf das sie verweisen sollen, und aktivieren Sie sie.

Wenn beide aktiviert sind, klicken Sie unten links auf den Projektnamen und scrollen Sie in der Pop-up-Liste mit dem Titel „Cloud Code“ nach unten zu „Neue Anwendung“.

ca08602b576ebd57.png

Wählen Sie in dieser Liste „Cloud Functions-Anwendung“ aus. Wählen Sie in der Liste, die eingeblendet wird, „Java“ aus:

ac2b44245949da68.png

Geben Sie in der angezeigten Liste anstelle von „helloworld“ den Projektnamen „duetai-gemini-calling“ ein und klicken Sie auf „OK“.

bf9cfe86e35cdced.png

Super! Sie haben Ihre einfache Java Cloud Functions-Anwendung mit Gemini erstellt und außer Aktivierungs- und Aktivierungskonfigurationen nicht viel getan, oder?

So sollte die Projektstruktur aussehen:

d56e410fb76f183f.png

Jetzt können Sie die Funktion bereitstellen. Aber das ist nicht der Grund, warum wir damit angefangen haben. Nun erstellen wir die Gemini Pro API-Implementierung in dieser Cloud-Funktion mit dem Java SDK.

Jetzt erstellen wir die Funktionalität für unseren Anwendungsfall, nämlich das Aufrufen des Gemini Pro-Modells in dieser Cloud-Funktion. Dazu können Sie weitere Prompts hinzufügen und den Code mit Gemini schrittweise entwickeln lassen oder die Logik selbst schreiben. Ich werde beides kombinieren.

6. Abhängigkeiten hinzufügen

Geben Sie in der Gemini-Chatkonsole (im Cloud Code Editor im linken Bereich) den folgenden Prompt ein:

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

Ich frage speziell nach dem Paket „com.google.cloud.vertexai“, weil ich es in meinem Quellcode verwende, in dem ich den Gemini-Aufrufcode implementiere.

Ich habe dieses Ergebnis erhalten:

62c4295b9b4654e9.png

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

Kopieren Sie diesen Code und fügen Sie ihn in die pom.xml-Datei ein, direkt vor dem Tag </dependencies>. Ersetzen Sie die Version durch 0.1.0. Sie können das <version>-Tag entfernen, wenn Sie die Spring Cloud GCP-BOM verwenden, um die Versionsnummern von spring-cloud-gcp zu verwalten.

Der Abschnitt „Abhängigkeit“ sollte so aussehen:

1800f10af9331210.png

Aktualisieren Sie die Versionsnummern bei Bedarf entsprechend den oben genannten. Wie Sie sehen, habe ich auch eine weitere Abhängigkeit hinzugefügt:

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

7. Funktionseinstiegspunkt und Klassenname ändern

  1. Rufen Sie die Datei „launch.json“ im Ordner „.vscode“ auf. Ändern Sie den Funktionsnamen von „function-hello-world“ in „function-gemini-calling“.
  2. Aktualisieren Sie den Wert von „entryPoint“ von „cloudcode.helloworld.HelloWorld“ auf „cloudcode.bookshelf.Bookshelf“.
  3. Rufen Sie nun die Java-Klassendatei „HelloWorld.java“ auf. Ändern Sie den Paketnamen in „package cloudcode.bookshelf;“. Klicken Sie im angezeigten Fehler auf die gelbe Glühbirne und dann auf die Option „Move HelloWorld.java“ to package cloudcode.bookshelf;“.

38d721978bddc8a8.png

  1. Ändern Sie den Klassennamen in „Bookshelf“ und klicken Sie im angezeigten Fehler auf die kleine gelbe Glühbirne. Wählen Sie dann „Rename file to Bookshelf.java“ (Datei in „Bookshelf.java“ umbenennen) aus. Wählen Sie diese Option aus.

8. Methode zum Aufrufen von Gemini Pro erstellen

Implementieren wir diese Funktion in der Klasse „Bookshelf.java“. Ersetzen Sie „Bookshelf.java“ durch den folgenden Code:

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

Diese Klasse erwartet die Eingabe in der folgenden JSON-Struktur:

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

Es wird eine Antwort wie unten zurückgegeben:

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

Probieren Sie die Gemini-Chatoption im Cloud Shell-Editor im linken Bereich aus, um den Code erklären zu lassen. Alternativ können Sie den gesamten Code auswählen, links oben in der Auswahl auf das gelbe Glühbirnensymbol klicken und die Option „Erkläre das“ auswählen.

66fb67507793e368.png

9. Cloud Functions-Funktion bereitstellen

Nachdem die Cloud Functions-Funktion fertig ist, fragen wir Gemini, wie wir sie bereitstellen können. Rufen Sie den Gemini-Chat im Cloud Code-Editor auf und geben Sie Folgendes ein:

   How to deploy this Cloud Function with a gcloud command?

Ich habe die folgende Antwort erhalten:

9f9db98933841864.png

Ich wollte das jetzt genauer untersuchen. Ich habe Gemini also gebeten, mir den vollständigen gcloud-Befehl zum Bereitstellen von Funktionen zu geben. Die Antwort sieht so aus:

b77701c00dc3eaf1.png

Ich kann nicht sagen, ob Sie dieselbe Antwort erhalten, aber ich fand es ziemlich interessant, dass sie überraschenderweise noch ein paar weitere Details enthält, wie im Bild unten zu sehen ist:

Format des Anfragetexts:

82bf20304143a374.png

und

Antwortformat:

ade55b3de5d823a6.png

Stellen wir nun die Funktion bereit, indem wir den gcloud-Befehl ausführen, den wir von Gemini erhalten haben. Dazu müssen wir das Cloud Shell-Terminal öffnen. Sie können es in einem neuen Tab unter https://console.cloud.google.com öffnen und darauf achten, dass das richtige Projekt ausgewählt ist. Öffnen Sie das Cloud Shell-Terminal, indem Sie rechts oben in der Konsole auf das Symbol „Cloud Shell aktivieren“ klicken. Prüfen Sie mit dem folgenden Befehl, ob Sie sich im richtigen Projektordner befinden:

cd duetai-gemini-calling

Führen Sie dann den folgenden Befehl aus:

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

Sie werden gefragt: „Nicht authentifizierte Aufrufe der neuen Funktion [bookshelf] zulassen?“ Sagen Sie „y“ und drücken Sie die Eingabetaste. Danach werden gegebenenfalls einige Fragen gestellt und Ihre serverlose Cloud-Funktion wird mit der bereitgestellten URL bereitgestellt: https://us-central1-*******.cloudfunctions.net/bookshelf.

Rufen wir nun die bereitgestellte Cloud Functions-Funktion auf und testen sie.

Hinweis: Wenn Sie die Frage „Nicht authentifizierte Aufrufe zulassen?“ versehentlich übersprungen oder „N“ ausgewählt haben, können Sie nicht auf das Ergebnis der Cloud Functions zugreifen und sehen ohne zusätzliche IAM-Einstellungen einen Berechtigungsfehler. Achten Sie also darauf.

10. Bereitgestellte Cloud Functions-Funktion aufrufen

Fragen wir Gemini. Ich habe den Prompt eingegeben

How to call the deployed cloud function?

Ich habe das folgende Ergebnis erhalten: (Möglicherweise sehen Sie nicht genau dieselbe Antwort. Sie können den Prompt gerne ausprobieren und die Unterschiede in den Antworten sehen.)

1d2242715571fe6f.png

Stelle dem Chatbot spezifische Fragen zu alternativen Möglichkeiten, die bereitgestellte Funktion aufzurufen, z. B. mit einem gcloud-Befehl. Ich habe den folgenden Prompt gesendet:

how to call the deployed cloud function using gcloud

Ich habe die folgende Antwort erhalten: e7b29b2cfb57782c.png

Sie können diese Antwort (Befehl „gcloud functions call“) im Terminal verwenden und an unser Szenario anpassen. Alternativ können Sie die Parameter auch im Prompt übergeben und sehen, ob Sie eine detaillierte Antwort zum „gcloud functions call“-Befehl erhalten:

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

Hier ist mein Ergebnis:

6f396d915251db78.png

11. Bereinigen

Sie können die zuvor erstellten Cloud Functions löschen, indem Sie auf der Detailseite der Cloud Functions auf die Schaltfläche „LÖSCHEN“ klicken.

12. Glückwunsch

Sie haben erfolgreich eine Java Cloud Functions-Funktion erstellt, bereitgestellt und getestet, um Gemini 1.0 Pro mit Gemini aufzurufen. Diese Anwendung verwendet den Eingabe-Prompt für Buchempfehlungen mit der Zusammenfassung und dem Thema von Büchern.