Mulai menggunakan Penyematan Vektor di Cloud SQL untuk PostgreSQL

1. Pengantar

Dalam codelab ini, Anda akan mempelajari cara menggunakan integrasi AI Cloud SQL untuk PostgreSQL dengan menggabungkan penelusuran vektor dengan penyematan Vertex AI.

30b7c4dcdd8bb68f.png

Prasyarat

  • Pemahaman dasar tentang Google Cloud, konsol
  • Keterampilan dasar dalam antarmuka command line dan Cloud Shell

Yang akan Anda pelajari

  • Cara men-deploy instance Cloud SQL untuk PostgreSQL
  • Cara membuat database dan mengaktifkan integrasi Cloud SQL AI
  • Cara memuat data ke database
  • Cara menggunakan model penyematan Vertex AI di Cloud SQL
  • Cara memperkaya hasil menggunakan model generatif Vertex AI
  • Cara meningkatkan performa menggunakan indeks vektor

Yang Anda butuhkan

  • Akun Google Cloud dan Project Google Cloud
  • Browser web seperti Chrome yang mendukung Konsol Google Cloud dan Cloud Shell

2. Penyiapan dan Persyaratan

Penyiapan lingkungan mandiri

  1. Login ke Google Cloud Console dan buat project baru atau gunakan kembali project yang sudah ada. Jika belum memiliki akun Gmail atau Google Workspace, Anda harus membuatnya.

fbef9caa1602edd0.png

a99b7ace416376c4.png

5e3ff691252acf41.png

  • Project name adalah nama tampilan untuk peserta project ini. String ini adalah string karakter yang tidak digunakan oleh Google API. Anda dapat memperbaruinya kapan saja.
  • Project ID bersifat unik di semua project Google Cloud dan tidak dapat diubah (tidak dapat diubah setelah ditetapkan). Cloud Console otomatis membuat string unik; biasanya Anda tidak mementingkan kata-katanya. Di sebagian besar codelab, Anda harus merujuk Project ID-nya (umumnya diidentifikasi sebagai PROJECT_ID). Jika tidak suka dengan ID yang dibuat, Anda dapat membuat ID acak lainnya. Atau, Anda dapat mencobanya sendiri, dan lihat apakah ID tersebut tersedia. ID tidak dapat diubah setelah langkah ini dan tersedia selama durasi project.
  • Sebagai informasi, ada nilai ketiga, Project Number, yang digunakan oleh beberapa API. Pelajari lebih lanjut ketiga nilai ini di dokumentasi.
  1. Selanjutnya, Anda harus mengaktifkan penagihan di Konsol Cloud untuk menggunakan resource/API Cloud. Menjalankan operasi dalam codelab ini tidak akan memakan banyak biaya, bahkan mungkin tidak sama sekali. Guna mematikan resource agar tidak menimbulkan penagihan di luar tutorial ini, Anda dapat menghapus resource yang dibuat atau menghapus project-nya. Pengguna baru Google Cloud memenuhi syarat untuk mengikuti program Uji Coba Gratis senilai $300 USD.

Mulai Cloud Shell

Meskipun Google Cloud dapat dioperasikan dari jarak jauh menggunakan laptop Anda, dalam codelab ini, Anda akan menggunakan Google Cloud Shell, lingkungan command line yang berjalan di Cloud.

Dari Google Cloud Console, klik ikon Cloud Shell di toolbar kanan atas:

55efc1aaa7a4d3ad.png

Hanya perlu waktu beberapa saat untuk penyediaan dan terhubung ke lingkungan. Jika sudah selesai, Anda akan melihat tampilan seperti ini:

7ffe5cbb04455448.png

Mesin virtual ini berisi semua alat pengembangan yang Anda perlukan. Layanan ini menawarkan direktori beranda tetap sebesar 5 GB dan beroperasi di Google Cloud, sehingga sangat meningkatkan performa dan autentikasi jaringan. Semua pekerjaan Anda dalam codelab ini dapat dilakukan di browser. Anda tidak perlu menginstal apa pun.

3. Sebelum memulai

Aktifkan API

Output:

