Erste Schritte mit Vektoreinbettungen in Cloud SQL for MySQL

Erste Schritte mit Vektoreinbettungen in Cloud SQL for MySQL

Informationen zu diesem Codelab

subjectZuletzt aktualisiert: Apr. 22, 2025
account_circleVerfasst von Gleb Otochkin

1. Einführung

In diesem Codelab erfahren Sie, wie Sie Cloud SQL für die Vertex AI-Integration in MySQL verwenden, indem Sie die Vektorsuche mit Vertex AI-Einbettungen kombinieren.

30b7c4dcdd8bb68f.png

Voraussetzungen

  • Grundlegende Kenntnisse von Google Cloud und der Console
  • Grundlegende Kenntnisse der Befehlszeile und Cloud Shell

Aufgaben in diesem Lab

  • Cloud SQL for MySQL-Instanz bereitstellen
  • Datenbank erstellen und Cloud SQL-KI-Integration aktivieren
  • Daten in die Datenbank laden
  • Vertex AI-Embedding-Modell in Cloud SQL verwenden
  • Ergebnisse mit dem generativen Modell von Vertex AI ergänzen
  • Leistung mithilfe eines Vektorindexes verbessern

Voraussetzungen

  • Ein Google Cloud-Konto und ein Google Cloud-Projekt
  • Ein Webbrowser wie Chrome, der die Google Cloud Console und Cloud Shell unterstützt

2. Einrichtung und Anforderungen

Einrichtung der Umgebung im eigenen Tempo

  1. Melden Sie sich in der Google Cloud Console an und erstellen Sie ein neues Projekt oder verwenden Sie ein vorhandenes. Wenn Sie noch kein Gmail- oder Google Workspace-Konto haben, müssen Sie ein Konto erstellen.

fbef9caa1602edd0.png

a99b7ace416376c4.png

5e3ff691252acf41.png

  • Der Projektname ist der Anzeigename für die Teilnehmer dieses Projekts. Es ist ein Zeichenstring, der von Google APIs nicht verwendet wird. Sie können ihn jederzeit aktualisieren.
  • Die Projekt-ID ist für alle Google Cloud-Projekte eindeutig und kann nach der Festlegung nicht mehr geändert werden. In der Cloud Console wird automatisch ein eindeutiger String generiert. In der Regel spielt es keine Rolle, wie er lautet. In den meisten Codelabs müssen Sie auf Ihre Projekt-ID verweisen (normalerweise als PROJECT_ID gekennzeichnet). Wenn Ihnen die generierte ID nicht gefällt, können Sie eine andere zufällige generieren. Alternativ können Sie Ihr eigenes Konto ausprobieren und prüfen, ob es verfügbar ist. Sie kann nach diesem Schritt nicht mehr geändert werden und bleibt für die Dauer des Projekts bestehen.
  • Zur Information: Es gibt einen dritten Wert, die Projektnummer, die von einigen APIs verwendet wird. Weitere Informationen zu diesen drei Werten finden Sie in der Dokumentation.
  1. Als Nächstes müssen Sie in der Cloud Console die Abrechnung aktivieren, um Cloud-Ressourcen/-APIs verwenden zu können. Die Durchführung dieses Codelabs ist kostenlos oder kostet nur sehr wenig. Wenn Sie die Ressourcen deaktivieren möchten, um weitere Kosten nach Abschluss dieser Anleitung zu vermeiden, können Sie die von Ihnen erstellten Ressourcen oder das Projekt löschen. Neuen Google Cloud-Nutzern steht das kostenlose Testprogramm mit einem Guthaben von 300$ zur Verfügung.

Cloud Shell starten

Sie können Google Cloud zwar per Fernzugriff von Ihrem Laptop aus nutzen, in diesem Codelab verwenden Sie jedoch Google Cloud Shell, eine Befehlszeilenumgebung, die in der Cloud ausgeführt wird.

Klicken Sie in der Google Cloud Console oben rechts in der Symbolleiste auf das Cloud Shell-Symbol:

55efc1aaa7a4d3ad.png

