1. Omówienie
W przypadku aplikacji do dbania o zdrowie i kondycję kluczowe znaczenie ma zapewnienie użytkownikom bogatego i atrakcyjnego wrażenia. W przypadku aplikacji do jogi oznacza to, że nie wystarczy już zwykły tekstowy opis asan. Należy zaoferować kompleksowe informacje, treści multimedialne i inteligentne funkcje wyszukiwania. W tym wpisie na blogu pokażemy, jak utworzyć niezawodną bazę danych dotyczących jogi za pomocą Firestore od Google Cloud, wykorzystać rozszerzenie wyszukiwania wektorów do dopasowywania kontekstowego oraz zintegrować potencjał Gemini 2.0 Flash (Experimental) do pracy z treściami multimodalnymi.
Dlaczego Firestore?
Firestore, bezserwerowa baza danych dokumentów NoSQL w Google Cloud, to doskonały wybór do tworzenia skalowalnych i dynamicznych aplikacji. Oto dlaczego jest ona idealna dla naszej aplikacji do jogi:
- Skalowalność i wydajność: Firestore automatycznie skaluje się, aby obsługiwać miliony użytkowników i ogromne zbiory danych, dzięki czemu aplikacja pozostaje responsywna nawet w miarę jej rozwoju.
- Aktualizacje w czasie rzeczywistym: wbudowana synchronizacja w czasie rzeczywistym zapewnia spójność danych na wszystkich połączonych klientach, co czyni ją idealną do korzystania z funkcji takich jak lekcje na żywo czy wspólne ćwiczenia.
- Elastyczny model danych: struktura oparta na dokumentach w Firestore umożliwia przechowywanie różnych typów danych, w tym tekstu, obrazów, a nawet elementów osadzonych, co czyni ją idealną do przedstawiania złożonych informacji o pozycjach jogi.
- Zaawansowane zapytania: Firestore obsługuje złożone zapytania, w tym zapytania oparte na równości i nierówności, a teraz, dzięki nowemu rozszerzeniu, także wyszukiwanie wektorów podobnych.
- Obsługa offline: Firestore przechowuje dane lokalnie, co pozwala aplikacji działać nawet wtedy, gdy użytkownicy są offline.
Ulepszanie wyszukiwania dzięki rozszerzeniu wyszukiwania wektorowego w Firestore
Tradycyjne wyszukiwanie oparte na słowach kluczowych może być ograniczone w przypadku złożonych pojęć, takich jak pozycje jogi. Użytkownik może wyszukiwać pozycji, która „otwiera biodra” lub „poprawia równowagę”, nie znając nazwy konkretnej pozycji. Właśnie tu do akcji wkraczają wyszukiwania wektorowe.
Wyszukiwanie wektorowe w Firestore umożliwia:
- Generowanie wektorów zastępczych: przekształcanie tekstowych opisów, a w przyszłości także obrazów i dźwięku, w liczbowe reprezentacje wektorowe (wektory zastępcze), które odzwierciedlają ich znaczenie semantyczne za pomocą modeli dostępnych w Vertex AI lub modeli niestandardowych.
- Zapisywanie wbudowanych elementów: zapisywanie tych wbudowanych elementów bezpośrednio w dokumentach Firestore.
- Wykonywanie wyszukiwania podobnych dokumentów: zapytanie w bazie danych, aby znaleźć dokumenty podobne semantycznie do danego wektora zapytania, co umożliwia dopasowanie kontekstowe.
Integracja Gemini 2.0 Flash (wersja eksperymentalna)
Gemini 2.0 Flash to zaawansowany multimodalny model AI od Google. Chociaż jest to nadal eksperymentalna funkcja, oferuje ekscytujące możliwości wzbogacenia naszej aplikacji Joga:
- Generowanie tekstu: użyj modelu Gemini 2.0 Flash do generowania szczegółowych opisów pozycji jogi, w tym korzyści, modyfikacji i przeciwwskazań.
- Generowanie obrazów (naśladowanie): chociaż bezpośrednie generowanie obrazów za pomocą Gemini nie jest jeszcze dostępne publicznie, symulowaliśmy to, używając Imagen od Google do generowania obrazów, które wizualnie odzwierciedlają pozy.
- Generowanie dźwięku (naśladowanie): podobnie możemy użyć usługi zamiany tekstu na mowę (TTS), aby utworzyć instrukcje dźwiękowe dla każdej pozycji, które będą służyć użytkownikom jako wskazówki.
Proponuję integrację, która pozwoli rozszerzyć możliwości aplikacji o te funkcje modelu:
- Interfejs API do obsługi multimodalnych transmisji na żywo: ten nowy interfejs API ułatwia tworzenie aplikacji do przesyłania obrazu i dźwięku w czasie rzeczywistym.
- Szybkość i wydajność: model Gemini 2.0 Flash znacznie skraca czas do pierwszego tokena (TTFT) w porównaniu z modelem Gemini 1.5 Flash.
- Ulepszenia w działaniu agenta: Gemini 2.0 wprowadza ulepszenia w rozumieniu multimodalnym, kodowaniu, wykonywaniu złożonych instrukcji i wywoływaniu funkcji. Te ulepszenia działają razem, aby zapewnić agentom lepsze wrażenia.
Więcej informacji znajdziesz w tej stronie w dokumentacji (dotyczy Gemini 1.5 Flash).
Grounding z użyciem wyszukiwarki Google
Aby zwiększyć wiarygodność i zapewnić dodatkowe zasoby, możemy zintegrować wyszukiwarkę Google z naszą aplikacją. Oznacza to:
- Wyszukiwanie kontekstowe: gdy użytkownik o dostępie administracyjnym wpisze szczegóły dotyczące pozy, możemy użyć nazwy tej pozy do przeprowadzenia wyszukiwania w Google.
- Wyodrębnianie adresów URL: z wyników wyszukiwania możemy wyodrębniać odpowiednie adresy URL, takie jak artykuły, filmy lub wiarygodne strony internetowe dotyczące jogi, i wyświetlać je w aplikacji.
Co utworzysz
W ramach tego laboratorium wykonasz te czynności:
- Tworzenie kolekcji Firestore i wczytywanie dokumentów dotyczących jogi
- Dowiedz się, jak tworzyć aplikacje CRUD za pomocą Firestore
- Generowanie opisu pozycji jogi za pomocą Gemini 2.0 Flash
- Włącz wyszukiwanie wektorowe Firebase z integracją Firestore
- Generowanie wektorów na podstawie opisu jogi
- wyszukiwanie podobnych tekstów w zapytaniach użytkowników;
Wymagania
2. Zanim zaczniesz
Utwórz projekt
- 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 .
- Użyjesz Cloud Shell, czyli środowiska wiersza poleceń działającego w Google Cloud, które jest wstępnie wczytane w bq. Kliknij Aktywuj Cloud Shell u góry konsoli Google Cloud.
- Po połączeniu z Cloud Shell sprawdź, czy jesteś już uwierzytelniony i czy projekt jest ustawiony na identyfikator Twojego projektu, używając tego polecenia:
gcloud auth list
- Aby sprawdzić, czy polecenie gcloud zna Twój projekt, uruchom w Cloud Shell to polecenie:
gcloud config list project
- Jeśli projekt nie jest ustawiony, użyj tego polecenia:
gcloud config set project <YOUR_PROJECT_ID>
- Włącz wymagane interfejsy API.
gcloud services enable firestore.googleapis.com \
compute.googleapis.com \
cloudresourcemanager.googleapis.com \
servicenetworking.googleapis.com \
run.googleapis.com \
cloudbuild.googleapis.com \
cloudfunctions.googleapis.com \
aiplatform.googleapis.com \
storage.googleapis.com \
secretmanager.googleapis.com \
texttospeech.googleapis.com
Alternatywą dla polecenia gcloud jest konsola, w której możesz wyszukać poszczególne usługi lub skorzystać z tego linku.
Jeśli pominiesz któryś interfejs API, możesz go włączyć w trakcie implementacji.
Więcej informacji o poleceniach i użytkowaniu gcloud znajdziesz w dokumentacji.
3. Konfiguracja bazy danych
W dokumentacji znajdziesz bardziej szczegółowe instrukcje dotyczące konfigurowania instancji Firestore. Na początek wykonam te czynności:
1 Otwórz Firestore Viewer i na ekranie Wybieranie usługi bazy danych wybierz Firestore w trybie natywnym.
- Wybieranie lokalizacji dla Firestore
- Kliknij Utwórz bazę danych (jeśli to Twoja pierwsza baza danych, pozostaw ją jako bazę danych „(domyślna)”).
Gdy tworzysz projekt Firestore, powoduje to również włączenie interfejsu API w Menedżerze interfejsów API Cloud.
- WAŻNE: aby dane były dostępne, wybierz wersję REGUŁ BEZPIECZEŃSTWA w trybie TESTOWYM (a nie PRODUKCYJNYM).
- Po skonfigurowaniu usługi powinny wyświetlić się widoki bazy danych, kolekcji i dokumentu Firestore w trybie natywnym, jak na poniższym obrazku:
- Nie wykonuj tego kroku, ale na wszelki wypadek możesz kliknąć „Rozpocznij kolekcję” i utworzyć nową kolekcję. Ustaw identyfikator kolekcji jako „poses”. Kliknij przycisk Zapisz.
Wskazówki dotyczące aplikacji produkcyjnej:
- Po sfinalizowaniu modelu danych i określeniu, kto powinien mieć dostęp do różnych rodzajów dokumentów, możesz tworzyć, edytować i monitorować reguły zabezpieczeń w interfejsie Firebase. Do zasad zabezpieczeń można uzyskać dostęp za pomocą tego linku: https://console.firebase.google.com/u/0/project/<<identyfikator_Twojego_projektu>>/firestore/rules
- Przed wdrożeniem projektu z fazy programowania pamiętaj o edytowaniu, monitorowaniu i testowaniu reguł bezpieczeństwa, ponieważ często są one przyczyną nieprawidłowego działania aplikacji.
W tym pokazie użyjemy trybu TEST.
4. Firestore REST API
- Interfejs API REST może być przydatny w tych zastosowaniach:a. Dostęp do Firestore z otoczenia o ograniczonej ilości zasobów, w którym nie można uruchomić pełnej biblioteki klienta. Automatyzacja administracji bazy danych lub pobieranie szczegółowych metadanych bazy danych
- Najłatwiej korzystać z Firestore za pomocą jednej z natywnych bibliotek klienta, ale w niektórych sytuacjach przydatne może być bezpośrednie wywołanie interfejsu API REST.
- W tym wpisie na blogu znajdziesz informacje o użyciu i demonstracji interfejsów REST API Firestore, a nie natywnych bibliotek klienta.
- Do uwierzytelniania interfejs Firestore REST API akceptuje token tożsamości Firebase Authentication lub token tożsamości Google OAuth 2.0. Więcej informacji o uwierzytelnianiu i autoryzacji znajdziesz w dokumentacji.
- Wszystkie punkty końcowe interfejsu API REST znajdują się pod adresem URL podstawowym https://firestore.googleapis.com/v1/.
Spring Boot i Firestore API
To rozwiązanie w ramach Spring Boot Framework ma na celu przedstawienie aplikacji klienckiej, która korzysta z interfejsów API Firestore do zbierania i modyfikowania szczegółów dotyczących pozycji i oddechu w jodze w ramach interakcji z użytkownikiem.
Szczegółowe instrukcje dotyczące tworzenia w Firestore operacji CRUD w ramach aplikacji Joga znajdziesz w poście na blogu.
Aby skupić się na bieżącym rozwiązaniu i nauczyć się na bieżąco części CRUD, klonuj całe rozwiązanie skupione na tym blogu z repozytorium poniżej w terminalu Cloud Shell i pobierz kopię bazy kodu.
git clone https://github.com/AbiramiSukumaran/firestore-poserecommender
Uwaga:
- Po skopiowaniu repozytorium musisz wprowadzić kilka zmian dotyczących identyfikatora projektu, interfejsów API itp. Nie musisz wprowadzać żadnych innych zmian, aby uruchomić aplikację. W kolejnych sekcjach omówimy poszczególne komponenty aplikacji. Oto lista zmian:
- W pliku
src/main/java/com/example/demo/GenerateImageSample.java
zastąp ciąg „<<YOUR_PROJECT_ID>>" identyfikatorem projektu. - W pliku
src/main/java/com/example/demo/GenerateEmbeddings.java
zastąp ciąg „<<YOUR_PROJECT_ID>>" identyfikatorem projektu. - W pliku
src/main/java/com/example/demo/PoseController.java
zastąp wszystkie wystąpienia „<<YOUR_PROJECT_ID>>"
” i nazwę bazy danych (w tym przypadku"(default)",
) odpowiednimi wartościami z konfiguracji:,
- W sekcji
src/main/java/com/example/demo/PoseController.java
zastąp „[YOUR_API_KEY]
” kluczem API dla Gemini 2.0 Flash. Możesz to zrobić w AI Studio. - Jeśli chcesz przetestować aplikację lokalnie, uruchom te polecenia w folderze projektu w terminalu Cloud Shell:
mvn package
mvn spring-boot:run
Obecnie możesz wyświetlić uruchomioną aplikację, klikając opcję „Podgląd w przeglądarce” w terminalu Cloud Shell. Nie jesteśmy jeszcze gotowi do przeprowadzenia testów i wypróbowania aplikacji.
- Opcjonalnie: jeśli chcesz wdrożyć aplikację w Cloud Run, musisz utworzyć od podstaw nową aplikację Java Cloud Run w edytorze Cloud Shell i dodać pliki src oraz pliki szablonów z repo do nowego projektu w odpowiednich folderach (ponieważ bieżący projekt repozytorium GitHub nie jest domyślnie skonfigurowany pod kątem konfiguracji wdrożenia Cloud Run). W takim przypadku należy wykonać te czynności (zamiast klonowania istniejącego repozytorium):
- Otwórz Edytor Cloud Shell (upewnij się, że otwarty jest edytor, a nie terminal). Po lewej stronie paska stanu kliknij ikonę nazwy projektu Google Cloud (zablokowana część na poniższym zrzucie ekranu).
- Na liście opcji wybierz Nowa aplikacja > Aplikacja Cloud Run > Java: Cloud Run i nadaj aplikacji nazwę „firestore-poserecommender”.
- Powinieneś teraz zobaczyć wstępnie skonfigurowany szablon pełnego pakietu aplikacji Java Cloud Run, który jest gotowy do użycia.
- Usuń dotychczasową klasę Controller i skopiuj do odpowiednich folderów w strukturze projektu te pliki:
firestore-poserecommender/src/main/java/com/example/demo/
- FirestoreSampleApplication.java
- GenerateEmbeddings.java
- GenerateImageSample.java
- Pose.java
- PoseController.java
- ServletInitializer.java
firestore-poserecommender/src/main/resources/static/
- Index.html
firestore-poserecommender/src/main/resources/templates/
- contextsearch.html
- createpose.html
- errmessage.html
- pose.html
- ryoq.html
- searchpose.html
- showmessage.html
firestore-poserecommender/
- Dockerfile
- Musisz wprowadzić zmiany w odpowiednich plikach, aby zastąpić wartościami PROJECT-ID i API-KEY swoje wartości. (czynności opisane powyżej w punktach 1a,b, c i d).
5. Pozyskiwanie danych
Dane aplikacji są dostępne w pliku data.json: https://github.com/AbiramiSukumaran/firestore-poserecommender/blob/main/data.json
Jeśli chcesz zacząć od wstępnie zdefiniowanych danych, możesz skopiować plik JSON i zastąpić wszystkie wystąpienia ciągu „<<YOUR_PROJECT_ID>>" swoją wartością.
- Otwórz Firestore Studio.
- Utwórz kolekcję o nazwie „poses”.
- Dodawanie dokumentów z wymienionego powyżej pliku repo ręcznie pojedynczo
Możesz też zaimportować dane jednorazowo z zawierconego zbioru, który utworzyliśmy dla Ciebie. Aby to zrobić:
- Otwórz terminal Cloud Shell i sprawdź, czy masz ustawiony aktywny projekt Google Cloud i czy masz uprawnienia. Utwórz zasobnik w projekcie za pomocą podanego niżej polecenia gsutil. W poniższym poleceniu zastąp zmienną <PROJECT_ID> identyfikatorem projektu Google Cloud:
gsutil mb -l us gs://<PROJECT_ID>-yoga-poses-bucket
- Teraz, gdy zasób został utworzony, musimy skopiować przygotowany wcześniej eksport bazy danych do tego zasobu, zanim będziemy mogli go zaimportować do bazy danych Firebase. Użyj podanego niżej polecenia:
gsutil cp -r gs://demo-bq-gemini-public/yoga_poses gs://<PROJECT_ID>-yoga-poses-bucket
Teraz, gdy mamy dane do zaimportowania, możemy przejść do ostatniego kroku, czyli zaimportować je do utworzonej przez nas bazy danych Firebase (domyślnej).
- Otwórz konsolę Firestore i w menu nawigacyjnym po lewej stronie kliknij Import/eksport.
Kliknij Importuj i wybierz ścieżkę Cloud Storage, którą właśnie utworzono. Przejdź do pliku „yoga_poses.overall_export_metadata”:
- Kliknij Importuj.
Importowanie zajmie kilka sekund. Gdy się zakończy, możesz zweryfikować bazę danych Firestore i kolekcję, odwiedzając stronę https://console.cloud.google.com/firestore/databases i wybierając bazę danych default oraz kolekcję poses, jak pokazano poniżej:
- Inną metodą jest ręczne tworzenie rekordów w aplikacji po wdrożeniu za pomocą działania „Utwórz nową pozę”.
6. Wyszukiwanie wektorowe
Włączanie rozszerzenia wyszukiwania wektorowego Firestore
Użyj tego rozszerzenia, aby automatycznie umieszczać dokumenty Firestore i wysyłać zapytania do nich za pomocą nowej funkcji wyszukiwania wektorowego. Otworzy się strona Firebase Extensions Hub.
Podczas instalowania rozszerzenia Vector Search musisz podać nazwę kolekcji i nazwę pola dokumentu. Dodanie lub zaktualizowanie dokumentu z tym polem powoduje, że rozszerzenie oblicza wektorowe zanurzanie dokumentu. Ten wektorowy embedding jest zapisywany w tym samym dokumencie, który jest indeksowany w magazynie wektorów, aby można było go używać w zapytaniach.
Wykonaj te czynności:
Instalowanie rozszerzenia:
Aby zainstalować rozszerzenie „Wyszukiwanie wektorów w Firestore”, kliknij „Zainstaluj w konsoli Firebase” na stronie Marketplace z rozszerzeniami Firebase.
WAŻNE:
Gdy po raz pierwszy otworzysz tę stronę rozszerzeń, musisz wybrać ten sam projekt, nad którym pracujesz w konsoli Google Cloud i który jest wymieniony w konsoli Firebase.
Jeśli Twojego projektu nie ma na liście, dodaj go w Firebase (wybierz istniejący projekt Google Cloud z listy).
Konfigurowanie rozszerzenia:
Określ kolekcję („poses”), pole zawierające tekst do osadzenia („posture”) i inne parametry, takie jak wymiary osadzenia.
Jeśli na tym etapie wymienione są interfejsy API, które należy włączyć, możesz to zrobić na stronie konfiguracji.
Jeśli po włączeniu interfejsów API strona nie reaguje przez jakiś czas, odśwież ją. Powinna się wtedy wyświetlić informacja o włączonych interfejsach API.
W jednym z następnych kroków możesz użyć wybranego modelu LLM do wygenerowania wektorów. Wybierz „Vertex AI”.
Kolejne ustawienia dotyczą kolekcji i pola, które chcesz osadzić:
LLM: Vertex AI
Ścieżka kolekcji: poses
Domyślny limit zapytań: 3
Pomiar odległości: cosinus
Nazwa pola wejściowego: postawa
Nazwa pola wyjściowego: wektor dystrybucyjny
Nazwa pola Stan: status
Umieszczenie dotychczasowych dokumentów: tak
Aktualizowanie dotychczasowych wektorów: tak
Lokalizacja w Cloud Functions: us-central1
Włącz zdarzenia: nie zaznaczone
Po skonfigurowaniu wszystkich tych ustawień kliknij przycisk Zainstaluj rozszerzenie. Zajmie to 3–5 minut.
Generowanie wektorów:
Gdy dodajesz dokumenty do kolekcji „poses” lub je aktualizujesz, rozszerzenie automatycznie wygeneruje zaszycia za pomocą wytrenowanego modelu lub wybranego przez Ciebie modelu za pomocą punktu końcowego interfejsu API. W tym przypadku w konfiguracji rozszerzenia wybrano Vertex AI.
Tworzenie indeksu
Wymaga utworzenia indeksu w polu umieszczenia w momencie użycia umieszczenia w aplikacji.
Firestore automatycznie tworzy indeksy dla podstawowych zapytań. Możesz jednak pozwolić Firestore na generowanie składni indeksu przez uruchamianie zapytań, które nie mają indeksu. W zgłoszeniu błędu po stronie aplikacji pojawi się link do wygenerowanego indeksu. Oto lista czynności do wykonania, aby utworzyć indeks wektorowy:
- Otwórz terminal Cloud Shell
- Uruchom to polecenie:
gcloud firestore indexes composite create --collection-group="poses" --query-scope=COLLECTION --database="(default)" --field-config vector-config='{"dimension":"768", "flat": "{}"}',field-path="embedding"
Więcej informacji znajdziesz tutaj.
Po utworzeniu indeksu wektorowego możesz przeprowadzić wyszukiwanie najbliższych sąsiadów za pomocą wektorów dystrybucyjnych.
Ważna uwaga:
Od tego momentu nie musisz wprowadzać żadnych zmian w źródle. Po prostu obserwuj, co robi aplikacja.
Wykonywanie wyszukiwania wektorowego
Zobaczmy, jak Twoja nowo utworzona aplikacja obsługuje wyszukiwanie wektorowe. Po zapisaniu wektorów dystrybucyjnych możesz użyć klasy VectorQuery z pakietu SDK Firestore w języku Java, aby wykonać wyszukiwanie wektorowe i uzyskać wyniki dotyczące najbliższych sąsiadów:
CollectionReference coll = firestore.collection("poses");
VectorQuery vectorQuery = coll.findNearest(
"embedding",
userSearchTextEmbedding,
/* limit */ 3,
VectorQuery.DistanceMeasure.EUCLIDEAN,
VectorQueryOptions.newBuilder().setDistanceResultField("vector_distance")
.setDistanceThreshold(2.0)
.build());
ApiFuture<VectorQuerySnapshot> future = vectorQuery.get();
VectorQuerySnapshot vectorQuerySnapshot = future.get();
List<Pose> posesList = new ArrayList<Pose>();
// Get the ID of the closest document (assuming results are sorted by distance)
String closestDocumentId = vectorQuerySnapshot.getDocuments().get(0).getId();
Ten fragment kodu porównuje wektor dystrybucyjny tekstu wyszukiwania użytkownika z wektorami dystrybucyjnymi dokumentów w Firestore i wyodrębnia ten, który jest najbardziej zbliżony pod względem kontekstu.
7. Gemini 2.0 Flash
Integracja Gemini 2.0 Flash (do generowania opisów)
Zobaczmy, jak Twoja nowo utworzona aplikacja obsługuje integrację z Gemini 2.0 Flash do generowania opisów.
Załóżmy, że użytkownik o roli administratora lub instruktor jogi chce wpisać szczegóły dotyczące póz za pomocą Gemini 2.0 Flash, a następnie przeprowadzić wyszukiwanie, aby wyświetlić najbliższe dopasowania. W efekcie wyodrębniamy szczegóły pasujących póz oraz obiektów multimodalnych, które wspierają wyniki.
String apiUrl = "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash-exp:generateContent?key=[YOUR_API_KEY]";
Map<String, Object> requestBody = new HashMap<>();
List<Map<String, Object>> contents = new ArrayList<>();
List<Map<String, Object>> tools = new ArrayList<>();
Map<String, Object> content = new HashMap<>();
List<Map<String, Object>> parts = new ArrayList<>();
Map<String, Object> part = new HashMap<>();
part.put("text", prompt);
parts.add(part);
content.put("parts", parts);
contents.add(content);
requestBody.put("contents", contents);
/**Setting up Grounding*/
Map<String, Object> googleSearchTool = new HashMap<>();
googleSearchTool.put("googleSearch", new HashMap<>());
tools.add(googleSearchTool);
requestBody.put("tools", tools);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(requestBody, headers);
ResponseEntity<String> response = restTemplate.exchange(apiUrl, HttpMethod.POST, requestEntity, String.class);
System.out.println("Generated response: " + response);
String responseBody = response.getBody();
JSONObject jsonObject = new JSONObject(responseBody);
JSONArray candidates = jsonObject.getJSONArray("candidates");
JSONObject candidate = candidates.getJSONObject(0);
JSONObject contentResponse = candidate.getJSONObject("content");
JSONArray partsResponse = contentResponse.getJSONArray("parts");
JSONObject partResponse = partsResponse.getJSONObject(0);
String generatedText = partResponse.getString("text");
System.out.println("Generated Text: " + generatedText);
a. Naśladowanie generowania obrazu i dźwięku
Gemini 2.0 Flash Experimental może generować wyniki multimodalne, ale nie zapisałeś/zapisałaś się jeszcze do programu wczesnego dostępu, więc symulowaliśmy obraz i dźwięk za pomocą interfejsów API Imagen i TTS. Wyobraź sobie, jak wygodnie jest wygenerować to wszystko za pomocą jednego wywołania interfejsu API do Gemini 2.0 Flash.
try (PredictionServiceClient predictionServiceClient =
PredictionServiceClient.create(predictionServiceSettings)) {
final EndpointName endpointName =
EndpointName.ofProjectLocationPublisherModelName(
projectId, location, "google", "imagen-3.0-generate-001");
Map<String, Object> instancesMap = new HashMap<>();
instancesMap.put("prompt", prompt);
Value instances = mapToValue(instancesMap);
Map<String, Object> paramsMap = new HashMap<>();
paramsMap.put("sampleCount", 1);
paramsMap.put("aspectRatio", "1:1");
paramsMap.put("safetyFilterLevel", "block_few");
paramsMap.put("personGeneration", "allow_adult");
Value parameters = mapToValue(paramsMap);
PredictResponse predictResponse =
predictionServiceClient.predict(
endpointName, Collections.singletonList(instances), parameters);
for (Value prediction : predictResponse.getPredictionsList()) {
Map<String, Value> fieldsMap = prediction.getStructValue().getFieldsMap();
if (fieldsMap.containsKey("bytesBase64Encoded")) {
bytesBase64Encoded = fieldsMap.get("bytesBase64Encoded").getStringValue();
}
}
return bytesBase64Encoded;
}
try {
// Create a Text-to-Speech client
try (TextToSpeechClient textToSpeechClient = TextToSpeechClient.create()) {
// Set the text input to be synthesized
SynthesisInput input = SynthesisInput.newBuilder().setText(postureString).build();
// Build the voice request, select the language code ("en-US") and the ssml
// voice gender
// ("neutral")
VoiceSelectionParams voice =
VoiceSelectionParams.newBuilder()
.setLanguageCode("en-US")
.setSsmlGender(SsmlVoiceGender.NEUTRAL)
.build();
// Select the type of audio file you want returned
AudioConfig audioConfig =
AudioConfig.newBuilder().setAudioEncoding(AudioEncoding.MP3).build();
// Perform the text-to-speech request on the text input with the selected voice
// parameters and audio file type
SynthesizeSpeechResponse response =
textToSpeechClient.synthesizeSpeech(input, voice, audioConfig);
// Get the audio contents from the response
ByteString audioContents = response.getAudioContent();
// Convert to Base64 string
String base64Audio = Base64.getEncoder().encodeToString(audioContents.toByteArray());
// Add the Base64 encoded audio to the Pose object
return base64Audio;
}
} catch (Exception e) {
e.printStackTrace(); // Handle exceptions appropriately. For a real app, log and provide user feedback.
return "Error in Audio Generation";
}
}
b. Grounding z użyciem wyszukiwarki Google:
Jeśli sprawdzisz kod wywołania Gemini w kroku 6, zauważysz ten fragment kodu, który umożliwia uziemienie w wyszukiwarce Google dla odpowiedzi LLM:
/**Setting up Grounding*/
Map<String, Object> googleSearchTool = new HashMap<>();
googleSearchTool.put("googleSearch", new HashMap<>());
tools.add(googleSearchTool);
requestBody.put("tools", tools);
Dzięki temu:
- dopasowanie modelu do rzeczywistych wyników wyszukiwania,
- wyodrębnianie odpowiednich adresów URL wymienionych w wyszukiwaniu;
8. Uruchamianie aplikacji
Przyjrzyjmy się wszystkim możliwościom nowo utworzonej aplikacji Java Spring Boot z prostym interfejsem internetowym Thymeleaf:
- Operacje CRUD w Firestore (tworzenie, odczyt, aktualizowanie, usuwanie)
- Wyszukiwanie z użyciem słów kluczowych
- Tworzenie kontekstu na podstawie generatywnej AI
- Wyszukiwanie kontekstowe (wyszukiwanie wektorowe)
- Wyjście wielomodalne powiązane z wyszukiwaniem
- Uruchamianie własnego zapytania (zapytania w formacie structuredQuery)
Przykład: {"structuredQuery":{"select":{"fields":[{"fieldPath":"name"}]},"from":[{"collectionId":"fitness_poses"}]}
Wszystkie omówione do tej pory funkcje są częścią aplikacji, którą właśnie utworzysz na podstawie repozytorium: https://github.com/AbiramiSukumaran/firestore-poserecommender.
Aby ją skompilować, uruchomić i wdrażać, uruchom w terminalu Cloud Shell te polecenia:
mvn package
mvn spring-boot:run
Powinieneś zobaczyć wynik i mieć możliwość wypróbowania funkcji aplikacji. Aby zobaczyć, jak działa ta funkcja, obejrzyj film poniżej:
Rekomendator pozycji z Firestore, wyszukiwaniem wektorów i Gemini 2.0 Flash
Krok opcjonalny:
Aby wdrożyć go w Cloud Run (zakładając, że masz nową aplikację z Dockerfile i skopiowane w razie potrzeby pliki), uruchom to polecenie w terminalu Cloud Shell w katalogu projektu:
gcloud run deploy --source .
Podaj nazwę aplikacji, kod regionu (wybierz ten dla us-central1) i w odpowiedzi na prompt wybierz „Y” (tak) w przypadku wywołania bez uwierzytelniania. Po udanym wdrożeniu w terminalu powinien pojawić się punkt końcowy aplikacji.
9. Czyszczenie danych
Aby uniknąć obciążenia konta Google Cloud opłatami za zasoby wykorzystane w tym poście, wykonaj te czynności:
- W konsoli Google Cloud otwórz stronę Zarządzanie zasobami.
- Na liście projektów wybierz projekt do usunięcia, a potem kliknij Usuń.
- W oknie wpisz identyfikator projektu i kliknij Wyłącz, aby usunąć projekt.
10. Gratulacje
Gratulacje! Udało Ci się użyć Firestore do utworzenia niezawodnej i inteligentnej aplikacji do zarządzania pozycją ciała podczas jogi. Łącząc możliwości Firestore, rozszerzenia Vector Search i funkcji Gemini 2.0 Flash (z symulowanym generowaniem obrazów i dźwięku), stworzyliśmy naprawdę angażujące i edukacyjne oprogramowanie do jogi, które umożliwia wykonywanie operacji CRUD, wyszukiwanie na podstawie słów kluczowych, wyszukiwanie wektorowe w kontekście oraz generowanie treści multimedialnych.
Takie podejście nie jest ograniczone do aplikacji związanych z jogą. Wraz z rozwojem modeli AI, takich jak Gemini, będą się zwiększać możliwości tworzenia jeszcze bardziej angażujących i spersonalizowanych wrażeń dla użytkowników. Aby w pełni wykorzystać możliwości tych technologii, pamiętaj, aby śledzić najnowsze informacje i dokumentację Google Cloud oraz Firebase.
Jeśli chciałbym rozszerzyć tę aplikację, spróbowałbym zrobić 2 rzeczy za pomocą Gemini 2.0 Flash:
- Użyj interfejsu Multimodal Live API, aby utworzyć strumieniowanie obrazu i dźwięku w czasie rzeczywistym na potrzeby danego przypadku użycia.
- Użyj Trybu myślenia, aby generować myśli stojące za odpowiedziami w ramach interakcji z danymi w czasie rzeczywistym i uczynić to doświadczenie bardziej realistycznym.
Możesz spróbować i wysłać żądanie pull :>D!!!