Crea un'app di consigli contestuali sulle posizioni yoga con Firestore, Ricerca vettoriale e Gemini 2.0.

1. Panoramica

Nel mondo delle app per il benessere e l'attività fisica, offrire agli utenti un'esperienza ricca e coinvolgente è fondamentale. Per un'app di yoga, significa andare oltre le semplici descrizioni testuali delle posizioni e offrire informazioni complete, contenuti multimediali e funzionalità di ricerca intelligente. In questo blog, scopriremo come creare un solido database di posizioni yoga utilizzando Firestore di Google Cloud, sfruttare la sua Estensione di ricerca di vettori per la corrispondenza contestuale e integrare la potenza di Gemini 2.0 Flash (sperimentale) per lavorare con contenuti multimodali.

Perché Firestore?

Firestore, il database di documenti NoSQL serverless di Google Cloud, è un'ottima scelta per creare applicazioni scalabili e dinamiche. Ecco perché è perfetta per la nostra app di yoga:

  • Scalabilità e prestazioni: Firestore si espande automaticamente per gestire milioni di utenti e set di dati di grandi dimensioni, garantendo che la tua app rimanga reattiva anche durante la crescita.
  • Aggiornamenti in tempo reale: la sincronizzazione in tempo reale integrata mantiene i dati coerenti su tutti i client connessi, il che la rende perfetta per funzionalità come i corsi dal vivo o gli esercizi collaborativi.
  • Modello di dati flessibile: la struttura basata su documenti di Firestore ti consente di archiviare diversi tipi di dati, tra cui testo, immagini e persino incorporamenti, il che lo rende ideale per rappresentare informazioni complesse sulle posizioni yoga.
  • Esecuzione di query efficaci:Firestore supporta query complesse, tra cui uguaglianza, disuguaglianza e, ora, con la nuova estensione, ricerche di somiglianza vettoriale.
  • Supporto offline:Firestore memorizza nella cache i dati a livello locale, consentendo alla tua app di funzionare anche quando gli utenti sono offline.

Migliorare la ricerca con l'estensione di ricerca vettoriale Firestore

La ricerca tradizionale basata sulle parole chiave può essere limitante quando si tratta di concetti complessi come le posizioni yoga. Un utente potrebbe cercare una posa che "apra i fianchi" o "migliori l'equilibrio" senza conoscere il nome specifico della posa. È qui che entra in gioco Vector Search.

La ricerca vettoriale con Firestore ti consente di:

  • Genera embedding:trasforma le descrizioni di testo e, in futuro, potenzialmente anche le immagini e l'audio, in rappresentazioni vettoriali numeriche (embedding) che ne acquisiscono il significato semantico utilizzando modelli come quelli disponibili in Vertex AI o modelli personalizzati.
  • Archivia incorporamenti:archivia questi incorporamenti direttamente nei documenti Firestore.
  • Esegui ricerche di somiglianza:esegui query sul database per trovare documenti semanticamente simili a un determinato vettore di query, attivando la corrispondenza contestuale.

Integrazione di Gemini 2.0 Flash (sperimentale)

Gemini 2.0 Flash è il modello di IA multimodale all'avanguardia di Google. Anche se è ancora in fase sperimentale, offre interessanti possibilità per arricchire la nostra app Yoga:

  • Generare testo: utilizza Gemini 2.0 Flash per generare descrizioni dettagliate delle posizioni yoga, inclusi benefici, modifiche e controindicazioni.
  • Generazione di immagini (simulata): anche se la generazione diretta di immagini con Gemini non è ancora disponibile pubblicamente, l'ho simulata utilizzando Imagen di Google, generando immagini che rappresentano visivamente le pose.
  • Genesi di audio (simulato): analogamente, possiamo utilizzare un servizio di conversione del testo in voce (TTS) per creare istruzioni audio per ogni posa, guidando gli utenti nell'esercizio.