Die Bereitstellung und Verbindung mit der Umgebung sollte nur wenige Minuten dauern. Wenn der Vorgang abgeschlossen ist, sollte in etwa Folgendes angezeigt werden:

7ffe5cbb04455448.png

Diese virtuelle Maschine verfügt über sämtliche Entwicklertools, die Sie benötigen. Sie bietet ein Basisverzeichnis mit 5 GB nichtflüchtigem Speicher und läuft auf Google Cloud. Dadurch werden Netzwerkleistung und Authentifizierung erheblich verbessert. Alle Aufgaben in diesem Codelab können in einem Browser ausgeführt werden. Sie müssen nichts installieren.

3. Hinweis

API aktivieren

Prüfen Sie in Cloud Shell, ob Ihre Projekt-ID eingerichtet ist:

gcloud config set project [YOUR-PROJECT-ID]

Legen Sie die Umgebungsvariable PROJECT_ID fest:

PROJECT_ID=$(gcloud config get-value project)

Aktivieren Sie alle erforderlichen Dienste:

gcloud services enable sqladmin.googleapis.com \
                       compute
.googleapis.com \
                       cloudresourcemanager
.googleapis.com \
                       servicenetworking
.googleapis.com \
                       aiplatform
.googleapis.com

Erwartete Ausgabe

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. Cloud SQL-Instanz erstellen

Cloud SQL-Instanz mit Datenbankeinbindung in Vertex AI erstellen

Datenbankpasswort erstellen

Legen Sie ein Passwort für den Standarddatenbanknutzer fest. Sie können ein eigenes Passwort definieren oder eine Zufallsfunktion verwenden, um eins zu generieren:

export CLOUDSQL_PASSWORD=`openssl rand -hex 12`

Notieren Sie sich den generierten Wert für das Passwort:

echo $CLOUDSQL_PASSWORD

Cloud SQL for MySQL-Instanz erstellen

Das Flag „cloudsql_vector“ kann beim Erstellen einer Instanz aktiviert werden. Die Vektorunterstützung ist derzeit für MySQL 8.0 R20241208.01_00 oder höher verfügbar.

Führen Sie in der Cloud Shell-Sitzung Folgendes aus:

gcloud sql instances create my-cloudsql-instance \
--database-version=MYSQL_8_4 \
--tier=db-custom-2-8192 \
--region=us-central1 \
--enable-google-ml-integration \
--edition=ENTERPRISE \
--root-password=$CLOUDSQL_PASSWORD

Wir können die Verbindung über Cloud Shell prüfen.

gcloud sql connect my-cloudsql-instance --user=root

Führen Sie den Befehl aus und geben Sie Ihr Passwort in die Aufforderung ein, wenn die Verbindung hergestellt werden kann.

Erwartete Ausgabe:

$gcloud sql connect my-cloudsql-instance --user=root
Allowlisting your IP for incoming connection for 5 minutes...done.                                                                                                                           
Connecting to database with SQL user [root].Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 71
Server version: 8.4.4-google (Google)

Copyright (c) 2000, 2025, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

Vertex AI-Einbindung aktivieren

Gewähren Sie dem internen Cloud SQL-Dienstkonto die erforderlichen Berechtigungen, damit die Vertex AI-Integration verwendet werden kann.

Ermitteln Sie die E-Mail-Adresse des internen Cloud SQL-Dienstkontos und exportieren Sie sie als Variable.

SERVICE_ACCOUNT_EMAIL=$(gcloud sql instances describe my-cloudsql-instance --format="value(serviceAccountEmailAddress)")
echo $SERVICE_ACCOUNT_EMAIL

Gewähren Sie dem Cloud SQL-Dienstkonto Zugriff auf Vertex AI:

gcloud projects add-iam-policy-binding $PROJECT_ID \
 
--member="serviceAccount:$SERVICE_ACCOUNT_EMAIL" \
 
--role="roles/aiplatform.user"

Weitere Informationen zum Erstellen und Konfigurieren von Instanzen finden Sie in der Cloud SQL-Dokumentation.

