Utwórz kontekstualną aplikację do rekomendowania pozycji jogi za pomocą Firestore, wyszukiwania wektorowego i Gemini 2.0.

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).

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:

  1. Tworzenie kolekcji Firestore i wczytywanie dokumentów dotyczących jogi
  2. Dowiedz się, jak tworzyć aplikacje CRUD za pomocą Firestore
  3. Generowanie opisu pozycji jogi za pomocą Gemini 2.0 Flash
  4. Włącz wyszukiwanie wektorowe Firebase z integracją Firestore
  5. Generowanie wektorów na podstawie opisu jogi
  6. wyszukiwanie podobnych tekstów w zapytaniach użytkowników;

Wymagania

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

2. Zanim zaczniesz

Utwórz projekt

  1. W konsoli Google Cloud na stronie selektora projektu 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 .
  3. 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.

Obraz przycisku aktywowania Cloud Shell

  1. 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
  1. Aby sprawdzić, czy 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:
gcloud config set project <YOUR_PROJECT_ID>
  1. 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.

  1. Wybieranie lokalizacji dla Firestore
  2. 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.

  1. WAŻNE: aby dane były dostępne, wybierz wersję REGUŁ BEZPIECZEŃSTWA w trybie TESTOWYM (a nie PRODUKCYJNYM).
  2. Po skonfigurowaniu usługi powinny wyświetlić się widoki bazy danych, kolekcji i dokumentu Firestore w trybie natywnym, jak na poniższym obrazku:

f7136d53253c59a.png

  1. 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.

a26eb470aa9bfda9.png

Wskazówki dotyczące aplikacji produkcyjnej:

  1. 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
  2. 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

  1. 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
  2. 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.
  3. W tym wpisie na blogu znajdziesz informacje o użyciu i demonstracji interfejsów REST API Firestore, a nie natywnych bibliotek klienta.
  4. 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.
  5. 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:

  1. 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:
  2. W pliku src/main/java/com/example/demo/GenerateImageSample.java zastąp ciąg „<<YOUR_PROJECT_ID>>" identyfikatorem projektu.
  3. W pliku src/main/java/com/example/demo/GenerateEmbeddings.java zastąp ciąg „<<YOUR_PROJECT_ID>>" identyfikatorem projektu.
  4. 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:,
  5. 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.
  6. 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.

  1. 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):
  2. 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).

d3f0de417094237d.png

  1. Na liście opcji wybierz Nowa aplikacja > Aplikacja Cloud Run > Java: Cloud Run i nadaj aplikacji nazwę „firestore-poserecommender”.

d5ef8b4ca8bf3f85.png

  1. Powinieneś teraz zobaczyć wstępnie skonfigurowany szablon pełnego pakietu aplikacji Java Cloud Run, który jest gotowy do użycia.
  2. Usuń dotychczasową klasę Controller i skopiuj do odpowiednich folderów w strukturze projektu te pliki:

firestore-poserecommender/src/main/java/com/example/demo/

  1. FirestoreSampleApplication.java
  2. GenerateEmbeddings.java
  3. GenerateImageSample.java
  4. Pose.java
  5. PoseController.java
  6. ServletInitializer.java
             firestore-poserecommender/src/main/resources/static/
    
  7. Index.html

firestore-poserecommender/src/main/resources/templates/

  1. contextsearch.html
  2. createpose.html
  3. errmessage.html
  4. pose.html
  5. ryoq.html
  6. searchpose.html
  7. showmessage.html

firestore-poserecommender/

  1. Dockerfile
  2. 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ć:

  1. 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

  1. 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).

  1. 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”:

f5c1d16df7d5a64a.png

  1. 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:

  1. 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.

715426b97c732649.png

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.

5ba59b45710c567b.png

W jednym z następnych kroków możesz użyć wybranego modelu LLM do wygenerowania wektorów. Wybierz „Vertex AI”.

bb528a04ebb5f976.png

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

fb8cdf1163fac7cb.png

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:

  1. Otwórz terminal Cloud Shell
  2. 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.

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:

  1. Operacje CRUD w Firestore (tworzenie, odczyt, aktualizowanie, usuwanie)
  2. Wyszukiwanie z użyciem słów kluczowych
  3. Tworzenie kontekstu na podstawie generatywnej AI
  4. Wyszukiwanie kontekstowe (wyszukiwanie wektorowe)
  5. Wyjście wielomodalne powiązane z wyszukiwaniem
  6. 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:

  1. W konsoli Google Cloud otwórz stronę Zarządzanie zasobami.
  2. Na liście projektów wybierz projekt do usunięcia, a potem kliknij Usuń.
  3. 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:

  1. Użyj interfejsu Multimodal Live API, aby utworzyć strumieniowanie obrazu i dźwięku w czasie rzeczywistym na potrzeby danego przypadku użycia.
  2. 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!!!