شروع کار با جاسازی های برداری در Cloud SQL برای PostgreSQL

1. مقدمه

در این کد لبه یاد خواهید گرفت که چگونه از Cloud SQL برای ادغام PostgreSQL AI با ترکیب جستجوی برداری با جاسازی‌های Vertex AI استفاده کنید.

30b7c4dcdd8bb68f.png

پیش نیازها

  • درک اولیه از Google Cloud، کنسول
  • مهارت های اولیه در رابط خط فرمان و Cloud Shell

چیزی که یاد خواهید گرفت

  • نحوه استقرار یک Cloud SQL برای نمونه PostgreSQL
  • نحوه ایجاد پایگاه داده و فعال کردن Cloud SQL AI
  • نحوه بارگذاری اطلاعات در پایگاه داده
  • نحوه استفاده از مدل جاسازی هوش مصنوعی Vertex در Cloud SQL
  • نحوه غنی سازی نتیجه با استفاده از مدل مولد Vertex AI
  • نحوه بهبود عملکرد با استفاده از شاخص برداری

آنچه شما نیاز دارید

  • یک حساب Google Cloud و پروژه Google Cloud
  • یک مرورگر وب مانند کروم که از کنسول Google Cloud و Cloud Shell پشتیبانی می کند

2. راه اندازی و الزامات

تنظیم محیط خود به خود

  1. به Google Cloud Console وارد شوید و یک پروژه جدید ایجاد کنید یا از یک موجود استفاده مجدد کنید. اگر قبلاً یک حساب Gmail یا Google Workspace ندارید، باید یک حساب ایجاد کنید .

fbef9caa1602edd0.png

a99b7ace416376c4.png

5e3ff691252acf41.png

  • نام پروژه نام نمایشی برای شرکت کنندگان این پروژه است. این یک رشته کاراکتری است که توسط API های Google استفاده نمی شود. همیشه می توانید آن را به روز کنید.
  • شناسه پروژه در تمام پروژه‌های Google Cloud منحصربه‌فرد است و تغییرناپذیر است (پس از تنظیم نمی‌توان آن را تغییر داد). Cloud Console به طور خودکار یک رشته منحصر به فرد تولید می کند. معمولاً برای شما مهم نیست که چیست. در اکثر کدها، باید شناسه پروژه خود را ارجاع دهید (معمولاً با نام PROJECT_ID شناخته می شود). اگر شناسه تولید شده را دوست ندارید، ممکن است یک شناسه تصادفی دیگر ایجاد کنید. از طرف دیگر، می‌توانید خودتان را امتحان کنید، و ببینید آیا در دسترس است یا خیر. پس از این مرحله نمی توان آن را تغییر داد و در طول مدت پروژه باقی می ماند.
  • برای اطلاع شما، یک مقدار سوم وجود دارد، یک شماره پروژه ، که برخی از API ها از آن استفاده می کنند. در مورد هر سه این مقادیر در مستندات بیشتر بیاموزید.
  1. در مرحله بعد، برای استفاده از منابع Cloud/APIها باید صورتحساب را در کنسول Cloud فعال کنید . اجرا کردن از طریق این کد لبه هزینه زیادی نخواهد داشت. برای خاموش کردن منابع برای جلوگیری از تحمیل صورت‌حساب فراتر از این آموزش، می‌توانید منابعی را که ایجاد کرده‌اید حذف کنید یا پروژه را حذف کنید. کاربران جدید Google Cloud واجد شرایط برنامه آزمایشی رایگان 300 دلاری هستند.

Cloud Shell را راه اندازی کنید

در حالی که Google Cloud را می توان از راه دور از لپ تاپ شما کار کرد، در این کد لبه از Google Cloud Shell استفاده خواهید کرد، یک محیط خط فرمان که در Cloud اجرا می شود.

از Google Cloud Console ، روی نماد Cloud Shell در نوار ابزار بالا سمت راست کلیک کنید:

55efc1aaa7a4d3ad.png

تهیه و اتصال به محیط فقط چند لحظه طول می کشد. وقتی تمام شد، باید چیزی شبیه به این را ببینید:

7ffe5cbb04455448.png

این ماشین مجازی با تمام ابزارهای توسعه که شما نیاز دارید بارگذاری شده است. این یک فهرست اصلی 5 گیگابایتی دائمی را ارائه می دهد و در Google Cloud اجرا می شود و عملکرد و احراز هویت شبکه را تا حد زیادی افزایش می دهد. تمام کارهای شما در این کد لبه را می توان در یک مرورگر انجام داد. شما نیازی به نصب چیزی ندارید.