Di dalam Cloud Shell, pastikan project ID Anda sudah disiapkan:

gcloud config set project [YOUR-PROJECT-ID]

Tetapkan variabel lingkungan PROJECT_ID:

PROJECT_ID=$(gcloud config get-value project)

Aktifkan semua layanan yang diperlukan:

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

Output yang diharapkan

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. Membuat instance Cloud SQL

Membuat instance Cloud SQL dengan integrasi database dengan Vertex AI.

Membuat Sandi database

Tentukan sandi untuk pengguna database default. Anda dapat menentukan sandi Anda sendiri atau menggunakan fungsi acak untuk membuatnya:

export CLOUDSQL_PASSWORD=`openssl rand -hex 12`

Perhatikan nilai yang dihasilkan untuk sandi:

echo $CLOUDSQL_PASSWORD

Membuat Instance Cloud SQL untuk PostgreSQL

Dalam sesi Cloud Shell, jalankan:

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

Setelah membuat instance, kita perlu menetapkan sandi untuk pengguna default di instance dan memverifikasi apakah kita dapat terhubung dengan sandi tersebut.

gcloud sql users set-password postgres \
    --instance=my-cloudsql-instance \
    --password=$CLOUDSQL_PASSWORD

Jalankan perintah dan masukkan sandi Anda di perintah saat siap terhubung.

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

Mengaktifkan Integrasi Vertex AI

Berikan hak istimewa yang diperlukan ke akun layanan cloud sql internal agar dapat menggunakan integrasi Vertex AI.

Cari tahu email akun layanan internal Cloud SQL dan ekspor sebagai variabel.

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

Berikan akses ke Vertex AI ke akun layanan Cloud SQL:

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

Baca selengkapnya tentang pembuatan dan konfigurasi instance dalam dokumentasi Cloud SQL di sini.

5. Menyiapkan Database

Sekarang kita perlu membuat database dan mengaktifkan dukungan vektor.

Buat Database

Buat database dengan nama quickstart_db .Untuk melakukannya, kita memiliki opsi yang berbeda seperti klien database command line seperti psql untuk PostgreSQL, SDK, atau Cloud SQL Studio. Kita akan menggunakan SDK (gcloud) untuk membuat database dan terhubung ke instance.

Di Cloud Shell, jalankan perintah untuk membuat database

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

Mengaktifkan Ekstensi

Agar dapat menggunakan Vertex AI dan vektor, kita perlu mengaktifkan dua ekstensi di database yang dibuat.

Di Cloud Shell, jalankan perintah untuk terhubung ke database yang dibuat (Anda harus memberikan sandi)

gcloud sql connect my-cloudsql-instance --database quickstart_db --user=postgres

Kemudian, setelah koneksi berhasil, dalam sesi sql, Anda perlu menjalankan dua perintah:

CREATE EXTENSION IF NOT EXISTS google_ml_integration CASCADE;
CREATE EXTENSION IF NOT EXISTS vector CASCADE;

Keluar dari sesi SQL:

exit;

6. Muat Data

Sekarang kita perlu membuat objek di database dan memuat data. Kita akan menggunakan data Cymbal Store fiktif. Data tersedia di bucket Google Storage publik dalam format CSV.

Pertama, kita perlu membuat semua objek yang diperlukan di database. Untuk melakukannya, kita akan menggunakan perintah gcloud sql connect dan gcloud storage yang sudah dikenal untuk mendownload dan mengimpor objek skema ke database kita.

Di cloud shell, jalankan dan berikan sandi yang dicatat saat kita membuat instance:

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

Apa yang sebenarnya kita lakukan dalam perintah sebelumnya? Kita terhubung ke database dan menjalankan kode SQL yang didownload yang membuat tabel, indeks, dan urutan.

Langkah berikutnya adalah memuat data dan untuk melakukannya, kita perlu mendownload file CSV dari 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 .

Kemudian, kita perlu terhubung ke database.

gcloud sql connect my-cloudsql-instance --database quickstart_db --user=postgres

Dan mengimpor data dari 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

Keluar dari sesi SQL:

exit;

