Kreator półki: użyj Gemini, aby utworzyć funkcję w Cloud Functions dla aplikacji Gemini w Javie

1. Wprowadzenie

Lubisz czytać książki, ale przytłacza Cię ogromny wybór? Wyobraź sobie aplikację opartą na AI, która nie tylko poleca idealną lekturę, ale też oferuje zwięzłe podsumowanie na podstawie wybranego gatunku, dając Ci wgląd w treść książki. W tym module pokażę Ci, jak utworzyć taką aplikację przy użyciu BigQuery i Cloud Functions z Gemini.

Project Overview

Nasz przypadek użycia opiera się na tych 4 kluczowych komponentach:

  • Baza danych książek: obszerny publiczny zbiór danych BigQuery z książkami z archiwum internetowego będzie służyć jako nasz kompleksowy katalog książek.
  • Silnik podsumowujący oparty na AI: Google Cloud Functions, wyposażony w model językowy Gemini Pro, będzie generować przydatne podsumowania dostosowane do żądań użytkowników.
  • Integracja z BigQuery: funkcja zdalna w BigQuery, która wywołuje naszą funkcję Cloud Function, aby dostarczać podsumowania i motywy książek na żądanie.
  • Interfejs użytkownika: aplikacja internetowa hostowana w Cloud Run, która będzie udostępniać użytkownikom aplikację internetową do wyświetlania wyników.

Implementację podzielimy na 3 warsztaty:

Codelab 1. Używanie Gemini do tworzenia funkcji w Cloud Functions w języku Java na potrzeby aplikacji Gemini.

Codelab 2. Używanie Gemini do tworzenia aplikacji generatywnej AI opartych wyłącznie na SQL w BigQuery.

Codelab 3. Użyj Gemini do utworzenia aplikacji internetowej Java Spring Boot, która wchodzi w interakcję z BigQuery.

2. Tworzenie aplikacji opartej na generatywnej AI bezserwerowo w Cloud Functions w języku Java za pomocą Gemini

Co utworzysz

Utworzysz

  • Aplikacja Java Cloud Functions, która implementuje Gemini 1.0 Pro, aby przyjmować określony prompt jako dane wejściowe w formacie tablicy JSON i zwracać odpowiedź (wartość JSON oznaczona jako „replies”).
  • Kroki kompilacji i wdrażania wykonasz z pomocą Gemini.

3. Wymagania

  • przeglądarka, np. Chrome lub Firefox;
  • projekt Google Cloud z włączonymi płatnościami;

Wymagania wstępne:

Tworzenie projektu

  1. W konsoli Google Cloud na stronie selektora projektów wybierz lub utwórz projekt Google Cloud.
  2. Sprawdź, czy w projekcie Cloud włączone są płatności. Dowiedz się, jak sprawdzić, czy w projekcie są włączone płatności.

Aktywuj Cloud Shell

  1. Będziesz używać Cloud Shell, czyli środowiska wiersza poleceń działającego w Google Cloud, które jest wstępnie załadowane narzędziem bq:

W konsoli Cloud kliknij Aktywuj Cloud Shell w prawym górnym rogu: 6757b2fb50ddcc2d.png

  1. Po połączeniu z Cloud Shell zobaczysz, że uwierzytelnianie zostało już przeprowadzone, a projekt jest już ustawiony na Twój identyfikator projektu. Aby potwierdzić, że uwierzytelnianie zostało przeprowadzone, uruchom w Cloud Shell to polecenie:
gcloud auth list
  1. Aby potwierdzić, że polecenie gcloud zna Twój projekt, uruchom w Cloud Shell to polecenie:
gcloud config list project
  1. Jeśli projekt nie jest ustawiony, użyj tego polecenia, aby go ustawić:
gcloud config set project <YOUR_PROJECT_ID>

Informacje o poleceniach gcloud i ich użyciu znajdziesz w dokumentacji.

4. Włączanie Gemini for Google Cloud i niezbędnych interfejsów API

Włącz Gemini

  1. Aby włączyć interfejs API, przejdź do Gemini for Google Cloud w Marketplace. Możesz też użyć tego polecenia:
gcloud services enable cloudaicompanion.googleapis.com --project PROJECT_ID
  1. Odwiedź stronę Gemini i kliknij „Rozpocznij czat”.

Ważne: aby rozpocząć korzystanie z Gemini i włączyć Gemini w środowisku IDE Cloud Shell, wykonaj kroki 1 i 2 w tym samouczku.

Włącz inne niezbędne interfejsy API

Jak to zrobić? Zapytajmy o to Gemini. Pamiętaj jednak, że:

Modele LLM nie są deterministyczne. Dlatego podczas testowania tych promptów otrzymana odpowiedź może wyglądać inaczej niż na moim zrzucie ekranu.

