ברוכים הבאים ל-PetVerse!

1. מבוא

ברוכים הבאים ל-Petverse! אפשר להביא את כל סוגי חיות המחמד! 🐈🐶🐍🐟🦄

דרישות מוקדמות

  • הבנה בסיסית של מסוף Google Cloud
  • הבנה בסיסית של הצהרות SQL

מה תלמדו

  • יצירת מערכי נתונים וטבלאות ב-BigQuery
  • יצירת עמודות ObjectRef להפניה למולטימדיה בקטגוריית אחסון ב-BigQuery
  • שימוש בפונקציות AI ב-BigQuery כדי לשפר את מערך הנתונים מתוכן של נתונים לא מובנים
  • יצירת הטמעות של מולטימדיה כדי לחפש מדיה דומה
  • יצירת הטמעות טקסט כדי לבצע חיפוש סמנטי באמצעות VECTOR_SEARCH
  • איך משתמשים ב-Gemini CLI כדי ליצור אפליקציית אינטרנט

מה תצטרכו

  • חשבון ב-Google Cloud ופרויקט ב-Google Cloud עם חשבון לחיוב
  • דפדפן אינטרנט כמו Chrome

2. הגדרה ודרישות

הגדרת סביבה בקצב אישי

  1. נכנסים ל-מסוף Google Cloud ויוצרים פרויקט חדש או משתמשים בפרויקט קיים. אם עדיין אין לכם חשבון Gmail או Google Workspace, אתם צריכים ליצור חשבון.

fbef9caa1602edd0.png

a99b7ace416376c4.png

5e3ff691252acf41.png

  • שם הפרויקט הוא השם המוצג של הפרויקט הזה למשתתפים. זו מחרוזת תווים שלא נמצאת בשימוש ב-Google APIs. תמיד אפשר לעדכן את המיקום.
  • מזהה הפרויקט הוא ייחודי לכל הפרויקטים ב-Google Cloud, והוא קבוע (אי אפשר לשנות אותו אחרי שהוא מוגדר). מסוף Cloud יוצר באופן אוטומטי מחרוזת ייחודית, ובדרך כלל לא צריך לדעת מה היא. ברוב ה-Codelabs, תצטרכו להפנות למזהה הפרויקט (בדרך כלל מסומן כ-PROJECT_ID). אם אתם לא אוהבים את המזהה שנוצר, אתם יכולים ליצור מזהה אקראי אחר. אפשר גם לנסות כתובת משלכם ולבדוק אם היא זמינה. אי אפשר לשנות את הערך הזה אחרי השלב הזה, והוא יישאר כזה למשך הפרויקט.
  • לידיעתכם, יש ערך שלישי, מספר פרויקט, שחלק מממשקי ה-API משתמשים בו. במאמרי העזרה מפורט מידע נוסף על שלושת הערכים האלה.
  1. בשלב הבא, תצטרכו להפעיל את החיוב במסוף Cloud כדי להשתמש במשאבי Cloud או בממשקי API של Cloud. השלמת ה-codelab הזה לא תעלה לכם הרבה, אם בכלל. כדי להשבית את המשאבים ולמנוע חיובים נוספים אחרי שתסיימו את המדריך הזה, תוכלו למחוק את המשאבים שיצרתם או למחוק את הפרויקט. משתמשים חדשים ב-Google Cloud זכאים לתוכנית תקופת ניסיון בחינם בשווי 300$.

3. פתיחת Cloud Shell

עוברים אל https://shell.cloud.google.com/?show=ide%2Cterminal . כשמופיעה בקשה, לוחצים על אישור.

1bfca4be2c270a9f.png

מוודאים שגם העורך וגם המסוף גלויים:

785d186a8b11b32b.png

4. יצירת סקריפט עזר

כדי לשפר את חוויית השימוש, תיצרו סקריפט עזר שמגדיר את משתני הסביבה הרלוונטיים.

מחליפים את <<מזהה הפרויקט>> במזהה הפרויקט שלכם.

מעתיקים את הפקודה הבאה לטרמינל של 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."

מחליפים את ה-placeholder של PROJECT_ID בשם הפרויקט:

aec2195d576244dd.png

מעתיקים את הפקודה הבאה ומריצים אותה בטרמינל:

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

הפלט אמור להיראות כך:

83d1f7405624443b.png

5. יצירה של קטגוריית אחסון

יוצרים קטגוריה של Cloud Storage ומעתיקים את המדיה שזמינה לקטגוריה שלכם. תשתמשו בזה כדי לאחסן מדיה זמינה של חיות המחמד המקסימות שלנו. תצטרכו גם ליצור חיבור כדי לגשת לקטגוריה דרך 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

6. יצירת הטבלה pets

עכשיו יוצרים טבלה ב-BigQuery לאחסון מידע על חיות המחמד.

פותחים כרטיסייה חדשה בדפדפן. עוברים לכתובת https://console.cloud.google.com/bigquery .

מוודאים שבמסוף בחרתם את אותו פרויקט שבו השתמשתם:

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

מחליפים את ה-placeholder של הקטגוריה בקוד בקטגוריה שיצרתם בשלב הקודם.