Jika Anda memiliki data sendiri dan file CSV Anda kompatibel dengan alat impor Cloud SQL yang tersedia dari Cloud Console, Anda dapat menggunakannya, bukan pendekatan command line.

7. Membuat Penyematan

Langkah berikutnya adalah membuat embedding untuk deskripsi produk menggunakan model textembedding-004 dari Google Vertex AI dan menyimpannya sebagai data vektor.

Menghubungkan ke database:

gcloud sql connect my-cloudsql-instance --database quickstart_db --user=postgres

Dan buat kolom virtual penyematan di tabel cymbal_products menggunakan fungsi penyematan.

ALTER TABLE cymbal_products ADD COLUMN embedding vector(768) GENERATED ALWAYS AS (embedding('text-embedding-004',product_description)) STORED;

Proses ini mungkin memerlukan waktu beberapa saat, tetapi untuk 900-1.000 baris, proses ini tidak boleh memerlukan waktu lebih dari 5 menit dan biasanya jauh lebih cepat.

8. Menjalankan Penelusuran Kemiripan

Sekarang kita dapat menjalankan penelusuran menggunakan penelusuran kemiripan berdasarkan nilai vektor yang dihitung untuk deskripsi dan nilai vektor yang kita dapatkan untuk permintaan kita.

Kueri SQL dapat dieksekusi dari antarmuka command line yang sama menggunakan gcloud sql connect atau, sebagai alternatif, dari Cloud SQL Studio. Kueri multibaris dan kompleks lebih baik dikelola di Cloud SQL Studio.

Memulai Cloud SQL Studio

Di konsol, klik instance Cloud SQL yang telah kita buat sebelumnya.

b8d4844da1114a0b.png

Saat terbuka di panel kanan, kita dapat melihat Cloud SQL Studio. Klik tombol tersebut.

ce3f27dc21367f2e.png

Tindakan ini akan membuka dialog tempat Anda memberikan nama database dan kredensial Anda:

  • Database: quickstart_db
  • Pengguna: postgres
  • Sandi: sandi yang Anda catat untuk pengguna database utama

Lalu klik tombol "AUTHENTICATE".

2591c8bbc93e4e97.png

Tindakan ini akan membuka jendela berikutnya tempat Anda mengklik tab "Editor" di sisi kanan untuk membuka SQL Editor.

74307cb101a3ba9d.png

Sekarang kita siap menjalankan kueri.

Jalankan Kueri

Jalankan kueri untuk mendapatkan daftar produk yang tersedia dan paling terkait dengan permintaan klien. Permintaan yang akan kita teruskan ke Vertex AI untuk mendapatkan nilai vektor terdengar seperti "Jenis pohon buah apa yang tumbuh dengan baik di sini?"

Berikut adalah kueri yang dapat Anda jalankan untuk memilih 10 item pertama yang paling sesuai dengan permintaan kita:

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;

Salin dan tempel kueri ke editor Cloud SQL Studio, lalu tekan tombol "JALANKAN" atau tempelkan di sesi command line yang terhubung ke database quickstart_db.

cd07549522fd04c9.png

Berikut adalah daftar produk yang dipilih yang cocok dengan kueri.

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. Meningkatkan Respons LLM Menggunakan Data yang Diambil

Kita dapat meningkatkan respons LLM AI Generatif ke aplikasi klien menggunakan hasil kueri yang dieksekusi dan menyiapkan output yang bermakna menggunakan hasil kueri yang disediakan sebagai bagian dari perintah ke model bahasa dasar generatif Vertex AI.

Untuk mencapainya, kita perlu membuat JSON dengan hasil dari penelusuran vektor, lalu menggunakan JSON yang dihasilkan sebagai tambahan perintah untuk model LLM di Vertex AI guna membuat output yang bermakna. Pada langkah pertama, kita membuat JSON, lalu mengujinya di Vertex AI Studio, dan pada langkah terakhir, kita menggabungkannya ke dalam pernyataan SQL yang dapat digunakan dalam aplikasi.

Membuat output dalam format JSON

Ubah kueri untuk menghasilkan output dalam format JSON dan hanya menampilkan satu baris untuk diteruskan ke Vertex AI

