برنامه جستجوی فروشگاه اسباب بازی با پایگاه داده های ابری، زمان اجرا بدون سرور و ادغام منبع باز

1. بررسی اجمالی

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

چالش: پیدا کردن آن محصول عالی که با تصورات شما مطابقت داشته باشد، می تواند دشوار باشد. عبارات جستجوی عمومی، کلمات کلیدی و جستجوهای مبهم اغلب کوتاه می آیند، مرور صفحات بی پایان می تواند خسته کننده باشد و قطع ارتباط بین آنچه تصور می کنید و آنچه در دسترس است می تواند منجر به ناامیدی شود.

راه حل: برنامه آزمایشی با این چالش مقابله می کند و از قدرت هوش مصنوعی برای ارائه یک تجربه واقعاً شخصی و یکپارچه با جستجوی متنی و تولید سفارشی محصول مطابق با زمینه جستجو استفاده می کند.

چیزی که خواهی ساخت

به عنوان بخشی از این آزمایشگاه، شما:

  1. یک نمونه AlloyDB ایجاد کنید و Toys Dataset را بارگیری کنید
  2. pgvector و پسوندهای مدل AI مولد را در AlloyDB فعال کنید
  3. جاسازی‌هایی را از توضیحات محصول ایجاد کنید و جستجوی شباهت کسینوس را در زمان واقعی برای متن جستجوی کاربر انجام دهید
  4. فلش Gemini 2.0 را برای توصیف تصویر آپلود شده توسط کاربر برای جستجوی متنی اسباب بازی فراخوانی کنید
  5. برای ایجاد سفارشی اسباب بازی بر اساس علاقه کاربر، Imagen 3 را فراخوانی کنید
  6. برای جزئیات قیمت اسباب بازی ایجاد شده سفارشی، یک ابزار پیش بینی قیمت ایجاد شده با استفاده از Gen AI Toolbox for Databases را فراخوانی کنید.
  7. راه حل را در توابع اجرای ابری بدون سرور مستقر کنید

الزامات

  • مرورگری مانند کروم یا فایرفاکس
  • یک پروژه Google Cloud با فعال کردن صورت‌حساب.

2. معماری

جریان داده: بیایید نگاهی دقیق تر به نحوه حرکت داده ها در سیستم خود بیندازیم:

  1. جستجوی متنی با RAG مبتنی بر هوش مصنوعی (نسل تقویت شده بازیابی)

به این شکل فکر کنید: به جای اینکه فقط به دنبال "ماشین قرمز" بگردید، سیستم موارد زیر را درک می کند:

"وسیله نقلیه کوچک مناسب برای پسر 3 ساله."

AlloyDB به عنوان پایه و اساس: ما از AlloyDB، پایگاه داده کاملاً مدیریت شده Google Cloud و سازگار با PostgreSQL، برای ذخیره داده های اسباب بازی خود، از جمله توضیحات، URL های تصویر، و سایر ویژگی های مرتبط استفاده می کنیم.

pgvector برای جستجوی معنایی: pgvector، یک پسوند PostgreSQL، به ما اجازه می‌دهد تا تعبیه‌های برداری را هم از توضیحات اسباب‌بازی و هم عبارت‌های جستجوی کاربر ذخیره کنیم. این امکان جستجوی معنایی را فراهم می کند، به این معنی که سیستم معنای پشت کلمات را درک می کند، نه فقط کلمات کلیدی دقیق را.

شباهت کسینوس برای ارتباط: ما از شباهت کسینوس برای اندازه‌گیری شباهت معنایی بین بردار جستجوی کاربر و بردارهای توصیف اسباب‌بازی استفاده می‌کنیم و مرتبط‌ترین نتایج را نشان می‌دهیم.

شاخص ScaNN برای سرعت و دقت: برای اطمینان از نتایج سریع و دقیق، به خصوص با افزایش موجودی اسباب‌بازی‌های ما، شاخص ScaNN (نزدیک‌ترین همسایه‌های مقیاس‌پذیر) را ادغام می‌کنیم. این به طور قابل توجهی کارایی و یادآوری جستجوی برداری ما را بهبود می بخشد.

  1. جستجو و درک مبتنی بر تصویر با فلش Gemini 2.0

به جای تایپ متن به عنوان متن، فرض کنید کاربر می خواهد تصویر یک اسباب بازی آشنا را آپلود کند که می خواهد با آن جستجو کند. کاربران می توانند تصویر اسباب بازی مورد علاقه خود را آپلود کنند و ویژگی های مرتبط را با این کار دریافت کنند. ما از مدل فلش Gemini 2.0 Google که با استفاده از LangChain4j فراخوانی شده است، برای تجزیه و تحلیل تصویر و استخراج زمینه مرتبط، مانند رنگ، مواد، نوع و گروه سنی مورد نظر اسباب‌بازی استفاده می‌کنیم.

  1. ساختن اسباب بازی رویایی خود را با هوش مصنوعی مولد سفارشی کنید: Imagen 3

جادوی واقعی زمانی اتفاق می افتد که کاربران تصمیم می گیرند اسباب بازی خود را بسازند. با استفاده از Imagen 3، به آنها اجازه می دهیم تا اسباب بازی رویایی خود را با استفاده از اعلان های متنی ساده توصیف کنند. تصور کنید بتوانید بگویید: "من یک اژدهای مخمل خواب دار با بال های بنفش و چهره ای دوستانه می خواهم" و آن اژدها را روی صفحه نمایش خود زنده کنید! سپس Imagen 3 تصویری از اسباب‌بازی سفارشی تولید می‌کند و به کاربر تجسم واضحی از خلقت خود می‌دهد.

  1. پیش‌بینی قیمت توسط Agents & Gen AI Toolbox برای پایگاه‌های داده