5. Datenbank vorbereiten

Jetzt müssen wir eine Datenbank erstellen und die Unterstützung von Vektoren aktivieren.

Datenbank erstellen

Erstellen Sie eine Datenbank mit dem Namen quickstart_db. Dazu haben Sie verschiedene Möglichkeiten, z. B. Befehlszeilen-Datenbankclients wie mysql für MySQL, SDK oder Cloud SQL Studio. Wir verwenden das SDK (gcloud), um die Datenbank zu erstellen.

Führen Sie in Cloud Shell den Befehl zum Erstellen der Datenbank aus.

gcloud sql databases create quickstart_db --instance=my-cloudsql-instance

6. Daten laden

Jetzt müssen wir Objekte in der Datenbank erstellen und Daten laden. Wir verwenden fiktive Daten des Cymbal-Shops. Die Daten sind im SQL-Format (für das Schema) und im CSV-Format (für die Daten) verfügbar.

Cloud Shell ist unsere Hauptumgebung, um eine Verbindung zu einer Datenbank herzustellen, alle Objekte zu erstellen und die Daten zu laden.

Zuerst müssen wir die öffentliche IP-Adresse von Cloud Shell der Liste der autorisierten Netzwerke für unsere Cloud SQL-Instanz hinzufügen. Führen Sie in Cloud Shell Folgendes aus:

gcloud sql instances patch my-cloudsql-instance --authorized-networks=$(curl ifconfig.me)

Wenn Ihre Sitzung verloren gegangen ist, zurückgesetzt wurde oder Sie mit einem anderen Tool arbeiten, exportieren Sie die Variable CLOUDSQL_PASSWORD noch einmal:

export CLOUDSQL_PASSWORD=...your password defined for the instance...

Jetzt können wir alle erforderlichen Objekte in unserer Datenbank erstellen. Dazu verwenden wir das MySQL-Dienstprogramm mysql in Kombination mit dem Dienstprogramm curl, das die Daten aus der öffentlichen Quelle abholt.

Führen Sie in Cloud Shell Folgendes aus:

export INSTANCE_IP=$(gcloud sql instances describe my-cloudsql-instance --format="value(ipAddresses.ipAddress)")
curl -LJ https://raw.githubusercontent.com/GoogleCloudPlatform/devrel-demos/main/infrastructure/cymbal-store-embeddings/cymbal_mysql_schema.sql | mysql --host=$INSTANCE_IP --user=root --password=$CLOUDSQL_PASSWORD quickstart_db

Was haben wir genau mit dem vorherigen Befehl getan? Wir haben eine Verbindung zu unserer Datenbank hergestellt und den heruntergeladenen SQL-Code ausgeführt, wodurch Tabellen, Indexe und Sequenzen erstellt wurden.

Im nächsten Schritt laden Sie die Daten für „cymbal_products“ (Beckenprodukte) hoch. Wir verwenden dieselben curl- und mysql-Dienstprogramme.

curl -LJ https://raw.githubusercontent.com/GoogleCloudPlatform/devrel-demos/main/infrastructure/cymbal-store-embeddings/cymbal_products.csv | mysql --enable-local-infile --host=$INSTANCE_IP --user=root --password=$CLOUDSQL_PASSWORD quickstart_db -e "LOAD DATA LOCAL INFILE '/dev/stdin'  INTO TABLE cymbal_products FIELDS TERMINATED BY ','  OPTIONALLY ENCLOSED BY '\"'  LINES TERMINATED BY '\n'  IGNORE 1 LINES;"

Fahren wir mit „cymbal_stores“ fort.

curl -LJ https://raw.githubusercontent.com/GoogleCloudPlatform/devrel-demos/main/infrastructure/cymbal-store-embeddings/cymbal_stores.csv | mysql --enable-local-infile --host=$INSTANCE_IP --user=root --password=$CLOUDSQL_PASSWORD quickstart_db -e "LOAD DATA LOCAL INFILE '/dev/stdin'  INTO TABLE cymbal_stores FIELDS TERMINATED BY ','  OPTIONALLY ENCLOSED BY '\"'  LINES TERMINATED BY '\n'  IGNORE 1 LINES;"