Cloud SQL untuk PostgreSQL

Berikut adalah contoh kueri:

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;

Berikut adalah JSON yang diharapkan dalam 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"}]

Menjalankan perintah di Vertex AI Studio

Kita dapat menggunakan JSON yang dihasilkan untuk menyediakannya sebagai bagian dari perintah ke model teks AI generatif di Vertex AI Studio

Buka Chat Vertex AI Studio di konsol cloud.

449b5959fa0e93bd.png

Anda mungkin diminta untuk mengaktifkan API tambahan, tetapi Anda dapat mengabaikan permintaan tersebut. Kita tidak memerlukan API tambahan untuk menyelesaikan lab.

Berikut adalah perintah yang akan kita gunakan:

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.

Dan berikut tampilannya saat kita mengganti placeholder JSON dengan respons dari kueri:

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.

Berikut adalah hasilnya saat kita menjalankan perintah dengan nilai JSON dan menggunakan model gemini-2.0-flash:

2c5145ebc04daae1.png

Berikut adalah jawaban yang kami dapatkan dari model dalam contoh ini. Perhatikan bahwa jawaban Anda mungkin berbeda karena perubahan model dan parameter dari waktu ke waktu:

"Oke, berdasarkan daftar produk yang tersedia, pohon terbaik yang kami miliki dan mungkin tumbuh dengan baik di area Anda adalah Pohon Ceri.

Harganya $75,00.

Meskipun saya tidak memiliki detail spesifik tentang kondisi pertumbuhan di kode pos persis Anda (93230), Pohon Ceri umumnya diketahui tumbuh subur di area dengan iklim sedang dan tanah yang memiliki drainase baik. Tanaman ini biasanya memerlukan periode dingin musim dingin tertentu untuk menghasilkan buah, jadi perhatikan hal ini. Namun, pohon ceri dapat menjadi tambahan yang indah untuk taman, memberikan keindahan dan ceri yang lezat jika kondisinya tepat."

Menjalankan perintah di PSQL

Kita juga dapat menggunakan integrasi AI Cloud SQL dengan Vertex AI untuk mendapatkan respons serupa dari model generatif menggunakan SQL langsung di database. Namun, untuk menggunakan model gemini-2.0-flash-exp, kita harus mendaftarkannya terlebih dahulu.

Berjalan di Cloud SQL untuk PostgreSQL

Upgrade ekstensi ke versi 1.4.2 atau yang lebih tinggi (jika versi saat ini lebih rendah). Hubungkan ke database quickstart_db dari gcloud sql connect seperti yang telah ditunjukkan sebelumnya (atau gunakan Cloud SQL Studio) dan jalankan:

SELECT extversion from pg_extension where extname='google_ml_integration';

Jika nilai yang ditampilkan kurang dari 1.4.2, jalankan:

ALTER EXTENSION google_ml_integration UPDATE TO '1.4.2';

Kemudian, kita perlu menetapkan flag database google_ml_integration.enable_model_support ke "aktif". Untuk melakukannya, Anda dapat menggunakan antarmuka konsol web atau menjalankan perintah gcloud berikut.

gcloud sql instances patch my-cloudsql-instance \
--database-flags google_ml_integration.enable_model_support=on,cloudsql.enable_google_ml_integration=on

Perintah ini memerlukan waktu sekitar 1-3 menit untuk dijalankan di latar belakang. Kemudian, Anda dapat memverifikasi flag baru dalam sesi psql atau menggunakan Cloud SQL Studio yang terhubung ke database quickstart_db.

show google_ml_integration.enable_model_support;

Output yang diharapkan dari sesi psql adalah "on":

quickstart_db => show google_ml_integration.enable_model_support;
 google_ml_integration.enable_model_support 
--------------------------------------------
 on
(1 row)

Kemudian, kita perlu mendaftarkan dua model. Yang pertama adalah model text-embedding-004 yang sudah digunakan. Model ini perlu didaftarkan karena kita mengaktifkan kemampuan pendaftaran model.

Untuk mendaftarkan model yang dijalankan di psql atau Cloud SQL Studio, jalankan kode berikut:

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