ما یک ویژگی پیش بینی قیمت را پیاده سازی کرده ایم که هزینه تولید اسباب بازی طراحی شده سفارشی را تخمین می زند. این توسط عاملی که شامل یک ابزار محاسبه قیمت پیچیده است، ارائه می شود.

Gener AI Toolbox for Databases: این عامل به طور یکپارچه با پایگاه داده ما با استفاده از ابزار منبع باز جدید Google، Gen AI Toolbox for Databases ادغام شده است. این به عامل اجازه می دهد تا به داده های بلادرنگ در مورد هزینه های مواد، فرآیندهای تولید و سایر عوامل مرتبط دسترسی پیدا کند تا تخمین دقیق قیمت ارائه دهد. اطلاعات بیشتر در مورد آن را اینجا بخوانید.

  1. Java Spring Boot، Gemini Code Assist و Cloud Run برای توسعه ساده و استقرار بدون سرور

کل برنامه با استفاده از Java Spring Boot، یک چارچوب قوی و مقیاس پذیر ساخته شده است. ما از Gemini Code Assist در طول فرآیند توسعه، به ویژه برای توسعه front-end استفاده کردیم، که چرخه توسعه را به طور قابل توجهی تسریع کرد و کیفیت کد را بهبود بخشید. ما از Cloud Run برای استقرار کل برنامه و از توابع Cloud Run برای استقرار پایگاه داده و عملکردهای عامل به عنوان نقاط پایانی مستقل استفاده کردیم.

3. قبل از شروع

یک پروژه ایجاد کنید

  1. در Google Cloud Console ، در صفحه انتخاب پروژه، یک پروژه Google Cloud را انتخاب یا ایجاد کنید.
  2. مطمئن شوید که صورتحساب برای پروژه Cloud شما فعال است. با نحوه بررسی فعال بودن صورت‌حساب در پروژه آشنا شوید.
  3. شما از Cloud Shell استفاده خواهید کرد، یک محیط خط فرمان در حال اجرا در Google Cloud که با bq از قبل بارگذاری شده است. روی Activate Cloud Shell در بالای کنسول Google Cloud کلیک کنید.

تصویر دکمه Cloud Shell را فعال کنید

  1. پس از اتصال به Cloud Shell، با استفاده از دستور زیر بررسی می‌کنید که قبلاً احراز هویت شده‌اید و پروژه به ID پروژه شما تنظیم شده است:
gcloud auth list
  1. دستور زیر را در Cloud Shell اجرا کنید تا تأیید کنید که دستور gcloud از پروژه شما اطلاع دارد.
gcloud config list project
  1. اگر پروژه شما تنظیم نشده است، از دستور زیر برای تنظیم آن استفاده کنید:
gcloud config set project <YOUR_PROJECT_ID>
  1. با اجرای دستورات زیر یکی یکی در ترمینال Cloud Shell خود، API های مورد نیاز را فعال کنید:

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

gcloud services enable alloydb.googleapis.com
gcloud services enable compute.googleapis.com 
gcloud services enable cloudresourcemanager.googleapis.com 
gcloud services enable servicenetworking.googleapis.com 
gcloud services enable run.googleapis.com 
gcloud services enable cloudbuild.googleapis.com 
gcloud services enable cloudfunctions.googleapis.com 
gcloud services enable aiplatform.googleapis.com

جایگزین دستور gcloud از طریق کنسول با جستجوی هر محصول یا استفاده از این پیوند است.

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

برای دستورات و استفاده از gcloud به اسناد مراجعه کنید.

4. راه اندازی پایگاه داده

در این آزمایشگاه از AlloyDB به عنوان پایگاه داده برای نگهداری داده های toystore استفاده می کنیم. از خوشه‌ها برای نگهداری همه منابع مانند پایگاه‌های داده و گزارش‌ها استفاده می‌کند. هر خوشه دارای یک نمونه اولیه است که یک نقطه دسترسی به داده ها را فراهم می کند. جداول داده های واقعی را نگه می دارند.

بیایید یک خوشه، نمونه و جدول AlloyDB ایجاد کنیم که مجموعه داده تجارت الکترونیک در آن بارگذاری شود.

یک خوشه و نمونه ایجاد کنید

  1. صفحه AlloyDB را در Cloud Console پیمایش کنید. یک راه آسان برای یافتن بیشتر صفحات در Cloud Console این است که آنها را با استفاده از نوار جستجوی کنسول جستجو کنید.
  2. CREATE CLUSTER را از آن صفحه انتخاب کنید:

f76ff480c8c889aa.png

  1. صفحه ای مانند تصویر زیر خواهید دید. یک خوشه و نمونه با مقادیر زیر ایجاد کنید (مطمئن شوید که مقادیر مطابقت دارند در صورتی که کد برنامه را از مخزن شبیه سازی می کنید):
  • cluster id : " vector-cluster "
  • رمز عبور : " alloydb "
  • سازگار با PostgreSQL 15
  • منطقه : " us-central1 "
  • شبکه سازی : " default "

538dba58908162fb.png

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

SET UP CONECTION را انتخاب کنید.
7939bbb6802a91bf.png

  1. از آنجا، « استفاده از محدوده IP خودکار اختصاص داده شده » را انتخاب کنید و ادامه دهید. پس از بررسی اطلاعات، CREATE CONNECTION را انتخاب کنید. 768ff5210e79676f.png
  2. هنگامی که شبکه شما راه اندازی شد، می توانید به ایجاد خوشه خود ادامه دهید. روی CREATE CLUSTER کلیک کنید تا راه اندازی خوشه مطابق شکل زیر کامل شود:

e06623e55195e16e.png