Potenzialmente, prevedi di proporre l'integrazione per migliorare l'app in modo da utilizzare le seguenti funzionalità del modello:

  • API Multimodal Live: questa nuova API ti aiuta a creare applicazioni di streaming audio e video in tempo reale con l'utilizzo di strumenti.
  • Velocità e prestazioni: il tempo di risposta al primo token (TTFT) di Gemini 2.0 Flash è migliorato in modo significativo rispetto a Gemini 1.5 Flash.
  • Esperienza agenti migliorate: Gemini 2.0 offre miglioramenti alla comprensione multimodale, alla programmazione, all'esecuzione di istruzioni complesse e alla chiamata di funzioni. Questi miglioramenti agiscono in sinergia per offrire esperienze migliori agli agenti.

Per maggiori dettagli, consulta questa pagina della documentazione su Gemini 1.5 Flash.

Per migliorare la credibilità e fornire ulteriori risorse, possiamo integrare la Ricerca Google per basare le informazioni fornite dalla nostra app. Ciò significa che:

  • Ricerca contestuale:quando un utente amministratore inserisce i dettagli di una posa, possiamo utilizzare il nome della posa per eseguire una ricerca su Google.
  • Estrazione di URL: dai risultati di ricerca possiamo estrarre URL pertinenti, come articoli, video o siti web di yoga affidabili, e mostrarli all'interno dell'app.

Cosa creerai

In questo lab imparerai a:

  1. Crea una raccolta Firestore e carica i documenti Yoga
  2. Scopri come creare applicazioni CRUD con Firestore
  3. Generare una descrizione della posa yoga con Gemini 2.0 Flash
  4. Attivare l'integrazione di Firebase Vector Search con Firestore
  5. Genera embedding dalla descrizione di Yoga
  6. Eseguire una ricerca di similarità per il testo di ricerca dell'utente

Requisiti

  • Un browser, ad esempio Chrome o Firefox
  • Un progetto Google Cloud con la fatturazione abilitata.

2. Prima di iniziare

Crea un progetto

  1. Nella console Google Cloud, nella pagina di selezione del progetto, seleziona o crea un progetto Google Cloud.
  2. Verifica che la fatturazione sia attivata per il tuo progetto Cloud. Scopri come verificare se la fatturazione è attivata per un progetto .
  3. Utilizzerai Cloud Shell, un ambiente a riga di comando in esecuzione in Google Cloud precaricato con bq. Fai clic su Attiva Cloud Shell nella parte superiore della console Google Cloud.

Immagine del pulsante Attiva Cloud Shell

  1. Una volta connesso a Cloud Shell, verifica di aver già eseguito l'autenticazione e che il progetto sia impostato sul tuo ID progetto utilizzando il seguente comando:
gcloud auth list
  1. Esegui il seguente comando in Cloud Shell per verificare che il comando gcloud conosca il tuo progetto.
gcloud config list project
  1. Se il progetto non è impostato, utilizza il seguente comando per impostarlo:
gcloud config set project <YOUR_PROJECT_ID>
  1. Abilita le API richieste.
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

L'alternativa al comando gcloud è tramite la console cercando ciascun prodotto o utilizzando questo link.

Se manca un'API, puoi sempre attivarla durante l'implementazione.

Consulta la documentazione per i comandi e l'utilizzo di gcloud.

3. Configurazione del database

La documentazione contiene passaggi più completi su come configurare un'istanza Firestore. In linea generale, per iniziare, seguirò questi passaggi:

1 Vai a Visualizzatore Firestore e dalla schermata Seleziona un servizio di database, scegli Firestore in modalità nativa

  1. Seleziona una località per Firestore
  2. Fai clic su Crea database (se è la prima volta, lascia il database come "(default)")

Quando crei un progetto Firestore, l'API viene abilitata anche in Cloud API Manager

  1. IMPORTANTE: scegli la versione di TEST (non PRODUZIONE) delle regole di sicurezza in modo che i dati siano accessibili
  2. Una volta configurato, dovresti vedere la visualizzazione del database, della raccolta e del documento Firestore in modalità nativa, come mostrato nell'immagine di seguito:

f7136d53253c59a.png

  1. Non eseguire ancora questo passaggio, ma tieni presente che potresti fare clic su "Avvia raccolta" e creare una nuova raccolta. Imposta l'ID raccolta su "pose". Fai clic sul pulsante Salva.

a26eb470aa9bfda9.png

