Crea un'app di consigli contestuali sulle posizioni yoga con Firestore, Vector Search e Gemini 2.0 (versione Java).

1. Panoramica

Nel mondo delle app per il benessere e l'attività fisica, è fondamentale offrire agli utenti un'esperienza ricca e coinvolgente. Per un'app di yoga, questo significa andare oltre le semplici descrizioni testuali delle pose e offrire informazioni complete, contenuti multimediali e funzionalità di ricerca intelligenti. In questo blog esploreremo come creare un solido database di posizioni yoga utilizzando Firestore di Google Cloud, sfruttare la sua estensione Vector Search 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, è una scelta eccellente per creare applicazioni scalabili e dinamiche. Ecco perché è perfetto per la nostra app di yoga:

  • Scalabilità e prestazioni:Firestore si adatta automaticamente per gestire milioni di utenti e set di dati di grandi dimensioni, garantendo che la tua app rimanga reattiva anche quando cresce.
  • Aggiornamenti in tempo reale: la sincronizzazione in tempo reale integrata mantiene i dati coerenti su tutti i client connessi, il che lo rende perfetto per funzionalità come le lezioni dal vivo o gli esercizi collaborativi.
  • Modello di dati flessibile:la struttura basata su documenti di Firestore 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 di yoga.
  • Query potenti:Firestore supporta query complesse, tra cui uguaglianza, disuguaglianza e ora, con la nuova estensione, ricerche di somiglianze vettoriali.
  • Supporto offline: Firestore memorizza i dati nella cache a livello locale, consentendo alla tua app di funzionare anche quando gli utenti sono offline.

Migliorare la ricerca con l'estensione Firestore Vector Search

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

La ricerca vettoriale con Firestore ti consente di:

  • Genera embedding:trasforma descrizioni testuali e, in futuro, potenzialmente immagini e audio, in rappresentazioni vettoriali numeriche (embedding) che ne acquisiscono il significato semantico utilizzando modelli come quelli disponibili in Vertex AI o modelli personalizzati.
  • Store Embeddings:memorizza questi incorporamenti direttamente nei documenti Firestore.
  • Esegui ricerche di somiglianze:esegui query sul database per trovare documenti semanticamente simili a un determinato vettore di query, consentendo la corrispondenza contestuale.

Integrazione di Gemini 2.0 Flash (sperimentale)

Gemini 2.0 Flash è il modello di AI multimodale all'avanguardia di Google. Sebbene sia ancora sperimentale, offre interessanti possibilità per arricchire la nostra app Yoga:

  • Generazione di testo: utilizza Gemini 2.0 Flash per generare descrizioni dettagliate delle posizioni di yoga, inclusi vantaggi, modifiche e controindicazioni.
  • Generazione di immagini (simulata): sebbene la generazione diretta di immagini con Gemini non sia ancora disponibile pubblicamente, l'ho simulata utilizzando Imagen di Google, generando immagini che rappresentano visivamente le pose.
  • Generazione audio (imitato): allo stesso modo, possiamo utilizzare un servizio di sintesi vocale (TTS) per creare istruzioni audio per ogni posa, guidando gli utenti durante la pratica.

Potenzialmente, prevedo di proporre l'integrazione per migliorare l'app in modo che utilizzi le seguenti funzionalità del modello:

  • API multimodale in tempo reale: questa nuova API ti aiuta a creare applicazioni di streaming audio e video in tempo reale con l'utilizzo di strumenti.
  • Velocità e prestazioni: Gemini 2.0 Flash ha un tempo al primo token (TTFT) notevolmente migliorato rispetto a Gemini 1.5 Flash.
  • Esperienze di agenti migliorate: Gemini 2.0 offre miglioramenti alla comprensione multimodale, alla programmazione, all'esecuzione di istruzioni complesse e alla chiamata di funzioni. Questi miglioramenti lavorano insieme per supportare esperienze migliori con gli agenti.

Per ulteriori 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 Google.
  • Estrazione degli URL:dai risultati di ricerca, possiamo estrarre URL pertinenti, come articoli, video o siti web di yoga affidabili, e visualizzarli all'interno dell'app.

Cosa creerai

Nell'ambito di questo lab, imparerai a:

  1. Crea una raccolta Firestore e carica i documenti di Yoga
  2. Scopri come creare applicazioni CRUD con Firestore
  3. Generare la descrizione di una posizione 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 la 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 è abilitata 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 eseguita la connessione a Cloud Shell, verifica di essere già autenticato e che il progetto sia impostato sul tuo ID progetto utilizzando il seguente comando:
gcloud auth list
  1. Esegui questo 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 seguendo questo link finché non riesci a fare clic sul pulsante "Abilita".

Se manca un'API, puoi sempre abilitarla 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. A livello generale, per iniziare seguirò questi passaggi:

1 Vai a Firestore Viewer e, dalla schermata Seleziona un servizio di database, scegli Firestore in modalità Native.

  1. Seleziona una località per Firestore (assicurati di scegliere us-central1 e di seguire questa procedura ovunque tu scelga la regione / località in questo codelab)
  2. Fai clic su Crea database (se è la prima volta, lascia il database "(default)")

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

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

f7136d53253c59a.png

  1. Non eseguire ancora questo passaggio, ma solo per la cronaca, potresti fare clic su "Avvia raccolta" e creare una nuova raccolta. Imposta l'ID raccolta su "poses". Fai clic sul pulsante Salva.

a26eb470aa9bfda9.png

Suggerimenti professionali per l'applicazione della produzione:

  1. Una volta finalizzato il modello di dati e identificato chi deve poter accedere ai diversi tipi di documenti, puoi creare, modificare e monitorare le regole di sicurezza dall'interfaccia 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 / il lancio del progetto dalla fase di sviluppo, perché spesso sono la causa silenziosa del diverso funzionamento della tua app. :)

Per questa demo, lo utilizzeremo in modalità TEST.

4. API REST di 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. 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 di Firestore accetta un token ID di Firebase Authentication o un token OAuth 2.0 di Google Identity. Per saperne di più sull'autenticazione e l'autorizzazione, consulta la documentazione.
  5. Tutti gli endpoint dell'API REST si trovano nell'URL di base https://firestore.googleapis.com/v1/.

Spring Boot e API Firestore

Questa soluzione nel framework Spring Boot ha lo scopo di dimostrare un'applicazione client che utilizza le API Firestore per raccogliere e modificare i dettagli di postura e respirazione dello yoga con un'esperienza interattiva per l'utente.

Per una spiegazione dettagliata passo passo della soluzione CRUD di Firestore che fa parte dell'app di posizioni di yoga, puoi consultare il link del blog.

Per concentrarti sulla soluzione attuale e imparare la parte CRUD mentre procedi, clona l'intera soluzione incentrata su questo blog dal repository riportato di seguito dal terminale Cloud Shell e ottieni una copia del codebase.

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

Nota:

  1. Una volta clonato questo repository, devi solo apportare alcune modifiche all'ID progetto, alle API e così via. Non è necessaria alcuna altra modifica per avviare l'applicazione. Ogni componente dell'applicazione è spiegato 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 tua 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 ottenerla da AI Studio.
  6. Se vuoi eseguire il test in locale, esegui questi 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 i test e provare l'applicazione.

  1. (Facoltativo) Se vuoi eseguire il deployment dell'app in Cloud Run, devi eseguire il bootstrap di una nuova applicazione Java Cloud Run da zero da Cloud Shell Editor e aggiungere i file src e i file modello dal repository 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, segui i passaggi riportati di seguito (anziché clonare il repository esistente):
  2. Vai all'editor di Cloud Shell (assicurati che l'editor sia aperto e non il terminale), fai clic sull'icona del nome del progetto Google Cloud nella parte sinistra 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 assegnale il nome "firestore-poserecommender".

d5ef8b4ca8bf3f85.png

  1. Ora dovresti vedere un modello full-stack per l'applicazione Java Cloud Run, preconfigurato e pronto all'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 riportati 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 "poses".
  • Aggiungi manualmente uno alla volta i documenti dal file repo menzionato in precedenza

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 cloud attivo sia impostato e di avere l'autorizzazione. Crea un bucket nel tuo progetto con il comando gsutil riportato di seguito. Sostituisci la variabile <PROJECT_ID> nel comando seguente con l'ID progetto Google Cloud:

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

  1. Ora che il bucket è stato creato, dobbiamo copiarvi l'esportazione del database che abbiamo preparato 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 nel database Firebase (predefinito) che abbiamo creato.

  1. Vai ora 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 e, una volta pronta, potrai convalidare il database Firestore e la raccolta visitando https://console.cloud.google.com/firestore/databases, selezionando il database default e la raccolta poses come mostrato di seguito:

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

6. Ricerca vettoriale

Attivare l'estensione di ricerca vettoriale di Firestore

Utilizza questa estensione per incorporare ed eseguire query automaticamente sui documenti Firestore con la nuova funzionalità di ricerca vettoriale. Verrà aperto l'hub di Firebase Extensions.