حتماً شناسه نمونه را به " تغییر دهید

vector-instance"

.

توجه داشته باشید که ایجاد Cluster حدود 10 دقیقه طول خواهد کشید. پس از موفقیت آمیز بودن، باید صفحه ای را ببینید که نمای کلی خوشه شما را که به تازگی ایجاد کرده اید نشان می دهد.

5. بلع داده ها

اکنون زمان اضافه کردن یک جدول با داده های مربوط به فروشگاه است. به AlloyDB بروید، خوشه اصلی و سپس AlloyDB Studio را انتخاب کنید:

847e35f1bf8a8bd8.png

ممکن است لازم باشد منتظر بمانید تا ایجاد نمونه شما به پایان برسد. پس از آن، با استفاده از اعتبارنامه هایی که هنگام ایجاد کلاستر ایجاد کردید، وارد AlloyDB شوید. از داده های زیر برای احراز هویت در PostgreSQL استفاده کنید:

  • نام کاربری: " postgres "
  • پایگاه داده: " postgres "
  • رمز عبور: " alloydb "

هنگامی که با موفقیت در AlloyDB Studio احراز هویت شدید، دستورات SQL در ویرایشگر وارد می شوند. می‌توانید چندین پنجره ویرایشگر را با استفاده از علامت مثبت در سمت راست آخرین پنجره اضافه کنید.

91a86d9469d499c4.png

در صورت لزوم با استفاده از گزینه‌های Run، Format و Clear، دستورات AlloyDB را در پنجره‌های ویرایشگر وارد می‌کنید.

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

برای ساخت این برنامه از پسوندهای pgvector و google_ml_integration استفاده خواهیم کرد. پسوند pgvector به شما امکان می دهد جاسازی های برداری را ذخیره و جستجو کنید. پسوند google_ml_integration توابعی را ارائه می دهد که شما برای دسترسی به نقاط پایانی پیش بینی هوش مصنوعی Vertex برای دریافت پیش بینی در SQL استفاده می کنید. با اجرای DDL های زیر این افزونه ها را فعال کنید :

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

اگر می خواهید افزونه هایی را که در پایگاه داده شما فعال شده اند بررسی کنید، این دستور SQL را اجرا کنید:

select extname, extversion from pg_extension;

یک جدول ایجاد کنید

با استفاده از دستور DDL زیر یک جدول ایجاد کنید:

CREATE TABLE toys ( id VARCHAR(25), name VARCHAR(25), description VARCHAR(20000), quantity INT, price FLOAT, image_url VARCHAR(200), text_embeddings vector(768)) ;

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

داده ها را بلعید

برای این آزمایشگاه، ما داده های آزمایشی حدود 72 رکورد را در این فایل SQL داریم. این شامل فیلدهای id, name, description, quantity, price, image_url است. فیلدهای دیگر بعداً در آزمایشگاه پر خواهند شد.

خطوط/عبارات را از آنجا کپی کنید و سپس آن خطوط را در یک برگه ویرایشگر خالی قرار دهید و RUN را انتخاب کنید.

برای دیدن محتویات جدول، بخش Explorer را گسترش دهید تا زمانی که جدولی به نام apparels را ببینید. برای مشاهده گزینه Query جدول، سه ویرگول (⋮) را انتخاب کنید. یک عبارت SELECT در یک تب جدید ویرایشگر باز می شود.

cfaa52b717f9aaed.png

اعطای مجوز

دستور زیر را اجرا کنید تا حقوق اجرای تابع embedding را به کاربر postgres اعطا کنید:

GRANT EXECUTE ON FUNCTION embedding TO postgres;

ROLE کاربر Vertex AI را به حساب سرویس AlloyDB اعطا کنید

به ترمینال Cloud Shell بروید و دستور زیر را بدهید:

PROJECT_ID=$(gcloud config get-value project)

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:service-$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")@gcp-sa-alloydb.iam.gserviceaccount.com" \
--role="roles/aiplatform.user"

6. تعبیه هایی برای زمینه ایجاد کنید

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

یک مکان ساحلی را توصیف کنید. ممکن است به آن «روی آب»، «کنار ساحل»، «از اتاق خود تا اقیانوس قدم بزنید»، «سور لا مر»، «на берегу океана» و غیره گفته شود.

اکنون که داده ها و زمینه آماده هستند، SQL را اجرا می کنیم تا جاسازی های توضیحات محصول را به جدول در فیلد embedding اضافه کنیم. انواع مدل های تعبیه شده وجود دارد که می توانید استفاده کنید. ما از text-embedding-005 از Vertex AI استفاده می کنیم. حتماً از همان مدل تعبیه در کل پروژه استفاده کنید!

توجه: اگر از یک پروژه Google Cloud موجود استفاده می‌کنید که چندی پیش ایجاد شده است، ممکن است لازم باشد از نسخه‌های قدیمی‌تر مدل جاسازی متن مانند textembedding-gecko استفاده کنید.

به تب AlloyDB Studio برگردید و DML زیر را تایپ کنید:

UPDATE toys set text_embeddings = embedding( 'text-embedding-005', description);

دوباره به میز toys نگاه کنید تا چند جاسازی را ببینید. حتماً عبارت SELECT را دوباره اجرا کنید تا تغییرات را ببینید.

SELECT id, name, description, price, quantity, image_url, text_embeddings FROM toys;

این باید بردار embeddings را که مانند آرایه ای از شناورها به نظر می رسد، برای توضیحات اسباب بازی که در زیر نشان داده شده است، برگرداند:

7d32f7cd7204e1f3.png