Model berikutnya yang perlu kita daftarkan adalah gemini-2.0-flash-001 yang akan digunakan untuk menghasilkan output yang mudah digunakan.

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

Anda selalu dapat memverifikasi daftar model terdaftar dengan memilih informasi dari google_ml.model_info_view.

select model_id,model_type from google_ml.model_info_view;

Berikut adalah contoh 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

Sekarang kita dapat menggunakan JSON subkueri yang dihasilkan untuk menyediakannya sebagai bagian dari perintah ke model teks AI generatif menggunakan SQL.

Di sesi psql atau Cloud SQL Studio ke database, jalankan kueri

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;

Dan berikut adalah output yang diharapkan. Output Anda mungkin berbeda bergantung pada versi model dan parameter.:

"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. Membuat indeks tetangga terdekat

Set data kami cukup kecil dan waktu responsnya terutama bergantung pada interaksi dengan model AI. Namun, jika Anda memiliki jutaan vektor, penelusuran vektor dapat menghabiskan sebagian besar waktu respons kami dan membebani sistem secara tinggi. Untuk meningkatkannya, kita dapat membuat indeks di atas vektor.

Membuat indeks HNSW

Kita akan mencoba jenis indeks HNSW untuk pengujian. HNSW adalah singkatan dari Hierarchical Navigable Small World dan mewakili indeks grafik multilapis.

Untuk membuat indeks kolom penyematan, kita perlu menentukan kolom penyematan, fungsi jarak, dan parameter opsional seperti m atau ef_constructions. Anda dapat membaca parameter secara mendetail di dokumentasi.

CREATE INDEX cymbal_products_embeddings_hnsw ON cymbal_products
  USING hnsw (embedding vector_cosine_ops)
  WITH (m = 16, ef_construction = 64);

Output yang diharapkan:

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=>

Bandingkan Respons

Sekarang kita dapat menjalankan kueri penelusuran vektor dalam mode EXPLAIN dan memverifikasi apakah indeks telah digunakan.

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;

Output yang diharapkan:

 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

Dari output, kita dapat melihat dengan jelas bahwa kueri menggunakan "Pemindaian Indeks menggunakan cymbal_products_embeddings_hnsw".

Dan jika kita menjalankan kueri tanpa 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;

Output yang diharapkan:

[{"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"}]

Kita dapat melihat bahwa hasilnya sama dan menampilkan pohon Cherry yang sama yang berada di bagian atas dalam penelusuran tanpa indeks. Bergantung pada parameter dan jenis indeks, hasil mungkin sedikit berbeda. Selama pengujian, kueri yang diindeks menampilkan hasil dalam 131.301 md vs 167.631 md tanpa indeks apa pun, tetapi kami menangani set data yang sangat kecil dan perbedaannya akan lebih signifikan pada data yang lebih besar.

Anda dapat mencoba berbagai indeks yang tersedia untuk vektor serta lab dan contoh lainnya dengan integrasi langchain yang tersedia di dokumentasi.

11. Membersihkan lingkungan

Hapus instance Cloud SQL

Menghancurkan instance Cloud SQL setelah Anda selesai mengerjakan lab

Di Cloud Shell, tentukan variabel project dan lingkungan jika koneksi Anda terputus dan semua setelan sebelumnya hilang:

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

Hapus instance:

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

Output konsol yang diharapkan:

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. Selamat

Selamat, Anda telah menyelesaikan codelab.

Yang telah kita bahas

  • Cara men-deploy instance Cloud SQL untuk PostgreSQL
  • Cara membuat database dan mengaktifkan integrasi Cloud SQL AI
  • Cara memuat data ke database
  • Cara menggunakan model penyematan Vertex AI di Cloud SQL
  • Cara memperkaya hasil menggunakan model generatif Vertex AI
  • Cara meningkatkan performa menggunakan indeks vektor

Coba codelab untuk AlloyDB serupa dengan indeks ScaNN, bukan HNSW

13. Survei

Output:

Bagaimana Anda akan menggunakan tutorial ini?

Hanya membacanya Membaca dan menyelesaikan latihannya