Ergänzen Sie die Tabelle mit „cymbal_inventory“, in der die Anzahl der einzelnen Produkte in den einzelnen Geschäften enthalten ist.

curl -LJ https://raw.githubusercontent.com/GoogleCloudPlatform/devrel-demos/main/infrastructure/cymbal-store-embeddings/cymbal_inventory.csv | mysql --enable-local-infile --host=$INSTANCE_IP --user=root --password=$CLOUDSQL_PASSWORD quickstart_db -e "LOAD DATA LOCAL INFILE '/dev/stdin'  INTO TABLE cymbal_inventory FIELDS TERMINATED BY ','  OPTIONALLY ENCLOSED BY '\"'  LINES TERMINATED BY '\n'  IGNORE 1 LINES;"

Wenn Sie eigene Beispieldaten haben und Ihre CSV-Dateien mit dem Cloud SQL-Importtool in der Cloud Console kompatibel sind, können Sie es anstelle des hier beschriebenen Ansatzes verwenden.

7. Einbettungen erstellen

Im nächsten Schritt erstellen wir mit dem Modell „textembedding-005“ von Google Vertex AI Einbettungen für unsere Produktbeschreibungen und speichern sie in der neuen Spalte in der Tabelle „cymbal_products“.

Um die Vektordaten zu speichern, müssen wir die Vektorfunktion in unserer Cloud SQL-Instanz aktivieren. Führen Sie in Cloud Shell Folgendes aus:

gcloud sql instances patch my-cloudsql-instance \
--database-flags=cloudsql_vector=on

Stellen Sie eine Verbindung zur Datenbank her:

mysql --host=$INSTANCE_IP --user=root --password=$CLOUDSQL_PASSWORD quickstart_db

Und erstellen Sie mit der Funktion „Einbetten“ eine virtuelle Spalte embedding in der Tabelle „cymbal_products“.

ALTER TABLE cymbal_products ADD COLUMN embedding vector(768) using varbinary;
UPDATE cymbal_products SET embedding = mysql.ml_embedding('text-embedding-005', product_description);

Das Generieren von Vektor-Embeddings für 2.000 Zeilen dauert in der Regel weniger als 5 Minuten, kann aber manchmal etwas länger dauern. Oft ist es aber auch viel schneller abgeschlossen.

8. Ähnlichkeitssuche ausführen

Wir können jetzt eine Ähnlichkeitssuche mit Vektorwerten ausführen, die für die Beschreibungen berechnet wurden, und dem Vektorwert, den wir für unsere Anfrage mit demselben Einbettungsmodell generieren.

Die SQL-Abfrage kann über dieselbe Befehlszeilenschnittstelle oder alternativ über Cloud SQL Studio ausgeführt werden. Mehrzeilige und komplexe Abfragen lassen sich in Cloud SQL Studio besser verwalten.

Nutzer erstellen

Wir benötigen einen neuen Nutzer, der Cloud SQL Studio verwenden kann. Wir erstellen einen Nutzer vom Typ „Nutzer“ mit demselben Passwort, das wir für den Root-Nutzer verwendet haben.

Führen Sie in Cloud Shell Folgendes aus:

gcloud sql users create student  --instance=my-cloudsql-instance --password=$CLOUDSQL_PASSWORD --host=%

Cloud SQL Studio starten

Klicken Sie in der Console auf die Cloud SQL-Instanz, die Sie zuvor erstellt haben.

667b658dbf98eb0b.png

Wenn er geöffnet ist, sehen wir im rechten Bereich Cloud SQL Studio. Wählen Sie diese Option aus.

a879e8ac914a8ce9.png

Daraufhin wird ein Dialogfeld geöffnet, in dem Sie den Datenbanknamen und Ihre Anmeldedaten angeben:

  • Datenbank: quickstart_db
  • Nutzer: Schüler/Student
  • Passwort: das von Ihnen notierte Passwort für den Nutzer

Klicken Sie auf die Schaltfläche „AUTHENTIFIEREN“.

36e6036847333d18.png

Das nächste Fenster wird geöffnet. Klicken Sie rechts auf den Tab „Editor“, um den SQL-Editor zu öffnen.

d803b7b6a798094f.png

Jetzt können wir unsere Abfragen ausführen.

Abfrage ausführen

Führe eine Abfrage aus, um eine Liste der verfügbaren Produkte zu erhalten, die der Anfrage eines Kunden am ehesten entsprechen. Die Anfrage, die wir an Vertex AI senden, um den Vektorwert zu erhalten, lautet: „Welche Obstbäume gedeihen hier gut?“

Mit der Funktion „cosine_distance“ können Sie die ersten fünf Elemente auswählen, die für unsere Anfrage am besten geeignet sind. Hier ist die entsprechende Abfrage:

SELECT mysql.ML_EMBEDDING('text-embedding-005','What kind of fruit trees grow well here?') into @query_vector;
SELECT
        cp.product_name,
        left(cp.product_description,80) as description,
        cp.sale_price,
        cs.zip_code,
        cosine_distance(cp.embedding ,@query_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 5;

Kopieren Sie die Abfrage, fügen Sie sie in den Cloud SQL Studio-Editor ein und klicken Sie auf die Schaltfläche „AUSFÜHREN“ oder fügen Sie sie in die Befehlszeilen-Sitzung ein, die eine Verbindung zur Datenbank „quickstart_db“ herstellt.

dffc70835901cf03.png

Und hier ist eine Liste der ausgewählten Produkte, die der Suchanfrage entsprechen.

+-----------------+----------------------------------------------------------------------------------+------------+----------+---------------------+
| product_name    | description                                                                      | sale_price | zip_code | distance            |
+-----------------+----------------------------------------------------------------------------------+------------+----------+---------------------+
| Malus Domestica | Malus Domestica, the classic apple tree, brings beauty and delicious fruit to yo |     100.00 |    93230 | 0.37740096545831603 |
| Cerasus         | Cerasus: A beautiful cherry tree that brings delicious fruit and vibrant color t |      75.00 |    93230 |   0.405704177142419 |
| Persica         | Persica: Enjoy homegrown, delicious peaches with this beautiful peach tree. Reac |     150.00 |    93230 | 0.41031799106722877 |
| Meyer Lemon     | Grow your own juicy Meyer Lemons with this semi-dwarf tree, California's favorit |      34.00 |    93230 | 0.42823360959352186 |
| Acer            | Acer, the classic maple. Known for vibrant fall foliage in reds, oranges, and ye |     100.00 |    93230 | 0.42953897057301615 |
+-----------------+----------------------------------------------------------------------------------+------------+----------+---------------------+
5 rows in set (0.13 sec)

Die Abfrageausführung mit der Funktion „cosine_distance“ dauerte 0,13 Sekunden.

Führen wir nun dieselbe Abfrage aus, aber mit der KNN-Suche mit der Funktion „approx_distance“. Wenn wir keinen ANN-Index für unsere Einbettungen haben, wird automatisch auf die genaue Suche zurückgegriffen:

SELECT mysql.ML_EMBEDDING('text-embedding-005','What kind of fruit trees grow well here?') into @query_vector;
SELECT
        cp.product_name,
        left(cp.product_description,80) as description,
        cp.sale_price,
        cs.zip_code,
        approx_distance(cp.embedding ,@query_vector, 'distance_measure=cosine') 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 5;

Und hier ist eine Liste der Produkte, die von der Abfrage zurückgegeben wurden.

+-----------------+----------------------------------------------------------------------------------+------------+----------+---------------------+
| product_name    | description                                                                      | sale_price | zip_code | distance            |
+-----------------+----------------------------------------------------------------------------------+------------+----------+---------------------+
| Malus Domestica | Malus Domestica, the classic apple tree, brings beauty and delicious fruit to yo |     100.00 |    93230 | 0.37740096545831603 |
| Cerasus         | Cerasus: A beautiful cherry tree that brings delicious fruit and vibrant color t |      75.00 |    93230 |   0.405704177142419 |
| Persica         | Persica: Enjoy homegrown, delicious peaches with this beautiful peach tree. Reac |     150.00 |    93230 | 0.41031799106722877 |
| Meyer Lemon     | Grow your own juicy Meyer Lemons with this semi-dwarf tree, California's favorit |      34.00 |    93230 | 0.42823360959352186 |
| Acer            | Acer, the classic maple. Known for vibrant fall foliage in reds, oranges, and ye |     100.00 |    93230 | 0.42953897057301615 |
+-----------------+----------------------------------------------------------------------------------+------------+----------+---------------------+
5 rows in set, 1 warning (0.12 sec)

Die Abfrageausführung dauerte nur 0,12 Sekunden. Wir erhalten dieselben Ergebnisse wie bei der Funktion „cosine_distance“.

9. LLM-Antwort mit abgerufenen Daten verbessern

Wir können die Antwort des LLM für die generative KI in einer Clientanwendung mit dem Ergebnis der ausgeführten Abfrage verbessern und eine aussagekräftige Ausgabe mit den bereitgestellten Abfrageergebnissen als Teil des Prompts für ein generatives Fundament-Sprachmodell von Vertex AI erstellen.

Dazu müssen wir ein JSON mit den Ergebnissen aus der Vektorsuche generieren und dieses dann als Ergänzung zu einem Prompt für ein LLM-Modell in Vertex AI verwenden, um eine aussagekräftige Ausgabe zu erstellen. Im ersten Schritt generieren wir die JSON-Datei, testen sie dann in Vertex AI Studio und fügen sie im letzten Schritt in eine SQL-Anweisung ein, die in einer Anwendung verwendet werden kann.

Ausgabe im JSON-Format generieren

Ändern Sie die Abfrage so, dass die Ausgabe im JSON-Format generiert wird und nur eine Zeile zurückgegeben wird, die an Vertex AI übergeben wird.

Hier ist ein Beispiel für die Abfrage mit ANN-Suche:

SELECT mysql.ML_EMBEDDING('text-embedding-005','What kind of fruit trees grow well here?') into @query_vector;
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
        (approx_distance(cp.embedding ,@query_vector, 'distance_measure=cosine')) ASC
LIMIT 1)
SELECT json_arrayagg(json_object('product_name',product_name,'description',description,'sale_price',sale_price,'zip_code',zip_code,'product_id',product_id)) FROM trees;