توجه: پروژه‌های Google Cloud جدید ایجاد شده در سطح رایگان ممکن است در مورد تعداد درخواست‌های جاسازی مجاز در هر ثانیه به مدل‌های Embedding با مشکلات سهمیه‌ای مواجه شوند. پیشنهاد ما این است که از یک پرس و جو فیلتر برای شناسه استفاده کنید و سپس همزمان با ایجاد جاسازی، 1-5 رکورد و غیره را انتخاب کنید.

7. جستجوی برداری را انجام دهید

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

فرض کنید کاربر بپرسد:

" I want a white plush teddy bear toy with a floral pattern ."

با اجرای پرس و جو زیر می توانید موارد منطبق برای این مورد را پیدا کنید:

select * from toys
ORDER BY text_embeddings <=> CAST(embedding('text-embedding-005', 'I want a white plush teddy bear toy with a floral pattern') as vector(768))
LIMIT 5;

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

در این پرس و جو،

  1. متن جستجوی کاربر این است: " I want a white plush teddy bear toy with a floral pattern. "
  2. ما در حال تبدیل آن به embedding در متد embedding() با استفاده از مدل: text-embedding-005 هستیم. این مرحله باید بعد از آخرین مرحله آشنا به نظر برسد، جایی که ما تابع embedding را برای همه موارد در جدول اعمال کردیم.
  3. " <=> " نشان دهنده استفاده از روش فاصله COSINE SIMILARITY است. شما می توانید تمام معیارهای شباهت موجود در مستندات pgvector را بیابید.
  4. ما در حال تبدیل نتیجه روش embedding به نوع برداری هستیم تا آن را با بردارهای ذخیره شده در پایگاه داده سازگار کنیم.
  5. LIMIT 5 نشان می دهد که ما می خواهیم 5 نزدیکترین همسایه را برای متن جستجو استخراج کنیم.

نتیجه به این صورت است:

fa7f0fc3a4c68804.png

همانطور که در نتایج خود مشاهده می کنید، مطابقت ها بسیار نزدیک به متن جستجو هستند. سعی کنید متن را تغییر دهید تا ببینید نتایج چگونه تغییر می کند.

نکته مهم:

حال فرض کنید می خواهیم عملکرد (زمان پرس و جو)، کارایی و فراخوانی این نتیجه جستجوی برداری را با استفاده از شاخص ScaNN افزایش دهیم. لطفا مراحل این وبلاگ را بخوانید تا تفاوت نتیجه را با و بدون شاخص مقایسه کنید.

مرحله اختیاری: بهبود کارایی و فراخوانی با ScaNN Index

برای راحتی، فقط مراحل ایجاد فهرست را در اینجا فهرست کنید:

  1. از آنجایی که ما قبلاً خوشه، نمونه، زمینه و جاسازی‌ها را ایجاد کرده‌ایم، فقط باید افزونه ScaNN را با استفاده از عبارت زیر نصب کنیم:
CREATE EXTENSION IF NOT EXISTS alloydb_scann;
  1. سپس ایندکس (ScaNN) را ایجاد می کنیم:
CREATE INDEX toysearch_index ON toys
USING scann (text_embeddings cosine)
WITH (num_leaves=9);

در DDL بالا، apparel_index نام ایندکس است

"اسباب بازی" میز من است

"اسکن" روش شاخص است

"Embedding" ستونی در جدولی است که می‌خواهم فهرست کنم

"کسینوس" روش فاصله ای است که من می خواهم با شاخص استفاده کنم

"8" تعداد پارتیشن هایی است که برای این شاخص اعمال می شود. روی هر مقداری بین 1 تا 1048576 تنظیم کنید. برای اطلاعات بیشتر در مورد چگونگی تعیین این مقدار، به تنظیم فهرست ScaNN مراجعه کنید.

من از یک ریشه مربع از تعداد نقاط داده همانطور که در مخزن ScaNN توصیه می شود استفاده کردم (هنگام پارتیشن بندی، num_leaves باید تقریباً جذر تعداد نقاط داده باشد.).

  1. بررسی کنید که آیا نمایه با استفاده از پرس و جو ایجاد شده است:
SELECT * FROM pg_stat_ann_indexes;
  1. جستجوی برداری را با استفاده از همان عبارتی که بدون ایندکس استفاده کردیم انجام دهید:
select * from toys
ORDER BY text_embeddings <=> CAST(embedding('text-embedding-005', 'I want a white plush teddy bear toy with a floral pattern') as vector(768))
LIMIT 5;

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

  1. با یک جستجوی ساده با و بدون ایندکس تست کنید (با حذف فهرست):

این مورد استفاده تنها 72 رکورد دارد، بنابراین شاخص واقعاً تأثیر نمی گذارد. برای آزمایش انجام شده در مورد استفاده دیگر ، نتایج به شرح زیر است:

همان جستجوی Vector در داده‌های جاسازی‌شده INDEXED نتایج جستجوی با کیفیت و کارایی را نشان می‌دهد. راندمان بسیار بهبود یافته است (از نظر زمان اجرا: 10.37ms بدون ScaNN و 0.87ms با ScaNN) با این شاخص. برای اطلاعات بیشتر در مورد این موضوع، لطفا به این وبلاگ مراجعه کنید.

8. مطابقت اعتبار با LLM

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

اطمینان از تنظیم نمونه برای Gemini

ابتدا بررسی کنید که آیا Google ML Integration قبلاً برای Cluster و Instance شما فعال است یا خیر. در AlloyDB Studio دستور زیر را بدهید:

show google_ml_integration.enable_model_support;

اگر مقدار به صورت "روشن" نشان داده شد، می توانید 2 مرحله بعدی را رد کنید و مستقیماً به راه اندازی AlloyDB و ادغام مدل AI Vertex بروید.

  1. به نمونه اولیه خوشه AlloyDB خود بروید و روی EDIT PRIMARY INSTANCE کلیک کنید.

