1. Panoramica
Immagina di entrare in un negozio di giocattoli, virtualmente o di persona, dove trovare il regalo perfetto è un gioco da ragazzi. Puoi descrivere ciò che stai cercando, caricare una foto di un giocattolo o persino progettare la tua creazione. Il negozio comprende immediatamente le tue esigenze e offre un'esperienza personalizzata. Non si tratta di una fantasia futuristica, ma di una realtà basata sull'IA, sulla tecnologia cloud e su una visione di e-commerce personalizzato.
La sfida: trovare il prodotto perfetto che soddisfi le tue aspettative può essere difficile. Termini di ricerca generici, parole chiave e ricerche approssimative spesso non soddisfano le aspettative, la navigazione tra pagine infinite può essere tediosa e la disconnessione tra ciò che immagini e ciò che è disponibile può portare a frustrazione.
La soluzione: l'applicazione di dimostrazione affronta questa sfida a viso aperto, sfruttando la potenza dell'IA per offrire un'esperienza davvero personalizzata e senza interruzioni con la ricerca contestuale e la generazione personalizzata del prodotto corrispondente al contesto di ricerca.
Cosa creerai
In questo lab imparerai a:
- Crea un'istanza AlloyDB e carica il set di dati Giocattoli
- Attiva le estensioni dei modelli di IA generativa e pgvector in AlloyDB
- Genera embedding dalla descrizione del prodotto ed esegui una ricerca di similarità di Cosine in tempo reale per il testo di ricerca dell'utente
- Richiama Gemini 2.0 Flash per descrivere l'immagine caricata dall'utente per la ricerca di giocattoli contestuale
- Richiama Imagen 3 per creare un giocattolo personalizzato in base all'interesse dell'utente
- Richiama uno strumento di previsione dei prezzi creato utilizzando la cassetta degli attrezzi dell'IA generativa per i database per i dettagli dei prezzi del giocattolo creato personalizzato
- Esegui il deployment della soluzione in Cloud Functions serverless
Requisiti
2. Architettura
Flusso di dati: diamo un'occhiata più da vicino a come i dati si spostano nel nostro sistema:
- Ricerca contestuale con RAG (Retrieval Augmented Generation) basata sull'IA
Pensaci in questo modo: invece di cercare semplicemente "auto rossa", il sistema comprende quanto segue:
"veicolo piccolo adatto a un bambino di 3 anni".
AlloyDB come base:utilizziamo AlloyDB, il database completamente gestito e compatibile con PostgreSQL di Google Cloud, per archiviare i dati dei nostri giocattoli, tra cui descrizioni, URL immagine e altri attributi pertinenti.
pgvector per la ricerca semantica:pgvector, un'estensione di PostgreSQL, ci consente di archiviare gli incorporamenti vettoriali sia delle descrizioni dei giocattoli sia delle query di ricerca degli utenti. In questo modo, viene attivata la ricerca semantica, il che significa che il sistema comprende il significato delle parole, non solo le parole chiave esatte.
Somiglianza di Cosine per la pertinenza:utilizziamo la somiglianza di Cosine per misurare la somiglianza semantica tra il vettore di ricerca dell'utente e i vettori di descrizione dei giocattoli, mostrando i risultati più pertinenti.
Indice ScaNN per velocità e precisione: per garantire risultati rapidi e accurati, in particolare con la crescita del nostro inventario di giocattoli, integriamo l'indice ScaNN (Scalable Nearest Neighbors). In questo modo, l'efficienza e il richiamo della nostra ricerca vettoriale migliorano notevolmente.
- Ricerca e comprensione basate sulle immagini con Gemini 2.0 Flash
Invece di digitare il contesto come testo, supponiamo che l'utente voglia caricare un'immagine di un giocattolo familiare con cui vuole eseguire la ricerca. Gli utenti possono caricare un'immagine di un giocattolo che gli piace e ottenere funzionalità pertinenti. Sfruttiamo il modello Gemini 2.0 Flash di Google, invocato utilizzando LangChain4j, per analizzare l'immagine ed estrarre il contesto pertinente, ad esempio il colore, il materiale, il tipo e la fascia d'età prevista del giocattolo.
- Costruire il giocattolo dei tuoi sogni personalizzato con l'IA generativa: immagine 3
La vera magia accade quando gli utenti decidono di creare il proprio giocattolo. Con Imagen 3, consentiamo loro di descrivere il giocattolo dei loro sogni utilizzando semplici prompt di testo. Immagina di poter dire: "Voglio un drago di peluche con ali viola e un muso amichevole" e vederlo prendere vita sullo schermo. Imagen 3 genera quindi un'immagine del giocattolo progettato su misura, offrendo all'utente una visualizzazione chiara della sua creazione.
- Previsione dei prezzi basata su agenti e cassetta degli attrezzi di IA generativa per i database
Abbiamo implementato una funzionalità di previsione dei prezzi che stima il costo di produzione del giocattolo progettato su misura. Questo servizio è basato su un agente che include uno strumento di calcolo dei prezzi sofisticato.
Gen AI Toolbox for Databases: questo agente è perfettamente integrato con il nostro database utilizzando il nuovo strumento open source di Google, Gen AI Toolbox for Databases. In questo modo, l'agente può accedere a dati in tempo reale su costi dei materiali, processi di produzione e altri fattori pertinenti per fornire una stima accurata del prezzo. Scopri di più qui.
- Java Spring Boot, Gemini Code Assist e Cloud Run per lo sviluppo semplificato e il deployment serverless
L'intera applicazione è realizzata utilizzando Java Spring Boot, un framework solido e scalabile. Abbiamo sfruttato Gemini Code Assist durante tutto il processo di sviluppo, in particolare per lo sviluppo front-end, accelerando notevolmente il ciclo di sviluppo e migliorando la qualità del codice. Abbiamo utilizzato Cloud Run per il deployment dell'intera applicazione e Cloud Run Functions per il deployment del database e delle funzionalità di agenti come endpoint indipendenti.
3. Prima di iniziare
Crea un progetto
- Nella console Google Cloud, nella pagina di selezione del progetto, seleziona o crea un progetto Google Cloud.
- Verifica che la fatturazione sia attivata per il tuo progetto Cloud. Scopri come verificare se la fatturazione è attivata in un progetto .
- 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.
- 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
- Esegui il seguente comando in Cloud Shell per verificare che il comando gcloud conosca il tuo progetto.
gcloud config list project
- Se il progetto non è impostato, utilizza il seguente comando per impostarlo:
gcloud config set project <YOUR_PROJECT_ID>
- Abilita le API richieste eseguendo uno alla volta i seguenti comandi nel terminale Cloud Shell:
Esiste anche un singolo comando per eseguire quanto segue, ma se sei un utente con un account di prova, potresti riscontrare problemi di quota durante l'attivazione collettiva. Per questo motivo, i comandi vengono evidenziati uno per riga.
gcloud services enable alloydb.googleapis.com
gcloud services enable compute.googleapis.com
gcloud services enable cloudresourcemanager.googleapis.com
gcloud services enable servicenetworking.googleapis.com
gcloud services enable run.googleapis.com
gcloud services enable cloudbuild.googleapis.com
gcloud services enable cloudfunctions.googleapis.com
gcloud services enable aiplatform.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.
4. Configurazione del database
In questo lab utilizzeremo AlloyDB come database per memorizzare i dati del negozio di giocattoli. Utilizza i cluster per contenere tutte le risorse, come database e log. Ogni cluster ha un'istanza principale che fornisce un punto di accesso ai dati. Le tabelle conterranno i dati effettivi.
Creiamo un cluster, un'istanza e una tabella AlloyDB in cui verrà caricato il set di dati di e-commerce.
Crea un cluster e un'istanza
- Esplora la pagina AlloyDB nella console Cloud. Un modo semplice per trovare la maggior parte delle pagine in Cloud Console è cercarle utilizzando la barra di ricerca della console.
- Seleziona CREA CLUSTER da questa pagina:
- Viene visualizzata una schermata come quella riportata di seguito. Crea un cluster e un'istanza con i seguenti valori (assicurati che i valori corrispondano nel caso in cui stia clonando il codice dell'applicazione dal repository):
- cluster id: "
vector-cluster
" - password: "
alloydb
" - Compatibile con PostgreSQL 15
- Regione: "
us-central1
" - Networking: "
default
"
- Quando selezioni la rete predefinita, viene visualizzata una schermata come quella riportata di seguito.
Seleziona CONFIGURA CONNESSIONE.
- Da qui, seleziona "Utilizza un intervallo IP allocato automaticamente" e Continua. Dopo aver esaminato le informazioni, seleziona CREA CONNESSIONE.
- Una volta configurata la rete, puoi continuare a creare il cluster. Fai clic su CREA CLUSTER per completare la configurazione del cluster come mostrato di seguito:
Assicurati di modificare l'ID istanza in "
vector-instance"
.
Tieni presente che la creazione del cluster richiede circa 10 minuti. Al termine dell'operazione, dovresti visualizzare una schermata che mostra la panoramica del cluster appena creato.
5. Importazione dati
Ora è il momento di aggiungere una tabella con i dati del negozio. Vai ad AlloyDB, seleziona il cluster principale e poi AlloyDB Studio:
Potresti dover attendere il completamento della creazione dell'istanza. Una volta completata la procedura, accedi ad AlloyDB utilizzando le credenziali che hai creato durante la creazione del cluster. Utilizza i seguenti dati per l'autenticazione in PostgreSQL:
- Nome utente : "
postgres
" - Database : "
postgres
" - Password : "
alloydb
"
Una volta autenticati in AlloyDB Studio, i comandi SQL vengono inseriti nell'editor. Puoi aggiungere più finestre di Editor utilizzando il segno Più a destra dell'ultima finestra.
Inserisci i comandi per AlloyDB nelle finestre dell'editor, utilizzando le opzioni Esegui, Formatta e Cancella in base alle tue esigenze.
Attivare le estensioni
Per creare questa app, utilizzeremo le estensioni pgvector
e google_ml_integration
. L'estensione pgvector ti consente di archiviare e cercare gli incorporamenti vettoriali. L'estensione google_ml_integration fornisce le funzioni che utilizzi per accedere agli endpoint di previsione di Vertex AI per ottenere le previsioni in SQL. Attiva queste estensioni eseguendo i seguenti DDL:
CREATE EXTENSION IF NOT EXISTS google_ml_integration CASCADE;
CREATE EXTENSION IF NOT EXISTS vector;
Se vuoi controllare le estensioni che sono state attivate nel tuo database, esegui questo comando SQL:
select extname, extversion from pg_extension;
Creare una tabella
Crea una tabella utilizzando l'istruzione DDL riportata di seguito:
CREATE TABLE toys ( id VARCHAR(25), name VARCHAR(25), description VARCHAR(20000), quantity INT, price FLOAT, image_url VARCHAR(200), text_embeddings vector(768)) ;
Se l'esecuzione del comando precedente è andata a buon fine, dovresti essere in grado di visualizzare la tabella nel database.
Importa i dati
Per questo lab, abbiamo dati di test di circa 72 record in questo file SQL. Contiene i campi id, name, description, quantity, price, image_url
. Gli altri campi verranno compilati più avanti nel lab.
Copia le righe/le istruzioni insert da lì, poi incollale in una scheda dell'editor vuota e seleziona ESEGUI.
Per visualizzare i contenuti della tabella, espandi la sezione Esplora fino a visualizzare la tabella denominata abbigliamento. Seleziona i tre puntini (⋮) per visualizzare l'opzione per eseguire una query sulla tabella. In una nuova scheda dell'editor si aprirà un'istruzione SELECT.
Concedi autorizzazione
Esegui la seguente istruzione per concedere all'utente postgres
i diritti di esecuzione sulla funzione embedding
:
GRANT EXECUTE ON FUNCTION embedding TO postgres;
Concedi il RUOLO Utente Vertex AI all'account di servizio AlloyDB
Vai al terminale Cloud Shell ed esegui il seguente comando:
PROJECT_ID=$(gcloud config get-value project)
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:service-$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")@gcp-sa-alloydb.iam.gserviceaccount.com" \
--role="roles/aiplatform.user"
6. Crea gli incorporamenti per il contesto
Per i computer è molto più facile elaborare numeri che testo. Un sistema di embedding converte il testo in una serie di numeri in virgola mobile che dovrebbero rappresentare il testo, indipendentemente dalla formulazione, dalla lingua utilizzata e così via.
Prova a descrivere una località sul mare. Potrebbe essere chiamato "on the water", "beachfront", "walk from your room to the ocean", "sur la mer", "на берегу океана" e così via. Questi termini sembrano tutti diversi, ma il loro significato semantico o, nella terminologia del machine learning, i relativi embedding dovrebbero essere molto vicini tra loro.
Ora che i dati e il contesto sono pronti, eseguiremo il codice SQL per aggiungere gli embedding della descrizione del prodotto alla tabella nel campo embedding
. Esistono diversi modelli di embedding che puoi utilizzare. Utilizziamo text-embedding-005
di Vertex AI. Assicurati di utilizzare lo stesso modello di embedding in tutto il progetto.
Nota: se utilizzi un progetto Google Cloud esistente creato un po' di tempo fa, potresti dover continuare a utilizzare versioni precedenti del modello di embedding del testo, come textembedding-gecko.
Torna alla scheda AlloyDB Studio e digita il seguente DML:
UPDATE toys set text_embeddings = embedding( 'text-embedding-005', description);
Esamina di nuovo la tabella toys
per vedere alcuni embedding. Assicurati di eseguire di nuovo l'istruzione SELECT per visualizzare le modifiche.
SELECT id, name, description, price, quantity, image_url, text_embeddings FROM toys;
Dovrebbe restituire il vettore di embedding, che ha la forma di un array di valori float, per la descrizione del giocattolo, come mostrato di seguito:
Nota:i progetti Google Cloud appena creati nel livello senza costi potrebbero riscontrare problemi di quota per quanto riguarda il numero di richieste di incorporamento consentite al secondo per i modelli di incorporamento. Ti consigliamo di utilizzare una query di filtro per l'ID e di scegliere in modo selettivo 1-5 record e così via durante la generazione dell'embedding.
7. Eseguire la ricerca vettoriale
Ora che la tabella, i dati e gli embedding sono pronti, eseguiamo la ricerca di vettori in tempo reale per il testo di ricerca dell'utente.
Supponiamo che l'utente chieda:
"I want a white plush teddy bear toy with a floral pattern
."
Puoi trovare corrispondenze per questo eseguendo la query riportata di seguito:
select * from toys
ORDER BY text_embeddings <=> CAST(embedding('text-embedding-005', 'I want a white plush teddy bear toy with a floral pattern') as vector(768))
LIMIT 5;
Esaminiamo questa query in dettaglio:
In questa query,
- Il testo di ricerca dell'utente è: "
I want a white plush teddy bear toy with a floral pattern.
" - Lo stiamo convertendo in embedding nel metodo
embedding()
utilizzando il modello:text-embedding-005
. Questo passaggio dovrebbe essere simile all'ultimo, in cui abbiamo applicato la funzione di incorporamento a tutti gli elementi della tabella. - "
<=>
" indica l'utilizzo del metodo di distanza COSINE SIMILARITY. Puoi trovare tutte le misure di somiglianza disponibili nella documentazione di pgvector. - Stiamo convertendo il risultato del metodo di embedding in tipo di vettore per renderlo compatibile con i vettori archiviati nel database.
- LIMIT 5 indica che vogliamo estrarre 5 vicini più prossimi per il testo di ricerca.
Il risultato sarà simile al seguente:
Come puoi notare nei risultati, le corrispondenze sono molto simili al testo di ricerca. Prova a cambiare il testo per vedere come cambiano i risultati.
Nota importante:
Supponiamo ora di voler aumentare il rendimento (tempo di query), l'efficienza e il richiamo di questo risultato di ricerca vettoriale utilizzando l'indice ScaNN. Leggi i passaggi descritti in questo post del blog per confrontare la differenza del risultato con e senza l'indice.
Passaggio facoltativo: migliora l'efficienza e il recupero con l'indice ScaNN
Per comodità, di seguito sono elencati i passaggi per la creazione dell'indice:
- Poiché abbiamo già creato il cluster, l'istanza, il contesto e gli embedding, dobbiamo solo installare l'estensione ScaNN utilizzando la seguente dichiarazione:
CREATE EXTENSION IF NOT EXISTS alloydb_scann;
- A questo punto creeremo l'indice (ScaNN):
CREATE INDEX toysearch_index ON toys
USING scann (text_embeddings cosine)
WITH (num_leaves=9);
Nel DDL riportato sopra, apparel_index è il nome dell'indice
"toys" è la mia tabella
"scann" è il metodo di indicizzazione
"embedding" è la colonna della tabella che voglio indicizzare
"cosine" è il metodo di distanza che voglio utilizzare con l'indice
"8" è il numero di partizioni da applicare a questo indice. Imposta un valore compreso tra 1 e 1048576. Per ulteriori informazioni su come decidere questo valore, consulta Ottimizzare un indice ScaNN.
Ho utilizzato la RADICE QUADRATA del numero di punti dati, come consigliato nel repo di ScaNN (durante la partizione, num_leaves deve essere approssimativamente la radice quadrata del numero di punti dati).
- Verifica se l'indice viene creato utilizzando la query:
SELECT * FROM pg_stat_ann_indexes;
- Esegui la ricerca vettoriale utilizzando la stessa query utilizzata senza l'indice:
select * from toys
ORDER BY text_embeddings <=> CAST(embedding('text-embedding-005', 'I want a white plush teddy bear toy with a floral pattern') as vector(768))
LIMIT 5;
La query riportata sopra è la stessa utilizzata nel laboratorio nel passaggio 8. Tuttavia, ora il campo è indicizzato.
- Esegui il test con una semplice query di ricerca con e senza l'indice (rimuovendo l'indice):
Questo caso d'uso contiene solo 72 record, pertanto l'indice non viene effettivamente applicato. Per un test condotto in un altro caso d'uso, i risultati sono i seguenti:
La stessa query di ricerca vettoriale sui dati degli incorporamenti INDICATI genera risultati di ricerca di qualità ed efficienza. L'efficienza è notevolmente migliorata (in termini di tempo di esecuzione: 10,37 ms senza ScaNN e 0,87 ms con ScaNN) con l'indice. Per ulteriori informazioni su questo argomento, consulta questo post del blog.
8. Convalida della corrispondenza con l'LLM
Prima di procedere e creare un servizio per restituire le corrispondenze migliori a un'applicazione, utilizziamo un modello di IA generativa per verificare se queste potenziali risposte sono davvero pertinenti e sicure da condividere con l'utente.
Verificare che l'istanza sia configurata per Gemini
Innanzitutto, controlla se l'integrazione di Google ML è già attivata per il cluster e l'istanza. In AlloyDB Studio, dai il seguente comando:
show google_ml_integration.enable_model_support;
Se il valore visualizzato è "on", puoi saltare i due passaggi successivi e andare direttamente alla configurazione dell'integrazione del modello AlloyDB e Vertex AI.
- Vai all'istanza principale del cluster AlloyDB e fai clic su MODIFICA ISTANZA PRINCIPALE.
- Vai alla sezione Indicatori nelle Opzioni di configurazione avanzata. e assicurati che
google_ml_integration.enable_model_support flag
sia impostato su "on
", come mostrato di seguito:
Se non è impostato su "on", impostalo su "on" e poi fai clic sul pulsante AGGIORNA INSTANCE. Questo passaggio richiederà alcuni minuti.
Integrazione del modello AlloyDB e Vertex AI
Ora puoi connetterti ad AlloyDB Studio ed eseguire il seguente statement DML per configurare l'accesso al modello Gemini da AlloyDB, utilizzando l'ID progetto dove indicato. Prima di eseguire il comando, potresti ricevere un avviso di errore di sintassi, ma l'esecuzione dovrebbe essere corretta.
Innanzitutto, creiamo la connessione del modello Gemini 1.5 come mostrato di seguito. Ricorda di sostituire $PROJECT_ID
nel comando seguente con il tuo ID progetto Google Cloud.
CALL
google_ml.create_model( model_id => 'gemini-1.5',
model_request_url => 'https://us-central1-aiplatform.googleapis.com/v1/projects/$PROJECT_ID/locations/us-central1/publishers/google/models/gemini-1.5-pro:streamGenerateContent',
model_provider => 'google',
model_auth_type => 'alloydb_service_agent_iam');
Puoi controllare i modelli configurati per l'accesso tramite il seguente comando in AlloyDB Studio:
select model_id,model_type from google_ml.model_info_view;
Infine, dobbiamo concedere agli utenti del database l'autorizzazione per eseguire la funzione ml_predict_row per eseguire le previsioni tramite i modelli Google Vertex AI. Esegui questo comando:
GRANT EXECUTE ON FUNCTION ml_predict_row to postgres;
Nota: se utilizzi un progetto Google Cloud esistente e un cluster/un'istanza di AlloyDB esistenti creati un po' di tempo fa, potresti dover eliminare i vecchi riferimenti al modello gemini-1.5 e ricrearli con l'istruzione CALL riportata sopra ed eseguire di nuovo grant execute on function ml_predict_row nel caso in cui riscontri problemi nelle prossime invocazioni di gemini-1.5.
Valutazione delle risposte
Anche se nella sezione successiva utilizzeremo una grande query per assicurarci che le risposte siano ragionevoli, la query può essere difficile da comprendere. Ora esamineremo i componenti e vedremo come si combinano tra loro in pochi minuti.
- Innanzitutto invieremo una richiesta al database per ottenere le 10 corrispondenze più vicine a una query dell'utente.
- Per determinare la validità delle risposte, utilizzeremo una query esterna in cui spiegheremo come valutarle. Utilizza il campo
recommended_text
, ovvero il testo di ricerca, econtent
(il campo della descrizione del giocattolo) della tabella interna come parte della query. - Utilizzando questo dato, esamineremo la "bontà" delle risposte restituite.
predict_row
restituisce il risultato in formato JSON. Il codice "-> 'candidates' -> 0 -> 'content' -> 'parts' -> 0 -> 'text'"
viene utilizzato per estrarre il testo effettivo dal JSON. Per visualizzare il JSON effettivo restituito, puoi rimuovere questo codice.- Infine, per ottenere la risposta dell'LLM, la estraiamo utilizzando
REGEXP_REPLACE(gemini_validation,
'[^a-zA-Z,: ]',
'',
'g')
SELECT id,
name,
content,
quantity,
price,
image_url,
recommended_text,
REGEXP_REPLACE(gemini_validation, '[^a-zA-Z,: ]', '', 'g') AS gemini_validation
FROM (SELECT id,
name,
content,
quantity,
price,
image_url,
recommended_text,
CAST(ARRAY_AGG(LLM_RESPONSE) AS TEXT) AS gemini_validation
FROM (SELECT id,
name,
content,
quantity,
price,
image_url,
recommended_text,
json_array_elements(google_ml.predict_row(model_id => 'gemini-1.5',
request_body => CONCAT('{ "contents": [ { "role": "user", "parts": [ { "text": "User wants to buy a toy and this is the description of the toy they wish to buy: ', recommended_text, '. Check if the following product items from the inventory are close enough to really, contextually match the user description. Here are the items: ', content, '. Return a ONE-LINE response with 3 values: 1) MATCH: if the 2 contexts are reasonably matching in terms of any of the color or color family specified in the list, approximate style match with any of the styles mentioned in the user search text: This should be a simple YES or NO. Choose NO only if it is completely irrelevant to users search criteria. 2) PERCENTAGE: percentage of match, make sure that this percentage is accurate 3) DIFFERENCE: A clear one-line easy description of the difference between the 2 products. Remember if the user search text says that some attribute should not be there, and the record has it, it should be a NO match. " } ] } ] }')::JSON)) -> 'candidates' -> 0 -> 'content' -> 'parts' -> 0 -> 'text' :: TEXT AS LLM_RESPONSE
FROM (SELECT id,
name,
description AS content,
quantity,
price,
image_url,
'Pink panther standing' AS recommended_text
FROM toys
ORDER BY text_embeddings <=> embedding('text-embedding-005',
'Pink panther standing')::VECTOR
LIMIT 10) AS xyz) AS X
GROUP BY id,
name,
content,
quantity,
price,
image_url,
recommended_text) AS final_matches
WHERE REGEXP_REPLACE(gemini_validation, '[^a-zA-Z,: ]', '', 'g') LIKE '%MATCH%:%YES%';
Anche se la procedura può sembrare scoraggiante, speriamo che tu possa capirla meglio. I risultati indicano se esiste o meno una corrispondenza, la percentuale di corrispondenza e una spiegazione della valutazione.
Tieni presente che lo streaming è attivo per impostazione predefinita nel modello Gemini, pertanto la risposta effettiva è suddivisa su più righe:
9. Eseguire la ricerca di giocattoli su Cloud in modo serverless
Vuoi portare questa app sul web? Per rendere questo Knowledge Engine serverless con le funzioni Cloud Run:
- Vai a Cloud Run Functions nella console Google Cloud per CREARE una nuova funzione Cloud Run o utilizza il link: https://console.cloud.google.com/functions/add.
- Seleziona l'ambiente come "Funzione Cloud Run". Fornisci il nome della funzione "get-toys-alloydb" e scegli la regione "us-central1". Imposta Autenticazione su "Consenti chiamate non autenticate" e fai clic su AVANTI. Scegli Java 17 come runtime e Editor incorporato per il codice sorgente.
- Per impostazione predefinita, il punto di ingresso viene impostato su "
gcfv2.HelloHttpFunction
". Sostituisci il codice segnaposto inHelloHttpFunction.java
epom.xml
della funzione Cloud Run con il codice di HelloHttpFunction.java e pom.xml, rispettivamente. - Ricorda di modificare il segnaposto <<YOUR_PROJECT>> e le credenziali di connessione AlloyDB con i tuoi valori nel file Java. Le credenziali AlloyDB sono quelle che abbiamo utilizzato all'inizio di questo codelab. Se hai utilizzato valori diversi, modificali nel file Java.
- Fai clic su Esegui il deployment.
Una volta eseguito il deployment, per consentire alla funzione Cloud di accedere all'istanza del database AlloyDB, creeremo il connettore VPC.
PASSAGGIO IMPORTANTE:
Una volta completato il deployment, dovresti essere in grado di vedere le funzioni nella console Cloud Run Functions di Google. Cerca la funzione appena creata (get-toys-alloydb
), fai clic su di essa, poi su MODIFICA e modifica quanto segue:
- Vai a Impostazioni di runtime, build, connessioni e sicurezza
- Aumenta il timeout a 180 secondi
- Vai alla scheda COLLEGAMENTI:
- Nelle impostazioni In entrata, assicurati che sia selezionata l'opzione "Consenti tutto il traffico".
- In Impostazioni di uscita, fai clic sul menu a discesa Rete e seleziona l'opzione "Aggiungi nuovo connettore VPC", quindi segui le istruzioni visualizzate nella finestra di dialogo visualizzata:
- Fornisci un nome per il connettore VPC e assicurati che la regione corrisponda a quella dell'istanza. Lascia il valore della rete predefinito e imposta la subnet come intervallo IP personalizzato con l'intervallo IP 10.8.0.0 o un valore simile disponibile.
- Espandi IMPOSTAZIONI DI SCALING DEL DISPLAY e assicurati che la configurazione sia impostata esattamente come segue:
- Fai clic su CREA e questo connettore dovrebbe essere elencato nelle impostazioni di uscita.
- Seleziona il connettore appena creato
- Scegli di instradare tutto il traffico attraverso questo connettore VPC.
- Fai clic su AVANTI e poi su ESEGUI IL DEPLOY.
10. Testa la funzione Cloud Run
Una volta eseguito il deployment della funzione Cloud aggiornata, dovresti vedere l'endpoint nel seguente formato:
https://us-central1-YOUR_PROJECT_ID.cloudfunctions.net/get-toys-alloydb
In alternativa, puoi testare la funzione Cloud Run come segue:
PROJECT_ID=$(gcloud config get-value project)
curl -X POST https://us-central1-$PROJECT_ID.cloudfunctions.net/get-toys-alloydb \
-H 'Content-Type: application/json' \
-d '{"search":"I want a standing pink panther toy"}' \
| jq .
E il risultato:
È tutto. È così semplice eseguire la ricerca vettoriale di similarità utilizzando il modello di embedding sui dati di AlloyDB.
11. Creazione del client dell'applicazione web.
In questa parte, creeremo un'applicazione web con cui l'utente potrà interagire e trovare giocattoli corrispondenti in base a testo, immagine e persino creare un nuovo giocattolo in base alle sue esigenze. Poiché l'applicazione è già stata compilata, puoi seguire i passaggi riportati di seguito per copiarla nell'IDE e avviarla.
- Poiché utilizziamo Gemini 2.0 Flash per descrivere l'immagine che l'utente potrebbe caricare per trovare i giocattoli corrispondenti, dobbiamo ottenere la CHIAVE API per questa applicazione. Per farlo, vai all'indirizzo https://aistudio.google.com/apikey, ottieni la chiave API per il tuo progetto Google Cloud attivo in cui stai implementando questa applicazione e salvala da qualche parte:
- Vai al terminale Cloud Shell
- Clona il repository con il seguente comando:
git clone https://github.com/AbiramiSukumaran/toysearch
cd toysearch
- Una volta clonato il repository, dovresti essere in grado di accedere al progetto dall'editor di Cloud Shell.
- Devi eliminare le cartelle "get-toys-alloydb" e "toolbox-toys" dal progetto clonato perché sono codice di Cloud Run Functions a cui puoi fare riferimento dal repository quando ti servono.
- Assicurati che tutte le variabili di ambiente necessarie siano impostate prima di compilare e implementare l'app. Vai al terminale Cloud Shell ed esegui quanto segue:
PROJECT_ID=$(gcloud config get-value project)
export PROJECT_ID $PROJECT_ID
export GOOGLE_API_KEY <YOUR API KEY that you saved>
- Crea ed esegui l'app localmente:
Assicurati di trovarti nella directory del progetto ed esegui i seguenti comandi:
mvn package
mvn spring-boot:run
- Esegui il deployment su Cloud Run
gcloud run deploy --source .
12. Informazioni dettagliate sull'IA generativa
Nessuna azione richiesta. Per tua informazione:
Ora che hai eseguito il deployment dell'applicazione, prenditi un momento per capire come abbiamo eseguito la ricerca (di testo e immagini) e la generazione.
- Ricerca vettoriale basata sul testo dell'utente:
Questo problema è già stato risolto nelle funzioni Cloud Run che abbiamo implementato nella sezione "Eseguire l'applicazione web di ricerca vettoriale".
- Ricerca vettoriale basata sul caricamento di immagini:
Invece di digitare il contesto come testo, supponiamo che l'utente voglia caricare un'immagine di un giocattolo familiare con cui vuole eseguire la ricerca. Gli utenti possono caricare un'immagine di un giocattolo che gli piace e ottenere funzionalità pertinenti.
Sfruttiamo il modello Gemini 2.0 Flash di Google, invocato utilizzando LangChain4j, per analizzare l'immagine ed estrarre il contesto pertinente, ad esempio il colore, il materiale, il tipo e la fascia d'età prevista del giocattolo.
In soli 5 passaggi, abbiamo utilizzato un framework open source per passare dall'inserimento dei dati multimodali dell'utente alla corrispondenza dei risultati con l'invocazione di un modello linguistico di grandi dimensioni. Scopri come:
package cloudcode.helloworld.web;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.googleai.GoogleAiGeminiChatModel;
import dev.langchain4j.data.message.UserMessage;
import dev.langchain4j.data.message.AiMessage;
import dev.langchain4j.model.output.Response;
import dev.langchain4j.data.message.ImageContent;
import dev.langchain4j.data.message.TextContent;
import java.util.Base64;
import java.util.Optional;
public class GeminiCall {
public String imageToBase64String(byte[] imageBytes) {
String base64Img = Base64.getEncoder().encodeToString(imageBytes);
return base64Img;
}
public String callGemini(String base64ImgWithPrefix) throws Exception {
String searchText = "";
// 1. Remove the prefix
String base64Img = base64ImgWithPrefix.replace("data:image/jpeg;base64,", "");
// 2. Decode base64 to bytes
byte[] imageBytes = Base64.getDecoder().decode(base64Img);
String image = imageToBase64String(imageBytes);
// 3. Get API key from environment variable
String apiKey = Optional.ofNullable(System.getenv("GOOGLE_API_KEY"))
.orElseThrow(() -> new IllegalArgumentException("GOOGLE_API_KEY environment variable not set"));
// 4. Invoke Gemini 2.0
ChatLanguageModel gemini = GoogleAiGeminiChatModel.builder()
.apiKey(apiKey)
.modelName("gemini-2.0-flash-001")
.build();
Response<AiMessage> response = gemini.generate(
UserMessage.from(
ImageContent.from(image, "image/jpeg"),
TextContent.from(
"The picture has a toy in it. Describe the toy in the image in one line. Do not add any prefix or title to your description. Just describe that toy that you see in the image in one line, do not describe the surroundings and other objects around the toy in the image. If you do not see any toy in the image, send response stating that no toy is found in the input image.")));
// 5. Get the text from the response and send it back to the controller
searchText = response.content().text().trim();
System.out.println("searchText inside Geminicall: " + searchText);
return searchText;
}
}
- Scopri come abbiamo utilizzato Imagen 3 per creare un giocattolo personalizzato in base alla richiesta dell'utente con l'IA generativa.
Imagen 3 genera quindi un'immagine del giocattolo progettato su misura, offrendo all'utente una visualizzazione chiara della sua creazione. Ecco come abbiamo fatto in soli 5 passaggi:
// Generate an image using a text prompt using an Imagen model
public String generateImage(String projectId, String location, String prompt)
throws ApiException, IOException {
final String endpoint = String.format("%s-aiplatform.googleapis.com:443", location);
PredictionServiceSettings predictionServiceSettings =
PredictionServiceSettings.newBuilder().setEndpoint(endpoint).build();
// 1. Set up the context and prompt
String context = "Generate a photo-realistic image of a toy described in the following input text from the user. Make sure you adhere to all the little details and requirements mentioned in the prompt. Ensure that the user is only describing a toy. If it is anything unrelated to a toy, politely decline the request stating that the request is inappropriate for the current context. ";
prompt = context + prompt;
// 2. Initialize a client that will be used to send requests. This client only needs to be created
// once, and can be reused for multiple requests.
try (PredictionServiceClient predictionServiceClient =
PredictionServiceClient.create(predictionServiceSettings)) {
// 3. Invoke Imagen 3
final EndpointName endpointName =
EndpointName.ofProjectLocationPublisherModelName(
projectId, location, "google", "imagen-3.0-generate-001"); //"imagegeneration@006"; 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");
paramsMap.put("guidanceScale", 21);
paramsMap.put("imagenControlScale", 0.95); //Setting imagenControlScale
Value parameters = mapToValue(paramsMap);
// 4. Get prediction response image
PredictResponse predictResponse =
predictionServiceClient.predict(
endpointName, Collections.singletonList(instances), parameters);
// 5. Return the Base64 Encoded String to the controller
for (Value prediction : predictResponse.getPredictionsList()) {
Map<String, Value> fieldsMap = prediction.getStructValue().getFieldsMap();
if (fieldsMap.containsKey("bytesBase64Encoded")) {
bytesBase64EncodedOuput = fieldsMap.get("bytesBase64Encoded").getStringValue();
}
}
return bytesBase64EncodedOuput.toString();
}
}
Previsione dei prezzi
Nella sezione precedente abbiamo discusso di come Imagen genera l'immagine di un giocattolo che l'utente vuole progettare autonomamente. Affinché possano acquistarlo, l'applicazione deve impostare un prezzo e abbiamo utilizzato una logica intuitiva per definire un prezzo per il giocattolo personalizzato su ordinazione. La logica è utilizzare il prezzo medio dei 5 giocattoli più simili (in termini di descrizione) al giocattolo progettato dall'utente.
La previsione del prezzo del giocattolo generato è una parte importante di questa applicazione e abbiamo utilizzato un approccio basato sugli agenti per generarla. Ti presentiamo la cassetta degli attrezzi di IA generativa per i database.
13. Cassetta degli attrezzi di IA generativa per i database
Gen AI Toolbox for Databases è un server open source di Google che semplifica la creazione di strumenti di AI generativa per interagire con i database. Ti consente di sviluppare strumenti in modo più semplice, rapido e sicuro gestendo complessità come il pooling delle connessioni, l'autenticazione e altro ancora. Ti aiuta a creare strumenti di IA generativa che consentono ai tuoi agenti di accedere ai dati nel tuo database.
Ecco i passaggi da seguire per configurare lo strumento e rendere la nostra applicazione agente: Link al Codelab di Toolbox
Ora la tua applicazione può utilizzare questo endpoint della funzione Cloud Run di cui è stato eseguito il deployment per compilare il prezzo insieme al risultato di Imagen generato per l'immagine del giocattolo personalizzato su ordinazione.
14. Testare l'applicazione web
Ora che tutti i componenti dell'applicazione sono stati creati e di cui è stato eseguito il deployment, l'applicazione è pronta per essere pubblicata sul cloud. Testa l'applicazione per tutti gli scenari. Ecco un link a un video che mostra cosa potresti aspettarti:
https://www.youtube.com/shorts/ZMqUAWsghYQ
Ecco come si presenta la pagina di destinazione:
15. Esegui la pulizia
Per evitare che al tuo account Google Cloud vengano addebitati costi relativi alle risorse utilizzate in questo post, segui questi passaggi:
- Nella console Google Cloud, vai alla pagina Gestisci risorse.
- Nell'elenco dei progetti, seleziona il progetto che vuoi eliminare, quindi fai clic su Elimina.
- Nella finestra di dialogo, digita l'ID progetto, quindi fai clic su Chiudi per eliminare il progetto.
16. Complimenti
Complimenti! Hai eseguito correttamente una ricerca e una generazione contestuale di negozi di giocattoli utilizzando AlloyDB, pgvector, Imagen e Gemini 2.0, sfruttando al contempo le librerie open source per creare integrazioni solide. Combinando le funzionalità di AlloyDB, Vertex AI e Vector Search, abbiamo fatto un enorme passo avanti nel rendere le ricerche contestuali e vettoriali accessibili, efficienti e basate sul significato.