3. قبل از شروع

فعال کردن API

خروجی:

در داخل Cloud Shell، مطمئن شوید که ID پروژه شما تنظیم شده است:

gcloud config set project [YOUR-PROJECT-ID]

تنظیم متغیر محیطی PROJECT_ID:

PROJECT_ID=$(gcloud config get-value project)

فعال کردن تمام خدمات لازم:

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

خروجی مورد انتظار

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 ایجاد کنید

ایجاد نمونه Cloud SQL با ادغام پایگاه داده با Vertex AI.

ایجاد رمز عبور پایگاه داده

تعریف رمز عبور برای کاربر پیش فرض پایگاه داده شما می توانید رمز عبور خود را تعریف کنید یا از یک تابع تصادفی برای ایجاد آن استفاده کنید:

export CLOUDSQL_PASSWORD=`openssl rand -hex 12`

به مقدار ایجاد شده برای رمز عبور توجه کنید:

echo $CLOUDSQL_PASSWORD

Cloud SQL را برای نمونه PostgreSQL ایجاد کنید

در جلسه Cloud Shell اجرا کنید:

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

پس از ایجاد نمونه، باید یک رمز عبور برای کاربر پیش‌فرض در نمونه تعیین کنیم و بررسی کنیم که آیا می‌توانیم با رمز عبور وصل شویم.

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

دستور را اجرا کنید و پس از آماده شدن برای اتصال، رمز عبور خود را در اعلان قرار دهید.

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

Vertex AI Integration را فعال کنید

امتیازات لازم را به حساب سرویس داخلی ابری sql اعطا کنید تا بتوانید از ادغام Vertex AI استفاده کنید.

ایمیل حساب سرویس داخلی Cloud SQL را بیابید و آن را به عنوان یک متغیر صادر کنید.

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

اعطای دسترسی به Vertex AI به حساب سرویس Cloud SQL:

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

درباره ایجاد و پیکربندی نمونه در مستندات Cloud SQL اینجا بیشتر بخوانید.

5. پایگاه داده را آماده کنید

اکنون باید یک پایگاه داده ایجاد کنیم و پشتیبانی از vectors را فعال کنیم.

ایجاد پایگاه داده

یک پایگاه داده با نام quickstart_db ایجاد کنید. برای این کار ما گزینه های مختلفی مانند سرویس گیرندگان پایگاه داده خط فرمان مانند psql برای PostgreSQL، SDK یا Cloud SQL Studio داریم. ما از SDK (gcloud) برای ایجاد پایگاه داده و اتصال به نمونه استفاده خواهیم کرد.

در Cloud Shell دستور را برای ایجاد پایگاه داده اجرا کنید

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

برنامه های افزودنی را فعال کنید

برای اینکه بتوانیم با Vertex AI و vector ها کار کنیم، باید دو پسوند را در پایگاه داده ایجاد شده خود فعال کنیم.

در دستور Cloud Shell برای اتصال به پایگاه داده ایجاد شده (شما باید رمز عبور خود را وارد کنید)

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

سپس، پس از اتصال موفق، در جلسه sql باید دو دستور را اجرا کنید:

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

خروج از جلسه SQL:

exit;

6. بارگذاری داده ها

حالا باید آبجکت هایی را در پایگاه داده ایجاد کنیم و داده ها را بارگذاری کنیم. ما می خواهیم از داده های خیالی فروشگاه Cymbal استفاده کنیم. داده ها در سطل ذخیره سازی عمومی Google در قالب CSV موجود است.

ابتدا باید تمام اشیاء مورد نیاز را در پایگاه داده خود ایجاد کنیم. برای انجام این کار، از دستورات gcloud sql connect و gcloud storage آشنا برای دانلود و وارد کردن آبجکت های طرحواره به پایگاه داده خود استفاده می کنیم.

در پوسته ابری رمز عبوری که در هنگام ایجاد نمونه ذکر شده بود را اجرا و ارائه کنید:

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

در دستور قبلی دقیقا چه کردیم؟ ما به پایگاه داده خود متصل شدیم و کد SQL دانلود شده را اجرا کردیم که جداول، فهرست ها و دنباله ها را ایجاد می کرد.

مرحله بعدی بارگیری داده ها است و برای انجام این کار باید فایل های CSV را از 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 .

سپس باید به دیتابیس متصل شویم.

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

و داده ها را از فایل های 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

خروج از جلسه SQL:

exit;

اگر داده‌های خود را دارید و فایل‌های CSV شما با ابزار وارد کردن Cloud SQL که از کنسول Cloud موجود است سازگار است، می‌توانید به جای رویکرد خط فرمان از آن استفاده کنید.

7. Embeddings ایجاد کنید

گام بعدی این است که با استفاده از مدل textembedding-004 از Google Vertex AI، تعبیه‌هایی را برای توضیحات محصول خود بسازیم و آنها را به عنوان داده‌های برداری ذخیره کنیم.

اتصال به پایگاه داده:

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

و با استفاده از تابع embedding یک جاسازی ستون مجازی در جدول cymbal_products خود ایجاد کنید.

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

ممکن است کمی طول بکشد اما برای 900-1000 ردیف نباید بیش از 5 دقیقه طول بکشد و معمولاً بسیار سریعتر است.

8. Similarity Search را اجرا کنید

اکنون می‌توانیم جستجوی خود را با استفاده از جستجوی شباهت بر اساس مقادیر برداری محاسبه‌شده برای توضیحات و مقدار برداری که برای درخواست خود دریافت می‌کنیم، اجرا کنیم.

کوئری SQL را می توان از همان رابط خط فرمان با استفاده از gcloud sql connec t یا به عنوان جایگزین از Cloud SQL Studio اجرا کرد. هر کوئری چند ردیفه و پیچیده بهتر است در Cloud SQL Studio مدیریت شود.

Cloud SQL Studio را راه اندازی کنید

در کنسول روی نمونه Cloud SQL که قبلا ایجاد کرده بودیم کلیک کنید.

b8d4844da1114a0b.png

وقتی در پنل سمت راست باز است، می‌توانیم Cloud SQL Studio را ببینیم. روی آن کلیک کنید.

ce3f27dc21367f2e.png

یک گفتگو باز می شود که در آن نام پایگاه داده و اعتبار خود را ارائه می دهید:

  • پایگاه داده: quickstart_db
  • کاربر: postgres
  • رمز عبور: رمز عبور یادداشت شده شما برای کاربر اصلی پایگاه داده

و بر روی دکمه "Authenticate" کلیک کنید.

2591c8bbc93e4e97.png

پنجره بعدی باز می شود که روی تب "Editor" در سمت راست کلیک می کنید تا ویرایشگر SQL باز شود.

74307cb101a3ba9d.png

اکنون ما آماده ایم تا درخواست های خود را اجرا کنیم.

Query را اجرا کنید

برای دریافت لیستی از محصولات موجود که بیشترین ارتباط را با درخواست مشتری دارد، یک پرس و جو انجام دهید. درخواستی که می‌خواهیم به Vertex AI ارسال کنیم تا مقدار برداری را به دست بیاوریم، به نظر می‌رسد: «چه نوع درختان میوه‌ای در اینجا رشد می‌کنند؟»

در اینجا پرس و جوی وجود دارد که می توانید برای انتخاب 10 مورد اول که برای درخواست ما مناسب هستند اجرا کنید:

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;

پرس و جو را در ویرایشگر Cloud SQL Studio کپی و جایگذاری کنید و دکمه "RUN" را فشار دهید یا آن را در جلسه خط فرمان خود که به پایگاه داده quickstart_db متصل می شود، قرار دهید.

cd07549522fd04c9.png

و در اینجا لیستی از محصولات انتخاب شده مطابق با پرس و جو وجود دارد.

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. بهبود پاسخ LLM با استفاده از داده های بازیابی شده

ما می‌توانیم پاسخ Gen AI LLM به یک برنامه مشتری را با استفاده از نتیجه کوئری اجرا شده بهبود بخشیم و خروجی معنی‌داری را با استفاده از نتایج جستجوی ارائه شده به عنوان بخشی از درخواست مدل زبان پایه مولد Vertex AI آماده کنیم.

برای رسیدن به این هدف، باید یک JSON با نتایج خود از جستجوی برداری تولید کنیم، سپس از JSON تولید شده به عنوان یک درخواست برای مدل LLM در Vertex AI برای ایجاد یک خروجی معنادار استفاده کنیم. در مرحله اول ما JSON را تولید می کنیم، سپس آن را در استودیو Vertex AI تست می کنیم و در مرحله آخر آن را در یک دستور SQL که می تواند در یک برنامه استفاده شود، وارد می کنیم.

خروجی با فرمت JSON تولید کنید