Otwórz konsolę rozmowy z Gemini, klikając ikonę „Otwórz Gemini” w prawym górnym rogu obok paska wyszukiwania w konsoli Google Cloud.

26e1491322855614.png

Wpisz to pytanie w sekcji „Tutaj wpisz prompta”:

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

Powinna pojawić się odpowiedź podobna do tej:

gcloud services enable cloudfunctions.googleapis.com

Skopiuj to polecenie (możesz użyć ikony kopiowania u góry fragmentu kodu) i uruchom je w terminalu Cloud Shell, aby włączyć Cloud Functions. Zrób to samo w przypadku Cloud Run, ponieważ potrzebujemy obu tych usług, aby utworzyć i wdrożyć Cloud Functions:

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

5. Przygotowywanie szablonu Cloud Functions za pomocą Gemini

Zakładam, że masz już włączoną usługę Gemini w środowisku IDE Cloud Shell.

Otwórz edytor Cloud Shell, klikając ikonę Otwórz edytor w prawym górnym rogu terminala Cloud Shell (zwykle wolę otwierać terminal i edytor równolegle w osobnych kartach, aby móc pisać kod w jednym i budować w drugim).

edd258384bc74f1f.png

Po otwarciu edytora upewnij się, że logo Gemini w prawym dolnym rogu konsoli edytora jest aktywne (nie jest przekreślone). Sprawdź też, czy w lewym dolnym rogu jest wyświetlany projekt Google Cloud, z którego chcesz korzystać. Jeśli są nieaktywne, kliknij je, autoryzuj, wybierz projekt Google Cloud, do którego mają prowadzić, i aktywuj je.

Gdy oba będą aktywne, kliknij nazwę projektu w lewym dolnym rogu, a następnie na liście, która się otworzy, zatytułowanej „Cloud Code” przewiń w dół do pozycji „New Application” (Nowa aplikacja).

ca08602b576ebd57.png

Na liście wybierz Aplikacja Cloud Functions. Z wyświetlonej listy wybierz Java:

ac2b44245949da68.png

Na wyświetlonej liście wpisz nazwę projektu „duetai-gemini-calling” zamiast helloworld i kliknij OK.

bf9cfe86e35cdced.png

Hurra! Uruchomiono prostą aplikację Java Cloud Functions z Gemini i nie wykonano żadnych innych czynności poza włączeniem i aktywacją konfiguracji, prawda?

Powinna pojawić się ta struktura projektu:

d56e410fb76f183f.png

Teraz możesz wdrożyć funkcję. Ale nie dlatego zaczęliśmy to robić. Teraz utworzymy implementację interfejsu Gemini Pro API w tej funkcji Cloud Function za pomocą pakietu Java SDK.

Teraz zbudujmy funkcję dla naszego przypadku użycia, czyli wywoływanie modelu Gemini Pro w tej funkcji w Cloud Functions. Aby to zrobić, możesz dodać więcej promptów i stopniowo rozwijać kod za pomocą Gemini lub samodzielnie napisać logikę. Zamierzam zrobić jedno i drugie.

6. Dodawanie zależności

W konsoli rozmowy z Gemini (w edytorze Cloud Code w panelu po lewej stronie) wpisz ten prompt:

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

Proszę o informacje dotyczące pakietu com.google.cloud.vertexai, ponieważ używam go w kodzie źródłowym, w którym implementuję kod wywołania Gemini.

Otrzymano ten wynik:

62c4295b9b4654e9.png

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

Skopiuj ten kod i wklej go do pliku pom.xml przed tagiem </dependencies>. Zastąp wersję numerem 0.1.0 (jeśli używasz Spring Cloud GCP BOM do zarządzania numerami wersji spring-cloud-gcp, możesz usunąć tag <version>).

Sekcja zależności powinna wyglądać tak:

1800f10af9331210.png

W razie potrzeby zaktualizuj numery wersji, aby były zgodne z powyższymi. Jak widzisz, dodałem też inną zależność:

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

7. Modyfikowanie punktu wejścia funkcji i nazwy klasy

  1. Otwórz plik „launch.json” w folderze „.vscode”. Zmień nazwę funkcji z „function-hello-world” na „function-gemini-calling”.
  2. Zmień wartość entryPoint z „cloudcode.helloworld.HelloWorld” na „cloudcode.bookshelf.Bookshelf”.
  3. Teraz przejdź do pliku klasy Java „HelloWorld.java”. Zmień nazwę pakietu na package cloudcode.bookshelf; W wyświetlonym błędzie kliknij żółtą żarówkę i wybierz opcję „Move HelloWorld.java” (Przenieś HelloWorld.java) do pakietu cloudcode.bookshelf;.