אפשר לבדוק את כל קטגוריות האחסון בכרטיסייה נפרדת בדפדפן בכתובת ה-URL הזו: https://console.cloud.google.com/storage/browser .

757813944bb3d8ba.png

משתמשים בלחצן Run כדי להריץ את השאילתה.

אחרי שהנתונים נטענים בהצלחה, לוחצים על מעבר לטבלה.

d6aab61d533bedde.png

לוחצים על תצוגה מקדימה כדי לראות את תוכן הטבלה. 20fb1cbf8826efca.png

7. חיבור BigQuery אל Storage Bucket

אם תבדקו את ה-bucket שיצרתם קודם, תמצאו בו קבוצה של קובצי מדיה שקשורים לכל חיית מחמד.

243751f1b0aab329.gif

ל-BigQuery יש יכולת לקרוא את הנתונים בדליים האלה ולהשתמש בקבצים לצד נתונים בטבלאות. סוג הערך הזה נקרא ObjectRef.

כדי למצוא את מזהה חשבון השירות של החיבור שיצרתם קודם, לוחצים על החיבור בקטע חיבורים חיצוניים.

1d9d3275483f5650.png

מעתיקים את המזהה של חשבון השירות.

עוברים למסוף IAM Admin בכרטיסייה חדשה בדפדפן ( https://console.cloud.google.com/iam-admin/ ).

נותנים לחשבון השירות את ההרשאות 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

8. הוספת אמצעי האחסון לנתונים המובְנים

אפשר לשפר את הטבלה pets ולהוסיף עמודה עם תמונת הפרופיל של כל חיית מחמד, אם יש כזו. תצטרכו גם להוסיף עוד עמודה עם מערך של הפניות למדיה, כדי להכיל את כל הקבצים האחרים שקשורים לכל חיית מחמד.

כדי לגשת לקובצי המולטימדיה, צריך חיבור שיצרתם בתחילת ה-Codelab הזה אחרי שיצרתם את הקטגוריה.

מדביקים את הפקודות הבאות במסוף 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>>;

מעתיקים את ההצהרות הבאות ומחליפים את ה-placeholder של 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

בודקים את התוצאות באמצעות התצוגה המקדימה של הטבלה. המטא-נתונים של תמונות הפרופיל הקיימות ושל המדיה הנוספת של החתול שנקרא פיקסל אמורים להופיע.

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

a1511d749e88d5f5.png

9. יצירת תיאורים של חיות מחמד

אם תציגו תצוגה מקדימה של הטבלה pets, תשימו לב שלחלק מחיות המחמד – כמו Yoda, ‏ Pixel או Rocky – חסר המזון או הצעצוע האהובים.

יכול להיות שהתשובות לשאלות האלה נמצאות בסרטונים ובאודיו שקשורים לחיות המחמד האלה. תשתמשו בפונקציות AI מוטמעות כדי לבדוק.

בודקים את זה באמצעות ההצהרה הבאה:

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

10. יצירת הטמעות

יוצרים טבלה לאחסון ההטמעות של תמונות הפרופיל, התיאורים והתחביבים לשימוש בחיפוש סמנטי. אנחנו נשתמש בחיפושי וקטור כדי למצוא נקודות דמיון בין חיות מחמד.

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 (מזהה: 3) ו-SQL (מזהה: 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 (מזהה: 14).

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 ולראות מה קורה. כאן אפשר לקרוא מידע נוסף על הפונקציות האלה.

11. תכנות דף פרופיל בשיטת Vibe coding

תשתמשו ב-Gemini CLI ב-Cloud Shell כדי להתחיל במהירות עם אפליקציית אינטרנט פשוטה להדגמה. הנחיה פשוטה יותר באפליקציית האינטרנט הזו מדגימה איך אפשר להפיח חיים ב-Petverse.

חוזרים אל Cloud Shell. החוויה תהיה טובה יותר אם תשתמשו רק במסוף במסך מלא:

b5061fb060f2a958.png

מריצים את סקריפט האתחול כדי לוודא שמשתני הסביבה מוגדרים, יוצרים ספרייה שתכיל את הפרויקט הזה ומריצים את Gemini CLI:

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

אתם אמורים לראות את Gemini CLI:

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 לפי ההוראות האלה. אם הפרויקט שלכם לא שייך לארגון, תוכלו לפעול לפי ההוראות האלה כדי לאבטח את הגישה לאפליקציה. במיוחד בהגדרות ייצור, אנחנו ממליצים לא לאפשר גישה לא מאומתת.

2365a90ac6a7d4e5.png

אם הפריסה פועלת, האפליקציה של Cloud Run אמורה לפעול במסוף Cloud Run.

מוודאים שהגישה היא רק ל-IAP. משתמשים באפשרות עריכת מדיניות כדי להוסיף את המשתמש לקישור ולוחצים על שמירה.

מחכים כמה דקות עד שהקישורים של הרכישות מתוך האפליקציה יתעדכנו ולוחצים על כתובת ה-URL בחלק העליון. האתר אמור להופיע.

3943c556ba912466.png

12. הסרת המשאבים

בשלב הזה תלמדו איך למחוק את המשאבים שנוצרו ב-Codelab הזה.

מחיקת שירות 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