کوئری را تغییر دهید تا خروجی با فرمت JSON تولید شود و تنها یک سطر برای انتقال به Vertex AI برگردانید.

Cloud SQL برای PostgreSQL

در اینجا مثالی از پرس و جو آورده شده است:

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;

و در اینجا JSON مورد انتظار در خروجی است:

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

دستور را در Vertex AI Studio اجرا کنید

ما می توانیم از JSON تولید شده برای ارائه آن به عنوان بخشی از مدل متنی AI مولد در Vertex AI Studio استفاده کنیم.

Vertex AI Studio Chat را در کنسول ابری باز کنید.

449b5959fa0e93bd.png

ممکن است از شما بخواهد API های اضافی را فعال کنید، اما می توانید درخواست را نادیده بگیرید. ما برای تکمیل آزمایشگاه خود به API اضافی نیاز نداریم.

در اینجا اعلانی است که ما می خواهیم استفاده کنیم:

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.

و در اینجا چگونه به نظر می رسد وقتی که جای جای JSON را با پاسخ از پرس و جو جایگزین می کنیم:

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.

و زمانی که دستور را با مقادیر JSON خود و با استفاده از مدل gemini-2.0-flash اجرا می کنیم، نتیجه این است:

2c5145ebc04daae1.png

پاسخی که از مدل در این مثال گرفتیم به شرح زیر است. توجه داشته باشید که پاسخ شما ممکن است به دلیل تغییر مدل و پارامترها در طول زمان متفاوت باشد:

"خوب، بر اساس لیست محصولات موجود، بهترین درختی که ممکن است در منطقه شما رشد خوبی داشته باشد، درخت گیلاس است.

قیمت آن 75.00 دلار است.

در حالی که من جزئیات خاصی در مورد شرایط رشد در کد پستی دقیق شما (93230) ندارم، درختان گیلاس معمولاً در مناطقی با آب و هوای معتدل و خاک با زهکشی خوب رشد می کنند. آنها معمولاً برای تولید میوه به دوره خاصی از سرمای زمستانی نیاز دارند، بنابراین این چیزی است که باید در نظر داشت. با این حال، آنها می توانند افزودنی فوق العاده برای یک باغ باشند و در صورت مهیا بودن شرایط، زیبایی و گیلاس های خوشمزه را ارائه دهند."

دستور را در PSQL اجرا کنید

همچنین می‌توانیم از ادغام Cloud SQL AI با Vertex AI برای دریافت پاسخ مشابه از یک مدل تولیدی با استفاده از SQL به طور مستقیم در پایگاه داده استفاده کنیم. اما برای استفاده از مدل gemini-2.0-flash-exp باید ابتدا آن را ثبت کنیم.

در Cloud SQL برای PostgreSQL اجرا کنید

برنامه افزودنی را به نسخه 1.4.2 یا بالاتر ارتقا دهید (اگر نسخه فعلی پایین تر است). همانطور که قبلا نشان داده شده است از طریق gcloud sql connect به پایگاه داده quickstart_db متصل شوید (یا از Cloud SQL Studio استفاده کنید) و اجرا کنید:

SELECT extversion from pg_extension where extname='google_ml_integration';

اگر مقدار بازگشتی کمتر از 1.4.2 باشد، آن را اجرا کنید:

ALTER EXTENSION google_ml_integration UPDATE TO '1.4.2';

سپس باید پرچم پایگاه داده google_ml_integration.enable_model_support را روی "روشن" تنظیم کنیم. برای انجام این کار می توانید از رابط کنسول وب استفاده کنید یا دستور gcloud زیر را اجرا کنید.

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

اجرای دستور در پس‌زمینه حدود 1 تا 3 دقیقه طول می‌کشد. سپس می توانید پرچم جدید را در جلسه psql یا با استفاده از Cloud SQL Studio که به پایگاه داده quickstart_db متصل می شود تأیید کنید.

show google_ml_integration.enable_model_support;

خروجی مورد انتظار از جلسه psql "روشن" است:

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

سپس باید دو مدل را ثبت کنیم. اولین مورد، مدل text-embedding-004 از قبل استفاده شده است. از آنجایی که ما قابلیت های ثبت مدل را فعال کرده ایم، باید ثبت شود.

برای ثبت مدل در psql یا 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');

و مدل بعدی که باید ثبت کنیم gemini-2.0-flash-001 است که برای تولید خروجی کاربرپسند استفاده خواهد شد.

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

همیشه می‌توانید فهرست مدل‌های ثبت‌شده را با انتخاب اطلاعات از google_ml.model_info_view تأیید کنید.

