ל-Cloud Functions for Firebase יש שיטה onCallGenkit
שמאפשרת ליצור פונקציה שניתן להפעיל באמצעות פעולת Genkit (Flow). אפשר להפעיל את הפונקציות האלה באמצעות genkit/beta/client
או באמצעות חבילת ה-SDK של לקוח Cloud Functions, שמוסיפה באופן אוטומטי את פרטי האימות.
לפני שמתחילים
- כדאי שתכירו את המושג תהליכים ב-Genkit ואת האופן שבו כותבים אותם. ההוראות בדף הזה מבוססות על ההנחה שכבר הגדרתם תהליכים מסוימים שרוצים לפרוס.
- אם כבר השתמשתם ב-Cloud Functions for Firebase, מומלץ להשתמש ב-Cloud Functions for Firebase, אבל זה לא חובה.
הגדרת פרויקט Firebase
יוצרים פרויקט Firebase חדש באמצעות מסוף Firebase או בוחרים פרויקט קיים.
שדרוג הפרויקט לתוכנית Blaze, שנדרשת לפריסה בסביבת הייצור של Cloud Functions.
מתקינים את Firebase CLI.
מתחברים באמצעות CLI של Firebase:
firebase login
firebase login --reauth # alternative, if necessary
firebase login --no-localhost # if running in a remote shell
יוצרים ספריית פרויקט חדשה:
export PROJECT_ROOT=~/tmp/genkit-firebase-project1
mkdir -p $PROJECT_ROOT
מפעילים פרויקט Firebase בספרייה:
cd $PROJECT_ROOT
firebase init functions
בהמשך הדף נניח שבחרתם לכתוב את הפונקציות ב-JavaScript.
גלישת התהליך ב-onCallGenkit
אחרי שמגדירים פרויקט Firebase עם Cloud Functions, אפשר להעתיק או לכתוב הגדרות של תהליכים בספרייה functions
של הפרויקט. הנה תהליך לדוגמה שממחיש את זה:
const ai = genkit({
plugins: [googleAI()],
model: gemini15Flash,
});
const jokeTeller = ai.defineFlow({
name: "jokeTeller",
inputSchema: z.string().nullable(),
outputSchema: z.string(),
streamSchema: z.string(),
}, async (jokeType = "knock-knock", {sendChunk}) => {
const prompt = `Tell me a ${jokeType} joke.`;
// Call the `generateStream()` method to
// receive the `stream` async iterable.
const {stream, response: aiResponse} = ai.generateStream(prompt);
// Send new words of the generative AI response
// to the client as they are generated.
for await (const chunk of stream) {
sendChunk(chunk.text);
}
// Return the full generative AI response
// to clients that may not support streaming.
return (await aiResponse).text;
},
);
כדי לפרוס תהליך כמו זה, צריך לעטוף אותו ב-onCallGenkit
, שזמין ב-firebase-functions/https
. לשיטת העזרה הזו יש את כל התכונות של פונקציות שניתן להפעיל, והיא תומכת באופן אוטומטי גם בתגובות בסטרימינג וגם בתגובות בפורמט JSON.
const {onCallGenkit} = require("firebase-functions/v2/https");
exports.tellJoke = onCallGenkit({
// Bind the Gemini API key secret parameter to the function.
secrets: [apiKey],
},
// Pass in the genkit flow.
jokeTeller,
);
איך מאפשרים לפרטי כניסה ל-API להיות זמינים לתהליכים שנפרסו
אחרי הפריסה, תצטרכו למצוא דרך לאמת את התהליכים מול כל השירותים המרוחקים שהם מסתמכים עליהם. לכל הפחות, ברוב התהליכים נדרשים פרטי כניסה כדי לגשת לשירות ה-API של המודל שבו הם משתמשים.
בדוגמה הזו, מבצעים אחת מהפעולות הבאות, בהתאם לספק המודל שבחרתם:
Gemini (AI מבית Google)
מוודאים ש-Google AI זמין באזור שלכם.
יוצרים מפתח API ל-Gemini API באמצעות Google AI Studio.
אחסון מפתח ה-API ב-Cloud Secret Manager:
firebase functions:secrets:set GOOGLE_GENAI_API_KEY
השלב הזה חשוב כדי למנוע דליפת מפתח ה-API בטעות, שמעניק גישה לשירות שעשוי להיות מותאם לחיוב.
למידע נוסף על ניהול סודות, ראו אחסון של מידע רגיש בתצורה וגישה אליו.
עורכים את הקובץ
src/index.js
ומוסיפים את הקטע הבא אחרי הייבוא הקיים:const {defineSecret} = require("firebase-functions/params"); // Store the Gemini API key in Cloud Secret Manager. const apiKey = defineSecret("GOOGLE_GENAI_API_KEY");
לאחר מכן, בהגדרה של הפונקציה שניתן לקרוא לה, מכריזים על כך שלפונקציה יש צורך בגישה לערך הסודי הזה:
// Bind the Gemini API key secret parameter to the function. secrets: [apiKey],
עכשיו, כשפורסים את הפונקציה הזו, מפתח ה-API יישמר ב-Cloud Secret Manager ויהיה זמין בסביבה של Cloud Functions.
Gemini (Vertex AI)
במסוף Cloud, מפעילים את Vertex AI API לפרויקט ב-Firebase.
בדף IAM, מוודאים שלחשבון השירות המוגדר כברירת מחדל ל-Compute הוקצה התפקיד Vertex AI User.
הסוד היחיד שצריך להגדיר במדריך הזה הוא של ספק המודל, אבל באופן כללי צריך לעשות משהו דומה לכל שירות שבו נעשה שימוש בתהליך.
(אופציונלי) הוספת אכיפה של בדיקת האפליקציה
Firebase App Check משתמש באימות מקומי כדי לוודא שהקריאה ל-API מתבצעת רק על ידי האפליקציה.
onCallGenkit
תומך באכיפה של בדיקת האפליקציות באופן דקלרטיבי.
export const generatePoem = onCallGenkit({
enforceAppCheck: true,
// Optional. Makes App Check tokens only usable once. This adds extra security
// at the expense of slowing down your app to generate a token for every API
// call
consumeAppCheckToken: true,
}, generatePoemFlow);
הגדרת CORS (שיתוף משאבים בין מקורות)
אפשר להשתמש באפשרות cors
כדי לקבוע לאילו מקורות תהיה גישה לפונקציה.
כברירת מחדל, פונקציות שניתן להפעיל מוגדרות עם CORS שמאפשר בקשות מכל המקורות. כדי לאפשר בקשות מסוימות ממקורות שונים, אבל לא את כולן, מעבירים רשימה של דומיינים ספציפיים או ביטויים רגולריים שצריך לאפשר. לדוגמה:
export const tellJoke = onCallGenkit({
cors: 'mydomain.com',
}, jokeTeller);
דוגמה מלאה
אחרי שמבצעים את כל השינויים שמפורטים למעלה, התהליך לפריסה ייראה בערך כך:
const {onCallGenkit} = require("firebase-functions/v2/https");
const {defineSecret} = require("firebase-functions/params");
// Dependencies for Genkit.
const {gemini15Flash, googleAI} = require("@genkit-ai/googleai");
const {genkit, z} = require("genkit");
// Store the Gemini API key in Cloud Secret Manager.
const apiKey = defineSecret("GOOGLE_GENAI_API_KEY");
const ai = genkit({
plugins: [googleAI()],
model: gemini15Flash,
});
const jokeTeller = ai.defineFlow({
name: "jokeTeller",
inputSchema: z.string().nullable(),
outputSchema: z.string(),
streamSchema: z.string(),
}, async (jokeType = "knock-knock", {sendChunk}) => {
const prompt = `Tell me a ${jokeType} joke.`;
// Call the `generateStream()` method to
// receive the `stream` async iterable.
const {stream, response: aiResponse} = ai.generateStream(prompt);
// Send new words of the generative AI response
// to the client as they are generated.
for await (const chunk of stream) {
sendChunk(chunk.text);
}
// Return the full generative AI response
// to clients that may not support streaming.
return (await aiResponse).text;
},
);
exports.tellJoke = onCallGenkit({
// Bind the Gemini API key secret parameter to the function.
secrets: [apiKey],
},
// Pass in the genkit flow.
jokeTeller,
);
פריסת תהליכים ב-Firebase
אחרי שמגדירים תהליכים באמצעות onCallGenkit
, אפשר לפרוס אותם כמו שפרסתם פונקציות אחרות:
cd $PROJECT_ROOT
firebase deploy --only functions