Und hier ist die erwartete JSON-Ausgabe:

[{"zip_code": 93230, "product_id": "23e41a71d63d8bbc9bdfa1d118cfddc5", "sale_price": 100.00, "description": "Malus Domestica, the classic apple tree, brings beauty and delicious fruit to yo", "product_name": "Malus Domestica"}]

Prompt in Vertex AI Studio ausführen

Wir können die generierte JSON-Datei als Teil des Prompts für das generative KI-Textmodell in Vertex AI Studio verwenden.

Öffnen Sie in der Cloud Console den Vertex AI Studio-Prompt.

411ffb9d164ac140.png

Möglicherweise werden Sie aufgefordert, zusätzliche APIs zu aktivieren. Sie können diese Aufforderung ignorieren. Für dieses Lab benötigen wir keine zusätzlichen APIs.

Hier ist der Prompt, den wir verwenden werden:

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.

So sieht es aus, wenn wir den JSON-Platzhalter durch die Antwort aus der Abfrage ersetzen:

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:
{"zip_code": 93230, "product_id": "23e41a71d63d8bbc9bdfa1d118cfddc5", "sale_price": 100.00, "description": "Malus Domestica, the classic apple tree, brings beauty and delicious fruit to yo", "product_name": "Malus Domestica"}
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.

Und hier ist das Ergebnis, wenn wir den Prompt mit unseren JSON-Werten und dem gemini-2.0-Flash-Modell ausführen:

9839af512686130d.png

Die Antwort, die wir in diesem Beispiel vom Modell erhalten haben, basiert auf den Ergebnissen der semantischen Suche und dem am besten passenden Produkt, das in der angegebenen Postleitzahl verfügbar ist.

