1. Introduzione
In questo codelab imparerai a utilizzare l'integrazione dell'AI di Cloud SQL per PostgreSQL combinando la ricerca vettoriale con gli embedding di Vertex AI.
Prerequisiti
- Conoscenza di base della console Google Cloud
- Competenze di base nell'interfaccia a riga di comando e in Cloud Shell
Cosa imparerai a fare
- Come eseguire il deployment di un'istanza Cloud SQL per PostgreSQL
- Come creare un database e attivare l'integrazione dell'IA di Cloud SQL
- Come caricare i dati nel database
- Come utilizzare il modello di embedding Vertex AI in Cloud SQL
- Come arricchire il risultato utilizzando il modello generativo di Vertex AI
- Come migliorare il rendimento utilizzando l'indice vettoriale
Che cosa ti serve
- Un account Google Cloud e un progetto Google Cloud
- Un browser web come Chrome che supporta la console Google Cloud e Cloud Shell
2. Configurazione e requisiti
Configurazione dell'ambiente a tuo ritmo
- Accedi alla console Google Cloud e crea un nuovo progetto o riutilizzane uno esistente. Se non hai ancora un account Gmail o Google Workspace, devi crearne uno.
- Il nome del progetto è il nome visualizzato per i partecipanti al progetto. Si tratta di una stringa di caratteri non utilizzata dalle API di Google. Puoi sempre aggiornarlo.
- L'ID progetto è univoco per tutti i progetti Google Cloud ed è immutabile (non può essere modificato dopo essere stato impostato). La console Cloud genera automaticamente una stringa univoca; di solito non ti interessa quale sia. Nella maggior parte dei codelab, dovrai fare riferimento al tuo ID progetto (in genere identificato come
PROJECT_ID
). Se l'ID generato non ti piace, puoi generarne un altro casuale. In alternativa, puoi provare il tuo e vedere se è disponibile. Non può essere modificato dopo questo passaggio e rimane invariato per tutta la durata del progetto. - Per tua informazione, esiste un terzo valore, un Numero progetto, utilizzato da alcune API. Scopri di più su tutti e tre questi valori nella documentazione.
- Successivamente, dovrai abilitare la fatturazione nella console Cloud per utilizzare le API/risorse Cloud. La partecipazione a questo codelab non ha costi, o quasi. Per arrestare le risorse ed evitare di incorrere in fatturazione al termine di questo tutorial, puoi eliminare le risorse che hai creato o il progetto. I nuovi utenti di Google Cloud sono idonei al programma Prova senza costi di 300$.
Avvia Cloud Shell
Sebbene Google Cloud possa essere utilizzato da remoto dal tuo laptop, in questo codelab utilizzerai Google Cloud Shell, un ambiente a riga di comando in esecuzione nel cloud.
Nella console Google Cloud, fai clic sull'icona di Cloud Shell nella barra degli strumenti in alto a destra:
Dovrebbero bastare pochi istanti per eseguire il provisioning e connettersi all'ambiente. Al termine, dovresti vedere qualcosa di simile a questo:
Questa macchina virtuale contiene tutti gli strumenti di sviluppo di cui avrai bisogno. Offre una home directory permanente da 5 GB e viene eseguita su Google Cloud, migliorando notevolmente le prestazioni e l'autenticazione di rete. Tutto il lavoro in questo codelab può essere svolto in un browser. Non devi installare nulla.
3. Prima di iniziare
Attiva l'API
Output:
In Cloud Shell, assicurati che l'ID progetto sia configurato:
gcloud config set project [YOUR-PROJECT-ID]
Imposta la variabile di ambiente PROJECT_ID:
PROJECT_ID=$(gcloud config get-value project)
Attiva tutti i servizi necessari:
gcloud services enable sqladmin.googleapis.com \
compute.googleapis.com \
cloudresourcemanager.googleapis.com \
servicenetworking.googleapis.com \
aiplatform.googleapis.com
Risultato previsto
student@cloudshell:~ (test-project-001-402417)$ gcloud config set project test-project-001-402417 Updated property [core/project]. student@cloudshell:~ (test-project-001-402417)$ PROJECT_ID=$(gcloud config get-value project) Your active configuration is: [cloudshell-14650] student@cloudshell:~ (test-project-001-402417)$ student@cloudshell:~ (test-project-001-402417)$ gcloud services enable sqladmin.googleapis.com \ compute.googleapis.com \ cloudresourcemanager.googleapis.com \ servicenetworking.googleapis.com \ aiplatform.googleapis.com Operation "operations/acat.p2-4470404856-1f44ebd8-894e-4356-bea7-b84165a57442" finished successfully.
4. Crea un'istanza Cloud SQL
Crea un'istanza Cloud SQL con l'integrazione del database con Vertex AI.
Crea password database
Definisci la password per l'utente del database predefinito. Puoi definire la tua password o utilizzare una funzione casuale per generarne una:
export CLOUDSQL_PASSWORD=`openssl rand -hex 12`
Prendi nota del valore generato per la password:
echo $CLOUDSQL_PASSWORD
Crea un'istanza Cloud SQL per PostgreSQL
Nella sessione Cloud Shell, esegui:
gcloud sql instances create my-cloudsql-instance \
--database-version=POSTGRES_16 \
--tier=db-custom-1-3840 \
--region=us-central1 \
--edition=ENTERPRISE \
--enable-google-ml-integration \
--database-flags cloudsql.enable_google_ml_integration=on
Dopo aver creato l'istanza, dobbiamo impostare una password per l'utente predefinito nell'istanza e verificare se possiamo connetterci con la password.
gcloud sql users set-password postgres \
--instance=my-cloudsql-instance \
--password=$CLOUDSQL_PASSWORD
Esegui il comando e inserisci la password nel prompt quando è tutto pronto per la connessione.
gcloud sql connect my-cloudsql-instance --user=postgres
Abilita l'integrazione di Vertex AI
Concedi i privilegi necessari all'account di servizio Cloud SQL interno per poter utilizzare l'integrazione di Vertex AI.
Individua l'indirizzo email dell'account di servizio interno Cloud SQL ed esportalo come variabile.
SERVICE_ACCOUNT_EMAIL=$(gcloud sql instances describe my-cloudsql-instance --format="value(serviceAccountEmailAddress)")
echo $SERVICE_ACCOUNT_EMAIL
Concedi l'accesso a Vertex AI all'account di servizio Cloud SQL:
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$SERVICE_ACCOUNT_EMAIL" \
--role="roles/aiplatform.user"
Scopri di più sulla creazione e sulla configurazione delle istanze nella documentazione di Cloud SQL qui.
5. Prepara il database
Ora dobbiamo creare un database e attivare il supporto dei vettori.
Crea database
Crea un database con il nome quickstart_db .A tale scopo, sono disponibili diverse opzioni, ad esempio client di database a riga di comando come psql per PostgreSQL, SDK o Cloud SQL Studio. Utilizzeremo l'SDK (gcloud) per creare i database e connetterci all'istanza.
In Cloud Shell, esegui il comando per creare il database
gcloud sql databases create quickstart_db --instance=my-cloudsql-instance
Attivare le estensioni
Per poter lavorare con Vertex AI e i vettori, dobbiamo attivare due estensioni nel database creato.
In Cloud Shell, esegui il comando per connetterti al database creato (dovrai fornire la password)
gcloud sql connect my-cloudsql-instance --database quickstart_db --user=postgres
Dopo la connessione, nella sessione SQL devi eseguire due comandi:
CREATE EXTENSION IF NOT EXISTS google_ml_integration CASCADE;
CREATE EXTENSION IF NOT EXISTS vector CASCADE;
Esci dalla sessione SQL:
exit;
6. Carica dati
Ora dobbiamo creare oggetti nel database e caricare i dati. Utilizzeremo dati fittizi del negozio Cymbal. I dati sono disponibili nel bucket pubblico Google Storage in formato CSV.
Innanzitutto dobbiamo creare tutti gli oggetti richiesti nel nostro database. A tal fine, utilizzeremo i comandi gcloud sql connect e gcloud storage già noti per scaricare e importare gli oggetti dello schema nel nostro database.
In Cloud Shell, esegui e fornisci la password annotata durante la creazione dell'istanza:
gcloud storage cat gs://cloud-training/gcc/gcc-tech-004/cymbal_demo_schema.sql |gcloud sql connect my-cloudsql-instance --database quickstart_db --user=postgres
Che cosa abbiamo fatto esattamente nel comando precedente? Ci siamo collegati al nostro database ed eseguito il codice SQL scaricato che ha creato tabelle, indici e sequenze.
Il passaggio successivo consiste nel caricare i dati e, per farlo, dobbiamo scaricare i file CSV da Google Cloud Storage.
gcloud storage cp gs://cloud-training/gcc/gcc-tech-004/cymbal_products.csv .
gcloud storage cp gs://cloud-training/gcc/gcc-tech-004/cymbal_inventory.csv .
gcloud storage cp gs://cloud-training/gcc/gcc-tech-004/cymbal_stores.csv .
Poi dobbiamo connetterci al database.
gcloud sql connect my-cloudsql-instance --database quickstart_db --user=postgres
E importare i dati dai nostri file CSV.
\copy cymbal_products from 'cymbal_products.csv' csv header
\copy cymbal_inventory from 'cymbal_inventory.csv' csv header
\copy cymbal_stores from 'cymbal_stores.csv' csv header
Esci dalla sessione SQL:
exit;
Se hai i tuoi dati e i tuoi file CSV sono compatibili con lo strumento di importazione Cloud SQL disponibile nella console Cloud, puoi utilizzarlo anziché l'approccio a riga di comando.
7. Crea incorporamenti
Il passaggio successivo consiste nel creare incorporamenti per le descrizioni dei prodotti utilizzando il modello textembedding-004 di Google Vertex AI e archiviarli come dati vettoriali.
Connettiti al database:
gcloud sql connect my-cloudsql-instance --database quickstart_db --user=postgres
Crea anche una colonna virtuale embedding nella tabella cymbal_products utilizzando la funzione di incorporamento.
ALTER TABLE cymbal_products ADD COLUMN embedding vector(768) GENERATED ALWAYS AS (embedding('text-embedding-004',product_description)) STORED;
L'operazione potrebbe richiedere del tempo, ma per 900-1000 righe non dovrebbe richiedere più di 5 minuti e in genere è molto più rapida.
8. Esegui ricerca di somiglianza
Ora possiamo eseguire la ricerca utilizzando la ricerca di similarità in base ai valori vettoriali calcolati per le descrizioni e al valore vettoriale che otteniamo per la nostra richiesta.
La query SQL può essere eseguita dalla stessa interfaccia a riga di comando utilizzando gcloud sql connect o, in alternativa, da Cloud SQL Studio. È meglio gestire qualsiasi query complessa e con più righe in Cloud SQL Studio.
Avvia Cloud SQL Studio
Nella console, fai clic sull'istanza Cloud SQL che abbiamo creato in precedenza.
Quando è aperto, nel riquadro a destra possiamo vedere Cloud SQL Studio. Fai clic.
Si aprirà una finestra di dialogo in cui dovrai fornire il nome del database e le tue credenziali:
- Database: quickstart_db
- Utente: postgres
- Password: la password annotata per l'utente principale del database
Fai clic sul pulsante "AUTENTICATI".
Si aprirà la finestra successiva in cui fai clic sulla scheda "Editor" sul lato destro per aprire l'editor SQL.
Ora siamo pronti per eseguire le query.
Esegui query
Esegui una query per ottenere un elenco dei prodotti disponibili più correlati alla richiesta di un cliente. La richiesta che passeremo a Vertex AI per ottenere il valore del vettore è simile a "Quali alberi da frutto crescono bene qui?"
Ecco la query che puoi eseguire per scegliere i primi 10 elementi più adatti alla nostra richiesta:
SELECT
cp.product_name,
left(cp.product_description,80) as description,
cp.sale_price,
cs.zip_code,
(cp.embedding <=> embedding('text-embedding-004','What kind of fruit trees grow well here?')::vector) as distance
FROM
cymbal_products cp
JOIN cymbal_inventory ci on
ci.uniq_id=cp.uniq_id
JOIN cymbal_stores cs on
cs.store_id=ci.store_id
AND ci.inventory>0
AND cs.store_id = 1583
ORDER BY
distance ASC
LIMIT 10;
Copia e incolla la query nell'editor di Cloud SQL Studio e premi il pulsante "Esegui" o incollala nella sessione della riga di comando connettendoti al database quickstart_db.
Ecco un elenco di prodotti scelti corrispondenti alla query.
product_name | description | sale_price | zip_code | distance -------------------------+----------------------------------------------------------------------------------+------------+----------+--------------------- Cherry Tree | This is a beautiful cherry tree that will produce delicious cherries. It is an d | 75.00 | 93230 | 0.43922018972266397 Meyer Lemon Tree | Meyer Lemon trees are California's favorite lemon tree! Grow your own lemons by | 34 | 93230 | 0.4685112926118228 Toyon | This is a beautiful toyon tree that can grow to be over 20 feet tall. It is an e | 10.00 | 93230 | 0.4835677149651668 California Lilac | This is a beautiful lilac tree that can grow to be over 10 feet tall. It is an d | 5.00 | 93230 | 0.4947204525907498 California Peppertree | This is a beautiful peppertree that can grow to be over 30 feet tall. It is an e | 25.00 | 93230 | 0.5054166905547247 California Black Walnut | This is a beautiful walnut tree that can grow to be over 80 feet tall. It is a d | 100.00 | 93230 | 0.5084219510932597 California Sycamore | This is a beautiful sycamore tree that can grow to be over 100 feet tall. It is | 300.00 | 93230 | 0.5140519790508755 Coast Live Oak | This is a beautiful oak tree that can grow to be over 100 feet tall. It is an ev | 500.00 | 93230 | 0.5143126438081371 Fremont Cottonwood | This is a beautiful cottonwood tree that can grow to be over 100 feet tall. It i | 200.00 | 93230 | 0.5174774727252058 Madrone | This is a beautiful madrona tree that can grow to be over 80 feet tall. It is an | 50.00 | 93230 | 0.5227400803389093 (10 rows)
9. Migliorare la risposta dell'LLM utilizzando i dati recuperati
Possiamo migliorare la risposta dell'LLM di AI generativa a un'applicazione client utilizzando il risultato della query eseguita e preparare un output significativo utilizzando i risultati della query forniti come parte del prompt per un modello linguistico di base generativo di Vertex AI.
Per farlo, dobbiamo generare un file JSON con i risultati della ricerca di vettori, quindi utilizzare il JSON generato come aggiunta a un prompt per un modello LLM in Vertex AI per creare un output significativo. Nel primo passaggio generiamo il JSON, poi lo testiamo in Vertex AI Studio e nell'ultimo passaggio lo incorporiamo in un'istruzione SQL che può essere utilizzata in un'applicazione.
Generare l'output in formato JSON
Modifica la query per generare l'output in formato JSON e restituire una sola riga da passare a Vertex AI
Cloud SQL per PostgreSQL
Ecco un esempio di query:
WITH trees as (
SELECT
cp.product_name,
left(cp.product_description,80) as description,
cp.sale_price,
cs.zip_code,
cp.uniq_id as product_id
FROM
cymbal_products cp
JOIN cymbal_inventory ci on
ci.uniq_id=cp.uniq_id
JOIN cymbal_stores cs on
cs.store_id=ci.store_id
AND ci.inventory>0
AND cs.store_id = 1583
ORDER BY
(cp.embedding <=> embedding('text-embedding-004','What kind of fruit trees grow well here?')::vector) ASC
LIMIT 1)
SELECT json_agg(trees) FROM trees;
Ed ecco il JSON previsto nell'output:
[{"product_name":"Cherry Tree","description":"This is a beautiful cherry tree that will produce delicious cherries. It is an d","sale_price":75.00,"zip_code":93230,"product_id":"d536e9e823296a2eba198e52dd23e712"}]
Esegui il prompt in Vertex AI Studio
Possiamo utilizzare il JSON generato per fornirlo come parte del prompt al modello di testo di IA generativa in Vertex AI Studio
Apri la chat di Vertex AI Studio nella console Cloud.
Potrebbe chiederti di attivare API aggiuntive, ma puoi ignorare la richiesta. Non sono necessarie API aggiuntive per completare il lab.
Ecco il prompt che utilizzeremo:
You are a friendly advisor helping to find a product based on the customer's needs.
Based on the client request we have loaded a list of products closely related to search.
The list in JSON format with list of values like {"product_name":"name","description":"some description","sale_price":10,"zip_code": 10234, "produt_id": "02056727942aeb714dc9a2313654e1b0"}
Here is the list of products:
[place your JSON here]
The customer asked "What tree is growing the best here?"
You should give information about the product, price and some supplemental information.
Do not ask any additional questions and assume location based on the zip code provided in the list of products.
Ecco come appare quando sostituiamo il segnaposto JSON con la risposta della query:
You are a friendly advisor helping to find a product based on the customer's needs. Based on the client request we have loaded a list of products closely related to search. The list in JSON format with list of values like {"product_name":"name","description":"some description","sale_price":10,"zip_code": 10234, "produt_id": "02056727942aeb714dc9a2313654e1b0"} Here is the list of products: [{"product_name":"Cherry Tree","description":"This is a beautiful cherry tree that will produce delicious cherries. It is an d","sale_price":75.00,"zip_code":93230,"product_id":"d536e9e823296a2eba198e52dd23e712"}] The customer asked "What tree is growing the best here?" You should give information about the product, price and some supplemental information. Do not ask any additional questions and assume location based on the zip code provided in the list of products.
Ed ecco il risultato quando eseguiamo il prompt con i nostri valori JSON e utilizziamo il modello gemini-2.0-flash:
Di seguito è riportata la risposta che abbiamo ricevuto dal modello in questo esempio. Tieni presente che la risposta potrebbe essere diversa a causa delle variazioni del modello e dei parametri nel tempo:
"Ok, in base all'elenco dei prodotti disponibili, l'albero migliore che potrebbe crescere bene nella tua zona è il ciliegio.
Il prezzo è 75,00 $.
Anche se non ho dettagli specifici sulle condizioni di crescita nel tuo codice postale esatto (93230), in genere i ciliegi prosperano in aree con climi moderati e terreno ben drenato. In genere richiedono un certo periodo di freddo invernale per produrre frutti, quindi è un aspetto da tenere presente. Tuttavia, possono essere una meravigliosa aggiunta a un giardino, offrendo bellezza e deliziose ciliegie quando le condizioni sono giuste."
Esegui il prompt in PSQL
Possiamo anche utilizzare l'integrazione dell'IA di Cloud SQL con Vertex AI per ottenere una risposta simile da un modello generativo utilizzando SQL direttamente nel database. Tuttavia, per utilizzare il modello gemini-2.0-flash-exp, dobbiamo prima registrarlo.
Esegui in Cloud SQL per PostgreSQL
Esegui l'upgrade dell'estensione alla versione 1.4.2 o successiva (se la versione corrente è precedente). Connettiti al database quickstart_db da gcloud sql connect come mostrato in precedenza (o utilizza Cloud SQL Studio) ed esegui:
SELECT extversion from pg_extension where extname='google_ml_integration';
Se il valore restituito è inferiore a 1.4.2, esegui:
ALTER EXTENSION google_ml_integration UPDATE TO '1.4.2';
Poi dobbiamo impostare il flag del database google_ml_integration.enable_model_support su "on". Per farlo, puoi utilizzare l'interfaccia della console web o eseguire il seguente comando gcloud.
gcloud sql instances patch my-cloudsql-instance \
--database-flags google_ml_integration.enable_model_support=on,cloudsql.enable_google_ml_integration=on
L'esecuzione del comando in background richiede circa 1-3 minuti. Dopodiché puoi verificare il nuovo flag nella sessione psql o utilizzando Cloud SQL Studio connettendoti al database quickstart_db.
show google_ml_integration.enable_model_support;
L'output previsto della sessione psql è "on":
quickstart_db => show google_ml_integration.enable_model_support; google_ml_integration.enable_model_support -------------------------------------------- on (1 row)
Poi dobbiamo registrare due modelli. Il primo è il modello text-embedding-004 già utilizzato. Deve essere registrato poiché abbiamo attivato le funzionalità di registrazione dei modelli.
Per registrare il modello, esegui il seguente codice in psql o Cloud SQL Studio:
CALL
google_ml.create_model(
model_id => 'text-embedding-004',
model_provider => 'google',
model_qualified_name => 'text-embedding-004',
model_type => 'text_embedding',
model_auth_type => 'cloudsql_service_agent_iam',
model_in_transform_fn => 'google_ml.vertexai_text_embedding_input_transform',
model_out_transform_fn => 'google_ml.vertexai_text_embedding_output_transform');
Il modello successivo che dobbiamo registrare è gemini-2.0-flash-001, che verrà utilizzato per generare l'output intuitivo.
CALL
google_ml.create_model(
model_id => 'gemini-2.0-flash-001',
model_request_url => 'https://us-central1-aiplatform.googleapis.com/v1/projects/$PROJECT_ID/locations/us-central1/publishers/google/models/gemini-2.0-flash-001:streamGenerateContent',
model_provider => 'google',
model_auth_type => 'cloudsql_service_agent_iam');
Puoi sempre verificare l'elenco dei modelli registrati selezionando le informazioni da google_ml.model_info_view.
select model_id,model_type from google_ml.model_info_view;
Ecco un esempio di output
quickstart_db=> select model_id,model_type from google_ml.model_info_view; model_id | model_type --------------------------------------+---------------- textembedding-gecko | text_embedding textembedding-gecko@001 | text_embedding gemini-1.5-pro:streamGenerateContent | generic gemini-1.5-pro:generateContent | generic gemini-1.0-pro:generateContent | generic text-embedding-004 | text_embedding gemini-2.0-flash-001 | generic
Ora possiamo utilizzare il JSON generato in una sottoquery per fornirlo come parte del prompt al modello di testo di IA generativa utilizzando SQL.
Nella sessione psql o Cloud SQL Studio del database, esegui la query
WITH trees AS (
SELECT
cp.product_name,
cp.product_description AS description,
cp.sale_price,
cs.zip_code,
cp.uniq_id AS product_id
FROM
cymbal_products cp
JOIN cymbal_inventory ci ON
ci.uniq_id = cp.uniq_id
JOIN cymbal_stores cs ON
cs.store_id = ci.store_id
AND ci.inventory>0
AND cs.store_id = 1583
ORDER BY
(cp.embedding <=> google_ml.embedding('text-embedding-004',
'What kind of fruit trees grow well here?')::vector) ASC
LIMIT 1),
prompt AS (
SELECT
'You are a friendly advisor helping to find a product based on the customer''s needs.
Based on the client request we have loaded a list of products closely related to search.
The list in JSON format with list of values like {"product_name":"name","product_description":"some description","sale_price":10}
Here is the list of products:' || json_agg(trees) || 'The customer asked "What kind of fruit trees grow well here?"
You should give information about the product, price and some supplemental information' AS prompt_text
FROM
trees),
response AS (
SELECT
json_array_elements(google_ml.predict_row( model_id =>'gemini-2.0-flash-001',
request_body => json_build_object('contents',
json_build_object('role',
'user',
'parts',
json_build_object('text',
prompt_text)))))->'candidates'->0->'content'->'parts'->0->'text' AS resp
FROM
prompt)
SELECT
string_agg(resp::text,
' ')
FROM
response;
Ed ecco l'output previsto. L'output potrebbe essere diverso a seconda della versione e dei parametri del modello.:
"That" "'s a great question! Based on your location (assuming you're" " in zip code 93230), I have a suggestion for a" " fruit tree that should thrive.\n\nWe have the **Cherry Tree** available.\n\n**Product Name:** Cherry Tree\n\n**Description:** This is a beautiful cherry" " tree that will produce delicious cherries. It's a deciduous tree (meaning it loses its leaves in the fall) growing to about 15 feet tall." " The leaves are dark green in summer, turning a beautiful red in the fall. Cherry trees are known for their beauty, shade, and privacy.\n\n**Sale Price:** $75.00\n\n**Important Considerations for Growing" " Cherry Trees:**\n\n* **Climate:** Cherry trees prefer a cool, moist climate, and 93230 falls within a suitable range (USDA zones 4-9). However, it's always a good idea to" " check the specific microclimate of your property (sun exposure, drainage etc.).\n* **Soil:** They do best in sandy soil. If your soil is different, you may need to amend it to improve drainage.\n* **Pollination:** Many cherry varieties require a second, compatible cherry tree for proper pollination" ". Check the specific pollination needs of this variety before purchase if you want a significant cherry yield.\n\nThis cherry tree is a beautiful addition to any yard and will provide you with delicious cherries if you can meet its needs. Would you like to know more about its pollination requirements, or perhaps see if we have any other" " fruit trees suitable for your area?\n" ""
10. Creare un indice del vicino più vicino
Il nostro set di dati è piuttosto piccolo e il tempo di risposta dipende principalmente dalle interazioni con i modelli di IA. Tuttavia, quando hai milioni di vettori, la ricerca di vettori può richiedere una parte significativa del tempo di risposta e comportare un carico elevato sul sistema. Per migliorare questo aspetto, possiamo creare un indice sui nostri vettori.
Crea indice HNSW
Proveremo il tipo di indice HNSW per il nostro test. HNSW è l'acronimo di Hierarchical Navigable Small World e rappresenta un indice di grafo a più livelli.
Per creare l'indice per la colonna di incorporamento, dobbiamo definire la colonna di incorporamento, la funzione di distanza e, facoltativamente, parametri come m o ef_constructions. Puoi trovare una descrizione dettagliata dei parametri nella documentazione.
CREATE INDEX cymbal_products_embeddings_hnsw ON cymbal_products
USING hnsw (embedding vector_cosine_ops)
WITH (m = 16, ef_construction = 64);
Risultato previsto:
quickstart_db=> CREATE INDEX cymbal_products_embeddings_hnsw ON cymbal_products USING hnsw (embedding vector_cosine_ops) WITH (m = 16, ef_construction = 64); CREATE INDEX quickstart_db=>
Confronta risposta
Ora possiamo eseguire la query di ricerca vettoriale in modalità EXPLAIN e verificare se l'indice è stato utilizzato.
EXPLAIN (analyze)
WITH trees as (
SELECT
cp.product_name,
left(cp.product_description,80) as description,
cp.sale_price,
cs.zip_code,
cp.uniq_id as product_id
FROM
cymbal_products cp
JOIN cymbal_inventory ci on
ci.uniq_id=cp.uniq_id
JOIN cymbal_stores cs on
cs.store_id=ci.store_id
AND ci.inventory>0
AND cs.store_id = 1583
ORDER BY
(cp.embedding <=> embedding('text-embedding-004','What kind of fruit trees grow well here?')::vector) ASC
LIMIT 1)
SELECT json_agg(trees) FROM trees;
Risultato previsto:
Aggregate (cost=779.12..779.13 rows=1 width=32) (actual time=1.066..1.069 rows=1 loops=1) -> Subquery Scan on trees (cost=769.05..779.12 rows=1 width=142) (actual time=1.038..1.041 rows=1 loops=1) -> Limit (cost=769.05..779.11 rows=1 width=158) (actual time=1.022..1.024 rows=1 loops=1) -> Nested Loop (cost=769.05..9339.69 rows=852 width=158) (actual time=1.020..1.021 rows=1 loops=1) -> Nested Loop (cost=768.77..9316.48 rows=852 width=945) (actual time=0.858..0.859 rows=1 loops=1) -> Index Scan using cymbal_products_embeddings_hnsw on cymbal_products cp (cost=768.34..2572.47 rows=941 width=941) (actual time=0.532..0.539 rows=3 loops=1) Order By: (embedding <=> '[0.008864171,0.03693164,-0.024245683,... <redacted> ...,0.017593635,-0.040275685,-0.03914233,-0.018452475,0.00826032,-0.07372604 ]'::vector) -> Index Scan using product_inventory_pkey on cymbal_inventory ci (cost=0.42..7.17 rows=1 width=37) (actual time=0.104..0.104 rows=0 loops=3) Index Cond: ((store_id = 1583) AND (uniq_id = (cp.uniq_id)::text)) Filter: (inventory > 0) Rows Removed by Filter: 1 -> Materialize (cost=0.28..8.31 rows=1 width=8) (actual time=0.133..0.134 rows=1 loops=1) -> Index Scan using product_stores_pkey on cymbal_stores cs (cost=0.28..8.30 rows=1 width=8) (actual time=0.129..0.129 rows=1 loops=1) Index Cond: (store_id = 1583) Planning Time: 112.398 ms Execution Time: 1.221 ms
Dall'output possiamo vedere chiaramente che la query utilizzava "Scansione dell'indice utilizzando cymbal_products_embeddings_hnsw".
Se eseguiamo la query senza explain:
WITH trees as (
SELECT
cp.product_name,
left(cp.product_description,80) as description,
cp.sale_price,
cs.zip_code,
cp.uniq_id as product_id
FROM
cymbal_products cp
JOIN cymbal_inventory ci on
ci.uniq_id=cp.uniq_id
JOIN cymbal_stores cs on
cs.store_id=ci.store_id
AND ci.inventory>0
AND cs.store_id = 1583
ORDER BY
(cp.embedding <=> embedding('text-embedding-004','What kind of fruit trees grow well here?')::vector) ASC
LIMIT 1)
SELECT json_agg(trees) FROM trees;
Risultato previsto:
[{"product_name":"Cherry Tree","description":"This is a beautiful cherry tree that will produce delicious cherries. It is an d","sale_price":75.00,"zip_code":93230,"product_id":"d536e9e823296a2eba198e52dd23e712"}]
Possiamo vedere che il risultato è lo stesso e restituisce la stessa pianta di ciliegio che era in cima alla nostra ricerca senza indice. A seconda dei parametri e del tipo di indice, è possibile che il risultato sia leggermente diverso. Durante i miei test, la query indicizzata ha restituito risultati in 131.301 ms rispetto a 167.631 ms senza alcun indice, ma avevamo a che fare con un set di dati molto piccolo e la differenza sarebbe stata più sostanziale su dati più grandi.
Puoi provare diversi indici disponibili per i vettori e altri lab ed esempi con l'integrazione di langchain disponibile nella documentazione.
11. Ripulire l'ambiente
Elimina l'istanza Cloud SQL
Distruggi l'istanza Cloud SQL al termine del lab
In Cloud Shell, definisci le variabili di progetto e di ambiente se la connessione è stata disconnessa e tutte le impostazioni precedenti sono andate perse:
export INSTANCE_NAME=my-cloudsql-instance
export PROJECT_ID=$(gcloud config get-value project)
Elimina l'istanza:
gcloud sql instances delete $INSTANCE_NAME --project=$PROJECT_ID
Output della console previsto:
student@cloudshell:~$ gcloud sql instances delete $INSTANCE_NAME --project=$PROJECT_ID All of the instance data will be lost when the instance is deleted. Do you want to continue (Y/n)? y Deleting Cloud SQL instance...done. Deleted [https://sandbox.googleapis.com/v1beta4/projects/test-project-001-402417/instances/my-cloudsql-instance].
12. Complimenti
Complimenti per aver completato il codelab.
Argomenti trattati
- Come eseguire il deployment di un'istanza Cloud SQL per PostgreSQL
- Come creare un database e attivare l'integrazione dell'IA di Cloud SQL
- Come caricare i dati nel database
- Come utilizzare il modello di embedding Vertex AI in Cloud SQL
- Come arricchire il risultato utilizzando il modello generativo di Vertex AI
- Come migliorare il rendimento utilizzando l'indice vettoriale
Prova un codelab per AlloyDB simile con l'indice ScaNN anziché HNSW
13. Sondaggio
Output: