1. מבוא
אתם אוהבים להתעמק בספרים אבל אתם מתקשים לבחור מתוך המבחר העצום? נסו לדמיין אפליקציה מבוססת-AI שממליצה לא רק על הקריאה המושלמת, אלא גם מציעה סיכום תמציתי על סמך הז'אנר שבחרתם, כדי לתת לכם הצצה לעצמת הספר. ב-codelab הזה אראה לכם איך ליצור אפליקציה כזו באמצעות BigQuery ו-Cloud Functions שמבוססים על Gemini.
סקירה כללית של הפרויקט
התרחיש לדוגמה שלנו מתמקד ב-4 הרכיבים העיקריים הבאים:
- מסד נתונים של ספרים: מערך הנתונים הציבורי העצום של BigQuery של ספרים בארכיון האינטרנט ישמש כקטלוג הספרים המקיף שלנו.
- AI Summarization Engine: Google Cloud Functions, שכולל את מודל השפה Gemini-Pro, ייצור סיכומים מועילים שמותאמים לבקשות המשתמשים.
- שילוב של BigQuery: פונקציה מרוחקת בתוך BigQuery שמפעילה את הפונקציה של Cloud Functions כדי לספק סיכומים ונושאים של ספרים על פי דרישה.
- ממשק משתמש: אפליקציית אינטרנט שמתארחת ב-Cloud Run ותציע אפליקציית אינטרנט למשתמשים כדי להציג את התוצאות.
נחלק את ההטמעה ל-3 Codelabs:
Codelab 1: שימוש ב-Gemini כדי ליצור פונקציית Java Cloud לאפליקציית Gemini.
Codelab 2: איך משתמשים ב-Gemini כדי לפתח אפליקציות בינה מלאכותית גנרטיבית ל-SQL בלבד באמצעות BigQuery.
Codelab 3: שימוש ב-Gemini כדי ליצור אפליקציית אינטרנט של Java Spring Boot שמקיימת אינטראקציה עם BigQuery.
2. שימוש ב-Gemini ליצירת אפליקציה של AI גנרטיבי ללא שרת (serverless) ב-Java Cloud Function
מה תפַתחו
תיצור
- אפליקציית Java Cloud Functions שמטמיעה את Gemini 1.0 Pro כדי לקבל הנחיה ספציפית כקלט בצורת מערך JSON ולהחזיר תגובה (ערך JSON שמסומן בתווית 'replies').
- תבצעו את שלבי ה-build והפריסה בעזרת Gemini
3. דרישות
אלה הדרישות המקדימות:
יצירת הפרויקט
- במסוף Google Cloud, בדף בורר הפרויקטים, בוחרים או יוצרים פרויקט ב-Google Cloud.
- הקפידו לוודא שהחיוב מופעל בפרויקט שלכם ב-Cloud. כך בודקים אם החיוב מופעל בפרויקט
הפעלת Cloud Shell
- נשתמש ב-Cloud Shell, סביבת שורת פקודה שפועלת ב-Google Cloud ומגיעה עם bq טעון מראש:
במסוף Cloud, לוחצים על Activate Cloud Shell בפינה הימנית העליונה: .
- אחרי שתתחברו ל-Cloud Shell, אמורה להופיע הודעה על כך שהאימות כבר בוצע והפרויקט כבר מוגדר לפי מזהה הפרויקט שלכם. מריצים את הפקודה הבאה ב-Cloud Shell כדי לוודא שהאימות בוצע:
gcloud auth list
- מריצים את הפקודה הבאה ב-Cloud Shell כדי לוודא שהפקודה ב-gcloud יודעת על הפרויקט שלכם.
gcloud config list project
- אם הפרויקט לא מוגדר, משתמשים בפקודה הבאה כדי להגדיר אותו:
gcloud config set project <YOUR_PROJECT_ID>
עיינו במסמכי העזרה לפקודות ולשימוש של gcloud.
4. הפעלת Gemini ל-Google Cloud וממשקי ה-API הנדרשים
הפעלה של Gemini
- כדי להפעיל את ה-API, נכנסים לדף Gemini ל-Google Cloud ב-Marketplace. אפשר גם להשתמש בפקודה הבאה:
gcloud services enable cloudaicompanion.googleapis.com --project PROJECT_ID
- נכנסים לדף של Gemini ולוחצים על 'התחלת צ'אט'.
חשוב: כדי להתחיל להשתמש ב-Gemini ולהפעיל את Gemini ב-IDE של Cloud Shell, פועלים לפי שלבים 1 ו-2 בcodelab הזה.
הפעלת ממשקי API נחוצים אחרים
איך עושים את זה? נשאל את Gemini, בסדר? אבל לפני כן, חשוב לזכור:
LLMs הם לא גורמים חד-משמעיים. לכן, כשמנסים את ההנחיות האלה, התשובה שתקבלו עשויה להיראות שונה מהתשובות שמוצגות בצילום המסך שלי.
כדי לעבור למסוף הצ'אט של Gemini, לוחצים על הסמל 'פתיחת Gemini' בפינה השמאלית העליונה של מסוף Google Cloud, ליד סרגל החיפוש.
מקלידים את השאלה הבאה בקטע 'הזנת הנחיה כאן':
How do I enable the cloud functions api using a gcloud command?
התגובה אמורה להיראות כך:
gcloud services enable cloudfunctions.googleapis.com
מעתיקים את הקוד (אפשר להשתמש בסמל ההעתקה בחלק העליון של קטע הקוד) ומריצים אותו ב-Cloud Shell Terminal כדי להפעיל את Cloud Functions. מבצעים את אותו תהליך ב-Cloud Run, כי אנחנו צריכים את שניהם כדי ליצור ולפרוס את Cloud Functions:
gcloud services enable \
cloudfunctions.googleapis.com \
aiplatform.googleapis.com \
run.googleapis.com \
cloudbuild.googleapis.com
5. הכנת התבנית של Cloud Functions עם Gemini
בשלב הזה, אנחנו יוצאים מנקודת הנחה שכבר הפעלת את Gemini בסביבת הפיתוח המשולבת של Cloud Shell.
פותחים את Cloud Shell Editor בלחיצה על הסמל Open Editor בפינה הימנית העליונה של הטרמינל ב-Cloud Shell (בדרך כלל אני מעדיפים לפתוח את הטרמינל ואת העורך במקביל בכרטיסיות נפרדות, כדי שנוכל לכתוב קוד באחד וליצור באחר).
אחרי שפותחים את העורך, מוודאים שלוגו Gemini בפינה השמאלית התחתונה של מסוף העורך פעיל (ולא מבוטל). כמו כן, צריך לוודא שהפרויקט ב-Google Cloud, שמופיע בפינה הימנית התחתונה, מפנה לפרויקט הפעיל הנוכחי שאיתו אתם רוצים לעבוד. אם הם לא פעילים, לוחצים עליהם, נותנים הרשאה, בוחרים את פרויקט Google Cloud שאליו רוצים שהם יצביעו ומפעילים אותם.
לאחר ששניהם פעילים, לוחצים על שם הפרויקט בפינה הימנית התחתונה, וברשימה הקופצת שנפתחת בשם Cloud Code, גוללים למטה אל New Application (אפליקציה חדשה).
ברשימה הזו, בוחרים באפליקציית Cloud Functions. ברשימה הקופצת, בוחרים באפשרות Java:
ברשימת הפרויקטים שתופיע, מקלידים את שם הפרויקט 'duetai-gemini-calling' במקום helloworld ולוחצים על 'אישור'.
מעולה! השתמשתם ב-Gemini כדי להפעיל את אפליקציית Java Cloud Functions הפשוטה שלכם, ולא עשיתם הרבה מלבד הפעלת הגדרות והפעלתן, נכון?
זה מבנה הפרויקט שאתם אמורים לראות:
עכשיו אפשר לפרוס את הפונקציה. אבל לא זו הסיבה שהתחלנו את זה. עכשיו נמשיך ונבנה את ההטמעה של Gemini Pro API ב-Cloud Function הזה באמצעות Java SDK.
עכשיו נבנה את הפונקציונליות של תרחיש לדוגמה שלנו, שמפעיל את מודל Gemini Pro בפונקציה הזו של Cloud Functions. כדי לעשות זאת, אתם יכולים להוסיף הנחיות נוספות ולפתח את הקוד באופן מצטבר באמצעות Gemini, או לכתוב את הלוגיקה בעצמכם. אני אשתמש בשילוב של שניהם.
6. הוספת יחסי תלות
במסוף הצ'אט של Gemini (זה שב-Cloud Code Editor בחלונית שמשמאל), מקלידים את ההנחיה הבאה:
what is the maven dependency for com.google.cloud.vertexai library
הסיבה לבקשה שלי ספציפית לחבילה של com.google.cloud.vertexai היא כי זה מה שהשתמשתי בו בקוד המקור שלי כשהטמעתי את קוד ההפעלה של Gemini.
קיבלתי את התוצאה הבאה:
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-vertexai</artifactId>
<version>0.1.0</version>
</dependency>
מעתיקים את הקוד הזה ומדביקים אותו בקובץ pom.xml, לפני התג </dependencies>. מחליפים את הגרסה ב-0.1.0 (אפשר להסיר את התג <version> אם אתם משתמשים ב-Spring Cloud GCP BOM כדי לנהל את מספרי הגרסאות של spring-cloud-gcp).
הקטע של יחסי התלות אמור להיראות כך:
אם צריך, חשוב לעדכן את מספרי הגרסאות כך שיתאימו למה שמפורט למעלה. שימו לב שצירפתי גם יחסי תלות אחרים:
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.10</version>
</dependency>
7. שינוי של נקודת הכניסה ושם הכיתה של הפונקציה
- מנווטים לקובץ 'launch.json' בתיקייה ' .vscode'. עורכים את שם הפונקציה מ-'function-hello-world' ל-'function-gemini-calling'.
- מעדכנים את הערך valuePoint מ-'cloudcode.helloworld.HelloWorld' ל-cloudcode.bookshelf.Bookshelf.
- עכשיו עוברים לקובץ הכיתה של Java "HelloWorld.java". משנים את שם החבילה ל-package cloudcode.bookshelf;. בהודעת השגיאה שמופיעה, לוחצים על הנורה הצהובה ואז על האפשרות 'העברת HelloWorld.java' לחבילה cloudcode.bookshelf;.
- מעדכנים את שם הכיתה ל-Bookshelf, ובהודעת השגיאה שמופיעה לוחצים על הנורה הצהובה הקטנה ובוחרים באפשרות 'שינוי שם הקובץ ל-Bookshelf.java'. בוחרים באפשרות הזו.
8. יצירת השיטה שמפעילה את Gemini Pro
ניישם את הפונקציונליות הזו במחלקה Bookshelf.java. מחליפים את Bookshelf.java בקוד הבא:
package cloudcode.bookshelf;
import java.io.BufferedWriter;
import com.google.cloud.functions.HttpFunction;
import com.google.cloud.functions.HttpRequest;
import com.google.cloud.functions.HttpResponse;
import com.google.cloud.vertexai.VertexAI;
import com.google.cloud.vertexai.api.GenerateContentResponse;
import com.google.cloud.vertexai.api.GenerationConfig;
import com.google.cloud.vertexai.generativeai.preview.GenerativeModel;
import com.google.cloud.vertexai.generativeai.preview.ResponseHandler;
import java.io.IOException;
import java.util.List;
import java.util.Arrays;
import java.util.Map;
import java.util.LinkedHashMap;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.JsonArray;
public class Bookshelf implements HttpFunction {
private static final Gson gson = new Gson();
@Override
public void service(HttpRequest request, HttpResponse response) throws Exception {
BufferedWriter writer = response.getWriter();
// Get the request body as a JSON object.
JsonObject requestJson = new Gson().fromJson(request.getReader(), JsonObject.class);
JsonArray calls_array = requestJson.getAsJsonArray("calls");
JsonArray calls = (JsonArray) calls_array.get(0);
String context = calls.get(0).toString().replace("\"", "");
//Invoke Gemini model
String raw_result = callGemini(context);
raw_result = raw_result.replace("\n","");
String trimmed = raw_result.trim();
List<String> result_list = Arrays.asList(trimmed);
Map<String, List<String>> stringMap = new LinkedHashMap<>();
stringMap.put("replies", result_list);
// Serialization
String return_value = gson.toJson(stringMap);
writer.write(return_value);
}
public String callGemini(String context) throws IOException{
String res = "";
try (VertexAI vertexAi = new VertexAI("REPLACE_WITH_YOUR_PROJECT_ID", "us-central1"); ) {
GenerationConfig generationConfig =
GenerationConfig.newBuilder()
.setMaxOutputTokens(2048)
.setTemperature(0.4F)
.setTopK(32)
.setTopP(1)
.build();
GenerativeModel model = new GenerativeModel("gemini-pro", generationConfig, vertexAi);
GenerateContentResponse response = model.generateContent(context);
res = ResponseHandler.getText(response);
}catch(Exception e){
System.out.println(e);
}
return res;
}
}
בכיתה הזו צריך להזין קלט במבנה JSON כפי שמתואר בהמשך:
{ "calls": [["YOUR_PROMPT_HERE"]] }
התגובה שתקבלו תהיה:
(Json) Map<String, List<String>> {"replies": ["response"]}
אפשר לנסות את האפשרות של Gemini Chat דרך Cloud Shell Editor בחלונית הימנית כדי להסביר את הקוד. לחלופין, אפשר לבחור את כל הקוד וללחוץ על הנורה הצהובה בפינה הימנית העליונה של החלק שנבחר, ואז לבחור באפשרות 'הסבר על הקוד הזה'.
9. פריסת הפונקציה ב-Cloud Functions
עכשיו, כשהפונקציה של Cloud Functions מוכנה, נשאל את Gemini איך לפרוס אותה. עוברים לצ'אט של Gemini בעורך Cloud Code ומזינים את הפקודה הבאה:
How to deploy this Cloud Function with a gcloud command?
קיבלתי את התשובה הבאה:
עכשיו רציתי לבדוק את זה לעומק. אז ביקשתי מ-Gemini לתת לי את הפקודה המלאה של gcloud functions deploy. התגובה אמורה להיראות כך:
לא אוכל לומר אם תקבל את אותה תשובה, אבל לידיעתך, לטעמי זה מעניין מאוד לראות שהיא כוללת עוד כמה פרטים, כפי שמוצג בתמונה שבהמשך:
הפורמט של גוף הבקשה:
וגם
פורמט התגובה:
עכשיו נפרוס את הפונקציה על ידי הפעלת פקודת gcloud שקיבלנו מ-Gemini. לשם כך, צריך לפתוח את Cloud Shell Terminal. אפשר לפתוח אותו בכרטיסייה חדשה בכתובת https://console.cloud.google.com ולוודא שבחרתם את הפרויקט הנכון. פותחים את Cloud Shell Terminal בלחיצה על הסמל של Activate Cloud Shell בפינה הימנית העליונה של המסוף, ומוודאים שנמצאים בתיקיית הפרויקט הנכונה באמצעות הפקודה הבאה:
cd duetai-gemini-calling
ואז את הפקודה הבאה:
gcloud functions deploy bookshelf --runtime java17 --trigger-http --entry-point cloudcode.bookshelf.Bookshelf --allow-unauthenticated
תוצג השאלה 'Allow unauthenticated invocations of new function [bookshelf]?' (האם לאפשר הפעלות לא מאומתות של פונקציה חדשה [bookshelf]?). אומרים "y" ומקישים על Enter. לאחר מכן יהיו כמה שאלות, אם הדבר רלוונטי, והמערכת תפרוס את הפונקציה של Cloud Functions ללא שרת (serverless) עם כתובת ה-URL שנפרסה: https://us-central1-*******.cloudfunctions.net/bookshelf.
עכשיו נפעיל את Cloud Functions שנפרס ונבדוק אותו.
הערה: אם דלגתם בטעות על השאלה 'Allow unauthenticated invocations' (הרשאה להפעלות לא מאומתות) או שבחרתם באפשרות 'N', לא תוכלו לגשת לתוצאה של Cloud Functions ותופיע הודעת השגיאה 'permissions error' (שגיאת הרשאות) בלי להעניק הגדרות IAM נוספות. לכן חשוב לשים לב לזה.
10. שליחת קריאה לפונקציה של Cloud Functions שנפרסה
רוצה שנשאל את Gemini? הזנתי את ההנחיה
How to call the deployed cloud function?
קיבלתי את התוצאה הבאה: (יכול להיות שתקבלו את אותה תשובה בדיוק, ויכול להיות שלא. אפשר להתנסות בהנחיה ולראות את ההבדלים בתשובות).
כדאי לשאול שאלות ספציפיות בצ'אט לגבי דרכים חלופיות להפעלת הפונקציה שנפרסה, קריאה באמצעות פקודת gcloud וכו'. שלחתי את ההנחיה הבאה:
how to call the deployed cloud function using gcloud
קיבלתי את התשובה הבאה:
אפשר להשתמש בתגובה הזו (הפקודה 'gcloud functions call') מהמסוף עם שינויים כדי שתתאים לתרחיש שלנו (לחלופין, אפשר לנסות להעביר את הפרמטרים בהנחיה עצמה ולבדוק אם ניתן לקבל את הקריאה המפורטת של gcloud functions בתגובה):
gcloud functions call bookshelf --region=us-central1 --gen2 --data '{"calls":[["Hello! This is my test prompt."]]}'
הנה התוצאה שלי:
11. הסרת המשאבים
כדי למחוק את הפונקציות של Cloud Functions שיצרתם מקודם, לוחצים על הלחצן DELETE בדף הפרטים של Cloud Functions.
12. מזל טוב
סיימתם ליצור, לפרוס ולבדוק פונקציה של Java Cloud Functions כדי לבצע קריאה ל-Gemini 1.0 Pro באמצעות Gemini. האפליקציה הזו מקבלת את הבקשה להזנת קלט שקשורה להמלצה על ספרים, עם הסיכום והנושא של הספרים.