Prompt in PSQL ausführen

Wir können auch die Cloud SQL-KI-Integration mit Vertex AI verwenden, um die ähnliche Antwort von einem generativen Modell mit SQL direkt in der Datenbank abzurufen.

Jetzt können wir die generierten Daten in einer untergeordneten Abfrage mit JSON-Ergebnissen verwenden, um sie als Teil des Prompts an das generative KI-Textmodell mit SQL zu übergeben.

Führen Sie die Abfrage in der MySQL- oder Cloud SQL Studio-Sitzung für die Datenbank aus.

SELECT mysql.ML_EMBEDDING('text-embedding-005','What kind of fruit trees grow well here?') into @query_vector;
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
         (approx_distance(cp.embedding ,@query_vector, 'distance_measure=cosine')) ASC
LIMIT 1),
prompt AS (
SELECT
       CONCAT( '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_arrayagg(json_object('product_name',trees.product_name,'description',trees.description,'sale_price',trees.sale_price,'zip_code',trees.zip_code,'product_id',trees.product_id)) , '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
       mysql.ML_PREDICT_ROW('publishers/google/models/gemini-2.0-flash-001:generateContent',
        json_object('contents',
        json_object('role',
        'user',
        'parts',
        json_array(
        json_object('text',
        prompt_text))))) AS resp
FROM
        prompt)
SELECT
JSON_EXTRACT(resp, '$.candidates[0].content.parts[0].text')
FROM
        response;

Und hier ist die Beispielausgabe. Die Ausgabe kann je nach Modellversion und Parametern variieren:

"Okay, I see you're looking for fruit trees that grow well in your area. Based on the available product, the **Malus Domestica** (Apple Tree) is a great option to consider!\n\n* **Product:** Malus Domestica (Apple Tree)\n* **Description:** This classic apple tree grows to about 30 feet tall and provides beautiful seasonal color with green leaves in summer and fiery colors in the fall. It's known for its strength and provides good shade. Most importantly, it produces delicious apples!\n* **Price:** \\$100.00\n* **Growing Zones:** This particular apple tree is well-suited for USDA zones 4-8. Since your zip code is 93230, you are likely in USDA zone 9a or 9b. While this specific tree is rated for zones 4-8, with proper care and variety selection, apple trees can still thrive in slightly warmer climates. You may need to provide extra care during heat waves.\n\n**Recommendation:** I would recommend investigating varieties of Malus Domestica suited to slightly warmer climates or contacting a local nursery/arborist to verify if it is a good fit for your local climate conditions.\n"

Die Ausgabe wird im Markdown-Format bereitgestellt.

10. Index für den nächsten Nachbarn erstellen

Unser Datenbestand ist relativ klein und die Antwortzeit hängt hauptsächlich von den Interaktionen mit KI-Modellen ab. Bei Millionen von Vektoren kann die Vektorsuche jedoch einen erheblichen Teil unserer Antwortzeit in Anspruch nehmen und das System stark belasten. Um das zu verbessern, können wir einen Index auf unseren Vektoren erstellen.

ScANN-Index erstellen

Wir verwenden für unseren Test den Indextyp „ScANN“.

Um den Index für die Einbettungsspalte zu erstellen, müssen wir die Entfernungsmessung für die Einbettungsspalte definieren. Weitere Informationen zu den Parametern finden Sie in der Dokumentation.

CREATE VECTOR INDEX cymbal_products_embedding_idx ON cymbal_products(embedding) USING SCANN DISTANCE_MEASURE=COSINE;

Antwort vergleichen

Jetzt können wir die Vektorsuchabfrage noch einmal ausführen und die Ergebnisse ansehen.

SELECT mysql.ML_EMBEDDING('text-embedding-005','What kind of fruit trees grow well here?') into @query_vector;
SELECT
        cp.product_name,
        left(cp.product_description,80) as description,
        cp.sale_price,
        cs.zip_code,
        approx_distance(cp.embedding ,@query_vector, 'distance_measure=cosine') 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 5;

Erwartete Ausgabe:

+-----------------+----------------------------------------------------------------------------------+------------+----------+---------------------+
| product_name    | description                                                                      | sale_price | zip_code | distance            |
+-----------------+----------------------------------------------------------------------------------+------------+----------+---------------------+
| Malus Domestica | Malus Domestica, the classic apple tree, brings beauty and delicious fruit to yo |     100.00 |    93230 | 0.37740096545831603 |
| Cerasus         | Cerasus: A beautiful cherry tree that brings delicious fruit and vibrant color t |      75.00 |    93230 |   0.405704177142419 |
| Persica         | Persica: Enjoy homegrown, delicious peaches with this beautiful peach tree. Reac |     150.00 |    93230 | 0.41031799106722877 |
| Meyer Lemon     | Grow your own juicy Meyer Lemons with this semi-dwarf tree, California's favorit |      34.00 |    93230 | 0.42823360959352186 |
| Acer            | Acer, the classic maple. Known for vibrant fall foliage in reds, oranges, and ye |     100.00 |    93230 | 0.42953897057301615 |
+-----------------+----------------------------------------------------------------------------------+------------+----------+---------------------+
5 rows in set (0.08 sec)

Die Ausführungszeit hat sich nur geringfügig geändert, was bei einem so kleinen Datensatz aber zu erwarten ist. Bei großen Datensätzen mit Millionen von Vektoren sollte der Effekt viel stärker ausgeprägt sein.

Mit dem Befehl EXPLAIN können wir uns den Ausführungsplan ansehen:

SELECT mysql.ML_EMBEDDING('text-embedding-005','What kind of fruit trees grow well here?') into @query_vector;
EXPLAIN ANALYZE SELECT
        cp.product_name,
        left(cp.product_description,80) as description,
        cp.sale_price,
        cs.zip_code,
        approx_distance(cp.embedding ,@query_vector, 'distance_measure=cosine') 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 5;

Ausführungsplan (Auszug):

...
-> Nested loop inner join  (cost=443 rows=5) (actual time=1.14..1.18 rows=5 loops=1)
                                -> Vector index scan on cp  (cost=441 rows=5) (actual time=1.1..1.1 rows=5 loops=1)
                                -> Single-row index lookup on cp using PRIMARY (uniq_id=cp.uniq_id)  (cost=0.25 rows=1) (actual time=0.0152..0.0152 rows=1 loops=5)

...

Wir sehen, dass der Vektorindex-Scan für cp (Alias für die Tabelle „cymbal_products“) verwendet wurde.

Sie können mit Ihren eigenen Daten experimentieren oder verschiedene Suchanfragen testen, um zu sehen, wie die semantische Suche in MySQL funktioniert.

11. Umgebung bereinigen

Cloud SQL-Instanz löschen

Cloud SQL-Instanz nach Abschluss des Labs löschen

Definieren Sie in Cloud Shell die Projekt- und Umgebungsvariablen, wenn die Verbindung getrennt wurde und alle vorherigen Einstellungen verloren gegangen sind:

export INSTANCE_NAME=my-cloudsql-instance
export PROJECT_ID=$(gcloud config get-value project)

Löschen Sie die Instanz:

gcloud sql instances delete $INSTANCE_NAME --project=$PROJECT_ID

Erwartete Console-Ausgabe:

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. Glückwunsch

Herzlichen Glückwunsch zum Abschluss des Codelabs.

Behandelte Themen

  • Cloud SQL for MySQL-Instanz bereitstellen
  • Datenbank erstellen und Cloud SQL-KI-Integration aktivieren
  • Daten in die Datenbank laden
  • Vertex AI-Embedding-Modell in Cloud SQL verwenden
  • Ergebnisse mit dem generativen Modell von Vertex AI ergänzen
  • Leistung mithilfe eines Vektorindexes verbessern

Ähnliches Codelab für AlloyDB oder Codelab für Cloud SQL for Postgres ausprobieren

13. Umfrage

Ausgabe:

Wie möchten Sie diese Anleitung verwenden?