cb76b934ba3735bd.png

  1. در قسمت Advanced Configuration Options به بخش Flags بروید. و مطمئن شوید که google_ml_integration.enable_model_support flag روی " on " مطابق شکل زیر تنظیم شده است:

6a59351fcd2a9d35.png

اگر روی "روشن" تنظیم نشده است، آن را روی "روشن" تنظیم کنید و سپس روی دکمه UPDATE INSTANCE کلیک کنید. این مرحله چند دقیقه طول خواهد کشید.

ادغام مدل AlloyDB و Vertex AI

اکنون می توانید به AlloyDB Studio متصل شوید و دستور DML زیر را برای تنظیم دسترسی مدل Gemini از AlloyDB، با استفاده از شناسه پروژه خود در جایی که نشان داده شده است، اجرا کنید. ممکن است قبل از اجرای دستور در مورد یک خطای نحوی هشدار داده شود، اما باید به خوبی اجرا شود.

ابتدا اتصال مدل Gemini 1.5 را مطابق شکل زیر ایجاد می کنیم. به یاد داشته باشید که $PROJECT_ID در دستور زیر با شناسه پروژه Google Cloud خود جایگزین کنید.

CALL
 google_ml.create_model( model_id => 'gemini-1.5',
   model_request_url => 'https://us-central1-aiplatform.googleapis.com/v1/projects/$PROJECT_ID/locations/us-central1/publishers/google/models/gemini-1.5-pro:streamGenerateContent',
   model_provider => 'google',
   model_auth_type => 'alloydb_service_agent_iam');

می توانید مدل های پیکربندی شده برای دسترسی را از طریق دستور زیر در AlloyDB Studio بررسی کنید:

select model_id,model_type from google_ml.model_info_view;        

در نهایت، ما باید به کاربران پایگاه داده اجازه دهیم تا تابع ml_predict_row را برای اجرای پیش‌بینی‌ها از طریق مدل‌های Google Vertex AI اجرا کنند. دستور زیر را اجرا کنید:

GRANT EXECUTE ON FUNCTION ml_predict_row to postgres;

توجه: اگر از یک پروژه Google Cloud موجود و یک خوشه/نمونه موجود از AlloyDB که چندی پیش ایجاد شده استفاده می‌کنید، ممکن است لازم باشد ارجاعات قدیمی را به مدل gemini-1.5 رها کنید و دوباره با عبارت CALL بالا ایجاد کنید و درصورتی‌که در فراخوانی‌های آتی gemini-1 با مشکلاتی مواجه شوید، دوباره grant execute را روی تابع ml_predict_row اجرا کنید.

ارزیابی پاسخ ها

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

  1. ابتدا درخواستی را به پایگاه داده ارسال می کنیم تا 10 مورد مطابقت با یک جستجوی کاربر را دریافت کند.
  2. برای تعیین اینکه پاسخ ها چقدر معتبر هستند، از یک پرس و جو بیرونی استفاده می کنیم که در آن نحوه ارزیابی پاسخ ها را توضیح می دهیم. از فیلد recommended_text که متن و content جستجو (که قسمت توضیحات اسباب بازی است) جدول داخلی به عنوان بخشی از پرس و جو استفاده می کند.
  3. با استفاده از آن، «خوبی» پاسخ‌های برگشتی را بررسی می‌کنیم.
  4. predict_row نتیجه خود را در قالب JSON برمی گرداند. کد " -> 'candidates' -> 0 -> 'content' -> 'parts' -> 0 -> 'text'" برای استخراج متن واقعی از آن JSON استفاده می‌شود. برای دیدن JSON واقعی که برگردانده شده است، می توانید این کد را حذف کنید.
  5. در نهایت، برای دریافت پاسخ LLM، آن را با استفاده از REGEXP_REPLACE(gemini_validation, '[^a-zA-Z,: ]', '', 'g')
SELECT id,
       name,
       content,
       quantity,
       price,
       image_url,
       recommended_text,
       REGEXP_REPLACE(gemini_validation, '[^a-zA-Z,: ]', '', 'g') AS gemini_validation
  FROM (SELECT id,
               name,
               content,
               quantity,
               price,
               image_url,
               recommended_text,
               CAST(ARRAY_AGG(LLM_RESPONSE) AS TEXT) AS gemini_validation
          FROM (SELECT id,
                       name,
                       content,
                       quantity,
                       price,
                       image_url,
                       recommended_text,
                       json_array_elements(google_ml.predict_row(model_id => 'gemini-1.5',
                                                                   request_body => CONCAT('{ "contents": [ { "role": "user", "parts": [ { "text": "User wants to buy a toy and this is the description of the toy they wish to buy: ',                                                                                              recommended_text,                                                                                              '. Check if the following product items from the inventory are close enough to really, contextually match the user description. Here are the items: ',                                                                                         content,                                                                                         '. Return a ONE-LINE response with 3 values: 1) MATCH: if the 2 contexts are reasonably matching in terms of any of the color or color family specified in the list, approximate style match with any of the styles mentioned in the user search text: This should be a simple YES or NO. Choose NO only if it is completely irrelevant to users search criteria. 2) PERCENTAGE: percentage of match, make sure that this percentage is accurate 3) DIFFERENCE: A clear one-line easy description of the difference between the 2 products. Remember if the user search text says that some attribute should not be there, and the record has it, it should be a NO match. " } ] } ] }')::JSON)) -> 'candidates' -> 0 -> 'content' -> 'parts' -> 0 -> 'text' :: TEXT AS LLM_RESPONSE
                  FROM (SELECT id,
                               name,
                               description AS content,
                               quantity,
                               price,
                               image_url,
                               'Pink panther standing' AS recommended_text
                          FROM toys
                         ORDER BY text_embeddings <=> embedding('text-embedding-005',
                                                                'Pink panther standing')::VECTOR
                         LIMIT 10) AS xyz) AS X
         GROUP BY id,
                  name,
                  content,
                  quantity,
                  price,
                  image_url,
                  recommended_text) AS final_matches
 WHERE REGEXP_REPLACE(gemini_validation, '[^a-zA-Z,: ]', '', 'g') LIKE '%MATCH%:%YES%';

