به PetVerse خوش آمدید!

۱. مقدمه

به دنیای حیوانات خانگی خوش آمدید! ورود همه حیوانات خانگی آزاد است! 🐈🐶🐍🐟🦄

پیش‌نیازها

  • آشنایی اولیه با کنسول ابری گوگل
  • درک اولیه از دستورات SQL

آنچه یاد خواهید گرفت

  • ایجاد مجموعه داده‌ها و جداول در BigQuery
  • ستون‌های ObjectRef را برای ارجاع به چندرسانه‌ای در یک سطل ذخیره‌سازی در BigQuery ایجاد کنید
  • از توابع هوش مصنوعی در BigQuery برای بهبود مجموعه داده‌های خود از محتوای داده‌های بدون ساختار استفاده کنید.
  • برای جستجوی رسانه‌های مشابه، جاسازی‌های چندرسانه‌ای ایجاد کنید
  • ایجاد جاسازی‌های متنی برای انجام جستجوی معنایی با VECTOR_SEARCH
  • استفاده از رابط خط فرمان Gemini برای ایجاد یک برنامه وب

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

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

۲. تنظیمات و الزامات

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

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

fbef9caa1602edd0.pnga99b7ace416376c4.png5e3ff691252acf41.png

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

۳. پوسته ابری را باز کنید

به آدرس https://shell.cloud.google.com/?show=ide%2Cterminal بروید. وقتی از شما خواسته شد، روی «مجوز دادن» کلیک کنید.

1bfca4be2c270a9f.png

مطمئن شوید که هم ویرایشگر و هم کنسول قابل مشاهده هستند:

785d186a8b11b32b.png

۴. یک اسکریپت کمکی ایجاد کنید

برای روان‌تر کردن این تجربه، یک اسکریپت کمکی ایجاد خواهید کرد که متغیرهای محیطی مربوطه را تنظیم می‌کند.

به جای <<شناسه پروژه>>، شناسه پروژه خود را در زیر قرار دهید.

دستور زیر را در ترمینال Cloud Shell کپی کنید و برای اجرا، Enter را فشار دهید.**.**

gcloud config set project <<PROJECT_ID>>

ffd97bad1f398b4b.png

دستور زیر را در ترمینال Cloud Shell کپی کنید و برای اجرا Enter را فشار دهید.**.** این کار سرویس‌های لازم را فعال کرده و فایل را ایجاد و در Cloud Shell ویرایش می‌کند.

gcloud services enable compute.googleapis.com \
                       cloudresourcemanager.googleapis.com \
                       aiplatform.googleapis.com \
                       storage-component.googleapis.com  \
                       bigqueryconnection.googleapis.com \
run.googleapis.com \
secretmanager.googleapis.com \
cloudbuild.googleapis.com \
artifactregistry.googleapis.com  \
iap.googleapis.com
edit  ~/petverse-setup.sh

شما باید یک تب جدید با نام فایل ببینید. اسکریپت زیر را در فایل جدید قرار دهید:

#!/bin/bash

# -----------------------------------------------------------------------------
# 1. Global Variables: Set your desired project ID and region here.
# -----------------------------------------------------------------------------

# 🦄 🦄 Set your project ID here ⬇️.

# Example: PROJECT_ID="your-project-id"
PROJECT_ID=""

# Set your desired region here. Default is 'us-central1'.
# Example: REGION="us-east1"
REGION="us-central1"

# -----------------------------------------------------------------------------
# 2. Check and Authenticate
# -----------------------------------------------------------------------------

echo "  ➡️   Checking for active Google Cloud authentication..."

# Check if the user is authenticated; if not, prompt for authentication.
if ! gcloud auth list --format="value(account)" | grep -q @; then
  echo "⚠️   Not authenticated. Please authenticate now."
  gcloud auth login
fi

echo "  ✅   Authentication check passed."

# -----------------------------------------------------------------------------
# 3. Get Project ID from User if not set
# -----------------------------------------------------------------------------

# If PROJECT_ID is not set in the script or as an environment variable,
# prompt the user to choose one.
if [[ -z "$PROJECT_ID" ]] && [[ -n "$DEVSHELL_PROJECT_ID" ]]; then
  PROJECT_ID=$DEVSHELL_PROJECT_ID
fi

if [[ -z "$PROJECT_ID" ]]; then
  echo "  ⚠️   Project ID is not set. Listing available projects:"
 
  # List projects and store them in an array.
  projects_array=($(gcloud projects list --format="value(projectId)"))
 
  # Check if projects were found.
  if [[ ${#projects_array[@]} -eq 0 ]]; then
    echo "  ❌   No projects found. Please ensure your account has access to projects."
    exit 1
  fi
 
  # Display the projects and prompt for input.
  echo " "
  echo "Available Projects:"
  for project in "${projects_array[@]}"; do
    echo "$project"
  done
 
  echo " "
  read -p "Please enter your desired project ID from the list above: " PROJECT_ID
 
  # Validate the user's input by checking if it's in the array.
  if [[ ! " ${projects_array[@]} " =~ " ${PROJECT_ID} " ]]; then
    echo "  ❌   Invalid project ID. Please run the script again and select a valid ID."
    exit 1
  fi
fi

echo "  ✅   Project ID set to: $PROJECT_ID"

# -----------------------------------------------------------------------------
# 4. Set Environment Variables
# -----------------------------------------------------------------------------

# Set the project and region for the current session.
echo "  🔄   Setting Google Cloud configuration for this session..."
gcloud config set project "$PROJECT_ID"
gcloud config set compute/region "$REGION"

echo "  ✅   Google Cloud configuration updated."
echo "Project ID: $PROJECT_ID"
echo "Region: $REGION"
echo " "
echo "  🎉 🦄 🦄   Script execution complete. You can now use Google Cloud commands in this shell session."

به جای عبارت PROJECT_ID، نام پروژه خود را قرار دهید:

aec2195d576244dd.png

دستور زیر را کپی کرده و در ترمینال اجرا کنید:

chmod +x petverse-setup.sh
~/petverse-setup.sh

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

83d1f7405624443b.png

۵. یک سطل ذخیره‌سازی ایجاد کنید

یک سطل ذخیره‌سازی ابری ایجاد کنید و رسانه‌های موجود را در سطل خودتان کپی کنید. از این برای ذخیره رسانه‌های موجود برای حیوانات خانگی شگفت‌انگیز ما استفاده خواهید کرد. همچنین یک اتصال برای دسترسی به سطل از طریق BigQuery ایجاد خواهید کرد.

دستور زیر را در ترمینال پیست و اجرا کنید:

~/petverse-setup.sh
cd ~/
gcloud storage buckets create gs://$DEVSHELL_PROJECT_ID-petverse --uniform-bucket-level-access --location=us-central1
gcloud storage cp -r gs://sample-data-and-media/petverse/* gs://$DEVSHELL_PROJECT_ID-petverse/
bq mk --dataset --location=us-central1 --project_id=$DEVSHELL_PROJECT_ID petverse
bq mk --connection --location=us-central1 --project_id=$DEVSHELL_PROJECT_ID \
--connection_type=CLOUD_RESOURCE pet-connection
echo "your bucket is gs://$DEVSHELL_PROJECT_ID-petverse "

379f72ee2908da36.png

۶. جدول حیوانات خانگی را ایجاد کنید

اکنون یک جدول در BigQuery ایجاد خواهید کرد تا اطلاعات مربوط به حیوانات خانگی خود را ذخیره کنید.

یک تب جدید در مرورگر باز کنید . به آدرس https://console.cloud.google.com/bigquery?utm_campaign=CDR_0x6cb6c9c7_default_b533854388&utm_medium=external&utm_source=lab بروید.

مطمئن شوید که همان پروژه‌ای که استفاده کرده‌اید در کنسول انتخاب شده باشد:

f82010a317866e6.png

اکنون می‌توانید با استفاده از داده‌های موجود در فایل pets.csv یک جدول ایجاد کنید. این فایل شامل نام‌ها، غذاهای مورد علاقه، اسباب‌بازی‌ها و سایر اطلاعات جالب در مورد حیوانات خانگی ما است.

کد زیر را در یک کوئری SQL جدید کپی کنید تا یک جدول فیزیکی ایجاد شود و داده‌ها بارگذاری شوند.

LOAD DATA INTO petverse.pets
OPTIONS(
    description="Table for furry friend data"
  )
FROM FILES (
  skip_leading_rows=1,
  uris = ['gs://<<your_bucket_name>>/pets.csv'],
  format = 'CSV'
);

جای خالی مربوط به سطل را در کد با سطلی که در مرحله قبل ایجاد کرده‌اید، جایگزین کنید.

شما می‌توانید تمام فضای ذخیره‌سازی خود را در یک تب مرورگر جداگانه که به این URL اشاره دارد، بررسی کنید: https://console.cloud.google.com/storage/browser?utm_campaign=CDR_0x6cb6c9c7_default_b533854388&utm_medium=external&utm_source=lab .

757813944bb3d8ba.png

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

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

d6aab61d533bedde.png

برای مشاهده محتوای جدول، روی پیش‌نمایش کلیک کنید. 20fb1cbf8826efca.png

۷. اتصال BigQuery به Storage Bucket

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

243751f1b0aab329.gif

BigQuery قابلیت خواندن این سطل‌ها و استفاده از فایل‌ها در کنار داده‌های جداول را دارد. این نوع مقدار ObjectRef نامیده می‌شود.

با کلیک روی آن در زیر «اتصالات خارجی» ، شناسه حساب سرویس را برای اتصالی که قبلاً ایجاد کرده‌اید، دریافت کنید.

۱d9d3275483f5650.png

شناسه حساب سرویس را کپی کنید .

در یک تب جدید مرورگر ( https://console.cloud.google.com/iam-admin/ ) به کنسول مدیریت IAM بروید.

حساب کاربری سرویس را با Storage Object Viewer و Vertex AI User اعطا کنید (بعداً از این مجوز استفاده خواهید کرد).

f1ff6b305d914532.png

روی ذخیره کلیک کنید و 🕰️ چند دقیقه صبر کنید .

به تب BigQuery برگردید ، از کوئری زیر در BigQuery studio برای آزمایش ارتباط بین BigQuery و مخزن ذخیره‌سازی استفاده کنید.

به جای <<PROJECT_ID>> شناسه پروژه خود را قرار دهید.

SET @@location='us-central1';
SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/yoda_profile_picture.png', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection'))

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

9e3d986b797e413a.png

۸. رسانه ذخیره‌سازی را به داده‌های ساختاریافته خود اضافه کنید

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

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

دستورات زیر را در کنسول BigQuery SQL وارد کنید و آنها را اجرا کنید تا دو ستون به جدول pets شما اضافه شود.

SET @@location='us-central1';
ALTER TABLE petverse.pets
ADD COLUMN IF NOT EXISTS profile_picture STRUCT<uri STRING, version STRING, authorizer STRING, details JSON>,
ADD COLUMN IF NOT EXISTS additional_media ARRAY<STRUCT<uri STRING, version STRING, authorizer STRING, details JSON>>;

دستورات زیر را کپی کنید و به جای PROJECT_ID، شناسه پروژه خود را قرار دهید.

SET @@location='us-central1';

UPDATE petverse.pets
SET profile_picture = (SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/yoda_profile_picture.png', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection'))),
    additional_media = [(SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/additional_media/Yoda_asks_for_cuddles.mp4', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection')))]
WHERE Id = 1;

UPDATE petverse.pets
SET profile_picture = (SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/madonna_profile_picture.jpg', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection'))),
    additional_media = [(SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/additional_media/Madonna_description.wav', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection')))]
WHERE Id = 2;

UPDATE petverse.pets
SET profile_picture = (SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/pixel_profile_picture.png', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection'))),
    additional_media = [(SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/additional_media/pixel_thug_life.mp4', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection'))),
                       (SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/additional_media/pixel_description.wav', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection')))]
WHERE Id = 3;

UPDATE petverse.pets
SET profile_picture = (SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/sql_profile_picture.png', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection'))),
    additional_media = [(SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/additional_media/SQL_description.wav', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection'))),
                       (SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/additional_media/SQL_favorite_toy.mp4', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection')))]
WHERE Id = 4;

UPDATE petverse.pets
SET profile_picture = (SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/buddy_golden_retriever.png', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection'))),
    additional_media = NULL
WHERE Id = 5;

UPDATE petverse.pets
SET profile_picture = (SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/daisy_french_bulldog.png', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection'))),
    additional_media = NULL
WHERE Id = 6;

UPDATE petverse.pets
SET profile_picture = (SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/max_german_shepherd.png', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection'))),
    additional_media = [(SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/additional_media/max_description_tells_jokes.mp4', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection')))]
WHERE Id = 7;

UPDATE petverse.pets SET profile_picture = NULL, additional_media = NULL WHERE Id = 8;

UPDATE petverse.pets SET profile_picture = NULL, additional_media = [(SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/additional_media/rocky_description.mp4', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection')))] WHERE Id = 9;

UPDATE petverse.pets
SET profile_picture = (SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/pip_hamster.png', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection'))),
    additional_media = [(SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/additional_media/pip_Hamster_Wheel_Video_Generated.mp4', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection')))]
WHERE Id = 10;

UPDATE petverse.pets SET profile_picture = NULL, additional_media = NULL WHERE Id = 11;

UPDATE petverse.pets
SET profile_picture = (SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/scales_snake.png', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection'))),
    additional_media = NULL
WHERE Id = 12;

UPDATE petverse.pets SET profile_picture = NULL, additional_media = NULL WHERE Id = 13;

UPDATE petverse.pets
SET profile_picture = (SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/Joel_Profile_Picture.jpg', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection'))),
    additional_media = [(SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/additional_media/Joel_Catwalk.jpg', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection'))),
                       (SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/additional_media/Joel_Flowers.jpg', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection'))),
                       (SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/additional_media/Joel_Plays.jpg', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection')))]
WHERE Id = 14;

دستور را اجرا کنید. پس از چند دقیقه باید شاهد اجرای موفقیت‌آمیز دستورات باشید:

4fa3bba70440fa65.png

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

SELECT *
FROM `petverse.pets`
WHERE name = 'Pixel'

a1511d749e88d5f5.png

۹. توضیحاتی در مورد حیوانات خانگی تهیه کنید

اگر جدول حیوانات خانگی را مرور کنید، متوجه خواهید شد که برخی از حیوانات خانگی - مانند یودا، پیکسل یا راکی ​​- غذای مورد علاقه یا اسباب‌بازی مورد علاقه خود را از دست داده‌اند.

پاسخ این سوالات ممکن است در ویدیوها و فایل‌های صوتی مربوط به این حیوانات خانگی باشد. شما از توابع هوش مصنوعی تعبیه شده برای بررسی این موضوع استفاده خواهید کرد.

این را با عبارت زیر آزمایش کنید:

SELECT name,
AI.GENERATE(
   prompt=> ('What are this pet\'s favorite toy and favorite foods', additional_media ),
    connection_id => 'us-central1.pet-connection',
    endpoint => 'gemini-2.5-flash',
output_schema => 'food STRING, toy STRING')
FROM petverse.pets
WHERE name = 'Rocky'

می‌تونی ویدیوی راکی ​​رو توی سطل ذخیره‌سازی‌ات ببینی.

برای به‌روزرسانی توضیحات از دست رفته، از دستور زیر استفاده کنید:

UPDATE petverse.pets AS p
SET FavoriteFood = aigen.food
FROM
  (
    SELECT Id, name,
          AI.GENERATE(
                prompt=> ('What are this pet\'s favorite toy and favorite foods', additional_media ),
                connection_id => 'us-central1.pet-connection',
                endpoint => 'gemini-2.5-flash',
                output_schema => 'food STRING').food
    FROM petverse.pets ) AS  aigen
WHERE p.Id = aigen.Id
AND p.FavoriteFood IS NULL
AND p.additional_media IS NOT NULL

از دستور زیر برای ایجاد توضیحی در مورد حیوانات خانگی بر اساس محتوای چندرسانه‌ای آنها در یک ستون جدید استفاده کنید:

ALTER TABLE petverse.pets ADD COLUMN MediaDescription STRING;
UPDATE petverse.pets AS p
SET MediaDescription = aigen.description
FROM
  (
    SELECT Id, name,
          AI.GENERATE(
                prompt=> ('Create a description in an epic tone for this pet based on these media: ', additional_media ),
                connection_id => 'us-central1.pet-connection',
                endpoint => 'gemini-2.5-flash',
                output_schema => 'description STRING').description
    FROM petverse.pets ) AS  aigen
WHERE p.Id = aigen.Id
AND p.MediaDescription IS NULL
AND p.additional_media IS NOT NULL

بعد از چند دقیقه باید توضیحات خلاقانه‌ای ببینید:

fab3b59caa69aec7.png

۱۰. ایجاد جاسازی‌ها

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

SET @@location='us-central1';

CREATE OR REPLACE MODEL petverse.multimodalembedding
  REMOTE WITH CONNECTION `us-central1.pet-connection`
  OPTIONS(ENDPOINT = 'multimodalembedding@001');

CREATE TABLE IF NOT EXISTS petverse.profile_embeddings
AS
SELECT *
FROM ML.GENERATE_EMBEDDING(
  MODEL petverse.multimodalembedding,
    (
      SELECT profile_picture as content,
      Id
      FROM petverse.pets)
 );

CREATE OR REPLACE MODEL petverse.textembedding
  REMOTE WITH CONNECTION `us-central1.pet-connection`
  OPTIONS (ENDPOINT = 'text-embedding-005');

CREATE OR REPLACE TABLE petverse.text_embeddings AS
SELECT * FROM ML.GENERATE_EMBEDDING(
  MODEL petverse.textembedding,
  (
    SELECT CONCAT(AdoptionStory, ' . This pet\'s hobby is: ', Hobby, ' and their nickname(s) is: ', COALESCE(Nicknames, Name)) AS content,
    Id, Name
    FROM petverse.pets
    WHERE LENGTH(AdoptionStory) > 0 AND LENGTH(Hobby) > 0
  )
)
WHERE LENGTH(ml_generate_embedding_status) = 0;

جدول جدید را از تب نتایج بررسی کنید.

c9e876d75147c343.png

برای بررسی وضعیت همه جاسازی‌ها از دستور زیر استفاده کنید:

SELECT DISTINCT(ml_generate_embedding_status),
  COUNT(content.uri) AS num_rows
FROM petverse.profile_embeddings
GROUP BY 1;

اگر خطایی وجود داشته باشد ، آنها را در وضعیت غیر خالی مشاهده خواهید کرد. این خروجی صحیح است - هیچ رکوردی در وضعیت خطا وجود ندارد**:**

e6754936c31ca5cf.png

در زیر مثالی از رکوردهای دارای خطا آمده است. این موارد مورد انتظار نیستند، اما قبل از ادامه مراحل بعدی باید اصلاح شوند:

736545fbc7ce4ac8.png

به دنبال حیوانات خانگی مشابه باشید

مجموعه داده پیش‌فرض، حیوانات خانگی مشابهی دارد. در اینجا دو مثال Pixel (Id: 3) و SQL (Id: 4) آورده شده است:

cfebe01afc5f4858.png

شما می‌توانید از فاصله بین جاسازی‌ها برای محاسبه حیوانات خانگی مشابه استفاده کنید:

SELECT
t2.id AS similar_pet_id,
COSINE_DISTANCE(t1.ml_generate_embedding_result, t2.ml_generate_embedding_result) AS distance
FROM
petverse.profile_embeddings AS t1,
petverse.profile_embeddings AS t2
WHERE
t1.Id = 3 -- The pet you want to find similar ones to
AND t1.Id != t2.Id -- Exclude the pet itself from the results
AND t1.content.uri IS NOT NULL
AND t2.content.uri IS NOT NULL
ORDER BY
distance
LIMIT 5;

شما باید نتایجی با شناسه‌های تصاویر مشابه یکدیگر دریافت کنید. این شامل همه چیز در تصویر خواهد بود. در این مثال، Pixel و SQL مشابه هستند و حیوان خانگی مشابه بعدی Joel (شناسه: ۱۴) است.

99ce203add04a6b1.png

برای راهنمایی بیشتر، عکس جوئل را در اینجا می‌بینید:

f78e0ca0fe235ba2.png

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

SELECT query.query, base.content, base.Name
FROM VECTOR_SEARCH(
  TABLE `petverse.text_embeddings`, 'ml_generate_embedding_result',
  (
  SELECT ml_generate_embedding_result, content AS query
  FROM ML.GENERATE_EMBEDDING(
  MODEL `petverse.textembedding`,
  (SELECT 'Pets who like to relax' AS content))
  ),
  top_k => 5, options => '{"fraction_lists_to_search": 0.50}')
ORDER BY distance DESC

سعی کنید عبارت جستجوی معنایی ( Pets who like to relax ) و همچنین پارامتر fraction_lists_to_search را تغییر دهید و ببینید چه اتفاقی می‌افتد. می‌توانید اطلاعات بیشتری در مورد این توابع را اینجا بیابید.

۱۱. کد وایب برای صفحه پروفایل

شما از رابط خط فرمان Gemini در Cloud Shell برای شروع یک برنامه وب ساده و آزمایشی استفاده خواهید کرد. این برنامه وب در قسمت اعلان خود ساده‌سازی شده است تا نشان دهد که چگونه Petverse می‌تواند به واقعیت تبدیل شود.

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

b5061fb060f2a958.png

اسکریپت مقداردهی اولیه را اجرا کنید تا مطمئن شوید متغیرهای محیطی تنظیم شده‌اند، یک دایرکتوری برای قرار دادن این پروژه ایجاد کنید و Gemini CLI را اجرا کنید:

~/petverse-setup.sh
mkdir petverse-profiles
cd petverse-profiles
gemini

شما باید CLI مربوط به Gemini را ببینید:

910fda2312082974.png

نام سطل را در اعلان زیر جایگزین کنید.

دستور را در خط فرمان Gemini پیست کنید.

You are a fullstack engineer creating an application to display the profiles of cats, dogs and other pets stored in BigQuery. The table where these are stored is called pets, in the dataset petverse.
1.Application Requirements: Display the pets with their profile picture, all the other information in the Pets table, and other media that may be available. The pictures are in a GCS bucket, the field in the table pets profile_picture.uri contains the URI for the storage bucket of that profile picture.  The field additional_media is an array of objectref that contains multiple URI to different media stored in a GCS bucket.
Important: In the code, in the values for the URIs retrieved from BigQuery, replace gs://<<YOUR_PROJECT_ID>>-petverse/ with https://storage.mtls.cloud.google.com/<<YOUR_PROJECT_ID>>-petverse/ as follows: replace('gs://', 'https://storage.mtls.cloud.google.com/'). Use the python library. Media can be pictures, videos and audio. Consider these formats in the code. Some pets may not have profile pictures or additional media.
2.Hosting: Create a web application hosted in a single container and service in Cloud Run, use the following syntax to deploy it using IAP. IMPORTANT: DO NOT ADD IAM AUTHENTICATION AND DO NOT ALLOW UNAUTHENTICATED: gcloud beta run deploy SERVICE_NAME  --region=REGION --image=IMAGE_URL  --no-allow-unauthenticated --iap
3.Database access: Display similar pets based on a similarity between embeddings in table petverse.profile_embeddings. 
Here's the schema for the pets table in CSV format (Field name, type, mode):
Id,INTEGER,NULLABLE
Name,STRING,NULLABLE
Species,STRING,NULLABLE
Breed,STRING,NULLABLE
Nationality,STRING,NULLABLE
Nicknames,STRING,NULLABLE
Hobby,STRING,NULLABLE
AdoptionStory,STRING,NULLABLE
FavoriteFood,STRING,NULLABLE
FavoriteToy,STRING,NULLABLE
profile_picture,RECORD,NULLABLE
additional_media,RECORD,REPEATED
profile_embeddings,FLOAT,REPEATED
Here's a sample query to check for similarity:
SELECT
t2.id AS similar_pet_id,
COSINE_DISTANCE(t1.ml_generate_embedding_result, t2.ml_generate_embedding_result) AS distance
FROM
petverse.profile_embeddings AS t1,
petverse.profile_embeddings AS t2
WHERE
t1.Id = 3 -- The pet you want to find similar ones to
AND t1.Id != t2.Id -- Exclude the pet itself from the results
AND t1.content.uri IS NOT NULL
AND t2.content.uri IS NOT NULL
ORDER BY
distance
LIMIT 5;
Complement the profile of each pet with a description. Here's an example of the access to such table:
SELECT Name, MediaDescription from petverse.pets;
4.For each access to BigQuery, show the SQL statement that is used in the console logs.
5.Search functionality: Add a search bar for a semantic search for pets. There's a text embedding for the Adoption story, the pet's past-time or hobby and their nicknames in the table: petverse.text_embeddings . This is a sample of semantic search:
SELECT query.query, base.content, base.Name FROM VECTOR_SEARCH(TABLE `petverse.text_embeddings`, 'ml_generate_embedding_result', ( SELECT ml_generate_embedding_result, content AS query FROM ML.GENERATE_EMBEDDING(MODEL `petverse.textembedding`,(SELECT 'Pets who like to relax' AS content))), top_k => 5, options => '{"fraction_lists_to_search": 0.50}') ORDER BY distance DESC
6.Use Python for the backend. Generate the deployment scripts for an authenticated service using IAP with the flags --no-allow-unauthenticated --iap
7. Make the UI look like a modern art museum.
8. Use the gunicorn library. Validate version dependencies.

این ماجراجویی شماست. در طول مسیر، برنامه‌ای به شما نشان داده می‌شود و از شما خواسته می‌شود که آن را تأیید کنید.

خیلی بعید است که کد و پیاده‌سازی تولید شده در اولین تلاش کار کند. شما باید با Gemini CLI آنقدر کار کنید تا درست شود.

اگر دیدید که فرآیند در یک حلقه گیر کرده است، آن را با CTRL/Command + C متوقف کنید، مشکل را بررسی کنید و دوباره آن را اجرا کنید.

47d6e394fc4f5b60.png

توصیه می‌کنیم هر یک از تأییدیه‌ها را با دقت و یکی یکی بخوانید تا بفهمید CLI چه کاری انجام خواهد داد:

6a62b9c077d4cd11.png

بعد از چند دقیقه، برنامه باید آماده اجرا باشد. ممکن است به نظر برسد که کنسول گیر کرده است:

ca51ecf7b1ce08bf.png

می‌توانید به صورت دستی برنامه را در یک تب جدید Cloud Shell با gunicorn امتحان کنید. مطمئن شوید که پروژه تنظیم شده است:

f0ee1095386f7ec.png

شما باید سایت جدید خود را ببینید (ممکن است با این متفاوت باشد). اگر چیزی کار نمی‌کند، باید بتوانید گزارش‌های خطا و اشکال‌زدایی را در خط فرمان Cloud Shell که به صورت محلی اجرا می‌شود، مشاهده کنید.

27bf3e2a8d429169.gif

اگر همه چیز خوب به نظر برسد، می‌توانید به صورت اختیاری برنامه را در Cloud Run مستقر کنید.

اگر پروژه شما متعلق به یک سازمان است، مطمئن شوید که IAP را طبق این دستورالعمل‌ها پیکربندی می‌کنید. اگر پروژه شما بخشی از یک سازمان نیست، می‌توانید به جای آن از این دستورالعمل‌ها برای ایمن‌سازی دسترسی به برنامه خود پیروی کنید. به خصوص برای تنظیمات تولید، توصیه می‌کنیم دسترسی غیرمجاز را مجاز نکنید.

۲۳۶۵a۹۰ac۶a۷d۴e۵.png

با فرض اینکه استقرار (deployment) به درستی انجام شود، باید اجرای برنامه Cloud Run را در کنسول Cloud Run مشاهده کنید.

مطمئن شوید که دسترسی فقط IAP است. از Edit Policy برای اضافه کردن کاربر خود به binding استفاده کنید و آن را ذخیره کنید .

چند دقیقه صبر کنید تا اتصالات IAP منتشر شوند و سپس روی URL در بالا کلیک کنید. سایت باید ظاهر شود.

3943c556ba912466.png

۱۲. تمیز کردن

این مرحله شما را در حذف منابع ایجاد شده در این آزمایشگاه کد راهنمایی می‌کند.

سرویس Cloud Run را حذف کنید (نام سرویس‌ها و منطقه را در صورت نیاز تغییر دهید):

gcloud run services delete petverse-profiles --region us-central1

حذف تمام فایل‌های BigQuery:

bq rm -f petverse
gcloud bigquery connections delete pet-connection --location=us-central1
،

۱. مقدمه

به دنیای حیوانات خانگی خوش آمدید! ورود همه حیوانات خانگی آزاد است! 🐈🐶🐍🐟🦄

پیش‌نیازها

  • آشنایی اولیه با کنسول ابری گوگل
  • درک اولیه از دستورات SQL

آنچه یاد خواهید گرفت

  • ایجاد مجموعه داده‌ها و جداول در BigQuery
  • ستون‌های ObjectRef را برای ارجاع به چندرسانه‌ای در یک سطل ذخیره‌سازی در BigQuery ایجاد کنید
  • از توابع هوش مصنوعی در BigQuery برای بهبود مجموعه داده‌های خود از محتوای داده‌های بدون ساختار استفاده کنید.
  • برای جستجوی رسانه‌های مشابه، جاسازی‌های چندرسانه‌ای ایجاد کنید
  • ایجاد جاسازی‌های متنی برای انجام جستجوی معنایی با VECTOR_SEARCH
  • استفاده از رابط خط فرمان Gemini برای ایجاد یک برنامه وب

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

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

۲. تنظیمات و الزامات

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

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

fbef9caa1602edd0.pnga99b7ace416376c4.png5e3ff691252acf41.png

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

۳. پوسته ابری را باز کنید

به آدرس https://shell.cloud.google.com/?show=ide%2Cterminal بروید. وقتی از شما خواسته شد، روی «مجوز دادن» کلیک کنید.

1bfca4be2c270a9f.png

مطمئن شوید که هم ویرایشگر و هم کنسول قابل مشاهده هستند:

785d186a8b11b32b.png

۴. یک اسکریپت کمکی ایجاد کنید

برای روان‌تر کردن این تجربه، یک اسکریپت کمکی ایجاد خواهید کرد که متغیرهای محیطی مربوطه را تنظیم می‌کند.

به جای <<شناسه پروژه>>، شناسه پروژه خود را در زیر قرار دهید.

دستور زیر را در ترمینال Cloud Shell کپی کنید و برای اجرا، Enter را فشار دهید.**.**

gcloud config set project <<PROJECT_ID>>

ffd97bad1f398b4b.png

دستور زیر را در ترمینال Cloud Shell کپی کنید و برای اجرا Enter را فشار دهید.**.** این کار سرویس‌های لازم را فعال کرده و فایل را ایجاد و در Cloud Shell ویرایش می‌کند.

gcloud services enable compute.googleapis.com \
                       cloudresourcemanager.googleapis.com \
                       aiplatform.googleapis.com \
                       storage-component.googleapis.com  \
                       bigqueryconnection.googleapis.com \
run.googleapis.com \
secretmanager.googleapis.com \
cloudbuild.googleapis.com \
artifactregistry.googleapis.com  \
iap.googleapis.com
edit  ~/petverse-setup.sh

شما باید یک تب جدید با نام فایل ببینید. اسکریپت زیر را در فایل جدید قرار دهید:

#!/bin/bash

# -----------------------------------------------------------------------------
# 1. Global Variables: Set your desired project ID and region here.
# -----------------------------------------------------------------------------

# 🦄 🦄 Set your project ID here ⬇️.

# Example: PROJECT_ID="your-project-id"
PROJECT_ID=""

# Set your desired region here. Default is 'us-central1'.
# Example: REGION="us-east1"
REGION="us-central1"

# -----------------------------------------------------------------------------
# 2. Check and Authenticate
# -----------------------------------------------------------------------------

echo "  ➡️   Checking for active Google Cloud authentication..."

# Check if the user is authenticated; if not, prompt for authentication.
if ! gcloud auth list --format="value(account)" | grep -q @; then
  echo "⚠️   Not authenticated. Please authenticate now."
  gcloud auth login
fi

echo "  ✅   Authentication check passed."

# -----------------------------------------------------------------------------
# 3. Get Project ID from User if not set
# -----------------------------------------------------------------------------

# If PROJECT_ID is not set in the script or as an environment variable,
# prompt the user to choose one.
if [[ -z "$PROJECT_ID" ]] && [[ -n "$DEVSHELL_PROJECT_ID" ]]; then
  PROJECT_ID=$DEVSHELL_PROJECT_ID
fi

if [[ -z "$PROJECT_ID" ]]; then
  echo "  ⚠️   Project ID is not set. Listing available projects:"
 
  # List projects and store them in an array.
  projects_array=($(gcloud projects list --format="value(projectId)"))
 
  # Check if projects were found.
  if [[ ${#projects_array[@]} -eq 0 ]]; then
    echo "  ❌   No projects found. Please ensure your account has access to projects."
    exit 1
  fi
 
  # Display the projects and prompt for input.
  echo " "
  echo "Available Projects:"
  for project in "${projects_array[@]}"; do
    echo "$project"
  done
 
  echo " "
  read -p "Please enter your desired project ID from the list above: " PROJECT_ID
 
  # Validate the user's input by checking if it's in the array.
  if [[ ! " ${projects_array[@]} " =~ " ${PROJECT_ID} " ]]; then
    echo "  ❌   Invalid project ID. Please run the script again and select a valid ID."
    exit 1
  fi
fi

echo "  ✅   Project ID set to: $PROJECT_ID"

# -----------------------------------------------------------------------------
# 4. Set Environment Variables
# -----------------------------------------------------------------------------

# Set the project and region for the current session.
echo "  🔄   Setting Google Cloud configuration for this session..."
gcloud config set project "$PROJECT_ID"
gcloud config set compute/region "$REGION"

echo "  ✅   Google Cloud configuration updated."
echo "Project ID: $PROJECT_ID"
echo "Region: $REGION"
echo " "
echo "  🎉 🦄 🦄   Script execution complete. You can now use Google Cloud commands in this shell session."

به جای عبارت PROJECT_ID، نام پروژه خود را قرار دهید:

aec2195d576244dd.png

دستور زیر را کپی کرده و در ترمینال اجرا کنید:

chmod +x petverse-setup.sh
~/petverse-setup.sh

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

83d1f7405624443b.png

۵. یک سطل ذخیره‌سازی ایجاد کنید

یک سطل ذخیره‌سازی ابری ایجاد کنید و رسانه‌های موجود را در سطل خودتان کپی کنید. از این برای ذخیره رسانه‌های موجود برای حیوانات خانگی شگفت‌انگیز ما استفاده خواهید کرد. همچنین یک اتصال برای دسترسی به سطل از طریق BigQuery ایجاد خواهید کرد.

دستور زیر را در ترمینال پیست و اجرا کنید:

~/petverse-setup.sh
cd ~/
gcloud storage buckets create gs://$DEVSHELL_PROJECT_ID-petverse --uniform-bucket-level-access --location=us-central1
gcloud storage cp -r gs://sample-data-and-media/petverse/* gs://$DEVSHELL_PROJECT_ID-petverse/
bq mk --dataset --location=us-central1 --project_id=$DEVSHELL_PROJECT_ID petverse
bq mk --connection --location=us-central1 --project_id=$DEVSHELL_PROJECT_ID \
--connection_type=CLOUD_RESOURCE pet-connection
echo "your bucket is gs://$DEVSHELL_PROJECT_ID-petverse "

379f72ee2908da36.png

۶. جدول حیوانات خانگی را ایجاد کنید

اکنون یک جدول در BigQuery ایجاد خواهید کرد تا اطلاعات مربوط به حیوانات خانگی خود را ذخیره کنید.

یک تب جدید در مرورگر باز کنید . به آدرس https://console.cloud.google.com/bigquery?utm_campaign=CDR_0x6cb6c9c7_default_b533854388&utm_medium=external&utm_source=lab بروید.

مطمئن شوید که همان پروژه‌ای که استفاده کرده‌اید در کنسول انتخاب شده باشد:

f82010a317866e6.png

اکنون می‌توانید با استفاده از داده‌های موجود در فایل pets.csv یک جدول ایجاد کنید. این فایل شامل نام‌ها، غذاهای مورد علاقه، اسباب‌بازی‌ها و سایر اطلاعات جالب در مورد حیوانات خانگی ما است.

کد زیر را در یک کوئری SQL جدید کپی کنید تا یک جدول فیزیکی ایجاد شود و داده‌ها بارگذاری شوند.

LOAD DATA INTO petverse.pets
OPTIONS(
    description="Table for furry friend data"
  )
FROM FILES (
  skip_leading_rows=1,
  uris = ['gs://<<your_bucket_name>>/pets.csv'],
  format = 'CSV'
);

جای خالی مربوط به سطل را در کد با سطلی که در مرحله قبل ایجاد کرده‌اید، جایگزین کنید.

شما می‌توانید تمام فضای ذخیره‌سازی خود را در یک تب مرورگر جداگانه که به این URL اشاره دارد، بررسی کنید: https://console.cloud.google.com/storage/browser?utm_campaign=CDR_0x6cb6c9c7_default_b533854388&utm_medium=external&utm_source=lab .

757813944bb3d8ba.png

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

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

d6aab61d533bedde.png

برای مشاهده محتوای جدول، روی پیش‌نمایش کلیک کنید. 20fb1cbf8826efca.png

۷. اتصال BigQuery به Storage Bucket

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

243751f1b0aab329.gif

BigQuery قابلیت خواندن این سطل‌ها و استفاده از فایل‌ها در کنار داده‌های جداول را دارد. این نوع مقدار ObjectRef نامیده می‌شود.

با کلیک روی آن در زیر «اتصالات خارجی» ، شناسه حساب سرویس را برای اتصالی که قبلاً ایجاد کرده‌اید، دریافت کنید.

۱d9d3275483f5650.png

شناسه حساب سرویس را کپی کنید .

در یک تب جدید مرورگر ( https://console.cloud.google.com/iam-admin/ ) به کنسول مدیریت IAM بروید.

حساب کاربری سرویس را با Storage Object Viewer و Vertex AI User اعطا کنید (بعداً از این مجوز استفاده خواهید کرد).

f1ff6b305d914532.png

روی ذخیره کلیک کنید و 🕰️ چند دقیقه صبر کنید .

به تب BigQuery برگردید ، از کوئری زیر در BigQuery studio برای آزمایش ارتباط بین BigQuery و مخزن ذخیره‌سازی استفاده کنید.

به جای <<PROJECT_ID>> شناسه پروژه خود را قرار دهید.

SET @@location='us-central1';
SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/yoda_profile_picture.png', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection'))

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

9e3d986b797e413a.png

۸. رسانه ذخیره‌سازی را به داده‌های ساختاریافته خود اضافه کنید

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

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

دستورات زیر را در کنسول BigQuery SQL وارد کنید و آنها را اجرا کنید تا دو ستون به جدول pets شما اضافه شود.

SET @@location='us-central1';
ALTER TABLE petverse.pets
ADD COLUMN IF NOT EXISTS profile_picture STRUCT<uri STRING, version STRING, authorizer STRING, details JSON>,
ADD COLUMN IF NOT EXISTS additional_media ARRAY<STRUCT<uri STRING, version STRING, authorizer STRING, details JSON>>;

دستورات زیر را کپی کنید و به جای PROJECT_ID، شناسه پروژه خود را قرار دهید.

SET @@location='us-central1';

UPDATE petverse.pets
SET profile_picture = (SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/yoda_profile_picture.png', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection'))),
    additional_media = [(SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/additional_media/Yoda_asks_for_cuddles.mp4', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection')))]
WHERE Id = 1;

UPDATE petverse.pets
SET profile_picture = (SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/madonna_profile_picture.jpg', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection'))),
    additional_media = [(SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/additional_media/Madonna_description.wav', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection')))]
WHERE Id = 2;

UPDATE petverse.pets
SET profile_picture = (SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/pixel_profile_picture.png', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection'))),
    additional_media = [(SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/additional_media/pixel_thug_life.mp4', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection'))),
                       (SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/additional_media/pixel_description.wav', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection')))]
WHERE Id = 3;

UPDATE petverse.pets
SET profile_picture = (SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/sql_profile_picture.png', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection'))),
    additional_media = [(SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/additional_media/SQL_description.wav', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection'))),
                       (SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/additional_media/SQL_favorite_toy.mp4', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection')))]
WHERE Id = 4;

UPDATE petverse.pets
SET profile_picture = (SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/buddy_golden_retriever.png', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection'))),
    additional_media = NULL
WHERE Id = 5;

UPDATE petverse.pets
SET profile_picture = (SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/daisy_french_bulldog.png', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection'))),
    additional_media = NULL
WHERE Id = 6;

UPDATE petverse.pets
SET profile_picture = (SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/max_german_shepherd.png', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection'))),
    additional_media = [(SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/additional_media/max_description_tells_jokes.mp4', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection')))]
WHERE Id = 7;

UPDATE petverse.pets SET profile_picture = NULL, additional_media = NULL WHERE Id = 8;

UPDATE petverse.pets SET profile_picture = NULL, additional_media = [(SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/additional_media/rocky_description.mp4', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection')))] WHERE Id = 9;

UPDATE petverse.pets
SET profile_picture = (SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/pip_hamster.png', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection'))),
    additional_media = [(SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/additional_media/pip_Hamster_Wheel_Video_Generated.mp4', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection')))]
WHERE Id = 10;

UPDATE petverse.pets SET profile_picture = NULL, additional_media = NULL WHERE Id = 11;

UPDATE petverse.pets
SET profile_picture = (SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/scales_snake.png', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection'))),
    additional_media = NULL
WHERE Id = 12;

UPDATE petverse.pets SET profile_picture = NULL, additional_media = NULL WHERE Id = 13;

UPDATE petverse.pets
SET profile_picture = (SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/Joel_Profile_Picture.jpg', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection'))),
    additional_media = [(SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/additional_media/Joel_Catwalk.jpg', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection'))),
                       (SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/additional_media/Joel_Flowers.jpg', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection'))),
                       (SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/additional_media/Joel_Plays.jpg', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection')))]
WHERE Id = 14;

دستور را اجرا کنید. پس از چند دقیقه باید شاهد اجرای موفقیت‌آمیز دستورات باشید:

4fa3bba70440fa65.png

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

SELECT *
FROM `petverse.pets`
WHERE name = 'Pixel'

a1511d749e88d5f5.png

۹. توضیحاتی در مورد حیوانات خانگی تهیه کنید

اگر جدول حیوانات خانگی را مرور کنید، متوجه خواهید شد که برخی از حیوانات خانگی - مانند یودا، پیکسل یا راکی ​​- غذای مورد علاقه یا اسباب‌بازی مورد علاقه خود را از دست داده‌اند.

پاسخ این سوالات ممکن است در ویدیوها و فایل‌های صوتی مربوط به این حیوانات خانگی باشد. شما از توابع هوش مصنوعی تعبیه شده برای بررسی این موضوع استفاده خواهید کرد.

این را با عبارت زیر آزمایش کنید:

SELECT name,
AI.GENERATE(
   prompt=> ('What are this pet\'s favorite toy and favorite foods', additional_media ),
    connection_id => 'us-central1.pet-connection',
    endpoint => 'gemini-2.5-flash',
output_schema => 'food STRING, toy STRING')
FROM petverse.pets
WHERE name = 'Rocky'

می‌تونی ویدیوی راکی ​​رو توی سطل ذخیره‌سازی‌ات ببینی.

برای به‌روزرسانی توضیحات از دست رفته، از دستور زیر استفاده کنید:

UPDATE petverse.pets AS p
SET FavoriteFood = aigen.food
FROM
  (
    SELECT Id, name,
          AI.GENERATE(
                prompt=> ('What are this pet\'s favorite toy and favorite foods', additional_media ),
                connection_id => 'us-central1.pet-connection',
                endpoint => 'gemini-2.5-flash',
                output_schema => 'food STRING').food
    FROM petverse.pets ) AS  aigen
WHERE p.Id = aigen.Id
AND p.FavoriteFood IS NULL
AND p.additional_media IS NOT NULL

از دستور زیر برای ایجاد توضیحی در مورد حیوانات خانگی بر اساس محتوای چندرسانه‌ای آنها در یک ستون جدید استفاده کنید:

ALTER TABLE petverse.pets ADD COLUMN MediaDescription STRING;
UPDATE petverse.pets AS p
SET MediaDescription = aigen.description
FROM
  (
    SELECT Id, name,
          AI.GENERATE(
                prompt=> ('Create a description in an epic tone for this pet based on these media: ', additional_media ),
                connection_id => 'us-central1.pet-connection',
                endpoint => 'gemini-2.5-flash',
                output_schema => 'description STRING').description
    FROM petverse.pets ) AS  aigen
WHERE p.Id = aigen.Id
AND p.MediaDescription IS NULL
AND p.additional_media IS NOT NULL

بعد از چند دقیقه باید توضیحات خلاقانه‌ای ببینید:

fab3b59caa69aec7.png

۱۰. ایجاد جاسازی‌ها

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

SET @@location='us-central1';

CREATE OR REPLACE MODEL petverse.multimodalembedding
  REMOTE WITH CONNECTION `us-central1.pet-connection`
  OPTIONS(ENDPOINT = 'multimodalembedding@001');

CREATE TABLE IF NOT EXISTS petverse.profile_embeddings
AS
SELECT *
FROM ML.GENERATE_EMBEDDING(
  MODEL petverse.multimodalembedding,
    (
      SELECT profile_picture as content,
      Id
      FROM petverse.pets)
 );

CREATE OR REPLACE MODEL petverse.textembedding
  REMOTE WITH CONNECTION `us-central1.pet-connection`
  OPTIONS (ENDPOINT = 'text-embedding-005');

CREATE OR REPLACE TABLE petverse.text_embeddings AS
SELECT * FROM ML.GENERATE_EMBEDDING(
  MODEL petverse.textembedding,
  (
    SELECT CONCAT(AdoptionStory, ' . This pet\'s hobby is: ', Hobby, ' and their nickname(s) is: ', COALESCE(Nicknames, Name)) AS content,
    Id, Name
    FROM petverse.pets
    WHERE LENGTH(AdoptionStory) > 0 AND LENGTH(Hobby) > 0
  )
)
WHERE LENGTH(ml_generate_embedding_status) = 0;

جدول جدید را از تب نتایج بررسی کنید.

c9e876d75147c343.png

برای بررسی وضعیت همه جاسازی‌ها از دستور زیر استفاده کنید:

SELECT DISTINCT(ml_generate_embedding_status),
  COUNT(content.uri) AS num_rows
FROM petverse.profile_embeddings
GROUP BY 1;

اگر خطایی وجود داشته باشد ، آنها را در وضعیت غیر خالی مشاهده خواهید کرد. این خروجی صحیح است - هیچ رکوردی در وضعیت خطا وجود ندارد**:**

e6754936c31ca5cf.png

در زیر مثالی از رکوردهای دارای خطا آمده است. این موارد مورد انتظار نیستند، اما قبل از ادامه مراحل بعدی باید اصلاح شوند:

736545fbc7ce4ac8.png

به دنبال حیوانات خانگی مشابه باشید

مجموعه داده پیش‌فرض، حیوانات خانگی مشابهی دارد. در اینجا دو مثال Pixel (Id: 3) و SQL (Id: 4) آورده شده است:

cfebe01afc5f4858.png

شما می‌توانید از فاصله بین جاسازی‌ها برای محاسبه حیوانات خانگی مشابه استفاده کنید:

SELECT
t2.id AS similar_pet_id,
COSINE_DISTANCE(t1.ml_generate_embedding_result, t2.ml_generate_embedding_result) AS distance
FROM
petverse.profile_embeddings AS t1,
petverse.profile_embeddings AS t2
WHERE
t1.Id = 3 -- The pet you want to find similar ones to
AND t1.Id != t2.Id -- Exclude the pet itself from the results
AND t1.content.uri IS NOT NULL
AND t2.content.uri IS NOT NULL
ORDER BY
distance
LIMIT 5;

شما باید نتایجی با شناسه‌های تصاویر مشابه یکدیگر دریافت کنید. این شامل همه چیز در تصویر خواهد بود. در این مثال، Pixel و SQL مشابه هستند و حیوان خانگی مشابه بعدی Joel (شناسه: ۱۴) است.

99ce203add04a6b1.png

برای راهنمایی بیشتر، عکس جوئل را در اینجا می‌بینید:

f78e0ca0fe235ba2.png

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

SELECT query.query, base.content, base.Name
FROM VECTOR_SEARCH(
  TABLE `petverse.text_embeddings`, 'ml_generate_embedding_result',
  (
  SELECT ml_generate_embedding_result, content AS query
  FROM ML.GENERATE_EMBEDDING(
  MODEL `petverse.textembedding`,
  (SELECT 'Pets who like to relax' AS content))
  ),
  top_k => 5, options => '{"fraction_lists_to_search": 0.50}')
ORDER BY distance DESC

سعی کنید عبارت جستجوی معنایی ( Pets who like to relax ) و همچنین پارامتر fraction_lists_to_search را تغییر دهید و ببینید چه اتفاقی می‌افتد. می‌توانید اطلاعات بیشتری در مورد این توابع را اینجا بیابید.

۱۱. کد وایب برای صفحه پروفایل

شما از رابط خط فرمان Gemini در Cloud Shell برای شروع یک برنامه وب ساده و آزمایشی استفاده خواهید کرد. این برنامه وب در قسمت اعلان خود ساده‌سازی شده است تا نشان دهد که چگونه Petverse می‌تواند به واقعیت تبدیل شود.

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

b5061fb060f2a958.png

اسکریپت مقداردهی اولیه را اجرا کنید تا مطمئن شوید متغیرهای محیطی تنظیم شده‌اند، یک دایرکتوری برای قرار دادن این پروژه ایجاد کنید و Gemini CLI را اجرا کنید:

~/petverse-setup.sh
mkdir petverse-profiles
cd petverse-profiles
gemini

شما باید CLI مربوط به Gemini را ببینید:

910fda2312082974.png

نام سطل را در اعلان زیر جایگزین کنید.

دستور را در خط فرمان Gemini پیست کنید.

You are a fullstack engineer creating an application to display the profiles of cats, dogs and other pets stored in BigQuery. The table where these are stored is called pets, in the dataset petverse.
1.Application Requirements: Display the pets with their profile picture, all the other information in the Pets table, and other media that may be available. The pictures are in a GCS bucket, the field in the table pets profile_picture.uri contains the URI for the storage bucket of that profile picture.  The field additional_media is an array of objectref that contains multiple URI to different media stored in a GCS bucket.
Important: In the code, in the values for the URIs retrieved from BigQuery, replace gs://<<YOUR_PROJECT_ID>>-petverse/ with https://storage.mtls.cloud.google.com/<<YOUR_PROJECT_ID>>-petverse/ as follows: replace('gs://', 'https://storage.mtls.cloud.google.com/'). Use the python library. Media can be pictures, videos and audio. Consider these formats in the code. Some pets may not have profile pictures or additional media.
2.Hosting: Create a web application hosted in a single container and service in Cloud Run, use the following syntax to deploy it using IAP. IMPORTANT: DO NOT ADD IAM AUTHENTICATION AND DO NOT ALLOW UNAUTHENTICATED: gcloud beta run deploy SERVICE_NAME  --region=REGION --image=IMAGE_URL  --no-allow-unauthenticated --iap
3.Database access: Display similar pets based on a similarity between embeddings in table petverse.profile_embeddings. 
Here's the schema for the pets table in CSV format (Field name, type, mode):
Id,INTEGER,NULLABLE
Name,STRING,NULLABLE
Species,STRING,NULLABLE
Breed,STRING,NULLABLE
Nationality,STRING,NULLABLE
Nicknames,STRING,NULLABLE
Hobby,STRING,NULLABLE
AdoptionStory,STRING,NULLABLE
FavoriteFood,STRING,NULLABLE
FavoriteToy,STRING,NULLABLE
profile_picture,RECORD,NULLABLE
additional_media,RECORD,REPEATED
profile_embeddings,FLOAT,REPEATED
Here's a sample query to check for similarity:
SELECT
t2.id AS similar_pet_id,
COSINE_DISTANCE(t1.ml_generate_embedding_result, t2.ml_generate_embedding_result) AS distance
FROM
petverse.profile_embeddings AS t1,
petverse.profile_embeddings AS t2
WHERE
t1.Id = 3 -- The pet you want to find similar ones to
AND t1.Id != t2.Id -- Exclude the pet itself from the results
AND t1.content.uri IS NOT NULL
AND t2.content.uri IS NOT NULL
ORDER BY
distance
LIMIT 5;
Complement the profile of each pet with a description. Here's an example of the access to such table:
SELECT Name, MediaDescription from petverse.pets;
4.For each access to BigQuery, show the SQL statement that is used in the console logs.
5.Search functionality: Add a search bar for a semantic search for pets. There's a text embedding for the Adoption story, the pet's past-time or hobby and their nicknames in the table: petverse.text_embeddings . This is a sample of semantic search:
SELECT query.query, base.content, base.Name FROM VECTOR_SEARCH(TABLE `petverse.text_embeddings`, 'ml_generate_embedding_result', ( SELECT ml_generate_embedding_result, content AS query FROM ML.GENERATE_EMBEDDING(MODEL `petverse.textembedding`,(SELECT 'Pets who like to relax' AS content))), top_k => 5, options => '{"fraction_lists_to_search": 0.50}') ORDER BY distance DESC
6.Use Python for the backend. Generate the deployment scripts for an authenticated service using IAP with the flags --no-allow-unauthenticated --iap
7. Make the UI look like a modern art museum.
8. Use the gunicorn library. Validate version dependencies.