38d721978bddc8a8.png

  1. Zmień nazwę klasy na Bookshelf, a w wyświetlonym błędzie kliknij małą żółtą żarówkę i wybierz „Rename file to Bookshelf.java” (Zmień nazwę pliku na Bookshelf.java). Wybierz tę opcję.

8. Utwórz metodę, która wywołuje Gemini Pro

Zaimplementujmy tę funkcję w klasie Bookshelf.java. Zastąp plik Bookshelf.java poniższym kodem:

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

Ta klasa oczekuje danych wejściowych w strukturze JSON, jak poniżej:

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

Zwraca odpowiedź jak poniżej:

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

Aby wyjaśnić kod, wypróbuj opcję rozmowy z Gemini w edytorze Cloud Shell w panelu po lewej stronie. Możesz też zaznaczyć cały kod, kliknąć żółtą żarówkę w lewym górnym rogu zaznaczenia i wybrać opcję „Wyjaśnij to”.

66fb67507793e368.png

9. Wdrażanie funkcji w Cloud Functions

Funkcja Cloud Function jest już gotowa. Zapytajmy Gemini, jak ją wdrożyć. Otwórz rozmowę z Gemini w edytorze Cloud Code i wpisz:

   How to deploy this Cloud Function with a gcloud command?

Otrzymaliśmy taką odpowiedź:

9f9db98933841864.png

Chciałem teraz dokładniej zbadać tę kwestię. Poprosiłem więc Gemini o podanie pełnego polecenia gcloud functions deploy. Odpowiedź wygląda tak:

b77701c00dc3eaf1.png

Nie mogę zagwarantować, że otrzymasz taką samą odpowiedź, ale zaskoczyło mnie, że zawiera ona dodatkowe szczegóły, jak widać na obrazie poniżej:

Format treści żądania:

82bf20304143a374.png

i

Format odpowiedzi:

ade55b3de5d823a6.png

Teraz wdróżmy funkcję, uruchamiając polecenie gcloud, które podał Gemini. W tym celu musimy otworzyć terminal Cloud Shell. Możesz otworzyć ją w nowej karcie na stronie https://console.cloud.google.com i sprawdzić, czy wybrany jest właściwy projekt. Otwórz terminal Cloud Shell, klikając ikonę Aktywuj Cloud Shell w prawym górnym rogu konsoli. Upewnij się, że jesteś w odpowiednim folderze projektu, używając tego polecenia:

cd duetai-gemini-calling

a następnie to polecenie:

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

Pojawi się pytanie „Allow unauthenticated invocations of new function [bookshelf]?”. Powiedz „y” i naciśnij Enter. Następnie wyświetli się kilka pytań (w zależności od potrzeb) i zostanie wdrożona bezserwerowa funkcja Cloud z adresem URL wdrożenia: https://us-central1-*******.cloudfunctions.net/bookshelf.

Teraz wywołajmy wdrożoną funkcję Cloud Functions i przetestujmy ją.

Uwaga: jeśli przypadkowo pominiesz pytanie „Zezwolić na wywołania bez uwierzytelniania” lub wybierzesz „N”, nie będziesz mieć dostępu do wyniku Cloud Functions i zobaczysz „błąd uprawnień” bez przyznawania dodatkowych ustawień IAM. Zwróć na to uwagę.

10. Wywoływanie wdrożonej funkcji w Cloud Functions

Zapytajmy o to Gemini. Wpisuję prompt

How to call the deployed cloud function?

Otrzymano ten wynik: (możesz otrzymać inną odpowiedź. Eksperymentuj z promptem i sprawdzaj, jak się zmieniają odpowiedzi).

1d2242715571fe6f.png

Zadaj czatowi konkretne pytania dotyczące alternatywnych sposobów wywoływania wdrożonej funkcji, wywoływania jej za pomocą polecenia gcloud itp. Ja przesłałem(-am) ten prompt:

how to call the deployed cloud function using gcloud

Otrzymałem(-am) tę odpowiedź: e7b29b2cfb57782c.png

Możesz użyć tej odpowiedzi (polecenie „gcloud functions call”) w terminalu, wprowadzając w niej zmiany, aby dostosować ją do naszego scenariusza. Możesz też spróbować przekazać parametry w prompcie i sprawdzić, czy w odpowiedzi otrzymasz szczegółowe wywołanie funkcji gcloud:

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

Oto mój wynik:

6f396d915251db78.png

11. Czyszczenie danych

Utworzone wcześniej funkcje w Cloud Functions możesz usunąć, klikając przycisk USUŃ na stronie szczegółów funkcji w Cloud Functions.

12. Gratulacje

Udało Ci się utworzyć, wdrożyć i przetestować funkcję Cloud Functions w języku Java, która wywołuje Gemini 1.0 Pro za pomocą Gemini. Ta aplikacja przyjmuje prompt związany z rekomendacją książki, zawierający podsumowanie i temat książek.