הפעלת תהליכים של Genkit מהאפליקציה

ל-Cloud Functions for Firebase יש method onCallGenkit שמאפשרת ליצור פונקציה שאפשר להפעיל עם פעולה Genkit (תהליך). אפשר להפעיל את הפונקציות האלה באמצעות genkit/beta/client או Cloud Functions for Firebase Client SDK, שמוסיפות באופן אוטומטי פרטי אימות.

לפני שמתחילים

  • חשוב להכיר את המושג של Genkit תהליכי עבודה ואיך כותבים אותם. ההוראות בדף הזה מניחות שכבר הגדרתם כמה תהליכים שאתם רוצים לפרוס.
  • זה יעזור, אבל לא חובה, אם השתמשתם ב-Cloud Functions for Firebase בעבר.

הגדרת פרויקט Firebase

  1. יוצרים פרויקט חדש ב-Firebase באמצעות Firebaseהמסוף או בוחרים פרויקט קיים.

  2. משדרגים את הפרויקט לתוכנית התמחור Blaze בתשלום לפי שימוש, שנדרשת לCloud Functionsפריסה בסביבת ייצור.

  3. מתקינים את Firebase CLI.

  4. מתחברים אל Firebase CLI:

    firebase login
    firebase login --reauth # alternative, if necessary
    firebase login --no-localhost # if running in a remote shell
  5. יוצרים ספריית פרויקט חדשה:

    export PROJECT_ROOT=~/tmp/genkit-firebase-project1
    mkdir -p $PROJECT_ROOT
  6. מאתחלים פרויקט 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/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)

  1. יצירת מפתח API ל-Gemini Developer API באמצעות Google AI Studio.

  2. מאחסנים את מפתח ה-API ב-Google Cloud Secret Manager:

    firebase functions:secrets:set GOOGLE_GENAI_API_KEY

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

    מידע נוסף על ניהול סודות זמין במאמר אחסון וגישה למידע רגיש על הגדרות.

  3. עורכים את 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 מאוחסן ב-Google Cloud Secret Manager וזמין בסביבת Cloud Functions.

‫Gemini (Vertex AI)

  1. במסוף Google Cloud, מפעילים את Vertex AI API בפרויקט Firebase.

  2. בדף IAM, מוודאים שלחשבון השירות שמוגדר כברירת מחדל ל-Compute הוקצה התפקיד משתמש ב-Vertex AI.

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

(אופציונלי) הוספת אכיפה של Firebase App Check

‫Firebase App Check משתמש באימות מקורי כדי לוודא שממשק ה-API שלנו נקרא רק על ידי האפליקציה שלכם. השיטה onCallGenkit תומכת באכיפה הצהרתית של App Check.

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/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