این ماجراجویی شماست. در طول مسیر، برنامه‌ای به شما نشان داده می‌شود و از شما خواسته می‌شود که آن را تأیید کنید.

خیلی بعید است که کد و پیاده‌سازی تولید شده در اولین تلاش کار کند. شما باید با Gemini CLI آنقدر کار کنید تا درست شود.

اگر دیدید که فرآیند در یک حلقه گیر کرده است، آن را با CTRL/Command + C متوقف کنید، مشکل را بررسی کنید و دوباره آن را اجرا کنید.

47d6e394fc4f5b60.png

توصیه می‌کنیم هر یک از تأییدیه‌ها را با دقت و یکی یکی بخوانید تا بفهمید CLI چه کاری انجام خواهد داد:

6a62b9c077d4cd11.png

بعد از چند دقیقه، برنامه باید آماده اجرا باشد. ممکن است به نظر برسد که کنسول گیر کرده است:

ca51ecf7b1ce08bf.png

می‌توانید به صورت دستی برنامه را در یک تب جدید Cloud Shell با gunicorn امتحان کنید. مطمئن شوید که پروژه تنظیم شده است:

f0ee1095386f7ec.png

شما باید سایت جدید خود را ببینید (ممکن است با این متفاوت باشد). اگر چیزی کار نمی‌کند، باید بتوانید گزارش‌های خطا و اشکال‌زدایی را در خط فرمان Cloud Shell که به صورت محلی اجرا می‌شود، مشاهده کنید.

27bf3e2a8d429169.gif

اگر همه چیز خوب به نظر برسد، می‌توانید به صورت اختیاری برنامه را در Cloud Run مستقر کنید.

اگر پروژه شما متعلق به یک سازمان است، مطمئن شوید که IAP را طبق این دستورالعمل‌ها پیکربندی می‌کنید. اگر پروژه شما بخشی از یک سازمان نیست، می‌توانید به جای آن از این دستورالعمل‌ها برای ایمن‌سازی دسترسی به برنامه خود پیروی کنید. به خصوص برای تنظیمات تولید، توصیه می‌کنیم دسترسی غیرمجاز را مجاز نکنید.

۲۳۶۵a۹۰ac۶a۷d۴e۵.png

با فرض اینکه استقرار (deployment) به درستی انجام شود، باید اجرای برنامه Cloud Run را در کنسول Cloud Run مشاهده کنید.

مطمئن شوید که دسترسی فقط IAP است. از Edit Policy برای اضافه کردن کاربر خود به binding استفاده کنید و آن را ذخیره کنید .

چند دقیقه صبر کنید تا اتصالات IAP منتشر شوند و سپس روی URL در بالا کلیک کنید. سایت باید ظاهر شود.

3943c556ba912466.png

۱۲. تمیز کردن

این مرحله شما را در حذف منابع ایجاد شده در این آزمایشگاه کد راهنمایی می‌کند.

سرویس Cloud Run را حذف کنید (نام سرویس‌ها و منطقه را در صورت نیاز تغییر دهید):

gcloud run services delete petverse-profiles --region us-central1

حذف تمام فایل‌های BigQuery:

bq rm -f petverse
gcloud bigquery connections delete pet-connection --location=us-central1
،

۱. مقدمه

به دنیای حیوانات خانگی خوش آمدید! ورود همه حیوانات خانگی آزاد است! 🐈🐶🐍🐟🦄

پیش‌نیازها

  • آشنایی اولیه با کنسول ابری گوگل
  • درک اولیه از دستورات SQL

آنچه یاد خواهید گرفت

  • ایجاد مجموعه داده‌ها و جداول در BigQuery
  • ستون‌های ObjectRef را برای ارجاع به چندرسانه‌ای در یک سطل ذخیره‌سازی در BigQuery ایجاد کنید
  • از توابع هوش مصنوعی در BigQuery برای بهبود مجموعه داده‌های خود از محتوای داده‌های بدون ساختار استفاده کنید.
  • برای جستجوی رسانه‌های مشابه، جاسازی‌های چندرسانه‌ای ایجاد کنید
  • ایجاد جاسازی‌های متنی برای انجام جستجوی معنایی با VECTOR_SEARCH
  • استفاده از رابط خط فرمان Gemini برای ایجاد یک برنامه وب

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

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

۲. تنظیمات و الزامات

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

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

fbef9caa1602edd0.pnga99b7ace416376c4.png5e3ff691252acf41.png

  • نام پروژه، نام نمایشی برای شرکت‌کنندگان این پروژه است. این یک رشته کاراکتری است که توسط APIهای گوگل استفاده نمی‌شود. شما همیشه می‌توانید آن را به‌روزرسانی کنید.
  • شناسه پروژه در تمام پروژه‌های گوگل کلود منحصر به فرد است و تغییرناپذیر است (پس از تنظیم، قابل تغییر نیست). کنسول کلود به طور خودکار یک رشته منحصر به فرد تولید می‌کند؛ معمولاً برای شما مهم نیست که چه باشد. در اکثر آزمایشگاه‌های کد، باید شناسه پروژه خود را (که معمولاً با عنوان PROJECT_ID شناخته می‌شود) ارجاع دهید. اگر شناسه تولید شده را دوست ندارید، می‌توانید یک شناسه تصادفی دیگر ایجاد کنید. به عنوان یک جایگزین، می‌توانید شناسه خودتان را امتحان کنید و ببینید که آیا در دسترس است یا خیر. پس از این مرحله قابل تغییر نیست و در طول پروژه باقی می‌ماند.
  • برای اطلاع شما، یک مقدار سوم، شماره پروژه ، وجود دارد که برخی از APIها از آن استفاده می‌کنند. برای کسب اطلاعات بیشتر در مورد هر سه این مقادیر، به مستندات مراجعه کنید.
  1. Next, you'll need to enable billing in the Cloud Console to use Cloud resources/APIs. Running through this codelab won't cost much, if anything at all. To shut down resources to avoid incurring billing beyond this tutorial, you can delete the resources you created or delete the project. New Google Cloud users are eligible for the $300 USD Free Trial program.

3. Open the Cloud Shell

Navigate to https://shell.cloud.google.com/?show=ide%2Cterminal . When prompted, click Authorize .

1bfca4be2c270a9f.png

Make sure both the editor and the console are visible:

785d186a8b11b32b.png

4. Create a helper script

To make this experience smoother, you will create a helper script that sets relevant environment variables.

Replace the <<Project ID>> with your project ID below.

Copy the following command into the Cloud Shell terminal and press Enter to execute**.**

gcloud config set project <<PROJECT_ID>>

ffd97bad1f398b4b.png

Copy the following command into the Cloud Shell terminal and press Enter to execute**.** This will enable necessary services and create the file and edit it in the Cloud Shell.

gcloud services enable compute.googleapis.com \
                       cloudresourcemanager.googleapis.com \
                       aiplatform.googleapis.com \
                       storage-component.googleapis.com  \
                       bigqueryconnection.googleapis.com \
run.googleapis.com \
secretmanager.googleapis.com \
cloudbuild.googleapis.com \
artifactregistry.googleapis.com  \
iap.googleapis.com
edit  ~/petverse-setup.sh

You should see a new tab with the name of the file. Paste the following script into the new file:

#!/bin/bash

# -----------------------------------------------------------------------------
# 1. Global Variables: Set your desired project ID and region here.
# -----------------------------------------------------------------------------

# 🦄 🦄 Set your project ID here ⬇️.

# Example: PROJECT_ID="your-project-id"
PROJECT_ID=""

# Set your desired region here. Default is 'us-central1'.
# Example: REGION="us-east1"
REGION="us-central1"

# -----------------------------------------------------------------------------
# 2. Check and Authenticate
# -----------------------------------------------------------------------------

echo "  ➡️   Checking for active Google Cloud authentication..."

# Check if the user is authenticated; if not, prompt for authentication.
if ! gcloud auth list --format="value(account)" | grep -q @; then
  echo "⚠️   Not authenticated. Please authenticate now."
  gcloud auth login
fi

echo "  ✅   Authentication check passed."

# -----------------------------------------------------------------------------
# 3. Get Project ID from User if not set
# -----------------------------------------------------------------------------

# If PROJECT_ID is not set in the script or as an environment variable,
# prompt the user to choose one.
if [[ -z "$PROJECT_ID" ]] && [[ -n "$DEVSHELL_PROJECT_ID" ]]; then
  PROJECT_ID=$DEVSHELL_PROJECT_ID
fi

if [[ -z "$PROJECT_ID" ]]; then
  echo "  ⚠️   Project ID is not set. Listing available projects:"
 
  # List projects and store them in an array.
  projects_array=($(gcloud projects list --format="value(projectId)"))
 
  # Check if projects were found.
  if [[ ${#projects_array[@]} -eq 0 ]]; then
    echo "  ❌   No projects found. Please ensure your account has access to projects."
    exit 1
  fi
 
  # Display the projects and prompt for input.
  echo " "
  echo "Available Projects:"
  for project in "${projects_array[@]}"; do
    echo "$project"
  done
 
  echo " "
  read -p "Please enter your desired project ID from the list above: " PROJECT_ID
 
  # Validate the user's input by checking if it's in the array.
  if [[ ! " ${projects_array[@]} " =~ " ${PROJECT_ID} " ]]; then
    echo "  ❌   Invalid project ID. Please run the script again and select a valid ID."
    exit 1
  fi
fi

echo "  ✅   Project ID set to: $PROJECT_ID"

# -----------------------------------------------------------------------------
# 4. Set Environment Variables
# -----------------------------------------------------------------------------

# Set the project and region for the current session.
echo "  🔄   Setting Google Cloud configuration for this session..."
gcloud config set project "$PROJECT_ID"
gcloud config set compute/region "$REGION"

echo "  ✅   Google Cloud configuration updated."
echo "Project ID: $PROJECT_ID"
echo "Region: $REGION"
echo " "
echo "  🎉 🦄 🦄   Script execution complete. You can now use Google Cloud commands in this shell session."

Replace the placeholder for PROJECT_ID with the name of your project:

aec2195d576244dd.png

Copy the following command and execute in the terminal:

chmod +x petverse-setup.sh
~/petverse-setup.sh

Expected output:

83d1f7405624443b.png

5. Create a storage bucket

Create a Cloud Storage Bucket and copy the available media to your own bucket. You will use this to store available media for our wonderful pets. You will also create a connection to access the bucket through BigQuery.

Paste and execute the following in the terminal:

~/petverse-setup.sh
cd ~/
gcloud storage buckets create gs://$DEVSHELL_PROJECT_ID-petverse --uniform-bucket-level-access --location=us-central1
gcloud storage cp -r gs://sample-data-and-media/petverse/* gs://$DEVSHELL_PROJECT_ID-petverse/
bq mk --dataset --location=us-central1 --project_id=$DEVSHELL_PROJECT_ID petverse
bq mk --connection --location=us-central1 --project_id=$DEVSHELL_PROJECT_ID \
--connection_type=CLOUD_RESOURCE pet-connection
echo "your bucket is gs://$DEVSHELL_PROJECT_ID-petverse "

379f72ee2908da36.png

6. Create the pets table

You will now create a table in BigQuery to store information about your pets.

Open a new tab in the browser. Navigate to https://console.cloud.google.com/bigquery?utm_campaign=CDR_0x6cb6c9c7_default_b533854388&utm_medium=external&utm_source=lab .

Make sure the same project you have been using is selected in the console:

f82010a317866e6.png

You can now create a table using the data in the file pets.csv. This file contains the names, favorite foods, toys and other interesting information about our pets.

Copy the following code into a new SQL query to create a physical table and load the data.

LOAD DATA INTO petverse.pets
OPTIONS(
    description="Table for furry friend data"
  )
FROM FILES (
  skip_leading_rows=1,
  uris = ['gs://<<your_bucket_name>>/pets.csv'],
  format = 'CSV'
);

Replace the placeholder for the bucket in the code with the bucket you created in the previous step.

You can check all your storage buckets in a separate browser tab pointed to this URL: https://console.cloud.google.com/storage/browser?utm_campaign=CDR_0x6cb6c9c7_default_b533854388&utm_medium=external&utm_source=lab .

757813944bb3d8ba.png

Use the Run button to execute the query.

Once the data is loaded successfully, click Go to table .

d6aab61d533bedde.png

Click Preview to see the contents of the table. 20fb1cbf8826efca.png

7. Connect BigQuery to the Storage Bucket

If you look in the bucket you created earlier, you will find a set of media files related to each pet.

243751f1b0aab329.gif

BigQuery has the capability to read into these buckets and use the files alongside data in tables. This value type is called ObjectRef .

Get the service account id for the connection you created earlier by clicking on it under External connections .

1d9d3275483f5650.png

Copy the service account id .

Navigate to the IAM Admin console in a new browser tab ( https://console.cloud.google.com/iam-admin/ ).

Grant the service account with Storage Object Viewer and Vertex AI User (you will use this permission later).

f1ff6b305d914532.png

Click Save and 🕰️ wait a couple of minutes .

Back in the BigQuery tab , use the following query in BigQuery studio to test the connection between BigQuery and the storage bucket.

Replace <<PROJECT_ID>> with your project ID.

SET @@location='us-central1';
SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/yoda_profile_picture.png', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection'))

Click View Results. You should get the metadata in the results:

9e3d986b797e413a.png

8. Add the storage media to your structured data

You can enhance the pets table to add a column with each pet's profile picture where available. You will also add another column with an array of media references, to hold all the other files related to each pet.

The access to the multimedia requires a connection, which you created in the beginning of this codelab after creating your bucket.

Paste the following commands into a BigQuery SQL console and execute them to add two columns to your pets table.

SET @@location='us-central1';
ALTER TABLE petverse.pets
ADD COLUMN IF NOT EXISTS profile_picture STRUCT<uri STRING, version STRING, authorizer STRING, details JSON>,
ADD COLUMN IF NOT EXISTS additional_media ARRAY<STRUCT<uri STRING, version STRING, authorizer STRING, details JSON>>;

Copy the following statements and replace the place holder for PROJECT_ID with your project id.

SET @@location='us-central1';

UPDATE petverse.pets
SET profile_picture = (SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/yoda_profile_picture.png', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection'))),
    additional_media = [(SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/additional_media/Yoda_asks_for_cuddles.mp4', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection')))]
