1. บทนำ
ในโค้ดแล็บนี้ คุณจะได้เรียนรู้วิธีใช้ Cloud SQL สําหรับการผสานรวม AI ของ PostgreSQL ด้วยการรวมการค้นหาแบบเวกเตอร์เข้ากับการฝัง Vertex AI
ข้อกำหนดเบื้องต้น
- ความเข้าใจพื้นฐานเกี่ยวกับคอนโซล Google Cloud
- ทักษะพื้นฐานในอินเทอร์เฟซบรรทัดคำสั่งและ Cloud Shell
สิ่งที่คุณจะได้เรียนรู้
- วิธีทำให้อินสแตนซ์ Cloud SQL สำหรับ PostgreSQL พร้อมใช้งาน
- วิธีสร้างฐานข้อมูลและเปิดใช้การผสานรวม AI ของ Cloud SQL
- วิธีโหลดข้อมูลไปยังฐานข้อมูล
- วิธีใช้โมเดลการฝังของ Vertex AI ใน Cloud SQL
- วิธีเพิ่มประสิทธิภาพผลลัพธ์โดยใช้โมเดล Generative ของ Vertex AI
- วิธีปรับปรุงประสิทธิภาพโดยใช้ดัชนีเวกเตอร์
สิ่งที่ต้องมี
- บัญชี Google Cloud และโปรเจ็กต์ Google Cloud
- เว็บเบราว์เซอร์ เช่น Chrome ที่รองรับ Google Cloud Console และ Cloud Shell
2. การตั้งค่าและข้อกําหนด
การตั้งค่าสภาพแวดล้อมด้วยตนเอง
- ลงชื่อเข้าใช้ Google Cloud Console แล้วสร้างโปรเจ็กต์ใหม่หรือใช้โปรเจ็กต์ที่มีอยู่ซ้ำ หากยังไม่มีบัญชี Gmail หรือ Google Workspace คุณต้องสร้างบัญชี
- ชื่อโปรเจ็กต์คือชื่อที่แสดงสำหรับผู้เข้าร่วมโปรเจ็กต์นี้ ซึ่งเป็นสตริงอักขระที่ Google APIs ไม่ได้ใช้ คุณจะอัปเดตได้ทุกเมื่อ
- รหัสโปรเจ็กต์จะซ้ำกันไม่ได้ในโปรเจ็กต์ Google Cloud ทั้งหมดและจะเปลี่ยนแปลงไม่ได้ (เปลี่ยนแปลงไม่ได้หลังจากตั้งค่าแล้ว) คอนโซล Cloud จะสร้างสตริงที่ไม่ซ้ำกันโดยอัตโนมัติ ซึ่งปกติแล้วคุณไม่จำเป็นต้องสนใจว่าสตริงนั้นจะเป็นอะไร ในโค้ดแล็บส่วนใหญ่ คุณจะต้องอ้างอิงรหัสโปรเจ็กต์ (ปกติจะระบุเป็น
PROJECT_ID
) หากไม่ชอบรหัสที่สร้างขึ้น คุณอาจสร้างรหัสอื่นแบบสุ่มได้ หรือจะลองใช้อุปกรณ์ของคุณเองเพื่อดูว่าอุปกรณ์พร้อมใช้งานหรือไม่ก็ได้ คุณจะเปลี่ยนแปลงชื่อหลังจากขั้นตอนนี้ไม่ได้ และชื่อจะคงอยู่ตลอดระยะเวลาของโปรเจ็กต์ - โปรดทราบว่ามีค่าที่ 3 ซึ่งเป็นหมายเลขโปรเจ็กต์ที่ API บางรายการใช้ ดูข้อมูลเพิ่มเติมเกี่ยวกับค่าทั้ง 3 รายการนี้ได้ในเอกสารประกอบ
- ถัดไป คุณจะต้องเปิดใช้การเรียกเก็บเงินใน Cloud Console เพื่อใช้ทรัพยากร/API ของ Cloud การทำตามโค้ดแล็บนี้จะไม่เสียค่าใช้จ่ายมากนัก หากต้องการปิดทรัพยากรเพื่อหลีกเลี่ยงการเรียกเก็บเงินหลังจากบทแนะนำนี้ คุณลบทรัพยากรที่สร้างไว้หรือลบโปรเจ็กต์ได้ ผู้ใช้ Google Cloud รายใหม่มีสิทธิ์เข้าร่วมโปรแกรมช่วงทดลองใช้ฟรีมูลค่า$300 USD
เริ่ม Cloud Shell
แม้ว่าคุณจะดำเนินการกับ Google Cloud จากระยะไกลจากแล็ปท็อปได้ แต่ในโค้ดแล็บนี้ คุณจะใช้ Google Cloud Shell ซึ่งเป็นสภาพแวดล้อมบรรทัดคำสั่งที่ทำงานในระบบคลาวด์
จากคอนโซล Google Cloud ให้คลิกไอคอน Cloud Shell ในแถบเครื่องมือด้านขวาบน
การจัดสรรและเชื่อมต่อกับสภาพแวดล้อมจะใช้เวลาเพียงไม่กี่นาที เมื่อดำเนินการเสร็จแล้ว คุณควรเห็นข้อมูลดังต่อไปนี้
เครื่องเสมือนนี้โหลดเครื่องมือการพัฒนาทั้งหมดที่คุณต้องการ ซึ่งจะมีไดเรกทอรีหลักขนาด 5 GB ถาวรและทำงานบน Google Cloud ซึ่งจะช่วยเพิ่มประสิทธิภาพเครือข่ายและการรับรองได้อย่างมีประสิทธิภาพ คุณทํางานทั้งหมดในโค้ดแล็บนี้ได้ภายในเบราว์เซอร์ คุณไม่จำเป็นต้องติดตั้งอะไรเลย
3. ก่อนเริ่มต้น
เปิดใช้ API
เอาต์พุต:
ใน Cloud Shell ให้ตรวจสอบว่าได้ตั้งค่ารหัสโปรเจ็กต์แล้ว โดยทำดังนี้
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
ให้สิทธิ์ที่จำเป็นแก่บัญชีบริการ Cloud 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. เตรียมฐานข้อมูล
ตอนนี้เราต้องสร้างฐานข้อมูลและเปิดใช้การรองรับเวกเตอร์
สร้างฐานข้อมูล
สร้างฐานข้อมูลชื่อ quickstart_db ในการทำเช่นนี้ เรามีตัวเลือกต่างๆ เช่น ไคลเอ็นต์ฐานข้อมูลบรรทัดคำสั่ง เช่น psql สำหรับ PostgreSQL, SDK หรือ Cloud SQL Studio เราจะใช้ SDK (gcloud) ในการสร้างฐานข้อมูลและเชื่อมต่อกับอินสแตนซ์
ใน Cloud Shell ให้เรียกใช้คําสั่งเพื่อสร้างฐานข้อมูล
gcloud sql databases create quickstart_db --instance=my-cloudsql-instance
เปิดใช้ส่วนขยาย
หากต้องการทํางานกับ Vertex AI และเวกเตอร์ เราต้องเปิดใช้ส่วนขยาย 2 รายการในฐานข้อมูลที่สร้างขึ้น
ใน Cloud Shell ให้เรียกใช้คําสั่งเพื่อเชื่อมต่อกับฐานข้อมูลที่สร้างขึ้น (คุณจะต้องระบุรหัสผ่าน)
gcloud sql connect my-cloudsql-instance --database quickstart_db --user=postgres
จากนั้นหลังจากเชื่อมต่อสําเร็จแล้ว ในเซสชัน sql คุณต้องเรียกใช้คําสั่ง 2 รายการต่อไปนี้
CREATE EXTENSION IF NOT EXISTS google_ml_integration CASCADE;
CREATE EXTENSION IF NOT EXISTS vector CASCADE;
วิธีออกจากเซสชัน SQL
exit;
6. โหลดข้อมูล
ตอนนี้เราต้องสร้างออบเจ็กต์ในฐานข้อมูลและโหลดข้อมูล เราจะใช้ข้อมูลของ Cymbal Store สมมติ ข้อมูลจะอยู่ในที่เก็บข้อมูล Google Storage สาธารณะในรูปแบบ CSV
ก่อนอื่นเราต้องสร้างออบเจ็กต์ที่จำเป็นทั้งหมดในฐานข้อมูล โดยเราจะใช้คำสั่ง gcloud sql connect และ gcloud storage ที่คุ้นเคยอยู่แล้วเพื่อดาวน์โหลดและนําเข้าออบเจ็กต์สคีมาไปยังฐานข้อมูล
ใน Cloud Shell ให้ดำเนินการและป้อนรหัสผ่านที่บันทึกไว้เมื่อเราสร้างอินสแตนซ์
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 Console คุณก็ใช้เครื่องมือดังกล่าวแทนการใช้บรรทัดคําสั่งได้
7. สร้างการฝัง
ขั้นตอนถัดไปคือการสร้างการฝังสําหรับคําอธิบายผลิตภัณฑ์โดยใช้โมเดล textembedding-004 จาก Google Vertex AI และจัดเก็บเป็นข้อมูลเวกเตอร์
เชื่อมต่อกับฐานข้อมูล
gcloud sql connect my-cloudsql-instance --database quickstart_db --user=postgres
และสร้างคอลัมน์เสมือนที่ฝังในตาราง cymbal_products โดยใช้ฟังก์ชันการฝัง
ALTER TABLE cymbal_products ADD COLUMN embedding vector(768) GENERATED ALWAYS AS (embedding('text-embedding-004',product_description)) STORED;
การดำเนินการนี้อาจใช้เวลาสักครู่ แต่สำหรับแถว 900-1,000 แถว การดำเนินการนี้ไม่ควรใช้เวลาเกิน 5 นาที และโดยปกติจะใช้เวลาเร็วกว่านั้นมาก
8. เรียกใช้การค้นหาความคล้ายคลึง
ตอนนี้เราเรียกใช้การค้นหาโดยใช้การค้นหาแบบคล้ายกันตามค่าเวกเตอร์ที่คำนวณสำหรับคำอธิบายและค่าเวกเตอร์ที่เราได้รับสำหรับคำขอได้แล้ว
คุณสามารถเรียกใช้การค้นหา SQL จากอินเทอร์เฟซบรรทัดคำสั่งเดียวกันได้โดยใช้ gcloud sql connect หรือเรียกใช้จาก Cloud SQL Studio แทนก็ได้ การค้นหาแบบหลายแถวและซับซ้อนจะจัดการได้ง่ายขึ้นใน Cloud SQL Studio
เริ่มใช้ Cloud SQL Studio
ในคอนโซล ให้คลิกอินสแตนซ์ Cloud SQL ที่เราสร้างไว้ก่อนหน้านี้
เมื่อเปิดในแผงด้านขวา เราจะเห็น Cloud SQL Studio คลิกที่ไอคอน
ซึ่งจะเปิดกล่องโต้ตอบที่ให้คุณระบุชื่อฐานข้อมูลและข้อมูลเข้าสู่ระบบ
- ฐานข้อมูล: quickstart_db
- ผู้ใช้: postgres
- รหัสผ่าน: รหัสผ่านที่บันทึกไว้สำหรับผู้ใช้ฐานข้อมูลหลัก
แล้วคลิกปุ่ม "ตรวจสอบสิทธิ์"
ซึ่งจะเปิดหน้าต่างถัดไปที่คุณคลิกแท็บ "เครื่องมือแก้ไข" ทางด้านขวาเพื่อเปิดเครื่องมือแก้ไข SQL
ตอนนี้เราพร้อมที่จะเรียกใช้การค้นหาแล้ว
ดำเนินการค้นหา
เรียกใช้การค้นหาเพื่อดูรายการผลิตภัณฑ์ที่มีจำหน่ายซึ่งเกี่ยวข้องกับคำขอของลูกค้ามากที่สุด คําขอที่เราส่งไปยัง 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 แล้วกดปุ่ม "เรียกใช้" หรือวางลงในเซสชันบรรทัดคำสั่งที่เชื่อมต่อกับฐานข้อมูล quickstart_db
และนี่คือรายการผลิตภัณฑ์ที่เลือกซึ่งตรงกับคำค้นหา
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 โดยใช้ข้อมูลที่ดึงมา
เราปรับปรุงคำตอบ LLM ของ Gen AI ในแอปพลิเคชันไคลเอ็นต์ได้โดยใช้ผลลัพธ์ของการค้นหาที่ดำเนินการ และเตรียมเอาต์พุตที่สื่อความหมายโดยใช้ผลการค้นหาที่ระบุเป็นส่วนหนึ่งของพรอมต์สำหรับโมเดลภาษาพื้นฐานแบบ Generative ของ Vertex AI
ในการทำเช่นนั้น เราจำเป็นต้องสร้าง JSON ที่มีผลลัพธ์จากการค้นหาเวกเตอร์ จากนั้นใช้ JSON ที่สร้างขึ้นนั้นเพิ่มเติมจากพรอมต์สำหรับโมเดล LLM ใน Vertex AI เพื่อสร้างเอาต์พุตที่มีความหมาย ในขั้นตอนแรก เราจะสร้าง JSON จากนั้นทดสอบใน Vertex AI Studio และขั้นตอนสุดท้ายเราจะรวม JSON ไว้ในคำสั่ง SQL ซึ่งสามารถใช้ในแอปพลิเคชันได้
สร้างเอาต์พุตในรูปแบบ JSON
แก้ไขการค้นหาเพื่อสร้างเอาต์พุตในรูปแบบ JSON และแสดงผลเพียง 1 แถวเพื่อส่งไปยัง 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 ที่สร้างขึ้นเพื่อเป็นส่วนหนึ่งของพรอมต์สำหรับโมเดลข้อความ Generative AI ใน Vertex AI Studio
เปิดแชท Vertex AI Studio ใน Cloud Console
ระบบอาจขอให้คุณเปิดใช้ 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 มีดังนี้
คำตอบที่เราได้รับจากโมเดลในตัวอย่างนี้แสดงอยู่ด้านล่าง โปรดทราบว่าคําตอบอาจแตกต่างออกไปเนื่องจากรูปแบบและพารามิเตอร์มีการเปลี่ยนแปลงเมื่อเวลาผ่านไป
"เอาล่ะ จากรายการผลิตภัณฑ์ที่มี ต้นไม้ที่ดีที่สุดที่เรามีซึ่งอาจเติบโตได้ดีในพื้นที่ของคุณคือต้นเชอร์รี่
ราคาอยู่ที่ $75.00
แม้ว่าเราจะไม่มีรายละเอียดเฉพาะเกี่ยวกับสภาพการเจริญเติบโตในรหัสไปรษณีย์ที่แน่นอนของคุณ (93230) แต่โดยทั่วไปแล้วเป็นที่ทราบกันดีว่าต้นเชอร์รี่จะเจริญเติบโตได้ดีในพื้นที่ที่มีภูมิอากาศแบบอบอุ่นและดินมีการระบายน้ำได้ดี โดยปกติแล้ว พืชเหล่านี้ต้องการความหนาวเย็นในฤดูหนาวเป็นระยะเวลาหนึ่งจึงจะออกผลได้ อย่างไรก็ตาม เชอร์รี่ก็เป็นส่วนเสริมที่ยอดเยี่ยมสำหรับสวน ทั้งยังให้ทั้งความสวยงามและเชอร์รี่แสนอร่อยเมื่อสภาพอากาศเหมาะสม"
เรียกใช้พรอมต์ใน PSQL
นอกจากนี้ เรายังใช้การผสานรวม AI ของ Cloud SQL กับ Vertex AI เพื่อรับคำตอบที่คล้ายกันจากโมเดล Generative โดยใช้ SQL ในฐานข้อมูลโดยตรงได้ด้วย แต่หากต้องการใช้โมเดล gemini-2.0-flash-exp เราต้องลงทะเบียนโมเดลก่อน
ทำงานใน Cloud SQL สำหรับ PostgreSQL
อัปเกรดส่วนขยายเป็นเวอร์ชัน 1.4.2 ขึ้นไป (หากเวอร์ชันปัจจุบันต่ำกว่า) เชื่อมต่อกับฐานข้อมูล quickstart_db จาก gcloud sql connect ตามที่แสดงไว้ก่อนหน้านี้ (หรือใช้ 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';
จากนั้นเราต้องตั้งค่า Flag ฐานข้อมูล google_ml_integration.enable_model_support เป็น "on" ซึ่งคุณสามารถทำได้โดยใช้อินเทอร์เฟซเว็บคอนโซลหรือเรียกใช้คำสั่ง 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 นาทีในการดำเนินการในเบื้องหลัง จากนั้นคุณสามารถยืนยัน Flag ใหม่ในเซสชัน psql หรือใช้ Cloud SQL Studio ที่เชื่อมต่อกับฐานข้อมูล quickstart_db
show google_ml_integration.enable_model_support;
ผลลัพธ์ที่คาดหวังจากเซสชัน psql คือ "on"
quickstart_db => show google_ml_integration.enable_model_support; google_ml_integration.enable_model_support -------------------------------------------- on (1 row)
จากนั้นเราต้องลงทะเบียน 2 โมเดล รายการแรกคือรูปแบบ 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 ของคำถามย่อยที่สร้างขึ้นเพื่อส่งเป็นพรอมต์ไปยังโมเดลข้อความ Generative 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. สร้างดัชนีเพื่อนบ้านที่ใกล้ที่สุด
ชุดข้อมูลของเราค่อนข้างเล็กและเวลาในการตอบสนองจะขึ้นอยู่กับการโต้ตอบกับโมเดล AI เป็นหลัก แต่หากคุณมีเวกเตอร์หลายล้านรายการ การค้นหาเวกเตอร์อาจใช้เวลาในการตอบสนองส่วนใหญ่และทำให้ระบบมีภาระงานสูง เราสามารถปรับปรุงได้โดยสร้างดัชนีบนเวกเตอร์
สร้างดัชนี 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
จากเอาต์พุต เราเห็นได้อย่างชัดเจนว่าคำค้นหาใช้ "การสแกนดัชนีโดยใช้ 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 มิลลิวินาทีหากไม่มีดัชนี แต่เรากําลังจัดการกับชุดข้อมูลขนาดเล็กมาก และความแตกต่างจะมากขึ้นเมื่อเป็นข้อมูลขนาดใหญ่
คุณสามารถลองใช้ดัชนีต่างๆ ที่มีสำหรับเวกเตอร์ รวมถึงดูห้องทดลองและตัวอย่างเพิ่มเติมที่มีการผสานรวม langchain ได้ในเอกสารประกอบ
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. ขอแสดงความยินดี
ขอแสดงความยินดีที่ทํา Codelab จนเสร็จสมบูรณ์
สิ่งที่เราได้พูดถึง
- วิธีทำให้อินสแตนซ์ Cloud SQL สำหรับ PostgreSQL พร้อมใช้งาน
- วิธีสร้างฐานข้อมูลและเปิดใช้การผสานรวม AI ของ Cloud SQL
- วิธีโหลดข้อมูลไปยังฐานข้อมูล
- วิธีใช้โมเดลการฝังของ Vertex AI ใน Cloud SQL
- วิธีเพิ่มประสิทธิภาพผลลัพธ์โดยใช้โมเดล Generative ของ Vertex AI
- วิธีปรับปรุงประสิทธิภาพโดยใช้ดัชนีเวกเตอร์
ลองใช้ codelab สําหรับ AlloyDB ที่คล้ายกันซึ่งมีดัชนี ScaNN แทน HNSW
13. แบบสำรวจ
เอาต์พุต: