1. סקירה כללית
בעולם של אפליקציות בתחומי הבריאות והכושר, חשוב מאוד לספק למשתמשים חוויה עשירה ומרתקת. לדוגמה, באפליקציה לתרגול יוגה, זה אומר לא להסתפק בתיאורים פשוטים של תנוחות, אלא להציע מידע מקיף, תוכן מולטימדיה ויכולות חיפוש חכמות. בבלוג הזה נסביר איך לבנות מסד נתונים חזק של תנוחות יוגה באמצעות Firestore של Google Cloud, איך להשתמש בתוסף Vector Search שלו להתאמה לפי הקשר, ואיך לשלב את היכולות של Gemini 2.0 Flash (ניסיוני) כדי לעבוד עם תוכן מולטימודאלי.
למה כדאי להשתמש ב-Firestore?
Firestore, מסד נתונים מסוג NoSQL לאחסון מסמכים בלי שרת (serverless) מבית Google Cloud, הוא בחירה מצוינת לפיתוח אפליקציות דינמיות עם יכולת הרחבה. הנה כמה סיבות לכך שהאפליקציה מתאימה מאוד לאפליקציית היוגה שלנו:
- יכולת הרחבה וביצועים: מערכת Firestore מתרחבת באופן אוטומטי כדי לטפל במיליוני משתמשים ובמערכי נתונים גדולים, וכך מוודאת שהאפליקציה תמשיך להגיב גם כשהיא גדלה.
- עדכונים בזמן אמת: סנכרון מובנה בזמן אמת שומר על עקביות הנתונים בכל הלקוחות המחוברים, ולכן הוא מושלם לתכונות כמו שיעורים בשידור חי או תרגול שיתופי.
- מודל נתונים גמיש: המבנה מבוסס-המסמכים של Firestore מאפשר לכם לאחסן סוגים שונים של נתונים, כולל טקסט, תמונות ואפילו הטמעות. לכן הוא אידיאלי לייצוג מידע מורכב על תנוחות יוגה.
- שליחת שאילתות מתקדמות: Firestore תומך בשאילתות מורכבות, כולל שוויון, אי-שוויון ועכשיו, עם התוסף החדש, חיפושים של דמיון וקטורי.
- תמיכה באופליין: Firestore שומר נתונים במטמון באופן מקומי, כך שהאפליקציה יכולה לפעול גם כשהמשתמשים במצב אופליין.
שיפור החיפוש באמצעות התוסף Firestore Vector Search
חיפוש מסורתי שמבוסס על מילות מפתח יכול להיות מוגבל כשמדובר במושגים מורכבים כמו תנוחות יוגה. משתמש עשוי לחפש תנוחה ש "פותחת את הירכיים" או "משפרת את שיווי המשקל" בלי לדעת את השם הספציפי של התנוחה. כאן נכנס לתמונה Vector Search.
חיפוש וקטורי ב-Firestore מאפשר לכם:
- יצירת הטמעות: המרת תיאורי טקסט, ובעתיד אולי גם תמונות ואודיו, לייצוגים וקטוריים מספריים (הטמעות) שמשקפים את המשמעות הסמנטית שלהם באמצעות מודלים כמו אלה שזמינים ב-Vertex AI או מודלים בהתאמה אישית.
- שמירת הטמעות: שמירת ההטמעות האלה ישירות במסמכי Firestore.
- ביצוע חיפושים של מסמכים דומים: אפשר להריץ שאילתה במסד הנתונים כדי למצוא מסמכים שדומים מבחינה סמנטית לווקטור שאילתה נתון, וכך לבצע התאמה לפי הקשר.
שילוב של Gemini 2.0 Flash (ניסיוני)
Gemini 2.0 Flash הוא מודל AI מולטי-מודאלי מתקדם של Google. התכונה הזו עדיין ניסיונית, אבל היא מציעה אפשרויות מרתקות להעשרת אפליקציית היוגה שלנו:
- יצירת טקסט: אפשר להשתמש ב-Gemini 2.0 Flash כדי ליצור תיאורים מפורטים של תנוחות יוגה, כולל היתרונות, השינויים וההתוויות נגד.
- יצירת תמונות (חיקוי): למרות שעדיין אי אפשר ליצור תמונות ישירות באמצעות Gemini, סימלצתי את התהליך הזה באמצעות Imagen של Google, ויצרתי תמונות שמייצגות חזותית את התנוחות.
- יצירת אודיו (חיקוי): באופן דומה, אנחנו יכולים להשתמש בשירות המרת טקסט לדיבור (TTS) כדי ליצור הוראות אודיו לכל תנוחה, וכך להנחות את המשתמשים במהלך התרגול.
אני רואה אפשרות להציע שילוב שישפר את האפליקציה באמצעות התכונות הבאות של המודל:
- Multimodal Live API: ממשק ה-API החדש הזה עוזר לכם ליצור אפליקציות של סטרימינג בזמן אמת של נתונים חזותיים ואודיו, עם שימוש בכלי.
- מהירות וביצועים: הזמן עד לטוקן הראשון (TTFT) ב-Gemini 2.0 Flash קצר משמעותית בהשוואה ל-Gemini 1.5 Flash.
- שיפורים בחוויית השימוש בממשק מבוסס-סוכן: מודל Gemini 2.0 מציע שיפורים בהבנה מולטי-מודאלית, בכתיבת קוד, בביצוע הוראות מורכבות ובקריאה לפונקציות. השיפורים האלה פועלים יחד כדי לתמוך בחוויית שימוש טובה יותר.
פרטים נוספים מופיעים בדף הזה.
עיגון באמצעות חיפוש Google
כדי לשפר את המהימנות ולספק משאבים נוספים, אנחנו יכולים לשלב את חיפוש Google כדי לבסס את המידע שמסופק על ידי האפליקציה שלנו. המשמעות היא:
- חיפוש לפי הקשר: כשמשתמש עם הרשאות אדמין מזין את הפרטים של תנוחה, אנחנו יכולים להשתמש בשם התנוחה כדי לבצע חיפוש ב-Google.
- חילוץ כתובות URL: מתוצאות החיפוש, אנחנו יכולים לחלץ כתובות URL רלוונטיות, כמו מאמרים, סרטונים או אתרים מהימנים בנושא יוגה, ולהציג אותן באפליקציה.
מה תפַתחו
במסגרת ה-Lab הזה:
- יצירת אוסף Firestore וטעינת מסמכי יוגה
- איך יוצרים אפליקציות CRUD באמצעות Firestore
- יצירת תיאור של תנוחת יוגה באמצעות Gemini 2.0 Flash
- הפעלת חיפוש וקטורי ב-Firebase עם שילוב של Firestore
- יצירת הטמעות מתיאור של יוגה
- ביצוע חיפוש דמיון לטקסט חיפוש של משתמש
דרישות
2. לפני שמתחילים
יצירת פרויקט
- ב-מסוף Google Cloud, בדף לבחירת הפרויקט, בוחרים או יוצרים פרויקט ב-Google Cloud.
- הקפידו לוודא שהחיוב מופעל בפרויקט שלכם ב-Cloud. כך בודקים אם החיוב מופעל בפרויקט
- תשתמשו ב-Cloud Shell, סביבת שורת פקודה שפועלת ב-Google Cloud ומגיעה עם bq שנטען מראש. לוחצים על 'הפעלת Cloud Shell' בחלק העליון של מסוף Google Cloud.