WHERE Id = 1;

UPDATE petverse.pets
SET profile_picture = (SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/madonna_profile_picture.jpg', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection'))),
    additional_media = [(SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/additional_media/Madonna_description.wav', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection')))]
WHERE Id = 2;

UPDATE petverse.pets
SET profile_picture = (SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/pixel_profile_picture.png', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection'))),
    additional_media = [(SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/additional_media/pixel_thug_life.mp4', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection'))),
                       (SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/additional_media/pixel_description.wav', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection')))]
WHERE Id = 3;

UPDATE petverse.pets
SET profile_picture = (SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/sql_profile_picture.png', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection'))),
    additional_media = [(SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/additional_media/SQL_description.wav', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection'))),
                       (SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/additional_media/SQL_favorite_toy.mp4', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection')))]
WHERE Id = 4;

UPDATE petverse.pets
SET profile_picture = (SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/buddy_golden_retriever.png', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection'))),
    additional_media = NULL
WHERE Id = 5;

UPDATE petverse.pets
SET profile_picture = (SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/daisy_french_bulldog.png', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection'))),
    additional_media = NULL
WHERE Id = 6;

UPDATE petverse.pets
SET profile_picture = (SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/max_german_shepherd.png', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection'))),
    additional_media = [(SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/additional_media/max_description_tells_jokes.mp4', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection')))]
WHERE Id = 7;

UPDATE petverse.pets SET profile_picture = NULL, additional_media = NULL WHERE Id = 8;

UPDATE petverse.pets SET profile_picture = NULL, additional_media = [(SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/additional_media/rocky_description.mp4', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection')))] WHERE Id = 9;

UPDATE petverse.pets
SET profile_picture = (SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/pip_hamster.png', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection'))),
    additional_media = [(SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/additional_media/pip_Hamster_Wheel_Video_Generated.mp4', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection')))]
WHERE Id = 10;

UPDATE petverse.pets SET profile_picture = NULL, additional_media = NULL WHERE Id = 11;

UPDATE petverse.pets
SET profile_picture = (SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/scales_snake.png', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection'))),
    additional_media = NULL
WHERE Id = 12;

UPDATE petverse.pets SET profile_picture = NULL, additional_media = NULL WHERE Id = 13;

UPDATE petverse.pets
SET profile_picture = (SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/Joel_Profile_Picture.jpg', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection'))),
    additional_media = [(SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/additional_media/Joel_Catwalk.jpg', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection'))),
                       (SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/additional_media/Joel_Flowers.jpg', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection'))),
                       (SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/additional_media/Joel_Plays.jpg', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection')))]
WHERE Id = 14;

Run the statement. You should see successful executions after a few minutes:

4fa3bba70440fa65.png

Check the results using the table preview. You should see the metadata for existing profile pictures and additional media for the cat called Pixel.

SELECT *
FROM `petverse.pets`
WHERE name = 'Pixel'

a1511d749e88d5f5.png

9. Generate descriptions of pets

If you preview the pets table, you will notice that some pets - like Yoda, Pixel or Rocky - are missing their favorite food or favorite toy.

The answers to these questions may be in the videos and audios related to these pets. You will use embedded AI functions to check.

Test this with the following statement:

SELECT name,
AI.GENERATE(
   prompt=> ('What are this pet\'s favorite toy and favorite foods', additional_media ),
    connection_id => 'us-central1.pet-connection',
    endpoint => 'gemini-2.5-flash',
output_schema => 'food STRING, toy STRING')
FROM petverse.pets
WHERE name = 'Rocky'

You can see Rocky's video in your storage bucket .

Use the following statement to update the missing descriptions:

UPDATE petverse.pets AS p
SET FavoriteFood = aigen.food
FROM
  (
    SELECT Id, name,
          AI.GENERATE(
                prompt=> ('What are this pet\'s favorite toy and favorite foods', additional_media ),
                connection_id => 'us-central1.pet-connection',
                endpoint => 'gemini-2.5-flash',
                output_schema => 'food STRING').food
    FROM petverse.pets ) AS  aigen
WHERE p.Id = aigen.Id
AND p.FavoriteFood IS NULL
AND p.additional_media IS NOT NULL

Use the following statement to create a description of the pets based on their multimedia into a new column:

ALTER TABLE petverse.pets ADD COLUMN MediaDescription STRING;
UPDATE petverse.pets AS p
SET MediaDescription = aigen.description
FROM
  (
    SELECT Id, name,
          AI.GENERATE(
                prompt=> ('Create a description in an epic tone for this pet based on these media: ', additional_media ),
                connection_id => 'us-central1.pet-connection',
                endpoint => 'gemini-2.5-flash',
                output_schema => 'description STRING').description
    FROM petverse.pets ) AS  aigen
WHERE p.Id = aigen.Id
AND p.MediaDescription IS NULL
AND p.additional_media IS NOT NULL

You should see some creative descriptions after a few minutes:

fab3b59caa69aec7.png

10. Create embeddings

Create a table to store the embeddings for the profile pictures and for the descriptions and hobbies to use in a semantic search. We will find similarities within pets using vector searches.

SET @@location='us-central1';

CREATE OR REPLACE MODEL petverse.multimodalembedding
  REMOTE WITH CONNECTION `us-central1.pet-connection`
  OPTIONS(ENDPOINT = 'multimodalembedding@001');

CREATE TABLE IF NOT EXISTS petverse.profile_embeddings
AS
SELECT *
FROM ML.GENERATE_EMBEDDING(
  MODEL petverse.multimodalembedding,
    (
      SELECT profile_picture as content,
      Id
      FROM petverse.pets)
 );

CREATE OR REPLACE MODEL petverse.textembedding
  REMOTE WITH CONNECTION `us-central1.pet-connection`
  OPTIONS (ENDPOINT = 'text-embedding-005');

CREATE OR REPLACE TABLE petverse.text_embeddings AS
SELECT * FROM ML.GENERATE_EMBEDDING(
  MODEL petverse.textembedding,
  (
    SELECT CONCAT(AdoptionStory, ' . This pet\'s hobby is: ', Hobby, ' and their nickname(s) is: ', COALESCE(Nicknames, Name)) AS content,
    Id, Name
    FROM petverse.pets
    WHERE LENGTH(AdoptionStory) > 0 AND LENGTH(Hobby) > 0
  )
)
WHERE LENGTH(ml_generate_embedding_status) = 0;

Check the new table from the results tab.

c9e876d75147c343.png

Use the following statement to check the status of all embeddings:

SELECT DISTINCT(ml_generate_embedding_status),
  COUNT(content.uri) AS num_rows
FROM petverse.profile_embeddings
GROUP BY 1;

If there are any errors , you will see them in a non-blank status. This is the right output - there are no records in error**:**

e6754936c31ca5cf.png

The following is an example of records with errors. These are not expected but need to be fixed before continuing with the next steps:

736545fbc7ce4ac8.png

Look for similar pets

The default dataset has similar pets in it. Here are two examples Pixel (Id: 3) and SQL (Id: 4):

cfebe01afc5f4858.png

You can use the distance between the embeddings to calculate similar pets:

SELECT
t2.id AS similar_pet_id,
COSINE_DISTANCE(t1.ml_generate_embedding_result, t2.ml_generate_embedding_result) AS distance
FROM
petverse.profile_embeddings AS t1,
petverse.profile_embeddings AS t2
WHERE
t1.Id = 3 -- The pet you want to find similar ones to
AND t1.Id != t2.Id -- Exclude the pet itself from the results
AND t1.content.uri IS NOT NULL
AND t2.content.uri IS NOT NULL
ORDER BY
distance
LIMIT 5;

You should get results with the Ids of pictures that are similar to each other. This will include everything in the picture. In this example, Pixel and SQL are similar, and the next most similar pet is Joel (Id: 14).

99ce203add04a6b1.png

Here's a picture of Joel for reference:

f78e0ca0fe235ba2.png

You can use the VECTOR_SEARCH function to semantically search across text embeddings. If this table was larger, you would need to create and index for the embeddings.

SELECT query.query, base.content, base.Name
FROM VECTOR_SEARCH(
  TABLE `petverse.text_embeddings`, 'ml_generate_embedding_result',
  (
  SELECT ml_generate_embedding_result, content AS query
  FROM ML.GENERATE_EMBEDDING(
  MODEL `petverse.textembedding`,
  (SELECT 'Pets who like to relax' AS content))
  ),
  top_k => 5, options => '{"fraction_lists_to_search": 0.50}')
ORDER BY distance DESC

Try changing the semantic search term ( Pets who like to relax ) as well as the parameter fraction_lists_to_search and see what happens. You can learn more about these functions here .

11. Vibe code a profile page

You'll use the Gemini CLI in the Cloud Shell to jump start a simple, demo web application. This web application has been simplified in its prompt to demonstrate how the Petverse could come to life.

Return to the Cloud Shell . You'll have a better experience with just the console in full screen:

b5061fb060f2a958.png

Run the initialization script to make sure environment variables are set, create a directory to contain this project and execute the Gemini CLI:

~/petverse-setup.sh
mkdir petverse-profiles
cd petverse-profiles
gemini

You should see Gemini's CLI:

910fda2312082974.png

Replace the name of the bucket in the prompt below.

Paste the prompt into the Gemini command line.

You are a fullstack engineer creating an application to display the profiles of cats, dogs and other pets stored in BigQuery. The table where these are stored is called pets, in the dataset petverse.
1.Application Requirements: Display the pets with their profile picture, all the other information in the Pets table, and other media that may be available. The pictures are in a GCS bucket, the field in the table pets profile_picture.uri contains the URI for the storage bucket of that profile picture.  The field additional_media is an array of objectref that contains multiple URI to different media stored in a GCS bucket.
Important: In the code, in the values for the URIs retrieved from BigQuery, replace gs://<<YOUR_PROJECT_ID>>-petverse/ with https://storage.mtls.cloud.google.com/<<YOUR_PROJECT_ID>>-petverse/ as follows: replace('gs://', 'https://storage.mtls.cloud.google.com/'). Use the python library. Media can be pictures, videos and audio. Consider these formats in the code. Some pets may not have profile pictures or additional media.
2.Hosting: Create a web application hosted in a single container and service in Cloud Run, use the following syntax to deploy it using IAP. IMPORTANT: DO NOT ADD IAM AUTHENTICATION AND DO NOT ALLOW UNAUTHENTICATED: gcloud beta run deploy SERVICE_NAME  --region=REGION --image=IMAGE_URL  --no-allow-unauthenticated --iap
3.Database access: Display similar pets based on a similarity between embeddings in table petverse.profile_embeddings. 
Here's the schema for the pets table in CSV format (Field name, type, mode):
Id,INTEGER,NULLABLE
Name,STRING,NULLABLE
Species,STRING,NULLABLE
Breed,STRING,NULLABLE
Nationality,STRING,NULLABLE
Nicknames,STRING,NULLABLE
Hobby,STRING,NULLABLE
AdoptionStory,STRING,NULLABLE
FavoriteFood,STRING,NULLABLE
FavoriteToy,STRING,NULLABLE
profile_picture,RECORD,NULLABLE
additional_media,RECORD,REPEATED
profile_embeddings,FLOAT,REPEATED
Here's a sample query to check for similarity:
SELECT
t2.id AS similar_pet_id,
COSINE_DISTANCE(t1.ml_generate_embedding_result, t2.ml_generate_embedding_result) AS distance
FROM
petverse.profile_embeddings AS t1,
petverse.profile_embeddings AS t2
WHERE
t1.Id = 3 -- The pet you want to find similar ones to
AND t1.Id != t2.Id -- Exclude the pet itself from the results
AND t1.content.uri IS NOT NULL
AND t2.content.uri IS NOT NULL
ORDER BY
distance
LIMIT 5;
Complement the profile of each pet with a description. Here's an example of the access to such table:
SELECT Name, MediaDescription from petverse.pets;
4.For each access to BigQuery, show the SQL statement that is used in the console logs.
5.Search functionality: Add a search bar for a semantic search for pets. There's a text embedding for the Adoption story, the pet's past-time or hobby and their nicknames in the table: petverse.text_embeddings . This is a sample of semantic search:
SELECT query.query, base.content, base.Name FROM VECTOR_SEARCH(TABLE `petverse.text_embeddings`, 'ml_generate_embedding_result', ( SELECT ml_generate_embedding_result, content AS query FROM ML.GENERATE_EMBEDDING(MODEL `petverse.textembedding`,(SELECT 'Pets who like to relax' AS content))), top_k => 5, options => '{"fraction_lists_to_search": 0.50}') ORDER BY distance DESC
6.Use Python for the backend. Generate the deployment scripts for an authenticated service using IAP with the flags --no-allow-unauthenticated --iap
7. Make the UI look like a modern art museum.
8. Use the gunicorn library. Validate version dependencies.

