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

1. Einführung

Du liebst es, in Bücher einzutauchen, aber die schiere Menge an Optionen überfordert dich? Stellen Sie sich eine KI-gestützte App vor, die Ihnen nicht nur das perfekte Buch empfiehlt, sondern auch eine kurze Zusammenfassung basierend auf Ihrem bevorzugten Genre anbietet, die Ihnen einen Einblick in den Inhalt des Buches gibt. In diesem Codelab zeige ich Ihnen, wie Sie eine solche App mit BigQuery und Cloud Functions erstellen, die auf Gemini basieren.

Projektübersicht

Bei unserem Anwendungsfall geht es um diese 4 Hauptkomponenten:

  • Buchdatenbank: Der umfangreiche öffentliche BigQuery-Dataset mit Büchern aus dem Internetarchiv dient als umfassender Buchkatalog.
  • KI-Summarisierungs-Engine: Google Cloud Functions mit dem Gemini-Pro-Sprachmodell generieren aussagekräftige Zusammenfassungen, die auf Nutzeranfragen zugeschnitten sind.
  • BigQuery-Integration: Eine Remote-Funktion in BigQuery, die unsere Cloud Functions-Funktion aufruft, um Buchzusammenfassungen und Themen on demand bereitzustellen.
  • Benutzeroberfläche: Eine in Cloud Run gehostete Webanwendung, über die Nutzer die Ergebnisse abrufen können.

Wir unterteilen die Implementierung in drei Codelabs:

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

Codelab 2: Mit Gemini generative KI-Anwendungen mit reiner SQL-Programmierung in 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 eine

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

3. Voraussetzungen

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

Folgende Voraussetzungen müssen erfüllt sein:

Projekt erstellen

  1. Wählen Sie in der Google Cloud Console auf der Seite der Projektauswahl ein Google Cloud-Projekt aus oder erstellen Sie eines.
  2. Die Abrechnung für das Cloud-Projekt muss aktiviert sein. Hier erfahren Sie, wie Sie prüfen, 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 bq vorinstalliert hat:

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

  1. Sobald Sie mit Cloud Shell verbunden sind, sollten Sie sehen, dass Sie bereits authentifiziert sind und das Projekt bereits auf Ihre Projekt-ID festgelegt ist. Führen Sie in Cloud Shell den folgenden Befehl aus, um zu prüfen, ob Sie authentifiziert sind:
gcloud auth list
  1. Führen Sie in Cloud Shell den folgenden Befehl aus, um zu prüfen, ob der gcloud-Befehl Ihr Projekt kennt:
gcloud config list project
  1. Wenn Ihr Projekt noch nicht eingerichtet ist, verwenden Sie den folgenden Befehl, um es festzulegen:
gcloud config set project <YOUR_PROJECT_ID>

Weitere 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 für 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: Führen Sie die Schritte 1 und 2 in diesem Codelab aus, um mit Gemini zu beginnen und Gemini in der Cloud Shell-IDE zu aktivieren.

Weitere erforderliche APIs aktivieren

Wie würden wir das machen? Fragen wir Gemini. Beachten Sie aber Folgendes:

LLMs sind nicht deterministisch. Wenn Sie diese Prompts ausprobieren, kann die Antwort, die Sie erhalten, also von der in meinem Screenshot abweichen.

Klicken Sie in der Google Cloud Console rechts oben neben der Suchleiste auf das Symbol „Gemini öffnen“, um die Gemini-Chatkonsole aufzurufen.

26e1491322855614.png

Geben Sie diese Frage in den Bereich „Prompt eingeben“ 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 dazu das Kopiersymbol oben im Befehls-Snippet verwenden) und führen Sie ihn im Cloud Shell-Terminal aus, um die Cloud Functions zu aktivieren. Führen Sie dasselbe für Cloud Run aus, da wir beide benötigen, um die Cloud Functions 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

Ich gehe 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 bevorzuge es, das Terminal und den Editor parallel in separaten Tabs zu öffnen, damit wir Code in einem und Builds in einem anderen schreiben können.

edd258384bc74f1f.png

Achten Sie beim Öffnen des Editors darauf, dass das Gemini-Logo rechts unten in der Editorkonsole aktiv ist (nicht ausgegraut). Achten Sie außerdem darauf, dass Ihr Google Cloud-Projekt links unten auf das aktuell 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.

Sobald beide aktiv sind, klicken Sie unten links auf den Projektnamen und scrollen Sie in der Pop-up-Liste mit dem Titel „Cloud Code“ nach unten zu „New Application“.

ca08602b576ebd57.png

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

ac2b44245949da68.png

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

bf9cfe86e35cdced.png

Super! Sie haben Ihre einfache Java Cloud Functions-Anwendung mit Gemini per Bootstrapping verknüpft und nicht viel getan, abgesehen von der Aktivierung und Aktivierung von Konfigurationen, stimmten Sie?

Dies ist die Projektstruktur, die Sie sehen sollten:

d56e410fb76f183f.png