- אחרי שמתחברים ל-Cloud Shell, בודקים שכבר בוצע אימות ושהפרויקט מוגדר למזהה הפרויקט באמצעות הפקודה הבאה:
gcloud auth list
- מריצים את הפקודה הבאה ב-Cloud Shell כדי לוודא שפקודת gcloud מכירה את הפרויקט.
gcloud config list project
- אם הפרויקט לא מוגדר, משתמשים בפקודה הבאה כדי להגדיר אותו:
gcloud config set project <YOUR_PROJECT_ID>
- מפעילים את ממשקי ה-API הנדרשים באמצעות הקישור הזה עד שתוכלו ללחוץ על הלחצן 'הפעלה'.
אם פספסתם API כלשהו, תמיד תוכלו להפעיל אותו במהלך ההטמעה.
אפשר לעיין במאמרי העזרה בנושא פקודות gcloud ושימוש בהן.
3. הגדרת מסד נתונים
במסמכי התיעוד מפורטים שלבים נוספים להגדרת מופע של Firestore. כדי להתחיל, אבצע את השלבים הבאים:
1 עוברים אל Firestore Viewer ובמסך Select a database service בוחרים באפשרות Firestore in Native mode.
- בוחרים מיקום ל-Firestore (חשוב לבחור us-central1 ולפעול לפי ההוראות האלה בכל מקום שבו בוחרים אזור או מיקום במהלך ה-codelab הזה)
- לוחצים על Create Database (יצירת מסד נתונים) (אם זו הפעם הראשונה, משאירים את מסד הנתונים כברירת המחדל (default)).
כשיוצרים פרויקט Firestore, מערכת Cloud API Manager מפעילה גם את ה-API.
- חשוב: בוחרים בגרסת הבדיקה (ולא בגרסת הייצור) של כללי האבטחה כדי שהנתונים יהיו נגישים
- אחרי ההגדרה, אמורה להופיע תצוגה של מסד הנתונים, האוסף והמסמך של Firestore במצב Native, כמו בתמונה שלמטה:

- אל תבצעו את השלב הזה עדיין, אבל רק כדי שתדעו – אפשר ללחוץ על 'התחלת אוסף' וליצור אוסף חדש. מגדירים את מזהה האוסף כ-'poses'. לוחצים על הלחצן שמירה.

טיפים למתקדמים להגשת בקשה להפקה:
- אחרי שמסיימים את מודל הנתונים ומזהים למי צריכה להיות גישה לסוגים שונים של מסמכים, אפשר ליצור, לערוך ולעקוב אחרי כללי אבטחה מממשק Firebase. אפשר לגשת לכללי האבטחה מהקישור הזה: https://console.firebase.google.com/u/0/project/<<your_project_id>>/firestore/rules
- חשוב לערוך, לעקוב ולבדוק את כללי האבטחה לפני הפריסה או ההשקה של הפרויקט משלב הפיתוח, כי לעיתים קרובות הם הגורם השקט לכך שהאפליקציה פועלת בצורה שונה :)
בהדגמה הזו נשתמש בו במצב TEST.
4. Firestore REST API
- ה-API ל-REST יכול לעזור במקרים הבאים:א. גישה ל-Firestore מסביבה עם מגבלות על משאבים, שבה אי אפשר להריץ ספריית לקוח מלאה. אוטומציה של ניהול מסד נתונים או אחזור של מטא-נתונים מפורטים של מסד נתונים
- הדרך הכי קלה להשתמש ב-Firestore היא באמצעות אחת מספריות הלקוח המקוריות, אבל יש מצבים שבהם כדאי לקרוא ישירות ל-API בארכיטקטורת REST.
- בבלוג הזה נראה שימוש ב-Firestore REST APIs והדגמה שלהם, ולא בספריות לקוח מקוריות.
- לצורך אימות, ה-API בארכיטקטורת REST של Firestore מקבל אסימון מזהה של אימות ב-Firebase או אסימון OAuth 2.0 של Google Identity. מידע נוסף על אימות והרשאה זמין במאמרי העזרה.
- כל נקודות הקצה של API בארכיטקטורת REST נמצאות בכתובת ה-URL הבסיסית https://firestore.googleapis.com/v1/.
Spring Boot ו-Firestore API
הפתרון הזה ב-Spring Boot Framework נועד להדגים אפליקציית לקוח שמשתמשת בממשקי API של Firestore כדי לאסוף ולשנות פרטים על תנוחות יוגה ועל נשימה, עם חוויית משתמש אינטראקטיבית.
הסבר מפורט על הפתרון של Firestore CRUD באפליקציית תנוחות היוגה מופיע בקישור לבלוג.
כדי להתמקד בפתרון הנוכחי וללמוד את החלק של CRUD תוך כדי תנועה, משכפלים את הפתרון כולו שמתמקד בבלוג הזה מהמאגר שלמטה מטרמינל Cloud Shell ומקבלים עותק של בסיס הקוד.
git clone https://github.com/AbiramiSukumaran/firestore-poserecommender
חשוב לזכור:
- אחרי שמשכפלים את המאגר הזה, צריך לבצע רק כמה שינויים שקשורים למזהה הפרויקט, לממשקי ה-API וכו'. לא נדרשים שינויים נוספים כדי להפעיל את האפליקציה. בקטעים הבאים מוסבר על כל רכיב באפליקציה. לפניכם רשימת השינויים:
- בקובץ
src/main/java/com/example/demo/GenerateImageSample.java, מחליפים את "<<YOUR_PROJECT_ID>>" במזהה הפרויקט. - בקובץ
src/main/java/com/example/demo/GenerateEmbeddings.java, מחליפים את "<<YOUR_PROJECT_ID>>" במזהה הפרויקט. - ב-
src/main/java/com/example/demo/PoseController.java, מחליפים את כל המופעים של<<YOUR_PROJECT_ID>>"ואת שם מסד הנתונים,(במקרה הזה"(default)",) בערכים המתאימים מההגדרה שלכם: - ב-
src/main/java/com/example/demo/PoseController.java, מחליפים את[YOUR_API_KEY]במפתח ה-API של Gemini 2.0 Flash. אפשר לקבל את זה מ-AI Studio. - אם רוצים לבצע בדיקה מקומית, מריצים את הפקודות הבאות מתיקיית הפרויקט בטרמינל של Cloud Shell:
mvn package
mvn spring-boot:run
נכון לעכשיו, אפשר לראות את האפליקציה פועלת בלחיצה על האפשרות 'תצוגה מקדימה של אתר' ב-Cloud Shell Terminal. אנחנו עדיין לא מוכנים לבצע בדיקות ולנסות את האפליקציה.
- אופציונלי: אם רוצים לפרוס את האפליקציה ב-Cloud Run, צריך לאתחל אפליקציית Java Cloud Run חדשה לגמרי מאפס מ-Cloud Shell Editor, ולהוסיף את קובצי ה-src ואת קובצי התבניות מהמאגר לפרויקט החדש בתיקיות המתאימות (כי פרויקט המאגר הנוכחי ב-GitHub לא מוגדר כברירת מחדל להגדרת פריסה ב-Cloud Run). במקרה כזה, צריך לפעול לפי השלבים הבאים (במקום לשכפל את המאגר הקיים):
- עוברים אל Cloud Shell Editor (מוודאים שהעורך פתוח ולא הטרמינל), לוחצים על סמל שם הפרויקט ב-Google Cloud בצד ימין של שורת הסטטוס (החלק המוסתר בצילום המסך שלמטה).