select model_id,model_type from google_ml.model_info_view;

در اینجا خروجی نمونه است

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

اکنون می‌توانیم از JSON تولید شده در یک جست‌وجو فرعی برای ارائه آن به عنوان بخشی از مدل متنی AI مولد با استفاده از SQL استفاده کنیم.

در جلسه psql یا Cloud SQL Studio به پایگاه داده پرس و جو را اجرا کنید

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;

و در اینجا خروجی مورد انتظار است. ممکن است خروجی شما بسته به نسخه مدل و پارامترها متفاوت باشد.:

"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. یک نمایه نزدیکترین همسایه ایجاد کنید

مجموعه داده ما بسیار کوچک است و زمان پاسخ در درجه اول به تعامل با مدل های هوش مصنوعی بستگی دارد. اما وقتی میلیون‌ها بردار دارید، جستجوی برداری می‌تواند بخش قابل‌توجهی از زمان پاسخ ما را بگیرد و بار زیادی را روی سیستم وارد کند. برای بهبود آن می توانیم یک شاخص در بالای بردارهای خود بسازیم.

ایجاد نمایه HNSW

ما قصد داریم نوع شاخص HNSW را برای آزمایش خود امتحان کنیم. HNSW مخفف Hierarchical Navigable Small World است و نمایانگر نمودار چندلایه است.

برای ایجاد ایندکس برای ستون تعبیه شده، باید ستون جاسازی، تابع فاصله و پارامترهای اختیاری مانند m یا ef_constructions را تعریف کنیم. شما می توانید در مورد پارامترها به طور مفصل در مستندات مطالعه کنید.

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

خروجی مورد انتظار:

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

مقایسه پاسخ

اکنون می توانیم پرس و جو جستجوی برداری را در حالت EXPLAIN اجرا کنیم و بررسی کنیم که آیا از ایندکس استفاده شده است یا خیر.

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;

خروجی مورد انتظار:

 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

از خروجی می‌توانیم به وضوح ببینیم که پرس و جو از "Index Scan using cymbal_products_embeddings_hnsw" استفاده می‌کند.

و اگر کوئری را بدون توضیح اجرا کنیم:

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;

خروجی مورد انتظار:

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

می‌توانیم ببینیم که نتیجه یکسان است و همان درخت گیلاس را که در جستجوی ما در بالای صفحه بود، بدون فهرست برمی‌گردانیم. بسته به پارامترها و نوع شاخص ممکن است که نتیجه کمی متفاوت باشد. در طول آزمایش‌های من، پرس‌وجوی نمایه‌سازی‌شده نتایج را در 131.301 میلی‌ثانیه در مقابل 167.631 میلی‌ثانیه بدون هیچ شاخصی برگرداند، اما ما با مجموعه داده‌ای بسیار کوچک سروکار داشتیم و تفاوت در داده‌های بزرگ‌تر قابل توجه‌تر بود.

می‌توانید نمایه‌های مختلف موجود برای بردارها و آزمایشگاه‌ها و نمونه‌های بیشتری را با ادغام زنجیره‌ای که در مستندات موجود است، امتحان کنید.

11. محیط را تمیز کنید

نمونه Cloud SQL را حذف کنید

پس از اتمام کار با آزمایشگاه، نمونه Cloud SQL را نابود کنید

در پوسته ابری، متغیرهای پروژه و محیط را تعریف کنید، اگر اتصال شما قطع شده و تمام تنظیمات قبلی از بین رفته است:

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

نمونه را حذف کنید:

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

خروجی کنسول مورد انتظار:

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. تبریک می گویم

برای تکمیل کد لبه تبریک می گویم.

آنچه را پوشش داده ایم

  • نحوه استقرار یک Cloud SQL برای نمونه PostgreSQL
  • نحوه ایجاد پایگاه داده و فعال کردن Cloud SQL AI
  • نحوه بارگذاری اطلاعات در پایگاه داده
  • نحوه استفاده از مدل جاسازی هوش مصنوعی Vertex در Cloud SQL
  • نحوه غنی سازی نتیجه با استفاده از مدل مولد Vertex AI
  • نحوه بهبود عملکرد با استفاده از شاخص برداری

Codelab مشابه را برای AlloyDB با شاخص ScaNN به جای HNSW امتحان کنید

13. نظرسنجی

خروجی:

چگونه از این آموزش استفاده خواهید کرد؟

فقط آن را بخوانید آن را بخوانید و تمرینات را کامل کنید