This is your adventure now. You will be shown a plan and asked for confirmation along the way.

It is very unlikely that the code and deployment produced works on the first try. You will need to iterate with the Gemini CLI until it gets it right.

If you see the process stuck in a loop, stop it with CTRL/Command + C , investigate the problem, and prompt it again.

47d6e394fc4f5b60.png

We recommend reading each of the confirmations carefully, one by one, to understand what the CLI will do:

6a62b9c077d4cd11.png

After some minutes, the application should be ready to execute. It may happen that it looks like the console is stuck:

ca51ecf7b1ce08bf.png

You can manually try the application in a new Cloud Shell tab with gunicorn. Make sure the project is set:

f0ee1095386f7ec.png

You should see your new site (it may look different from this). If anything isn't working, you should be able to see the error and debugging logs in the Cloud Shell command line executing locally.

27bf3e2a8d429169.gif

If everything looks good, you can optionally deploy the application into Cloud Run.

If your project belongs in an organization, make sure you configure IAP following these instructions . If your project is not a part of an organization, you can follow these instructions instead to secure access to your application. Specially for production settings, we recommend NOT allowing unauthenticated access.

2365a90ac6a7d4e5.png

Assuming deployment works, you should see the Cloud Run application executing in the Cloud Run console.

Make sure the access is IAP only. Use Edit Policy to add your user to the binding and Save .

Wait a few minutes for the IAP bindings to propagate and click the URL at the top. The site should appear.

3943c556ba912466.png

12. Clean up

This step will guide you through the deletion of the resources created in this codelab.

Delete Cloud Run service (adapt the name of the services and region as needed):

gcloud run services delete petverse-profiles --region us-central1

Delete all BigQuery assets:

bq rm -f petverse
gcloud bigquery connections delete pet-connection --location=us-central1
،

۱. مقدمه

Welcome to the Petverse! All pets are welcome! 🐈🐶🐍🐟🦄

پیش‌نیازها

  • Basic understanding of the Google Cloud Console
  • Basic understanding of SQL statements

آنچه یاد خواهید گرفت

  • Create datasets and tables in BigQuery
  • Create ObjectRef columns to reference multimedia in a storage bucket in BigQuery
  • Use AI functions in BigQuery to enhance your dataset from the content of unstructured data
  • Create multimedia embeddings to search for similar media
  • Create text embeddings to perform semantic search with VECTOR_SEARCH
  • Use the Gemini CLI to create a web application

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

  • A Google Cloud Account and Google Cloud Project with a Billing account
  • یک مرورگر وب مانند کروم

2. Setup and Requirements

Self-paced environment setup

  1. Sign-in to the Google Cloud Console and create a new project or reuse an existing one. If you don't already have a Gmail or Google Workspace account, you must create one .

fbef9caa1602edd0.pnga99b7ace416376c4.png5e3ff691252acf41.png

  • The Project name is the display name for this project's participants. It is a character string not used by Google APIs. You can always update it.
  • The Project ID is unique across all Google Cloud projects and is immutable (cannot be changed after it has been set). The Cloud Console auto-generates a unique string; usually you don't care what it is. In most codelabs, you'll need to reference your Project ID (typically identified as PROJECT_ID ). If you don't like the generated ID, you might generate another random one. Alternatively, you can try your own, and see if it's available. It can't be changed after this step and remains for the duration of the project.
  • For your information, there is a third value, a Project Number , which some APIs use. Learn more about all three of these values in the documentation .
  1. Next, you'll need to enable billing in the Cloud Console to use Cloud resources/APIs. Running through this codelab won't cost much, if anything at all. To shut down resources to avoid incurring billing beyond this tutorial, you can delete the resources you created or delete the project. New Google Cloud users are eligible for the $300 USD Free Trial program.

3. Open the Cloud Shell

Navigate to https://shell.cloud.google.com/?show=ide%2Cterminal . When prompted, click Authorize .

1bfca4be2c270a9f.png

Make sure both the editor and the console are visible:

785d186a8b11b32b.png

4. Create a helper script

To make this experience smoother, you will create a helper script that sets relevant environment variables.

Replace the <<Project ID>> with your project ID below.

Copy the following command into the Cloud Shell terminal and press Enter to execute**.**

gcloud config set project <<PROJECT_ID>>

ffd97bad1f398b4b.png

Copy the following command into the Cloud Shell terminal and press Enter to execute**.** This will enable necessary services and create the file and edit it in the Cloud Shell.

gcloud services enable compute.googleapis.com \
                       cloudresourcemanager.googleapis.com \
                       aiplatform.googleapis.com \
                       storage-component.googleapis.com  \
                       bigqueryconnection.googleapis.com \
run.googleapis.com \
secretmanager.googleapis.com \
cloudbuild.googleapis.com \
artifactregistry.googleapis.com  \
iap.googleapis.com
edit  ~/petverse-setup.sh

You should see a new tab with the name of the file. Paste the following script into the new file:

#!/bin/bash

# -----------------------------------------------------------------------------
# 1. Global Variables: Set your desired project ID and region here.
# -----------------------------------------------------------------------------

# 🦄 🦄 Set your project ID here ⬇️.

# Example: PROJECT_ID="your-project-id"
PROJECT_ID=""

# Set your desired region here. Default is 'us-central1'.
# Example: REGION="us-east1"
REGION="us-central1"

# -----------------------------------------------------------------------------
# 2. Check and Authenticate
# -----------------------------------------------------------------------------

echo "  ➡️   Checking for active Google Cloud authentication..."

# Check if the user is authenticated; if not, prompt for authentication.
if ! gcloud auth list --format="value(account)" | grep -q @; then
  echo "⚠️   Not authenticated. Please authenticate now."
  gcloud auth login
fi

echo "  ✅   Authentication check passed."

# -----------------------------------------------------------------------------
# 3. Get Project ID from User if not set
# -----------------------------------------------------------------------------

# If PROJECT_ID is not set in the script or as an environment variable,
# prompt the user to choose one.
if [[ -z "$PROJECT_ID" ]] && [[ -n "$DEVSHELL_PROJECT_ID" ]]; then
  PROJECT_ID=$DEVSHELL_PROJECT_ID
fi

if [[ -z "$PROJECT_ID" ]]; then
  echo "  ⚠️   Project ID is not set. Listing available projects:"
 
  # List projects and store them in an array.
  projects_array=($(gcloud projects list --format="value(projectId)"))
 
  # Check if projects were found.
  if [[ ${#projects_array[@]} -eq 0 ]]; then
    echo "  ❌   No projects found. Please ensure your account has access to projects."
    exit 1
  fi
 
  # Display the projects and prompt for input.
  echo " "
  echo "Available Projects:"
  for project in "${projects_array[@]}"; do
    echo "$project"
  done
 
  echo " "
  read -p "Please enter your desired project ID from the list above: " PROJECT_ID
 
  # Validate the user's input by checking if it's in the array.
  if [[ ! " ${projects_array[@]} " =~ " ${PROJECT_ID} " ]]; then
    echo "  ❌   Invalid project ID. Please run the script again and select a valid ID."
    exit 1
  fi
fi

echo "  ✅   Project ID set to: $PROJECT_ID"

# -----------------------------------------------------------------------------
# 4. Set Environment Variables
# -----------------------------------------------------------------------------

# Set the project and region for the current session.
echo "  🔄   Setting Google Cloud configuration for this session..."
gcloud config set project "$PROJECT_ID"
gcloud config set compute/region "$REGION"

echo "  ✅   Google Cloud configuration updated."
echo "Project ID: $PROJECT_ID"
echo "Region: $REGION"
echo " "
echo "  🎉 🦄 🦄   Script execution complete. You can now use Google Cloud commands in this shell session."

Replace the placeholder for PROJECT_ID with the name of your project:

aec2195d576244dd.png

Copy the following command and execute in the terminal:

chmod +x petverse-setup.sh
~/petverse-setup.sh

Expected output:

83d1f7405624443b.png

5. Create a storage bucket

Create a Cloud Storage Bucket and copy the available media to your own bucket. You will use this to store available media for our wonderful pets. You will also create a connection to access the bucket through BigQuery.

Paste and execute the following in the terminal:

~/petverse-setup.sh
cd ~/
gcloud storage buckets create gs://$DEVSHELL_PROJECT_ID-petverse --uniform-bucket-level-access --location=us-central1
gcloud storage cp -r gs://sample-data-and-media/petverse/* gs://$DEVSHELL_PROJECT_ID-petverse/
bq mk --dataset --location=us-central1 --project_id=$DEVSHELL_PROJECT_ID petverse
bq mk --connection --location=us-central1 --project_id=$DEVSHELL_PROJECT_ID \
--connection_type=CLOUD_RESOURCE pet-connection
echo "your bucket is gs://$DEVSHELL_PROJECT_ID-petverse "

379f72ee2908da36.png

6. Create the pets table

You will now create a table in BigQuery to store information about your pets.

Open a new tab in the browser. Navigate to https://console.cloud.google.com/bigquery?utm_campaign=CDR_0x6cb6c9c7_default_b533854388&utm_medium=external&utm_source=lab .

Make sure the same project you have been using is selected in the console:

f82010a317866e6.png

You can now create a table using the data in the file pets.csv. This file contains the names, favorite foods, toys and other interesting information about our pets.

Copy the following code into a new SQL query to create a physical table and load the data.

LOAD DATA INTO petverse.pets
OPTIONS(
    description="Table for furry friend data"
  )
FROM FILES (
  skip_leading_rows=1,
  uris = ['gs://<<your_bucket_name>>/pets.csv'],
  format = 'CSV'
);

Replace the placeholder for the bucket in the code with the bucket you created in the previous step.

You can check all your storage buckets in a separate browser tab pointed to this URL: https://console.cloud.google.com/storage/browser?utm_campaign=CDR_0x6cb6c9c7_default_b533854388&utm_medium=external&utm_source=lab .

757813944bb3d8ba.png

Use the Run button to execute the query.

Once the data is loaded successfully, click Go to table .

d6aab61d533bedde.png

Click Preview to see the contents of the table. 20fb1cbf8826efca.png

7. Connect BigQuery to the Storage Bucket

If you look in the bucket you created earlier, you will find a set of media files related to each pet.

243751f1b0aab329.gif

BigQuery has the capability to read into these buckets and use the files alongside data in tables. This value type is called ObjectRef .

Get the service account id for the connection you created earlier by clicking on it under External connections .

1d9d3275483f5650.png

Copy the service account id .

Navigate to the IAM Admin console in a new browser tab ( https://console.cloud.google.com/iam-admin/ ).

Grant the service account with Storage Object Viewer and Vertex AI User (you will use this permission later).

f1ff6b305d914532.png

Click Save and 🕰️ wait a couple of minutes .

Back in the BigQuery tab , use the following query in BigQuery studio to test the connection between BigQuery and the storage bucket.

Replace <<PROJECT_ID>> with your project ID.

SET @@location='us-central1';
SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/yoda_profile_picture.png', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection'))

Click View Results. You should get the metadata in the results:

9e3d986b797e413a.png

8. Add the storage media to your structured data

You can enhance the pets table to add a column with each pet's profile picture where available. You will also add another column with an array of media references, to hold all the other files related to each pet.

The access to the multimedia requires a connection, which you created in the beginning of this codelab after creating your bucket.

Paste the following commands into a BigQuery SQL console and execute them to add two columns to your pets table.

SET @@location='us-central1';
ALTER TABLE petverse.pets
ADD COLUMN IF NOT EXISTS profile_picture STRUCT<uri STRING, version STRING, authorizer STRING, details JSON>,
ADD COLUMN IF NOT EXISTS additional_media ARRAY<STRUCT<uri STRING, version STRING, authorizer STRING, details JSON>>;

Copy the following statements and replace the place holder for PROJECT_ID with your project id.

SET @@location='us-central1';

UPDATE petverse.pets
SET profile_picture = (SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/yoda_profile_picture.png', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection'))),
    additional_media = [(SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/additional_media/Yoda_asks_for_cuddles.mp4', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection')))]
WHERE Id = 1;

UPDATE petverse.pets
SET profile_picture = (SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/madonna_profile_picture.jpg', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection'))),
    additional_media = [(SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/additional_media/Madonna_description.wav', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection')))]
WHERE Id = 2;

UPDATE petverse.pets
SET profile_picture = (SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/pixel_profile_picture.png', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection'))),
    additional_media = [(SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/additional_media/pixel_thug_life.mp4', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection'))),
                       (SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/additional_media/pixel_description.wav', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection')))]
WHERE Id = 3;

UPDATE petverse.pets
SET profile_picture = (SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/sql_profile_picture.png', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection'))),
    additional_media = [(SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/additional_media/SQL_description.wav', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection'))),
                       (SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/additional_media/SQL_favorite_toy.mp4', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection')))]
WHERE Id = 4;

UPDATE petverse.pets
SET profile_picture = (SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/buddy_golden_retriever.png', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection'))),
    additional_media = NULL
WHERE Id = 5;

UPDATE petverse.pets
SET profile_picture = (SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/daisy_french_bulldog.png', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection'))),
    additional_media = NULL
WHERE Id = 6;