اگرچه هنوز ممکن است دلهره آور به نظر برسد، امیدواریم که بتوانید کمی بیشتر از آن استفاده کنید. نتایج نشان می دهد که آیا مطابقت وجود دارد یا خیر، چند درصد تطابق است، و توضیحی در مورد رتبه بندی.

توجه داشته باشید که مدل Gemini به طور پیش‌فرض پخش جریانی دارد، بنابراین پاسخ واقعی در چندین خط پخش می‌شود:

c2b006aeb3f3a2fc.png

9. جستجوی اسباب بازی را بدون سرور به Cloud ببرید

برای بردن این برنامه به وب آماده هستید؟ برای ساختن این موتور دانش بدون سرور با توابع اجرای ابری، مراحل زیر را دنبال کنید:

  1. برای ایجاد یک عملکرد Cloud Run جدید، به Cloud Run Functions در Google Cloud Console بروید یا از پیوند استفاده کنید: https://console.cloud.google.com/functions/add .
  2. Environment را به عنوان " عملکرد Cloud Run " انتخاب کنید. نام تابع " get-toys-alloydb " را وارد کنید و منطقه را به عنوان "us-central1" انتخاب کنید. Authentication را روی "Allow unauthenticated invocation" تنظیم کنید و روی NEXT کلیک کنید. جاوا 17 را به عنوان زمان اجرا و ویرایشگر داخلی را برای کد منبع انتخاب کنید.
  3. به طور پیش فرض نقطه ورودی را روی " gcfv2.HelloHttpFunction " تنظیم می کند. کد مکان نگهدار در HelloHttpFunction.java و pom.xml تابع Cloud Run خود را به ترتیب با کد HelloHttpFunction.java و pom.xml جایگزین کنید.
  4. به یاد داشته باشید که مکان‌نمای <<YOUR_PROJECT>> و اعتبار اتصال AlloyDB را با مقادیر خود در فایل جاوا تغییر دهید. اعتبارنامه های AlloyDB آنهایی هستند که در ابتدای این کد لبه استفاده کرده بودیم. اگر از مقادیر متفاوتی استفاده کرده اید، لطفاً همان را در فایل جاوا تغییر دهید.
  5. روی Deploy کلیک کنید.

پس از استقرار، برای اینکه به تابع Cloud اجازه دهیم به نمونه پایگاه داده AlloyDB ما دسترسی پیدا کند، رابط VPC را ایجاد می کنیم.

گام مهم:

هنگامی که برای استقرار راه افتادید، باید بتوانید عملکردها را در کنسول Google Cloud Run Functions مشاهده کنید. تابع تازه ایجاد شده ( get-toys-alloydb ) را جستجو کنید، روی آن کلیک کنید، سپس روی EDIT کلیک کنید و موارد زیر را تغییر دهید:

  1. به Runtime، ساخت، اتصالات و تنظیمات امنیتی بروید
  2. تایم اوت را به 180 ثانیه افزایش دهید
  3. به تب اتصالات بروید:

4e83ec8a339cda08.png

  1. در تنظیمات Ingress، مطمئن شوید که "Allow all traffic" انتخاب شده است.
  2. در زیر تنظیمات Egress، روی منوی کشویی Network کلیک کنید و گزینه "Add New VPC Connector" را انتخاب کنید و دستورالعمل هایی را که در کادر محاوره ای ظاهر می شود دنبال کنید:

8126ec78c343f199.png

  1. نامی برای اتصال VPC ارائه دهید و مطمئن شوید که منطقه با نمونه شما یکسان است. مقدار Network را به عنوان پیش فرض بگذارید و Subnet را به عنوان محدوده IP سفارشی با محدوده IP 10.8.0.0 یا چیزی مشابه که در دسترس است تنظیم کنید.
  2. SHOW SCALING SETTINGS را باز کنید و مطمئن شوید که پیکربندی دقیقاً روی موارد زیر تنظیم شده است:

7baf980463a86a5c.png

  1. روی CREATE کلیک کنید و این رابط باید اکنون در تنظیمات خروج لیست شود.
  2. کانکتور تازه ایجاد شده را انتخاب کنید
  3. انتخاب کنید که تمام ترافیک از طریق این رابط VPC هدایت شود.
  4. روی NEXT و سپس DEPLOY کلیک کنید.

10. عملکرد Cloud Run را تست کنید

پس از به روز رسانی Cloud Function، باید نقطه پایانی را در قالب زیر مشاهده کنید:

https://us-central1-YOUR_PROJECT_ID.cloudfunctions.net/get-toys-alloydb

همچنین، می توانید عملکرد Cloud Run را به صورت زیر آزمایش کنید:

PROJECT_ID=$(gcloud config get-value project)

curl -X POST https://us-central1-$PROJECT_ID.cloudfunctions.net/get-toys-alloydb \
  -H 'Content-Type: application/json' \
  -d '{"search":"I want a standing pink panther toy"}' \
  | jq .

و نتیجه:

23861e9091565a64.png

همین! انجام جستجوی بردار تشابه با استفاده از مدل Embeddings در داده های AlloyDB بسیار ساده است.