Suggerimenti degli esperti per l'applicazione di produzione:

  1. Dopo aver finalizzato il modello di dati e aver identificato chi deve poter accedere a diversi tipi di documenti, puoi creare, modificare e monitorare le regole di sicurezza dall'interfaccia di Firebase. Puoi accedere alle Regole di sicurezza da questo link: https://console.firebase.google.com/u/0/project/<<your_project_id>>/firestore/rules
  2. Assicurati di modificare, monitorare e testare le regole di sicurezza prima di eseguire il deployment / l'implementazione del progetto dalla fase di sviluppo, perché spesso sono la causa silenziosa del funzionamento diverso dell'app.

Per questa demo, lo utilizzeremo in modalità TEST.

4. API REST Firestore

  1. L'API REST può essere utile per i seguenti casi d'uso:a. Accesso a Firestore da un ambiente con risorse limitate in cui non è possibile eseguire una libreria client completa. Automatizzare l'amministrazione del database o recuperare metadati dettagliati del database
  2. Il modo più semplice per utilizzare Firestore è utilizzare una delle librerie client native, ma in alcune situazioni è utile chiamare direttamente l'API REST
  3. Nell'ambito di questo blog, vedrai l'utilizzo e la dimostrazione delle API REST di Firestore e non delle librerie client native
  4. Per l'autenticazione, l'API REST Firestore accetta un token ID di autenticazione Firebase o un token OAuth 2.0 di Google Identity. Per ulteriori informazioni sull'argomento Autenticazione e autorizzazione, consulta la documentazione.
  5. Tutti gli endpoint dell'API REST esistono nell'URL base https://firestore.googleapis.com/v1/.

Spring Boot e API Firestore

Questa soluzione nel framework Spring Boot è pensata per dimostrare un'applicazione client che utilizza le API Firestore per raccogliere e modificare i dettagli della postura e del respiro dello yoga con un'esperienza interattiva per l'utente.

Per una spiegazione dettagliata passo passo della parte della soluzione CRUD di Firestore dell'app Pose yoga, puoi consultare il link al blog.

Per concentrarti sulla soluzione attuale e imparare la parte CRUD ovunque ti trovi, clona l'intera soluzione incentrata su questo blog dal repository di seguito dal terminale Cloud Shell e ricevi una copia del codice di base.

git clone https://github.com/AbiramiSukumaran/firestore-poserecommender

Nota:

  1. Dopo aver clonato questo repository, devi solo apportare alcune modifiche all'ID progetto, alle API e così via. Non è richiesta alcuna altra modifica per far funzionare l'applicazione. Ogni componente dell'applicazione è descritto nelle sezioni successive. Ecco un elenco delle modifiche:
  2. Nel file src/main/java/com/example/demo/GenerateImageSample.java, sostituisci "<<YOUR_PROJECT_ID>>" con il tuo ID progetto
  3. Nel file src/main/java/com/example/demo/GenerateEmbeddings.java, sostituisci "<<YOUR_PROJECT_ID>>" con il tuo ID progetto
  4. In src/main/java/com/example/demo/PoseController.java, sostituisci tutte le istanze di "<<YOUR_PROJECT_ID>>" e il nome del database, in questo caso "(default)", con i valori appropriati della configurazione:
  5. In src/main/java/com/example/demo/PoseController.java, sostituisci "[YOUR_API_KEY]" con la tua CHIAVE API per Gemini 2.0 Flash. Puoi scaricarla da AI Studio.
  6. Se vuoi eseguire il test in locale, esegui i seguenti comandi dalla cartella del progetto nel terminale Cloud Shell:
mvn package

mvn spring-boot:run