UPDATE petverse.pets
SET profile_picture = (SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/max_german_shepherd.png', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection'))),
    additional_media = [(SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/additional_media/max_description_tells_jokes.mp4', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection')))]
WHERE Id = 7;

UPDATE petverse.pets SET profile_picture = NULL, additional_media = NULL WHERE Id = 8;

UPDATE petverse.pets SET profile_picture = NULL, additional_media = [(SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/additional_media/rocky_description.mp4', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection')))] WHERE Id = 9;

UPDATE petverse.pets
SET profile_picture = (SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/pip_hamster.png', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection'))),
    additional_media = [(SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/additional_media/pip_Hamster_Wheel_Video_Generated.mp4', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection')))]
WHERE Id = 10;

UPDATE petverse.pets SET profile_picture = NULL, additional_media = NULL WHERE Id = 11;

UPDATE petverse.pets
SET profile_picture = (SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/scales_snake.png', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection'))),
    additional_media = NULL
WHERE Id = 12;

UPDATE petverse.pets SET profile_picture = NULL, additional_media = NULL WHERE Id = 13;

UPDATE petverse.pets
SET profile_picture = (SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/Joel_Profile_Picture.jpg', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection'))),
    additional_media = [(SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/additional_media/Joel_Catwalk.jpg', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection'))),
                       (SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/additional_media/Joel_Flowers.jpg', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection'))),
                       (SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://<<PROJECT_ID>>-petverse/additional_media/Joel_Plays.jpg', 'projects/<<PROJECT_ID>>/locations/us-central1/connections/pet-connection')))]
WHERE Id = 14;

Run the statement. You should see successful executions after a few minutes:

4fa3bba70440fa65.png

Check the results using the table preview. You should see the metadata for existing profile pictures and additional media for the cat called Pixel.

SELECT *
FROM `petverse.pets`
WHERE name = 'Pixel'

a1511d749e88d5f5.png

9. Generate descriptions of pets

If you preview the pets table, you will notice that some pets - like Yoda, Pixel or Rocky - are missing their favorite food or favorite toy.

The answers to these questions may be in the videos and audios related to these pets. You will use embedded AI functions to check.

Test this with the following statement:

SELECT name,
AI.GENERATE(
   prompt=> ('What are this pet\'s favorite toy and favorite foods', additional_media ),
    connection_id => 'us-central1.pet-connection',
    endpoint => 'gemini-2.5-flash',
output_schema => 'food STRING, toy STRING')
FROM petverse.pets
WHERE name = 'Rocky'

You can see Rocky's video in your storage bucket .

Use the following statement to update the missing descriptions:

UPDATE petverse.pets AS p
SET FavoriteFood = aigen.food
FROM
  (
    SELECT Id, name,
          AI.GENERATE(
                prompt=> ('What are this pet\'s favorite toy and favorite foods', additional_media ),
                connection_id => 'us-central1.pet-connection',
                endpoint => 'gemini-2.5-flash',
                output_schema => 'food STRING').food
    FROM petverse.pets ) AS  aigen
WHERE p.Id = aigen.Id
AND p.FavoriteFood IS NULL
AND p.additional_media IS NOT NULL

Use the following statement to create a description of the pets based on their multimedia into a new column:

ALTER TABLE petverse.pets ADD COLUMN MediaDescription STRING;
UPDATE petverse.pets AS p
SET MediaDescription = aigen.description
FROM
  (
    SELECT Id, name,
          AI.GENERATE(
                prompt=> ('Create a description in an epic tone for this pet based on these media: ', additional_media ),
                connection_id => 'us-central1.pet-connection',
                endpoint => 'gemini-2.5-flash',
                output_schema => 'description STRING').description
    FROM petverse.pets ) AS  aigen
WHERE p.Id = aigen.Id
AND p.MediaDescription IS NULL
AND p.additional_media IS NOT NULL

You should see some creative descriptions after a few minutes:

fab3b59caa69aec7.png

10. Create embeddings

Create a table to store the embeddings for the profile pictures and for the descriptions and hobbies to use in a semantic search. We will find similarities within pets using vector searches.

SET @@location='us-central1';

CREATE OR REPLACE MODEL petverse.multimodalembedding
  REMOTE WITH CONNECTION `us-central1.pet-connection`
  OPTIONS(ENDPOINT = 'multimodalembedding@001');

CREATE TABLE IF NOT EXISTS petverse.profile_embeddings
AS
SELECT *
FROM ML.GENERATE_EMBEDDING(
  MODEL petverse.multimodalembedding,
    (
      SELECT profile_picture as content,
      Id
      FROM petverse.pets)
 );

CREATE OR REPLACE MODEL petverse.textembedding
  REMOTE WITH CONNECTION `us-central1.pet-connection`
  OPTIONS (ENDPOINT = 'text-embedding-005');

CREATE OR REPLACE TABLE petverse.text_embeddings AS
SELECT * FROM ML.GENERATE_EMBEDDING(
  MODEL petverse.textembedding,
  (
    SELECT CONCAT(AdoptionStory, ' . This pet\'s hobby is: ', Hobby, ' and their nickname(s) is: ', COALESCE(Nicknames, Name)) AS content,
    Id, Name
    FROM petverse.pets
    WHERE LENGTH(AdoptionStory) > 0 AND LENGTH(Hobby) > 0
  )
)
WHERE LENGTH(ml_generate_embedding_status) = 0;

Check the new table from the results tab.

c9e876d75147c343.png

Use the following statement to check the status of all embeddings:

SELECT DISTINCT(ml_generate_embedding_status),
  COUNT(content.uri) AS num_rows
FROM petverse.profile_embeddings
GROUP BY 1;

If there are any errors , you will see them in a non-blank status. This is the right output - there are no records in error**:**

e6754936c31ca5cf.png

The following is an example of records with errors. These are not expected but need to be fixed before continuing with the next steps:

736545fbc7ce4ac8.png

Look for similar pets

The default dataset has similar pets in it. Here are two examples Pixel (Id: 3) and SQL (Id: 4):

cfebe01afc5f4858.png

You can use the distance between the embeddings to calculate similar pets:

SELECT
t2.id AS similar_pet_id,
COSINE_DISTANCE(t1.ml_generate_embedding_result, t2.ml_generate_embedding_result) AS distance
FROM
petverse.profile_embeddings AS t1,
petverse.profile_embeddings AS t2
WHERE
t1.Id = 3 -- The pet you want to find similar ones to
AND t1.Id != t2.Id -- Exclude the pet itself from the results
AND t1.content.uri IS NOT NULL
AND t2.content.uri IS NOT NULL
ORDER BY
distance
LIMIT 5;

You should get results with the Ids of pictures that are similar to each other. This will include everything in the picture. In this example, Pixel and SQL are similar, and the next most similar pet is Joel (Id: 14).

99ce203add04a6b1.png

Here's a picture of Joel for reference:

f78e0ca0fe235ba2.png

You can use the VECTOR_SEARCH function to semantically search across text embeddings. If this table was larger, you would need to create and index for the embeddings.

SELECT query.query, base.content, base.Name
FROM VECTOR_SEARCH(
  TABLE `petverse.text_embeddings`, 'ml_generate_embedding_result',
  (
  SELECT ml_generate_embedding_result, content AS query
  FROM ML.GENERATE_EMBEDDING(
  MODEL `petverse.textembedding`,
  (SELECT 'Pets who like to relax' AS content))
  ),
  top_k => 5, options => '{"fraction_lists_to_search": 0.50}')
ORDER BY distance DESC

Try changing the semantic search term ( Pets who like to relax ) as well as the parameter fraction_lists_to_search and see what happens. You can learn more about these functions here .

11. Vibe code a profile page

You'll use the Gemini CLI in the Cloud Shell to jump start a simple, demo web application. This web application has been simplified in its prompt to demonstrate how the Petverse could come to life.

Return to the Cloud Shell . You'll have a better experience with just the console in full screen:

b5061fb060f2a958.png

Run the initialization script to make sure environment variables are set, create a directory to contain this project and execute the Gemini CLI:

~/petverse-setup.sh
mkdir petverse-profiles
cd petverse-profiles
gemini

You should see Gemini's CLI:

910fda2312082974.png

Replace the name of the bucket in the prompt below.

Paste the prompt into the Gemini command line.

You are a fullstack engineer creating an application to display the profiles of cats, dogs and other pets stored in BigQuery. The table where these are stored is called pets, in the dataset petverse.
1.Application Requirements: Display the pets with their profile picture, all the other information in the Pets table, and other media that may be available. The pictures are in a GCS bucket, the field in the table pets profile_picture.uri contains the URI for the storage bucket of that profile picture.  The field additional_media is an array of objectref that contains multiple URI to different media stored in a GCS bucket.
Important: In the code, in the values for the URIs retrieved from BigQuery, replace gs://<<YOUR_PROJECT_ID>>-petverse/ with https://storage.mtls.cloud.google.com/<<YOUR_PROJECT_ID>>-petverse/ as follows: replace('gs://', 'https://storage.mtls.cloud.google.com/'). Use the python library. Media can be pictures, videos and audio. Consider these formats in the code. Some pets may not have profile pictures or additional media.
2.Hosting: Create a web application hosted in a single container and service in Cloud Run, use the following syntax to deploy it using IAP. IMPORTANT: DO NOT ADD IAM AUTHENTICATION AND DO NOT ALLOW UNAUTHENTICATED: gcloud beta run deploy SERVICE_NAME  --region=REGION --image=IMAGE_URL  --no-allow-unauthenticated --iap
3.Database access: Display similar pets based on a similarity between embeddings in table petverse.profile_embeddings. 
Here's the schema for the pets table in CSV format (Field name, type, mode):
Id,INTEGER,NULLABLE
Name,STRING,NULLABLE
Species,STRING,NULLABLE
Breed,STRING,NULLABLE
Nationality,STRING,NULLABLE
Nicknames,STRING,NULLABLE
Hobby,STRING,NULLABLE
AdoptionStory,STRING,NULLABLE
FavoriteFood,STRING,NULLABLE
FavoriteToy,STRING,NULLABLE
profile_picture,RECORD,NULLABLE
additional_media,RECORD,REPEATED
profile_embeddings,FLOAT,REPEATED
Here's a sample query to check for similarity:
SELECT
t2.id AS similar_pet_id,
COSINE_DISTANCE(t1.ml_generate_embedding_result, t2.ml_generate_embedding_result) AS distance
FROM
petverse.profile_embeddings AS t1,
petverse.profile_embeddings AS t2
WHERE
t1.Id = 3 -- The pet you want to find similar ones to
AND t1.Id != t2.Id -- Exclude the pet itself from the results
AND t1.content.uri IS NOT NULL
AND t2.content.uri IS NOT NULL
ORDER BY
distance
LIMIT 5;
Complement the profile of each pet with a description. Here's an example of the access to such table:
SELECT Name, MediaDescription from petverse.pets;
4.For each access to BigQuery, show the SQL statement that is used in the console logs.
5.Search functionality: Add a search bar for a semantic search for pets. There's a text embedding for the Adoption story, the pet's past-time or hobby and their nicknames in the table: petverse.text_embeddings . This is a sample of semantic search:
SELECT query.query, base.content, base.Name FROM VECTOR_SEARCH(TABLE `petverse.text_embeddings`, 'ml_generate_embedding_result', ( SELECT ml_generate_embedding_result, content AS query FROM ML.GENERATE_EMBEDDING(MODEL `petverse.textembedding`,(SELECT 'Pets who like to relax' AS content))), top_k => 5, options => '{"fraction_lists_to_search": 0.50}') ORDER BY distance DESC
6.Use Python for the backend. Generate the deployment scripts for an authenticated service using IAP with the flags --no-allow-unauthenticated --iap
7. Make the UI look like a modern art museum.
8. Use the gunicorn library. Validate version dependencies.

This is your adventure now. You will be shown a plan and asked for confirmation along the way.

It is very unlikely that the code and deployment produced works on the first try. You will need to iterate with the Gemini CLI until it gets it right.

If you see the process stuck in a loop, stop it with CTRL/Command + C , investigate the problem, and prompt it again.

47d6e394fc4f5b60.png

We recommend reading each of the confirmations carefully, one by one, to understand what the CLI will do:

6a62b9c077d4cd11.png

After some minutes, the application should be ready to execute. It may happen that it looks like the console is stuck:

ca51ecf7b1ce08bf.png

You can manually try the application in a new Cloud Shell tab with gunicorn. Make sure the project is set:

f0ee1095386f7ec.png

You should see your new site (it may look different from this). If anything isn't working, you should be able to see the error and debugging logs in the Cloud Shell command line executing locally.

27bf3e2a8d429169.gif

If everything looks good, you can optionally deploy the application into Cloud Run.

If your project belongs in an organization, make sure you configure IAP following these instructions . If your project is not a part of an organization, you can follow these instructions instead to secure access to your application. Specially for production settings, we recommend NOT allowing unauthenticated access.

2365a90ac6a7d4e5.png

Assuming deployment works, you should see the Cloud Run application executing in the Cloud Run console.

Make sure the access is IAP only. Use Edit Policy to add your user to the binding and Save .

Wait a few minutes for the IAP bindings to propagate and click the URL at the top. The site should appear.

3943c556ba912466.png

12. Clean up

This step will guide you through the deletion of the resources created in this codelab.

Delete Cloud Run service (adapt the name of the services and region as needed):

gcloud run services delete petverse-profiles --region us-central1

Delete all BigQuery assets:

bq rm -f petverse
gcloud bigquery connections delete pet-connection --location=us-central1