Quando installi l'estensione Vector Search, specifichi una raccolta e un nome del campo del documento. L'aggiunta o l'aggiornamento di un documento con questo campo attiva questa estensione per calcolare un vector embedding per il documento. Questo vector embedding viene riscritto nello stesso documento e il documento viene indicizzato nel vector store, pronto per essere interrogato.

Vediamo i passaggi:

Installare l'estensione:

Installa l'estensione "Vector Search with Firestore" dal Marketplace di Firebase Extensions 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 abilitate, la pagina di configurazione ti consentirà di farlo. Segui i passaggi di conseguenza.

Se la pagina non risponde dopo aver abilitato le API per un po' di tempo, aggiornala e dovresti visualizzare le API abilitate.

5ba59b45710c567b.png

In uno dei passaggi successivi, ti consente di utilizzare l'LLM che preferisci per generare gli incorporamenti. Scegli "Vertex AI".

bb528a04ebb5f976.png

Le successive impostazioni sono correlate alla raccolta e al campo che vuoi incorporare:

LLM: Vertex AI

Percorso di raccolta: pose

Limite di query predefinito: 3

Misura 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 configurato tutto, fai clic sul pulsante Installa estensione. L'operazione richiederà 3-5 minuti.

Genera embedding:

Man mano che aggiungi o aggiorni i documenti nella raccolta "pose", l'estensione genera automaticamente gli incorporamenti utilizzando un modello preaddestrato o un modello a 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 sul 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 hanno un indice e ti fornirà un link all'indice generato nel messaggio di errore sul lato applicazione. Ecco l'elenco dei passaggi per creare l'indice vettoriale:

  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ù prossimo con i tuoi vector embedding.

Nota importante:

Da questo momento in poi, non devi apportare modifiche all'origine. Segui i passaggi per capire cosa sta facendo l'applicazione.

Diamo un'occhiata a come la tua applicazione appena creata si avvicina alla ricerca vettoriale. Una volta memorizzati gli incorporamenti, puoi utilizzare la classe VectorQuery dell'SDK Java di Firestore per eseguire la ricerca vettoriale e ottenere i risultati del vicino più prossimo:

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'incorporamento del testo di ricerca dell'utente con gli incorporamenti dei documenti in Firestore ed estrae quello più vicino dal punto di vista contestuale.

7. Gemini 2.0 Flash

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

Vediamo come la tua applicazione appena creata gestisce l'integrazione di Gemini 2.0 Flash per la generazione di descrizioni.

Supponiamo ora che un utente amministratore / istruttore di yoga voglia inserire i dettagli delle pose con l'aiuto di Gemini 2.0 Flash e poi 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. Generazione di immagini e audio che imitano persone

Gemini 2.0 Flash Experimental è in grado di generare risultati multimodali, ma non ho ancora eseguito la registrazione per l'accesso in anteprima, quindi ho simulato l'output di immagini e l'uscita audio con le API Imagen e TTS rispettivamente. Immagina che bello ottenere 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 LLM:

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

In questo modo:

  • Basare 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 nuova applicazione Java Spring Boot con una semplice interfaccia web Thymeleaf:

  1. Operazioni CRUD di Firestore (creazione, lettura, aggiornamento, eliminazione)
  2. Ricerca per parole chiave
  3. Creazione di contesto basata sull'AI generativa
  4. Ricerca contestuale (ricerca vettoriale)
  5. Output multimodale correlato alla ricerca
  6. Esegui la tua query (query nel 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 implementarlo, esegui questi comandi dal terminale Cloud Shell:

mvn package

mvn spring-boot:run

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

Motore per suggerimenti sulle pose con Firestore, Vector Search e Gemini 2.0 Flash

Passaggio facoltativo:

Per eseguirne il deployment su Cloud Run (supponendo che tu abbia eseguito il bootstrap di una nuova applicazione con Dockerfile e copiato i file in base alle esigenze), esegui questo 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 la chiamata 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 correttamente Firestore per creare un'applicazione di gestione delle posture di yoga solida e intelligente. Combinando la potenza di Firestore, dell'estensione Vector Search e delle 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, ricerche vettoriali contestuali e generare contenuti multimediali.

Questo approccio non è limitato alle app di yoga. Man mano che i modelli di AI come Gemini continuano a evolversi, le possibilità di creare esperienze utente ancora più coinvolgenti e personalizzate aumenteranno. Ricorda di rimanere aggiornato sugli ultimi sviluppi e sulla 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 ragionamento per generare i pensieri alla base delle risposte per l'interazione con i dati in tempo reale, in modo da rendere l'esperienza più realistica.

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