1. Wprowadzenie
Czy uwielbiasz czytać książki, ale przytłacza Cię ich ogromna liczba? Wyobraź sobie aplikację z wykorzystaniem AI, która nie tylko poleca idealną książkę, ale też zawiera jej zwięzłe streszczenie na podstawie wybranego przez Ciebie gatunku, dzięki czemu możesz poznać esencję książki. W tym laboratorium programistycznym pokażę Ci, jak utworzyć taką aplikację za pomocą BigQuery i Cloud Functions z użyciem Gemini.
Przegląd projektu
Nasz przypadek użycia koncentruje się na 4 głównych komponentach:
- Baza książek: ogromny publiczny zbiór książek z archiwum internetowego BigQuery pełni rolę naszego wyczerpującego katalogu książek.
- Silnik podsumowywania AI: funkcje Google Cloud, korzystające z modelu językowego Gemini-Pro, będą generować trafne podsumowania dostosowane do żądań użytkowników.
- Integracja z BigQuery: funkcja zdalna w BigQuery, która wywołuje naszą funkcję w Cloud Functions, aby dostarczać na żądanie podsumowania i motywy książek.
- Interfejs: aplikacja internetowa hostowana w Cloud Run, która oferuje użytkownikom aplikację internetową do wyświetlania wyników.
Ćwiczenia z kodem podzieliliśmy na 3 części:
Ćwiczenie z programowania 1. Wykorzystanie Gemini do utworzenia funkcji w Cloud Functions dla aplikacji Gemini w języku Java.
Ćwiczenie z programowania 2: używanie Gemini do tworzenia aplikacji wykorzystujących generatywną AI tylko w języku SQL za pomocą BigQuery.
Codelab 3: użyj Gemini do utworzenia aplikacji internetowej Java Spring Boot, która będzie współpracować z BigQuery.
2. Korzystanie z Gemini do tworzenia bezserwerowej aplikacji generatywnej AI za pomocą funkcji Cloud Function w języku Java
Co utworzysz
Utwórz
- Aplikacja Java Cloud Functions, która implementuje Gemini 1.0 Pro, aby przyjmować jako dane wejściowe określony prompt w formie tablicy JSON i zwracać odpowiedź (wartość JSON o nazwie „replies”).
- Wykonywanie kroków kompilacji i wdrażania za pomocą Gemini
3. Wymagania
Oto wymagania wstępne:
Tworzenie projektu
- W konsoli Google Cloud na stronie selektora projektu wybierz lub utwórz projekt Google Cloud.
- Sprawdź, czy w projekcie Cloud włączone są płatności. Dowiedz się, jak sprawdzić, czy w projekcie są włączone płatności.
Aktywowanie Cloud Shell
- Użyjesz Cloud Shell, czyli środowiska wiersza poleceń działającego w Google Cloud i zawierającego wstępnie zainstalowane narzędzie bq:
W prawym górnym rogu konsoli Cloud Console kliknij Aktywuj Cloud Shell:
- Po połączeniu z Cloud Shell powinieneś zobaczyć, że jesteś już uwierzytelniony i że projekt jest już ustawiony na identyfikator Twojego projektu. Aby potwierdzić uwierzytelnianie, uruchom w Cloud Shell to polecenie:
gcloud auth list
- Aby potwierdzić, że polecenie gcloud zna Twój projekt, uruchom to polecenie w Cloud Shell:
gcloud config list project
- Jeśli Twój projekt nie jest skonfigurowany, ustaw go za pomocą tego polecenia:
gcloud config set project <YOUR_PROJECT_ID>
Więcej informacji o poleceniach i sposobie korzystania z gcloud znajdziesz w dokumentacji.
4. Włączam Gemini dla Google Cloud i niezbędnych interfejsów API
Włącz Gemini
- Aby włączyć interfejs API, otwórz Gemini for Google Cloud w Marketplace. Możesz też użyć tego polecenia:
gcloud services enable cloudaicompanion.googleapis.com --project PROJECT_ID
- Otwórz stronę Gemini i kliknij „Rozpocznij czat”.
Ważne: wykonaj kroki 1 i 2 z tego ćwiczenia z programowania, aby zacząć korzystać z Gemini i włączyć Gemini w Cloud Shell IDE.
Włączanie innych wymaganych interfejsów API
Jak to zrobić? Czy możemy zapytać o to Gemini? Pamiętaj jednak, że:
Modele LLM nie są deterministyczne. Podczas testowania tych promptów możesz otrzymać odpowiedź, która będzie wyglądać inaczej niż na moim zrzucie ekranu.
Otwórz konsolę czatu Gemini, klikając ikonę „Otwórz Gemini” w prawym górnym rogu obok paska wyszukiwania w konsoli Google Cloud.
Wpisz to pytanie w sekcji „Wpisz prompt tutaj”:
How do I enable the cloud functions api using a gcloud command?
Powinna pojawić się odpowiedź podobna do:
gcloud services enable cloudfunctions.googleapis.com
Skopiuj to polecenie (możesz użyć ikony kopiowania u góry fragmentu polecenia) i uruchom je w terminalu Cloud Shell, aby włączyć Cloud Functions. Zrób to samo w przypadku Cloud Run, ponieważ potrzebujemy obu usług do kompilowania i wdrażania funkcji w 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 Gemini jest już włączone 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ę otworzyć terminal i edytor jednocześnie w osobnych kartach, aby móc pisać kod w jednej, a w drugiej).
Po otwarciu edytora sprawdź, czy logo Gemini w prawym dolnym rogu konsoli edytora jest aktywne (czyli nie jest wyszarzone). Sprawdź też, czy Twój projekt Google Cloud w lewym dolnym rogu wskazuje na bieżący aktywny projekt, z którym chcesz pracować. Jeśli są nieaktywne, kliknij je, autoryzuj, wybierz projekt Google Cloud, do którego mają wskazywać, i aktywuj je.
Gdy oba te elementy są aktywne, kliknij nazwę projektu w lewym dolnym rogu. W otwartym oknie „Cloud Code” przewiń w dół do opcji „Nowa aplikacja”.
Z tej listy wybierz aplikację Cloud Functions. Z listy, która się pojawi, wybierz Java:
Na wyświetlonej liście wpisz zamiast helloworld nazwę projektu „duetai-gemini-calling” i kliknij OK.
Hurra! Udało Ci się uruchomić prostą aplikację Java Cloud Functions w Gemini przy pomocy Gemini. Oprócz włączenia i aktywacji konfiguracji niewiele zostało zadanych. Zgadza się?
Tak powinna wyglądać struktura projektu:
Możesz teraz wdrożyć funkcję. Nie dlatego jednak zaczęliśmy to robić. Zbudujmy implementację interfejsu Gemini Pro API w tej funkcji Cloud Functions za pomocą pakietu Java SDK.
Teraz skompilujemy funkcję naszego przypadku użycia, która wywołuje model Gemini Pro w tej funkcji w Cloud Functions. Aby to zrobić, możesz dodać więcej promptów i uzyskiwać kod rozwijany stopniowo za pomocą Gemini lub napisać logikę samodzielnie. Zrobię mieszankę obu.
6. Dodaj zależności
W konsoli czatu Gemini (znajduje się ona w lewym panelu edytora Cloud Code) wpisz:
what is the maven dependency for com.google.cloud.vertexai library
Pytam o pakiet com.google.cloud.vertexai, ponieważ właśnie tego używam w kodzie źródłowym, w którym implementuję kod wywołania Gemini.
Mam ten wynik:
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-vertexai</artifactId>
<version>0.1.0</version>
</dependency>
Skopiuj ten kod i wklej go w pliku pom.xml tuż przed tagiem </dependencies>. Zastąp wersję 0.1.0 (jeśli używasz pliku BOM Spring Cloud GCP do zarządzania numerami wersji spring-cloud-gcp, możesz usunąć tag <version>).
Sekcja zależności powinna wyglądać tak:
W razie potrzeby zaktualizuj numery wersji, tak aby były zgodne z numerami podanymi powyżej. Jak widać, 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
- Przejdź do pliku „launch.json” w folderze „.vscode”. Zmień nazwę funkcji z „function-hello-world” na „function-gemini-calling”.
- Zaktualizuj wartość entryPoint z „cloudcode.helloworld.HelloWorld” na „cloudcode.bookshelf.Bookshelf”.
- Teraz przejdź do pliku klasy Java „HelloWorld.java”. Zmień nazwę pakietu na package cloudcode.bookshelf. Gdy pojawi się komunikat o błędzie, kliknij żółtą żarówkę, a następnie opcję „Przenieś HelloWorld.java” do pakietu cloudcode.bookshelf.
- Zmień nazwę klasy na Bookshelf i w wyświetlonym komunikacie o błędzie kliknij żółtą lampkę i wybierz „Zmień nazwę pliku na Bookshelf.java”. Wybierz tę opcję.
8. Tworzenie metody wywołującej 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 o tym kształcie:
{ "calls": [["YOUR_PROMPT_HERE"]] }
Odpowiedź będzie taka:
(JSON) Map<String, List<String>> {"replies": ["response"]}
Aby wyjaśnić kod, użyj opcji czatu Gemini w edytorze Cloud Shell w lewym panelu. Możesz też zaznaczyć cały kod, kliknąć żółtą żarówkę w lewym górnym rogu zaznaczenia i wybrać opcję „Wyjaśnij to”.
9. Wdrażanie funkcji w Cloud Functions
Funkcja Cloud Functions jest już gotowa, więc poprośmy Gemini, jak ją wdrożyć. Otwórz czat Gemini w edytorze Cloud Code i wpisz:
How to deploy this Cloud Function with a gcloud command?
Otrzymaliśmy taką odpowiedź:
Teraz chcę to dokładniej sprawdzić. Poprosiłem Gemini o podanie pełnego polecenia wdrażania funkcji gcloud. Odpowiedź wygląda tak:
Teraz nie mogę powiedzieć, czy otrzymasz taką samą odpowiedź, ale zupełnie ciekawe, że zawiera ona dodatkowe szczegóły, takie jak na ilustracji poniżej:
Format treści żądania:
i
Format odpowiedzi:
Teraz wdróż funkcję, uruchamiając polecenie gcloud podane przez Gemini. W tym celu musimy otworzyć terminal Cloud Shell. Możesz otworzyć go w nowej karcie na stronie https://console.cloud.google.com i sprawdzić, czy wybrano odpowiedni projekt. Otwórz terminal Cloud Shell, klikając ikonę Aktywuj Cloud Shell w prawym górnym rogu konsoli, i sprawdź, czy jesteś w właściwym folderze projektu, wykonując to polecenie:
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 „Zezwolić na nieuwierzytelnione wywołania nowej funkcji [półka na książki]?” Powiedz „y” i naciśnij Enter. W razie potrzeby otrzymasz kilka pytań, a w razie potrzeby wdrożysz bezserwerową funkcję w Cloud Functions przy użyciu wdrożonego adresu URL: https://us-central1-*******.cloudfunctions.net/bookshelf.
Teraz wywołajmy wdrożone funkcje w Cloud Functions i przetestujmy je.
Uwaga: jeśli przypadkowo pominiesz pytanie „Zezwalaj na wywołania bez uwierzytelniania” lub wybierzesz odpowiedź „Nie”, nie będziesz mieć dostępu do wyników funkcji Cloud Functions i bez dodatkowych ustawień uprawnień zobaczysz komunikat „Błąd uprawnień”. Zwróć na to uwagę.
10. Wywołanie wdrożonej funkcji w Cloud Functions
Zapytajmy o to Gemini. Wpisałem prompt
How to call the deployed cloud function?
Oto wynik: (możesz zobaczyć dokładnie taką samą odpowiedź, ale nie musi tak być. Możesz też zmienić prompt i sprawdzić, jak się zmienią odpowiedzi).
Przeanalizuj czat za pomocą konkretnych pytań dotyczących alternatywnych sposobów wywoływania wdrożonej funkcji, wywołania za pomocą polecenia gcloud itp. Wysłałem/wysłałam ten prompt:
how to call the deployed cloud function using gcloud
Otrzymaliśmy taką odpowiedź:
Możesz użyć tej odpowiedzi (polecenia „gcloud features call”) w terminalu, wprowadzając poprawki, aby dostosować ją do naszego scenariusza. Możesz też przekazać parametry w samym prompcie i sprawdzić, czy w odpowiedzi uzyskasz 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:
11. Czyszczenie danych
Utworzone wcześniej funkcje w Cloud Functions możesz usunąć, klikając przycisk USUŃ na stronie z informacjami o funkcjach w Cloud Functions.
12. Gratulacje
Udało Ci się skompilować, wdrożyć i przetestować funkcję Java Cloud Functions, aby wywołać Gemini 1.0 Pro za pomocą Gemini. Aplikacja ta przyjmuje prompt dotyczący rekomendacji książek wraz z ich streszczeniem i tematem.