Al momento, puoi visualizzare l'applicazione in esecuzione facendo clic sull'opzione "Anteprima web" dal terminale Cloud Shell. Non siamo ancora pronti per eseguire test e provare l'applicazione.

  1. Facoltativo:se vuoi eseguire il deployment dell'app in Cloud Run, dovrai avviare da zero una nuova applicazione Java Cloud Run dall'editor Cloud Shell e aggiungere i file src e i file di modello dal repo al nuovo progetto nelle rispettive cartelle (poiché il progetto del repository GitHub corrente non è configurato per impostazione predefinita per la configurazione del deployment di Cloud Run). In questo caso, anziché clonare il repository esistente, segui i passaggi riportati di seguito:
  2. Vai a Cloud Shell Editor (assicurati che sia aperto l'editor e non il terminale), fai clic sull'icona del nome del progetto Google Cloud sul lato sinistro della barra di stato (la parte oscurata nello screenshot di seguito)

d3f0de417094237d.png

  1. Seleziona Nuova applicazione -> Applicazione Cloud Run -> Java: Cloud Run dall'elenco delle opzioni e assegna il nome "firestore-poserecommender".

d5ef8b4ca8bf3f85.png

  1. Ora dovresti vedere un modello full stack per l'applicazione Java Cloud Run, preconfigurato e pronto per l'uso
  2. Rimuovi la classe Controller esistente e copia i seguenti file nelle rispettive cartelle nella struttura del progetto:

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. Devi apportare le modifiche nei file corrispondenti per sostituire PROJECT_ID e API_KEY con i rispettivi valori. (passaggi 1 a,b, c e d sopra).

5. Importazione dati

I dati per l'applicazione sono disponibili in questo file data.json: https://github.com/AbiramiSukumaran/firestore-poserecommender/blob/main/data.json

Se vuoi iniziare con alcuni dati predefiniti, puoi copiare il file JSON e sostituire tutte le occorrenze di "<<YOUR_PROJECT_ID>>" con il tuo valore

  • Vai a Firestore Studio
  • Assicurati di aver creato una raccolta denominata "pose"
  • Aggiungi manualmente un documento alla volta dal file del repository sopra indicato

In alternativa, puoi importare i dati in un'unica operazione dal set predefinito che abbiamo creato per te seguendo questi passaggi:

  1. Vai al terminale Cloud Shell e assicurati che il progetto Google Cloud attivo sia impostato e che tu disponga dell'autorizzazione. Crea un bucket nel tuo progetto con il comando gsutil riportato di seguito. Sostituisci la variabile <PROJECT_ID> nel comando seguente con il tuo ID progetto Google Cloud:

gsutil mb -l us gs://<PROJECT_ID>-yoga-poses-bucket

  1. Ora che il bucket è stato creato, dobbiamo copiare l'esportazione del database che abbiamo preparato in questo bucket prima di poterla importare nel database Firebase. Utilizza il comando riportato di seguito:

gsutil cp -r gs://demo-bq-gemini-public/yoga_poses gs://<PROJECT_ID>-yoga-poses-bucket

Ora che abbiamo i dati da importare, possiamo passare al passaggio finale dell'importazione dei dati nel database Firebase (predefinito) che abbiamo creato.

  1. Vai alla console Firestore e fai clic su Importa/Esporta nel menu di navigazione a sinistra.

Seleziona Importa e scegli il percorso Cloud Storage che hai appena creato, quindi naviga fino a quando non puoi selezionare il file "yoga_poses.overall_export_metadata":

f5c1d16df7d5a64a.png

  1. Fare clic su Importa.

L'importazione richiederà alcuni secondi. Una volta completata, puoi convalidare il database Firestore e la raccolta visitando la pagina https://console.cloud.google.com/firestore/databases, selezionando il database predefinito e la raccolta pose come mostrato di seguito:

  1. Un altro metodo consiste nel creare i record manualmente tramite l'applicazione dopo il deployment utilizzando l'azione "Crea una nuova posa".

6. Vector Search

Attivare l'estensione Firestore Vector Search

Utilizza questa estensione per eseguire query e incorporare automaticamente i tuoi documenti Firestore con la nuova funzionalità di ricerca vettoriale. Verrà aperta la pagina dell'hub di Firebase Extensions.

Quando installi l'estensione Ricerca vettoriale, specifichi una raccolta e un nome di campo del documento. L'aggiunta o l'aggiornamento di un documento con questo campo attiva questa estensione per calcolare un embedding vettoriale per il documento. Questo embedding vettoriale viene riscritto nello stesso documento, che viene indicizzato nel repository di vettori e può essere sottoposto a query.

Vediamo i passaggi:

Installa l'estensione:

Installa l'estensione "Ricerca vettoriale con Firestore" dal marketplace di estensioni di Firebase facendo clic su "Installa nella Console Firebase".

IMPORTANTE:

Quando accedi per la prima volta a questa pagina delle estensioni, devi selezionare lo stesso progetto su cui stai lavorando nella console Google Cloud elencato nella console Firebase.

715426b97c732649.png

Se il tuo progetto non è elencato, aggiungilo in Firebase (scegli il tuo progetto Google Cloud esistente dall'elenco).

Configura l'estensione:

Specifica la raccolta ("poses"), il campo contenente il testo da incorporare ("posture") e altri parametri come le dimensioni dell'incorporamento.

Se in questo passaggio sono elencate API che devono essere attivate, la pagina di configurazione ti consentirà di farlo. Segui i passaggi di conseguenza.

Se la pagina non risponde dopo aver attivato le API per un po' di tempo, aggiornala e dovresti riuscire a vedere le API abilitate.

5ba59b45710c567b.png

In uno dei passaggi successivi, ti consente di utilizzare l'LLM di tua scelta per generare gli embedding. Scegli "Vertex AI".

bb528a04ebb5f976.png

Le impostazioni successive riguardano la raccolta e il campo che vuoi incorporare:

LLM: Vertex AI

Percorso raccolta: pose

Limite di query predefinito: 3

Misurazione della distanza: coseno

Nome del campo di immissione: postura

Nome del campo di output: embedding

Nome del campo Stato: stato

Incorpora documenti esistenti: Sì

Aggiorna gli embedding esistenti: Sì

Località di Cloud Functions: us-central1

Abilita eventi: non selezionato

fb8cdf1163fac7cb.png

Una volta completata la configurazione, fai clic sul pulsante Installa estensione. L'operazione richiederà 3-5 minuti.

Genera incorporamenti:

Man mano che aggiungi o aggiorni i documenti nella raccolta "poses", l'estensione genera automaticamente gli embedding utilizzando un modello preaddestrato o un modello di tua scelta tramite un endpoint API. In questo caso abbiamo scelto Vertex AI nella configurazione dell'estensione.

Creazione dell'indice

Imporrà la creazione dell'indice nel campo di incorporamento al momento dell'utilizzo dell'incorporamento nell'applicazione.

Firestore crea automaticamente gli indici per le query di base. Tuttavia, puoi consentire a Firestore di generare la sintassi dell'indice eseguendo query che non dispongono di un indice. Inoltre, ti fornirà un link all'indice generato nel messaggio di errore lato applicazione. Ecco l'elenco dei passaggi per creare l'indice di vettore:

  1. Vai al terminale Cloud Shell
  2. Esegui questo comando:
gcloud firestore indexes composite create --collection-group="poses" --query-scope=COLLECTION --database="(default)" --field-config vector-config='{"dimension":"768", "flat": "{}"}',field-path="embedding"

Scopri di più qui.

Una volta creato un indice vettoriale, puoi eseguire una ricerca del vicino più simile con gli incorporamenti vettoriali.

Nota importante:

Da questo punto in poi, non devi apportare modifiche all'origine. Segui la procedura per capire cosa fa l'applicazione.

Vediamo come l'applicazione appena creata si avvicina alla ricerca vettoriale. Una volta archiviati gli incorporamenti, puoi utilizzare la classe VectorQuery dell'SDK Java di Firestore per eseguire la ricerca vettoriale e ottenere i risultati del risultato più simile:

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();

Questo snippet confronta l'embedding del testo di ricerca dell'utente con gli embedding dei documenti in Firestore ed estrae quello più simile dal punto di vista del contesto.

7. Gemini 2.0 Flash

Integrazione di Gemini 2.0 Flash (per la generazione di descrizioni)

Vediamo in che modo l'applicazione appena creata gestisce l'integrazione di Gemini 2.0 Flash per la generazione di descrizioni.

Supponiamo che un utente amministratore / istruttore di yoga voglia inserire i dettagli delle pose con l'aiuto di Gemini 2.0 Flash ed eseguire una ricerca per visualizzare le corrispondenze più vicine. In questo modo vengono estratti i dettagli delle pose corrispondenti insieme agli oggetti multimodali che supportano i risultati.

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. Simulazione della generazione di immagini e audio

Gemini 2.0 Flash Experimental è in grado di generare risultati multimodali, ma non ho ancora effettuato la registrazione per l'accesso in anteprima, quindi ho simulato l'output di immagini e audio rispettivamente con le API Imagen e TTS. Immagina quanto sia fantastico generare tutto questo con una sola chiamata API a 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 con la Ricerca Google:

Se controlli il codice di chiamata di Gemini nel passaggio 6, noterai il seguente snippet di codice per attivare la fondatezza della Ricerca Google per la risposta dell'LLM:

 /**Setting up Grounding*/
Map<String, Object> googleSearchTool = new HashMap<>();
googleSearchTool.put("googleSearch", new HashMap<>());
tools.add(googleSearchTool);
requestBody.put("tools", tools);

Questo per garantire che:

  • Basiamo il nostro modello sui risultati di ricerca effettivi
  • Estrai gli URL pertinenti a cui viene fatto riferimento nella ricerca

8. Esegui l'applicazione

Diamo un'occhiata a tutte le funzionalità della tua applicazione Java Spring Boot appena creata con una semplice interfaccia web Thymeleaf:

  1. Operazioni CRUD di Firestore (creazione, lettura, aggiornamento ed eliminazione)
  2. Ricerca per parole chiave
  3. Creazione di contesti basata sull'IA generativa
  4. Ricerca contestuale (ricerca vettoriale)
  5. Output multimodale correlato alla ricerca
  6. Esegui la tua query (query in formato structuredQuery)

Esempio: {"structuredQuery":{"select":{"fields":[{"fieldPath":"name"}]},"from":[{"collectionId":"fitness_poses"}]}}

Tutte queste funzionalità discusse finora fanno parte dell'applicazione che hai appena creato dal repository: https://github.com/AbiramiSukumaran/firestore-poserecommender

Per compilarlo, eseguirlo e eseguirne il deployment, esegui i seguenti comandi dal terminale Cloud Shell:

mvn package

mvn spring-boot:run

Dovresti vedere il risultato e riuscire a provare le funzionalità delle tue applicazioni. Guarda il video qui sotto per la demo dell'output:

Consigliatore di pose con Firestore, Ricerca di vettori e Gemini 2.0 Flash

Passaggio facoltativo:

Per eseguirne il deployment su Cloud Run (supponendo che tu abbia avviato una nuova applicazione con Dockerfile e copiato i file in base alle esigenze), esegui il seguente comando dal terminale Cloud Shell all'interno della directory del progetto:

gcloud run deploy --source .

Fornisci il nome dell'applicazione, il codice regione (scegli quello per us-central1) e scegli l'invocazione non autenticata "Y" come richiesto. Una volta completato il deployment, dovresti ricevere l'endpoint dell'applicazione nel terminale.

9. Esegui la pulizia

Per evitare che al tuo account Google Cloud vengano addebitati costi relativi alle risorse utilizzate in questo post, segui questi passaggi:

  1. Nella console Google Cloud, vai alla pagina Gestisci risorse.
  2. Nell'elenco dei progetti, seleziona il progetto che vuoi eliminare, quindi fai clic su Elimina.
  3. Nella finestra di dialogo, digita l'ID progetto, quindi fai clic su Chiudi per eliminare il progetto.

10. Complimenti

Complimenti! Hai utilizzato Firestore per creare un'applicazione di gestione delle posizioni yoga solida e intelligente. Combinando la potenza di Firestore, l'estensione di ricerca vettoriale e le funzionalità di Gemini 2.0 Flash (con generazione simulata di immagini e audio), abbiamo creato un'app di yoga davvero coinvolgente e informativa per implementare le operazioni CRUD, eseguire ricerche basate su parole chiave, ricerca vettoriale contestuale e generare contenuti multimediali.

Questo approccio non è limitato alle app di yoga. Man mano che i modelli di IA come Gemini continuano a evolversi, le possibilità di creare esperienze utente ancora più immersive e personalizzate non faranno che aumentare. Ricorda di rimanere al passo con gli ultimi sviluppi e la documentazione di Google Cloud e Firebase per sfruttare tutto il potenziale di queste tecnologie.

Se dovessi estendere questa app, proverei a fare due cose con Gemini 2.0 Flash:

  1. Utilizza l'API Multimodal Live creando streaming audio e video in tempo reale per il caso d'uso.
  2. Attiva la modalità di pensiero per generare i pensieri alla base delle risposte per l'interazione con i dati in tempo reale e rendere l'esperienza più realistica.

Non esitare a provarlo e a inviare una richiesta pull :>D!!!