11. ساخت مشتری برنامه وب!

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

  1. از آنجایی که ما از Gemini 2.0 Flash برای توصیف تصویری که کاربر ممکن است برای یافتن اسباب‌بازی‌های مشابه آپلود کند، استفاده می‌کنیم، باید API KEY را برای این برنامه دریافت کنیم. برای انجام این کار، به https://aistudio.google.com/apikey بروید و کلید API را برای پروژه Google Cloud فعال خود که در حال پیاده سازی این برنامه در آن هستید دریافت کنید و کلید را در جایی ذخیره کنید:

ae2db169e6a94e4a.png

  1. به ترمینال Cloud Shell بروید
  2. با دستور زیر مخزن را کلون کنید:
git clone https://github.com/AbiramiSukumaran/toysearch

cd toysearch
  1. هنگامی که مخزن کلون شد، باید بتوانید از ویرایشگر Cloud Shell خود به پروژه دسترسی داشته باشید.
  2. باید پوشه‌های «get-toys-alloydb» و «toolbox-toys» را از پروژه شبیه‌سازی‌شده حذف کنید، زیرا این 2 کد عملکردهای Cloud Run هستند که در صورت نیاز می‌توانند از مخزن به آنها ارجاع داده شوند.
  3. اطمینان حاصل کنید که همه متغیرهای محیطی لازم قبل از ساخت و استقرار برنامه تنظیم شده اند. به ترمینال Cloud Shell بروید و موارد زیر را اجرا کنید:
PROJECT_ID=$(gcloud config get-value project)

export PROJECT_ID $PROJECT_ID

export GOOGLE_API_KEY <YOUR API KEY that you saved>
  1. برنامه را به صورت محلی بسازید و اجرا کنید:

برای اطمینان از اینکه در دایرکتوری پروژه هستید، دستورات زیر را اجرا کنید:

mvn package

mvn spring-boot:run 
  1. استقرار در Cloud Run
gcloud run deploy --source .

12. درک جزئیات هوش مصنوعی مولد

هیچ اقدامی لازم نیست فقط برای درک شما:

اکنون که برنامه را برای استقرار در اختیار دارید، کمی وقت بگذارید تا بفهمید چگونه جستجو (متن و تصویر) و تولید را انجام دادیم.

  1. جستجوی برداری مبتنی بر متن کاربر:

این قبلاً در توابع اجرای ابری که در بخش «برنامه وب اپلیکیشن جستجوی برداری را بگیرید» به کار گرفته شده است.

  1. جستجوی برداری مبتنی بر آپلود تصویر:

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

ما از مدل فلش Gemini 2.0 Google که با استفاده از LangChain4j فراخوانی شده است، برای تجزیه و تحلیل تصویر و استخراج زمینه مرتبط، مانند رنگ، مواد، نوع و گروه سنی مورد نظر اسباب‌بازی استفاده می‌کنیم.

تنها در 5 مرحله، ما ورودی داده چندوجهی کاربر را به نتایج تطبیق با فراخوانی مدل زبان بزرگ با استفاده از یک چارچوب منبع باز بردیم. یاد بگیرید چگونه:

package cloudcode.helloworld.web;

import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.googleai.GoogleAiGeminiChatModel;
import dev.langchain4j.data.message.UserMessage;
import dev.langchain4j.data.message.AiMessage;
import dev.langchain4j.model.output.Response;
import dev.langchain4j.data.message.ImageContent;
import dev.langchain4j.data.message.TextContent;
import java.util.Base64;
import java.util.Optional;

public class GeminiCall {
  public String imageToBase64String(byte[] imageBytes) {
    String base64Img = Base64.getEncoder().encodeToString(imageBytes);
    return base64Img;
  }

  public String callGemini(String base64ImgWithPrefix) throws Exception {
    String searchText = "";

    // 1. Remove the prefix
    String base64Img = base64ImgWithPrefix.replace("data:image/jpeg;base64,", "");

    // 2. Decode base64 to bytes
    byte[] imageBytes = Base64.getDecoder().decode(base64Img);
    String image = imageToBase64String(imageBytes);

    // 3. Get API key from environment variable
        String apiKey = Optional.ofNullable(System.getenv("GOOGLE_API_KEY"))
                .orElseThrow(() -> new IllegalArgumentException("GOOGLE_API_KEY environment variable not set"));

    // 4. Invoke Gemini 2.0
    ChatLanguageModel gemini = GoogleAiGeminiChatModel.builder()
        .apiKey(apiKey)
        .modelName("gemini-2.0-flash-001")
        .build();

    Response<AiMessage> response = gemini.generate(
        UserMessage.from(
            ImageContent.from(image, "image/jpeg"),
            TextContent.from(
                "The picture has a toy in it. Describe the toy in the image in one line. Do not add any prefix or title to your description. Just describe that toy that you see in the image in one line, do not describe the surroundings and other objects around the toy in the image. If you do not see any toy in the image, send  response stating that no toy is found in the input image.")));
   
    // 5. Get the text from the response and send it back to the controller
    searchText = response.content().text().trim();
    System.out.println("searchText inside Geminicall: " + searchText);
    return searchText;
  }
}
  1. درک کنید که چگونه از Imagen 3 برای ساختن یک اسباب بازی سفارشی بر اساس درخواست کاربر با هوش مصنوعی Generative استفاده کردیم.

سپس Imagen 3 تصویری از اسباب‌بازی سفارشی تولید می‌کند و به کاربر تجسم واضحی از خلقت خود می‌دهد. ما این کار را فقط در 5 مرحله انجام دادیم:

// Generate an image using a text prompt using an Imagen model
    public String generateImage(String projectId, String location, String prompt)
        throws ApiException, IOException {
      final String endpoint = String.format("%s-aiplatform.googleapis.com:443", location);
      PredictionServiceSettings predictionServiceSettings =
      PredictionServiceSettings.newBuilder().setEndpoint(endpoint).build();
     
      // 1. Set up the context and prompt
      String context = "Generate a photo-realistic image of a toy described in the following input text from the user. Make sure you adhere to all the little details and requirements mentioned in the prompt. Ensure that the user is only describing a toy. If it is anything unrelated to a toy, politely decline the request stating that the request is inappropriate for the current context. ";
      prompt = context + prompt;

      // 2. Initialize a client that will be used to send requests. This client only needs to be created
      // once, and can be reused for multiple requests.
      try (PredictionServiceClient predictionServiceClient =
          PredictionServiceClient.create(predictionServiceSettings)) {
 
      // 3. Invoke Imagen 3
        final EndpointName endpointName =
            EndpointName.ofProjectLocationPublisherModelName(
                projectId, location, "google", "imagen-3.0-generate-001"); //"imagegeneration@006"; imagen-3.0-generate-001
        Map<String, Object> instancesMap = new HashMap<>();
        instancesMap.put("prompt", prompt);
        Value instances = mapToValue(instancesMap);
        Map<String, Object> paramsMap = new HashMap<>();
        paramsMap.put("sampleCount", 1);
        paramsMap.put("aspectRatio", "1:1");
        paramsMap.put("safetyFilterLevel", "block_few");
        paramsMap.put("personGeneration", "allow_adult");
        paramsMap.put("guidanceScale", 21);
        paramsMap.put("imagenControlScale", 0.95); //Setting imagenControlScale
        Value parameters = mapToValue(paramsMap);
       
      // 4. Get prediction response image
        PredictResponse predictResponse =
            predictionServiceClient.predict(
                endpointName, Collections.singletonList(instances), parameters);

      // 5. Return the Base64 Encoded String to the controller
        for (Value prediction : predictResponse.getPredictionsList()) {
          Map<String, Value> fieldsMap = prediction.getStructValue().getFieldsMap();
          if (fieldsMap.containsKey("bytesBase64Encoded")) {
            bytesBase64EncodedOuput = fieldsMap.get("bytesBase64Encoded").getStringValue();
        }
      }
      return bytesBase64EncodedOuput.toString();
    }
  }

پیش بینی قیمت

در بخش قبلی در بالا، نحوه ایجاد تصویر اسباب‌بازی را که کاربر می‌خواهد به تنهایی طراحی کند، بحث کردیم. برای اینکه آنها بتوانند آن را بخرند، برنامه باید برای آن قیمت تعیین کند و ما از یک منطق بصری برای تعریف قیمت برای اسباب بازی سفارشی استفاده کرده ایم. منطق این است که از میانگین قیمت 5 اسباب بازی برتر مطابقت (از نظر توضیحات) از اسباب بازیی که کاربر طراحی می کند استفاده شود.

پیش بینی قیمت برای اسباب بازی تولید شده بخش مهمی از این برنامه است و ما از یک رویکرد عاملی برای تولید آن استفاده کرده ایم. معرفی Gen AI Toolbox برای پایگاه های داده.

13. Gener AI Toolbox for Database

Gen AI Toolbox for Databases یک سرور منبع باز از گوگل است که ساخت ابزارهای Gen AI را برای تعامل با پایگاه های داده آسان تر می کند. این به شما امکان می دهد تا با مدیریت پیچیدگی هایی مانند ادغام اتصال، احراز هویت و موارد دیگر، ابزارها را آسان تر، سریع تر و ایمن تر توسعه دهید. این به شما کمک می کند ابزارهای Gen AI بسازید که به عوامل شما اجازه می دهد به داده های پایگاه داده شما دسترسی داشته باشند.

در اینجا مراحلی وجود دارد که باید دنبال کنید تا بتوانید این را برای آماده کردن ابزار خود تنظیم کنید و برنامه ما را عاملی کنید: پیوند به جعبه ابزار Codelab

برنامه شما اکنون می‌تواند از این نقطه پایانی عملکرد Cloud Run برای تکمیل قیمت به همراه نتیجه Imagen تولید شده برای تصویر اسباب‌بازی سفارشی استفاده کند.

14. برنامه وب خود را تست کنید

اکنون که تمام اجزای برنامه شما ساخته و مستقر شده است، برای ارائه در فضای ابری آماده است. برنامه خود را برای همه سناریوها آزمایش کنید. در اینجا یک پیوند ویدیویی به آنچه ممکن است انتظار داشته باشید وجود دارد:

https://www.youtube.com/shorts/ZMqUAWsghYQ

صفحه فرود به این صورت است:

241db19e7176e93e.png

15. پاکسازی کنید

برای جلوگیری از تحمیل هزینه به حساب Google Cloud خود برای منابع استفاده شده در این پست، این مراحل را دنبال کنید:

  1. در کنسول Google Cloud، به صفحه مدیریت منابع بروید.
  2. در لیست پروژه، پروژه ای را که می خواهید حذف کنید انتخاب کنید و سپس روی Delete کلیک کنید.
  3. در محاوره، شناسه پروژه را تایپ کنید و سپس روی Shut down کلیک کنید تا پروژه حذف شود.

16. تبریک می گویم

تبریک می گویم! شما با استفاده از AlloyDB، pgvector، Imagen و Gemini 2.0 در حالی که از کتابخانه های منبع باز برای ایجاد ادغام قوی استفاده می کنید، یک جستجوی متنی Toystore و Generation را با موفقیت انجام دادید. با ترکیب قابلیت‌های AlloyDB ، Vertex AI ، و Vector Search ، ما جهشی بزرگ در ایجاد جستجوهای متنی و برداری در دسترس، کارآمد و واقعاً معنادار برداشته‌ایم.