Sie können die Funktion jetzt bereitstellen. Aber das war nicht der Grund, warum wir das Projekt gestartet haben. Als Nächstes erstellen wir mit dem Java SDK die Gemini Pro API-Implementierung in dieser Cloud Functions-Funktion.

Erstellen wir nun die Funktion für unseren Anwendungsfall, bei dem das Gemini Pro-Modell in dieser Cloud-Funktion aufgerufen wird. Dazu können Sie weitere Prompts hinzufügen und Ihren Code inkrementell mit Gemini entwickeln lassen oder die Logik selbst schreiben. Ich werde eine Mischung aus beiden verwenden.

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 Tag <version> entfernen, wenn Sie die Spring-Cloud-GCP-Versionsnummern mit der Spring Cloud GCP-BOM verwalten.

Der Abhängigkeitsbereich sollte so aussehen:

1800f10af9331210.png

Aktualisieren Sie gegebenenfalls die Versionsnummern entsprechend den obigen Angaben. Ich habe 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 Klassennamen ändern

  1. Gehen Sie im Ordner „.vscode“ zur Datei „launch.json“. Ändern Sie den Funktionsnamen von „function-hello-world“ in „function-gemini-calling“.
  2. Aktualisieren Sie den Wert „entryPoint“ von „cloudcode.helloworld.HelloWorld“ zu „cloudcode.bookshelf.Bookshelf“.
  3. Rufen Sie jetzt die Java-Klassendatei „HelloWorld.java“ auf. Ändern Sie den Paketnamen in „package cloudcode.bookshelf“. Klicken Sie in der Fehlermeldung auf die gelbe Glühbirne und dann auf die Option „HelloWorld.java in das Paket cloudcode.bookshelf verschieben“.

38d721978bddc8a8.png

  1. Ändern Sie den Klassennamen in „Bookshelf“ und klicken Sie im angezeigten Fehler auf die kleine gelbe Glühbirne und wählen Sie „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 eine Eingabe in der folgenden JSON-Struktur:

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

Es wird eine Antwort wie folgt 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 zu erklären. Alternativ können Sie den gesamten Code auswählen, oben links in der Auswahl auf die gelbe Glühbirne klicken und die Option „Erkläre das“ auswählen.

66fb67507793e368.png

9. Cloud Functions-Funktion bereitstellen

Da die Cloud Functions-Funktion nun bereit ist, können Sie Gemini fragen, wie sie bereitgestellt wird. Rufen Sie im Cloud Code-Editor den Gemini-Chat auf und geben Sie Folgendes ein:

   How to deploy this Cloud Function with a gcloud command?

Ich habe folgende Antwort erhalten:

9f9db98933841864.png

Ich wollte das jetzt genauer untersuchen. Ich habe Gemini also gebeten, mir den vollständigen Befehl „gcloud functions deploy“ zu nennen. Die Antwort sieht so aus:

b77701c00dc3eaf1.png

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

Format des Anfragetexts:

82bf20304143a374.png

und

Antwortformat:

ade55b3de5d823a6.png

Jetzt können wir die Funktion bereitstellen, indem wir den gcloud-Befehl ausführen, den Gemini uns gegeben hat. Dazu müssen wir das Cloud Shell-Terminal öffnen. Sie können es in einem neuen Tab für https://console.cloud.google.com öffnen und prüfen, ob 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

Darauf folgt der folgende Befehl:

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 „Ja“ und drücken Sie die Eingabetaste. Danach müssen Sie noch ein paar Fragen stellen und Ihre serverlose Cloud Functions-Funktion wird mit der bereitgestellten URL bereitgestellt: https://us-central1-*******.cloudfunctions.net/Bookshelf.

Rufen Sie nun die bereitgestellten Cloud Functions-Funktionen auf und testen Sie 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-Funktionen zugreifen. Es wird ein „Berechtigungsfehler“ angezeigt, ohne dass zusätzliche IAM-Einstellungen gewährt werden. 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: (Sie erhalten möglicherweise nicht genau dieselbe Antwort. Probieren Sie den Prompt einfach aus und sehen Sie sich die Unterschiede in den Antworten an.)

1d2242715571fe6f.png

Stellen Sie im Chat konkrete Fragen zu alternativen Möglichkeiten, die bereitgestellte Funktion aufzurufen, z. B. mit dem gcloud-Befehl. Ich habe den folgenden Prompt gesendet:

how to call the deployed cloud function using gcloud

Ich habe folgende Antwort erhalten: e7b29b2cfb57782c.png

Sie können diese Antwort (Befehl „gcloud functions call“) im Terminal verwenden und sie so anpassen, dass sie für unser Szenario funktioniert. Alternativ können Sie versuchen, die Parameter direkt im Prompt zu übergeben und zu prüfen, ob Sie den detaillierten gcloud functions call als Antwort 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 akzeptiert die Eingabeaufforderung in Bezug auf Buchempfehlungen mit der Zusammenfassung und dem Thema „Bücher“.