- בוחרים באפשרות New application (אפליקציה חדשה) -> Cloud Run Application (אפליקציית Cloud Run) -> Java: Cloud Run (ג'אווה: Cloud Run) מתוך רשימת האפשרויות ונותנים לה את השם firestore-poserecommender.

- עכשיו אמורה להופיע תבנית מלאה של Java Cloud Run Application, שהוגדרה מראש ומוכנה לשימוש
- מסירים את המחלקה הקיימת Controller ומעתיקים את הקבצים הבאים לתיקיות המתאימות במבנה הפרויקט:
firestore-poserecommender/src/main/java/com/example/demo/
- FirestoreSampleApplication.java
- GenerateEmbeddings.java
- GenerateImageSample.java
- Pose.java
- PoseController.java
- ServletInitializer.java
firestore-poserecommender/src/main/resources/static/ - Index.html
firestore-poserecommender/src/main/resources/templates/
- contextsearch.html
- createpose.html
- errmessage.html
- pose.html
- ryoq.html
- searchpose.html
- showmessage.html
firestore-poserecommender/
- קובץ Docker
- צריך לבצע את השינויים בקבצים המתאימים כדי להחליף את PROJECT ID ואת API KEY בערכים המתאימים. (שלבים 1 א,ב, ג ו-ד שלמעלה).
5. הטמעת נתונים
הנתונים של האפליקציה זמינים בקובץ data.json: https://github.com/AbiramiSukumaran/firestore-poserecommender/blob/main/data.json
אם רוצים להתחיל עם נתונים מוגדרים מראש, אפשר להעתיק את ה-JSON ולהחליף את כל המופעים של "<<YOUR_PROJECT_ID>>" בערך שלכם.
- עוברים אל Firestore Studio
- מוודאים שיצרתם אוסף בשם 'תנוחות'.
- מוסיפים ידנית כל מסמך בנפרד מקובץ המאגר שצוין למעלה
אפשר גם לייבא נתונים בבת אחת מהקבוצה המוגדרת מראש שיצרנו בשבילכם, באופן הבא:
- עוברים לטרמינל של Cloud Shell ומוודאים שהפרויקט בענן הפעיל ב-Google Cloud מוגדר ושיש לכם הרשאה. יוצרים קטגוריה בפרויקט באמצעות פקודת gsutil שמופיעה בהמשך. מחליפים את המשתנה <PROJECT_ID> בפקודה שלמטה במזהה הפרויקט שלכם ב-Google Cloud:
gsutil mb -l us gs://<PROJECT_ID>-yoga-poses-bucket
- אחרי שיוצרים את הדלי, צריך להעתיק אליו את קובץ הייצוא של מסד הנתונים שהכנו, כדי שנוכל לייבא אותו למסד הנתונים של Firebase. משתמשים בפקודה שמופיעה בהמשך:
gsutil cp -r gs://demo-bq-gemini-public/yoga_poses gs://<PROJECT_ID>-yoga-poses-bucket
עכשיו שיש לנו את הנתונים לייבוא, אפשר לעבור לשלב האחרון של ייבוא הנתונים למסד הנתונים של Firebase (ברירת מחדל) שיצרנו.
- עוברים עכשיו למסוף Firestore ובתפריט הניווט שמימין לוחצים על Import/Export (ייבוא/ייצוא).
בוחרים באפשרות 'ייבוא', בוחרים את הנתיב של Cloud Storage שיצרתם ועוברים עד שאפשר לבחור את הקובץ yoga_poses.overall_export_metadata:

- לחץ על 'ייבא'.
הייבוא יימשך כמה שניות. כשהוא יסתיים, תוכלו לאמת את מסד הנתונים של Firestore ואת האוסף. לשם כך, עוברים אל https://console.cloud.google.com/firestore/databases, בוחרים במסד הנתונים default ובאוסף poses כמו שמוצג בהמשך:
- שיטה נוספת היא ליצור את הרשומות באופן ידני דרך האפליקציה אחרי הפריסה באמצעות הפעולה Create a New Pose (יצירת תנוחה חדשה).
6. חיפוש תחום או ענף
הפעלת התוסף Firestore Vector Search
אתם יכולים להשתמש בתוסף הזה כדי להטמיע אוטומטית את מסמכי Firestore ולשאול עליהם שאלות באמצעות תכונת החיפוש הווקטורי החדשה. תועברו אל רכזת התוספים ל-Firebase.
כשמתקינים את התוסף Vector Search, מציינים אוסף ושם של שדה מסמך. הוספה או עדכון של מסמך עם השדה הזה מפעילים את התוסף הזה כדי לחשב הטמעת וקטורים עבור המסמך. הטמעת הווקטור הזו נכתבת בחזרה לאותו מסמך, והמסמך עובר אינדוקס בחנות הווקטורים, ומוכן לשליחת שאילתות.
בואו נראה את השלבים:
התקנת התוסף:
מתקינים את התוסף Vector Search with Firestore (חיפוש וקטורי ב-Firestore) מ-Extensions Marketplace (חנות התוספים) של Firebase על ידי לחיצה על Install in Firebase Console (התקנה במסוף Firebase).
חשוב:
כשעוברים לראשונה לדף התוספים הזה, צריך לבחור את אותו פרויקט שעליו עובדים במסוף Google Cloud, שמופיע במסוף Firebase.

אם הפרויקט לא מופיע ברשימה, מוסיפים אותו ב-Firebase (בוחרים את הפרויקט הקיים ב-Google Cloud מהרשימה).
הגדרת התוסף:
מציינים את האוסף (poses), את השדה שמכיל את הטקסט להטמעה (posture) ופרמטרים אחרים כמו ממדי ההטמעה.
אם יש ממשקי API שצריך להפעיל שמפורטים בשלב הזה, אפשר לעשות זאת בדף ההגדרות. צריך לפעול לפי השלבים.
אם הדף לא מגיב אחרי הפעלת ממשקי API במשך זמן מה, פשוט רעננו אותו ותוכלו לראות את ממשקי ה-API שהופעלו.

באחד מהשלבים הבאים, המערכת מאפשרת להשתמש ב-LLM שבחרתם כדי ליצור את ההטמעות. בוחרים באפשרות Vertex AI.

ההגדרות הבאות קשורות לאוסף ולשדה שרוצים להטמיע:
מודל שפה גדול (LLM): Vertex AI
נתיב לאוסף: תנוחות
מגבלת ברירת המחדל של השאילתות: 3
מדד המרחק: קוסינוס
שם שדה להזנת קלט: תנוחה
שם שדה הפלט: הטמעה
שם שדה הסטטוס: סטטוס
הטמעה של מסמכים קיימים: כן
עדכון הטמעות קיימות: כן
המיקום של Cloud Functions: us-central1
Enable Events (הפעלת אירועים): לא מסומן

אחרי שמגדירים את כל האפשרויות האלה, לוחצים על הלחצן Install Extension (התקנת התוסף). התהליך יימשך 3-5 דקות.
יצירת הטמעות:
כשמוסיפים או מעדכנים מסמכים באוסף 'תנוחות', התוסף יוצר באופן אוטומטי הטבעות באמצעות מודל שאומן מראש או מודל לבחירתכם דרך נקודת קצה ל-API. בדוגמה הזו בחרנו ב-Vertex AI בהגדרת התוסף.
יצירת אינדקס
היא תחייב יצירת אינדקס בשדה ההטמעה בזמן השימוש בהטמעה באפליקציה.
Firestore יוצר באופן אוטומטי אינדקסים לשאילתות בסיסיות, אבל אפשר להריץ שאילתות שאין להן אינדקס כדי לאפשר ל-Firestore ליצור תחביר של אינדקס, והוא יספק לכם קישור לאינדקס שנוצר בהודעת השגיאה בצד האפליקציה. אלה השלבים ליצירת אינדקס וקטורי:
- מעבר אל טרמינל Cloud Shell
- מריצים את הפקודה הבאה:
gcloud firestore indexes composite create --collection-group="poses" --query-scope=COLLECTION --database="(default)" --field-config vector-config='{"dimension":"768", "flat": "{}"}',field-path="embedding"
מידע נוסף זמין כאן.
אחרי שיוצרים אינדקס וקטורי, אפשר לבצע חיפוש של השכן הקרוב ביותר באמצעות הטמעות וקטוריות.
הערה חשובה:
מכאן ואילך, לא צריך לבצע שינויים במקור. פשוט פועלים לפי ההוראות כדי להבין מה האפליקציה עושה.
ביצוע חיפוש וקטורי
בואו נראה איך האפליקציה החדשה שלכם ניגשת לחיפוש וקטורי. אחרי שמאחסנים את ההטמעות, אפשר להשתמש במחלקה VectorQuery של Firestore Java SDK כדי לבצע חיפוש וקטורי ולקבל תוצאות של השכנים הקרובים ביותר:
CollectionReference coll = firestore.collection("poses");
VectorQuery vectorQuery = coll.findNearest(
"embedding",
userSearchTextEmbedding,
/* limit */ 3,
VectorQuery.DistanceMeasure.EUCLIDEAN,
VectorQueryOptions.newBuilder().setDistanceResultField("vector_distance")
.setDistanceThreshold(2.0)
.build());
ApiFuture<VectorQuerySnapshot> future = vectorQuery.get();
VectorQuerySnapshot vectorQuerySnapshot = future.get();
List<Pose> posesList = new ArrayList<Pose>();
// Get the ID of the closest document (assuming results are sorted by distance)
String closestDocumentId = vectorQuerySnapshot.getDocuments().get(0).getId();
בקטע הקוד הזה מוצגת השוואה בין ההטמעה של טקסט החיפוש של המשתמש לבין ההטמעות של המסמכים ב-Firestore, ומופקת ההטמעה שהכי קרובה מבחינת הקשר.
7. Gemini 2.0 Flash
שילוב של Gemini 2.0 Flash (ליצירת תיאורים)
בואו נראה איך האפליקציה החדשה שלכם מטפלת בשילוב של Gemini 2.0 Flash ליצירת תיאורים.
נניח שמשתמש עם הרשאת אדמין או מדריך יוגה רוצה להזין את פרטי התנוחות בעזרת Gemini 2.0 Flash, ואז לבצע חיפוש כדי לראות את ההתאמות הקרובות ביותר. התוצאה היא חילוץ של פרטי התנוחות התואמות, יחד עם אובייקטים מולטימודאליים שתומכים בתוצאות.
String apiUrl = "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash-exp:generateContent?key=[YOUR_API_KEY]";
Map<String, Object> requestBody = new HashMap<>();
List<Map<String, Object>> contents = new ArrayList<>();
List<Map<String, Object>> tools = new ArrayList<>();
Map<String, Object> content = new HashMap<>();
List<Map<String, Object>> parts = new ArrayList<>();
Map<String, Object> part = new HashMap<>();
part.put("text", prompt);
parts.add(part);
content.put("parts", parts);
contents.add(content);
requestBody.put("contents", contents);
/**Setting up Grounding*/
Map<String, Object> googleSearchTool = new HashMap<>();
googleSearchTool.put("googleSearch", new HashMap<>());
tools.add(googleSearchTool);
requestBody.put("tools", tools);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(requestBody, headers);
ResponseEntity<String> response = restTemplate.exchange(apiUrl, HttpMethod.POST, requestEntity, String.class);
System.out.println("Generated response: " + response);
String responseBody = response.getBody();
JSONObject jsonObject = new JSONObject(responseBody);
JSONArray candidates = jsonObject.getJSONArray("candidates");
JSONObject candidate = candidates.getJSONObject(0);
JSONObject contentResponse = candidate.getJSONObject("content");
JSONArray partsResponse = contentResponse.getJSONArray("parts");
JSONObject partResponse = partsResponse.getJSONObject(0);
String generatedText = partResponse.getString("text");
System.out.println("Generated Text: " + generatedText);
א. חיקוי של יצירת תמונות ואודיו
Gemini 2.0 Flash Experimental יכול ליצור תוצאות מולטימודאליות, אבל עדיין לא נרשמתי לגישה המוקדמת שלו, ולכן חיקיתי את פלט התמונה ופלט האודיו באמצעות ממשקי ה-API של Imagen ו-TTS בהתאמה. תארו לעצמכם כמה נהדר לקבל את כל זה באמצעות קריאה אחת ל-API של Gemini 2.0 Flash.
try (PredictionServiceClient predictionServiceClient =
PredictionServiceClient.create(predictionServiceSettings)) {
final EndpointName endpointName =
EndpointName.ofProjectLocationPublisherModelName(
projectId, location, "google", "imagen-3.0-generate-001");
Map<String, Object> instancesMap = new HashMap<>();
instancesMap.put("prompt", prompt);
Value instances = mapToValue(instancesMap);
Map<String, Object> paramsMap = new HashMap<>();
paramsMap.put("sampleCount", 1);
paramsMap.put("aspectRatio", "1:1");
paramsMap.put("safetyFilterLevel", "block_few");
paramsMap.put("personGeneration", "allow_adult");
Value parameters = mapToValue(paramsMap);
PredictResponse predictResponse =
predictionServiceClient.predict(
endpointName, Collections.singletonList(instances), parameters);
for (Value prediction : predictResponse.getPredictionsList()) {
Map<String, Value> fieldsMap = prediction.getStructValue().getFieldsMap();
if (fieldsMap.containsKey("bytesBase64Encoded")) {
bytesBase64Encoded = fieldsMap.get("bytesBase64Encoded").getStringValue();
}
}
return bytesBase64Encoded;
}
try {
// Create a Text-to-Speech client
try (TextToSpeechClient textToSpeechClient = TextToSpeechClient.create()) {
// Set the text input to be synthesized
SynthesisInput input = SynthesisInput.newBuilder().setText(postureString).build();
// Build the voice request, select the language code ("en-US") and the ssml
// voice gender
// ("neutral")
VoiceSelectionParams voice =
VoiceSelectionParams.newBuilder()
.setLanguageCode("en-US")
.setSsmlGender(SsmlVoiceGender.NEUTRAL)
.build();
// Select the type of audio file you want returned
AudioConfig audioConfig =
AudioConfig.newBuilder().setAudioEncoding(AudioEncoding.MP3).build();
// Perform the text-to-speech request on the text input with the selected voice
// parameters and audio file type
SynthesizeSpeechResponse response =
textToSpeechClient.synthesizeSpeech(input, voice, audioConfig);
// Get the audio contents from the response
ByteString audioContents = response.getAudioContent();
// Convert to Base64 string
String base64Audio = Base64.getEncoder().encodeToString(audioContents.toByteArray());
// Add the Base64 encoded audio to the Pose object
return base64Audio;
}
} catch (Exception e) {
e.printStackTrace(); // Handle exceptions appropriately. For a real app, log and provide user feedback.
return "Error in Audio Generation";
}
}
ב. עיגון בנתונים באמצעות חיפוש Google:
אם בודקים את קוד ההפעלה של Gemini בשלב 6, אפשר לראות את קטע הקוד הבא שמאפשר להשתמש בחיפוש Google כדי להצמיד את התשובה של ה-LLM למציאות:
/**Setting up Grounding*/
Map<String, Object> googleSearchTool = new HashMap<>();
googleSearchTool.put("googleSearch", new HashMap<>());
tools.add(googleSearchTool);
requestBody.put("tools", tools);
הסיבה לכך היא כדי לוודא שאנחנו:
- התבססות של המודל על תוצאות חיפוש בפועל
- שליפת כתובות URL רלוונטיות שמופיעות בחיפוש
8. הרצת האפליקציה
בואו נבחן את כל היכולות של אפליקציית Java Spring Boot החדשה שפיתחתם באמצעות ממשק אינטרנט פשוט של Thymeleaf:
- פעולות CRUD ב-Firestore (יצירה, קריאה, עדכון, מחיקה)
- חיפוש לפי מילות מפתח
- יצירת הקשר באמצעות AI גנרטיבי
- חיפוש לפי הקשר (חיפוש וקטור)
- פלט מולטי-מודאלי שקשור לחיפוש
- הרצת שאילתה משלכם (שאילתות בפורמט structuredQuery)
דוגמה: {"structuredQuery":{"select":{"fields":[{"fieldPath":"name"}]},"from":[{"collectionId":"fitness_poses"}]}}
כל התכונות שצוינו עד עכשיו הן חלק מהאפליקציה שיצרתם עכשיו מהמאגר: https://github.com/AbiramiSukumaran/firestore-poserecommender
כדי לבנות, להריץ ולפרוס את האפליקציה, מריצים את הפקודות הבאות בטרמינל של Cloud Shell:
mvn package
mvn spring-boot:run
אמורה להופיע התוצאה, ותהיה לכם אפשרות להתנסות בתכונות של האפליקציות. כדאי לצפות בסרטון הבא כדי לראות הדגמה של הפלט:
Pose Recommender עם Firestore, Vector Search ו-Gemini 2.0 Flash
שלב אופציונלי:
כדי לפרוס את האפליקציה ב-Cloud Run (בהנחה שיצרתם אפליקציה חדשה לגמרי עם Dockerfile והעתקתם את הקבצים לפי הצורך), מריצים את הפקודה הבאה מ-Cloud Shell Terminal מתוך ספריית הפרויקט:
gcloud run deploy --source .
מזינים את שם האפליקציה, קוד האזור (בוחרים את הקוד של us-central1) ומזינים Y כדי לאשר הפעלה לא מאומתת, כמו שמופיע בהנחיה. אחרי שהפריסה תסתיים בהצלחה, נקודת הקצה של האפליקציה תופיע במסוף.
9. הסרת המשאבים
כדי לא לצבור חיובים לחשבון Google Cloud על המשאבים שבהם השתמשתם במאמר הזה:
- במסוף Google Cloud, עוברים לדף Manage resources.
- ברשימת הפרויקטים, בוחרים את הפרויקט שרוצים למחוק ולוחצים על Delete.
- כדי למחוק את הפרויקט, כותבים את מזהה הפרויקט בתיבת הדו-שיח ולוחצים על Shut down.
10. מזל טוב
מעולה! השתמשתם בהצלחה ב-Firestore כדי ליצור אפליקציה חזקה וחכמה לניהול תנוחות יוגה. שילבנו את היכולות של Firestore, של התוסף Vector Search ואת היכולות של Gemini 2.0 Flash (עם סימולציה של יצירת תמונות ואודיו) כדי ליצור אפליקציית יוגה מרתקת ואינפורמטיבית. האפליקציה מאפשרת לבצע פעולות CRUD, חיפוש מבוסס מילות מפתח, חיפוש וקטורי לפי הקשר ויצירת תוכן מולטימדיה.
הגישה הזו לא מוגבלת לאפליקציות של יוגה. ככל שמודלים של AI כמו Gemini ממשיכים להתפתח, האפשרויות ליצירת חוויות משתמש סוחפות ומותאמות אישית רק יגדלו. כדי להפיק את המרב מהטכנולוגיות האלה, חשוב להתעדכן בחידושים האחרונים ובמסמכי התיעוד של Google Cloud ו-Firebase.
אם הייתי רוצה להרחיב את האפליקציה הזו, הייתי מנסה לעשות שני דברים עם Gemini 2.0 Flash:
- כדי להשתמש ב-API של Multimodal Live, יוצרים סטרימינג של וידאו ואודיו בזמן אמת לתרחיש השימוש.
- כדי שהחוויה תהיה יותר מציאותית, אפשר להפעיל את מצב החשיבה כדי ליצור את המחשבות שמאחורי התשובות לאינטראקציה עם נתונים בזמן אמת.
אתם מוזמנים לנסות ולשלוח בקשת מיזוג :>D!!!