אתם יכולים להריץ סקריפטים מותאמים אישית בצד השרת לפני ואחרי כל בקשה שהאפליקציה שולחת אל Gemini API דרך Firebase AI Logic – בלי לשנות את קוד הלקוח. מטמיעים את הסקריפטים האלה כפונקציות בסגנון קריאה חוזרת (callback) שמוצבות ב-Cloud Functions for Firebase.
היכולת הזו מאפשרת לכם לבצע פעולות כמו ניהול הנחיות, הגבלת השימוש באסימונים, רישום של יצירות לצורך ניתוח או צנזורה של תוכן בתשובות.
יש שני סוגים של אירועים:
beforeGenerateContent: מופעל לפני שבקשה מגיעה אל Gemini API. הפונקציה יכולה לבדוק או לשנות את הבקשה, או לחסום את הבקשה לחלוטין על ידי הפקת שגיאה.
afterGenerateContent: הפונקציה מופעלת אחרי שהתגובה נשלחת חזרה מ-Gemini API ולפני שהיא מוחזרת לאפליקציית הלקוח. הפונקציה יכולה לבדוק או לשנות את התגובה, לחסום את התגובה לחלוטין או רק לצפות בה (למשל לצורך רישום ביומן או ביקורת).
אחרי שפורסים את הסקריפטים כפונקציות ב-Cloud Functions for Firebase, הם נרשמים כטריגרים של Firebase AI Logic, כלומר הם יפעלו לכל בקשה של generateContent בפרויקט אל Gemini API דרך Firebase AI Logic (כולל בקשות שנוצרו באמצעות תבניות פרומפט של השרת).
הפונקציות האלה לא מופעלות על ידי בקשות שנשלחות אל Gemini API שלא דרך Firebase AI Logic.
דרישות מוקדמות
הגדרה של Firebase AI Logic: אם עדיין לא עשיתם את זה, עליכם להשלים את השלבים במדריך Firebase AI Logicתחילת העבודה. במדריך הזה מוסבר איך להגדיר את פרויקט Firebase, לקשר את האפליקציה ל-Firebase, להוסיף את ה-SDK, לאתחל את שירות ה-Backend עבור ספק Gemini API שבחרתם וליצור מופע
GenerativeModel.הרשאות נדרשות: מוודאים שיש לכם את הרשאות ה-IAM הנדרשות לפריסה ב-Cloud Functions for Firebase.
שלב 1: הגדרת הפרויקט ל-Cloud Functions for Firebase
אם אף פעם לא השתמשתם ב-Cloud Functions for Firebase בפרויקט Firebase, צריך להשלים את ההגדרה הבאה.
חשוב לוודא שפרויקט Firebase שלכם מוגדר למינוי Blaze בתשלום לפי שימוש (נדרש כדי להשתמש ב-Cloud Functions for Firebase).
מתקינים ממשקי שורת פקודה (CLI): gcloud CLI ו- Firebase CLI
נותנים לחשבון השירות שמוגדר כברירת מחדל ב-Compute את התפקיד Cloud Build Service Account (
roles/cloudbuild.builds.builder) שנדרש כדי לבנות את הפונקציה. מריצים את הפקודה הבאה:gcloud CLIgcloud projects add-iam-policy-binding PROJECT_ID \ --member="serviceAccount:PROJECT_NUMBER-compute@developer.gserviceaccount.com" \ --role="roles/cloudbuild.builds.builder"מאתחלים את Cloud Functions for Firebase בפרויקט Firebase:
מריצים את הפקודה הבאה ב-CLI:Firebase
firebase init functionsכשמופיעה בקשה, בוחרים באפשרות TypeScript.
מוודאים שגרסת
firebase-functionsב-functions/package.jsonהיא 6.3.0 ואילך. כך בודקים את הגרסה:npm --prefix functions list firebase-functions
שלב 2: כותבים את הפונקציות
כתיבת פונקציה לפני בקשה (beforeGenerateContent)
כתיבת פונקציה אחרי בקשה (afterGenerateContent)
כתיבת פונקציה לפני בקשה (beforeGenerateContent)
עם סוג האירוע beforeGenerateContent, הפונקציה מופעלת כשה-proxy של Firebase AI Logic מקבל בקשת generateContent. הפונקציה מופעלת על הבקשה לפני שהבקשה נשלחת אל Gemini API.
הפונקציה יכולה לשנות את הבקשה או לחסום אותה לחלוטין.
לפני שכותבים את הפונקציה, חשוב לעיין במידע הבא:
- נתוני אירועים שאפשר להשתמש בהם בפונקציה
- נקודות מרכזיות לגבי פונקציות של בקשות מראש
- מגבלות והתנהגויות של פונקציות
דוגמה
הנה דוגמה לפונקציית pre-request שמבצעת את הפעולות הבאות:
מציינים שהפונקציה תפעל רק אם הבקשה היא לספק Gemini API ספציפי.
בודק את ההנחיה כדי לראות אם יש בה נושאים חסומים, ודוחה את הבקשה על ידי הצגת שגיאה.
הגבלת מספר הטוקנים המקסימלי בפלט של מודלים ליצירת טקסט.
import { logger } from "firebase-functions";
import {
beforeGenerateContent,
HttpsError,
vertexV1Beta1,
type VertexV1Beta1GenerateContentRequest,
} from "firebase-functions/v2/ai";
const BLOCKED_TOPICS = ["weapon", "explosive", "self-harm"];
const MAX_OUTPUT_TOKENS = 4000;
export const guardPrompts = beforeGenerateContent((event) => {
// 1. Optional: If you want the function to only run for a specific Gemini API provider, specify it here.
if (event.data.api !== vertexV1Beta1) return;
const request = event.data.request as VertexV1Beta1GenerateContentRequest;
// 2. Read the prompt: contents[] -> parts[] -> text
const prompt = (request.contents ?? [])
.flatMap((c) => c.parts ?? [])
.map((p) => ("text" in p ? p.text : "") ?? "")
.join(" ")
.toLowerCase();
// 3. Throwing rejects the request. The request is never sent to the Gemini API.
const blocked = BLOCKED_TOPICS.find((t) => prompt.includes(t));
if (blocked) {
logger.warn("Blocked a prompt", { topic: blocked });
throw new HttpsError("invalid-argument", `We don't return content about ${blocked}.`);
}
logger.info("Allowing generation", {
model: event.data.model,
authType: event.authType,
authId: event.authId,
appId: event.appId,
});
// 4. The next step truncates the response, but that will break images.
if (event.data.model.includes("image")) return;
// 5. Return the WHOLE request, edited. Returning nothing leaves it untouched.
return {
...request,
generationConfig: {
...request.generationConfig,
maxOutputTokens: Math.min(
request.generationConfig?.maxOutputTokens ?? MAX_OUTPUT_TOKENS,
MAX_OUTPUT_TOKENS,
),
},
};
});
שיקולים חשובים לגבי פונקציות לפני בקשה
מציינים את ספק Gemini API:
event.data.requestיכול להיות Gemini Developer API או Agent Platform Gemini API (formerly Vertex AI). לאובייקטים של הבקשות בממשקי ה-API השונים האלה יש צורות שונות. כדי לעבוד בבטחה עם אובייקט הבקשה, צריך לבדוק אתevent.data.api(למשל, להשוות ל-geminiV1Betaאו ל-vertexV1Beta1, בהתאמה).הוספת throw חוסמת את הבקשה: אם מוסיפים throw של
HttpsError, הבקשה תידחה.החזרת הבקשה כולה: אם הפונקציה משנה את הבקשה, צריך להחזיר את אובייקט הבקשה המלא והמשונה. אם לא מחזירים כלום (או
undefined), הבקשה לא משתנה.בדיקת זמן האחזור: בהתאם לפעולה של הפונקציה, היא עלולה להוסיף זמן אחזור ולהשפיע על חוויית המשתמש.
כתיבת פונקציה של בקשה (afterGenerateContent)
בסוג האירוע afterGenerateContent, הפונקציה מופעלת כשה-proxy של Firebase AI Logic מקבל תגובה מבקשת generateContent. הפונקציה מופעלת על התשובה לפני שהתשובה מוחזרת לאפליקציית הלקוח. הפונקציה יכולה לרשום את השימוש, לשנות את התשובה או לחסום אותה לחלוטין.
לפני שכותבים את הפונקציה, חשוב לעיין במידע הבא:
- נתוני אירועים שאפשר להשתמש בהם בפונקציה
- שיקולים חשובים לגבי פונקציות אחרי בקשה
- מגבלות והתנהגויות של פונקציות
דוגמה
הנה דוגמה לפונקציה post-request שמתעדת את השימוש בטוקן ואת הסיבה לסיום:
import { logger } from "firebase-functions";
import {
afterGenerateContent,
vertexV1Beta1,
type VertexV1Beta1GenerateContentResponse,
} from "firebase-functions/v2/ai";
export const recordGenerationUsage = afterGenerateContent((event) => {
// Optional: If you want the function to only run for a specific Gemini API provider, specify it here.
if (event.data.api !== vertexV1Beta1) return;
const response = event.data.response as VertexV1Beta1GenerateContentResponse;
logger.info("Generation finished", {
model: event.data.model,
promptTokens: response.usageMetadata?.promptTokenCount,
totalTokens: response.usageMetadata?.totalTokenCount,
finishReason: response.candidates?.[0]?.finishReason,
});
// To leave the response untouched, return nothing.
// To modify the response, return a modified response object here.
});
שיקולים חשובים לגבי פונקציות אחרי בקשה
מציינים את ספק Gemini API:
event.data.responseיכול להיות Gemini Developer API או Agent Platform Gemini API (formerly Vertex AI). כדי להשתמש בבטחה באובייקט הבקשה, צריך לבדוק אתevent.data.api(למשל, להשוות ל-geminiV1Betaאו ל-vertexV1Beta1, בהתאמה).בדיקת זמן האחזור: בהתאם לפעולה של הפונקציה, היא עלולה להוסיף זמן אחזור ולהשפיע על חוויית המשתמש.
שלב 3: פריסת הפונקציות
פריסת הפונקציות ב-Firebase מעניקה לסוכן השירות Firebase AI Logic הרשאה להפעיל את הפונקציות האלה, ורושמת כל פונקציה כטריגר Firebase AI Logic.
פורסים את הפונקציות באמצעות Firebase CLI:
firebase deploy --only functionsאחרי הפריסה, מוודאים שהפונקציות נפרסו ב-Firebase:
firebase functions:listאם אתם צריכים לבצע איטרציה בפונקציה:
מעדכנים את הפונקציה בספריית הפרויקט ומריצים את
firebase deploy --only functionsשוב.
הפסקת ההרצה של פונקציה
כדי להפסיק את ההרצה של אחת מהפונקציות האלה, צריך למחוק אותה מהשרתים שלנו ולבטל את הרישום שלה כFirebase AI Logic טריגר. אפשר לעשות את זה באמצעות Firebase CLI באחת מהדרכים הבאות:
אפשרות 1: מחיקה משתמעת של הפונקציה
מסירים את הפונקציה מבסיס הקוד של ספריית הפרויקט.
מריצים את הפקודה הבאה ב-CLI:Firebase
firebase deploy --only functions
אפשרות 2: מחיקה מפורשת של הפונקציה
מסירים את הפונקציה מבסיס הקוד של ספריית הפרויקט.
מריצים את הפקודה הבאה Firebaseב-CLI:
firebase functions:delete FUNCTION_NAME
מידע על נתוני אירועים
גם beforeGenerateContent וגם afterGenerateContent מקבלים אובייקט AIBlockingEvent שמכיל הקשר ומטא-נתונים לגבי הבקשה.
מטא-נתונים של בקשה ברמה העליונה (AIBlockingEvent)
אובייקט AIBlockingEvent ברמה העליונה מספק מידע על המתקשר ועל סביבת ההפעלה:
-
event.authType: מצב האימות של המתקשר:"app_user", "unauthenticated"או"unknown". -
event.authId: ה-UID של המתקשר באימות ב-Firebase, אם הוא מחובר לחשבון. -
event.authClaims: טענות אימות מותאמות אישית של המתקשר, אם יש כאלה. -
event.appId: מזהה האפליקציה ב-Firebase ששלחה את הבקשה. -
event.androidPackageName/event.iosBundleId: שם החבילה או מזהה החבילה של האפליקציה שקוראת (רלוונטי לפלטפורמות Android או Apple, בהתאמה). -
event.data: מטען הייעודי (payload) של האירוע, ששונה בין פונקציות שלפני הבקשה לבין פונקציות שאחרי הבקשה:- עבור
beforeGenerateContent, זהו אובייקטBeforeGenerateContentData. - עבור
afterGenerateContent, זהו אובייקטAfterGenerateContentData.
- עבור
נתוני אירועים לפני בקשה (beforeGenerateContent)
בפונקציה beforeGenerateContent, הערך event.data מאוכלס באובייקט BeforeGenerateContentData:
-
event.data.api: הספק Gemini API:geminiV1Beta(Gemini Developer API) אוvertexV1Beta1(Agent Platform Gemini API (formerly Vertex AI)). -
event.data.model: נתיב המשאב המלא של המודל (לדוגמה,projects/{PROJECT_ID}/locations/global/publishers/google/models/gemini-3.8-flash). -
event.data.template: מטא-נתונים על תבנית לפרומפט של השרת שנעשה בה שימוש (PromptTemplateInfo), אם רלוונטי. -
event.data.request: מטען הייעודי (payload) של הבקשה היוצאת. סוג האובייקט והמאפיינים תלויים בספק Gemini API:- Gemini Developer API (
geminiV1Beta):GeminiV1BetaGenerateContentRequest - Agent Platform Gemini API (formerly Vertex AI) (
vertexV1Beta1):VertexV1Beta1GenerateContentRequest
- Gemini Developer API (
נתוני אירועים אחרי בקשה (afterGenerateContent)
בפונקציה afterGenerateContent, הפרמטר event.data מאוכלס באובייקט AfterGenerateContentData. האובייקט הזה מרחיב את BeforeGenerateContentData (מספק api, model, template ו-request) ומוסיף את התגובה של המודל:
-
event.data.response: מטען הייעודי (payload) של התגובה של המודל. סוג האובייקט והמאפיינים תלויים בספק Gemini API:- Gemini Developer API (
geminiV1Beta):GeminiV1BetaGenerateContentResponse - Agent Platform Gemini API (formerly Vertex AI) (
vertexV1Beta1):VertexV1Beta1GenerateContentResponse
- Gemini Developer API (
מגבלות והתנהגויות
כשמטמיעים את הפונקציות האלה, חשוב לזכור את ההתנהגויות והמגבלות הבאות:
בקשות
generateContentבלבד: אפשר להפעיל את הפונקציות האלה רק באמצעות בקשותgenerateContentאל Gemini API דרך Firebase AI Logic.הפעולות הבאות לא יפעילו את הפונקציות האלה, והפונקציות יעקפו את הבקשה בשקט:
בקשות ל-
generateContentStreamלא יפעילו את הפונקציות האלה.בקשות אל Gemini Live API לא יפעילו את הפונקציות האלה.
אין צורך לבצע שינויים בקוד בצד הלקוח: כדי להריץ את הפונקציות האלה, צריך לוודא שאתם משתמשים בבקשות מסוג
generateContent, אבל לא נדרשים שינויים אחרים בבסיס הקוד בצד הלקוח.הפונקציות האלה נפרסות בשרתים שלנו ונרשמות כטריגרים של Firebase AI Logic, כדי ששרת ה-proxy של Firebase AI Logic יוכל ליירט בקשות ותגובות בצד השרת.
היקף ברמת הפרויקט: אפשר לפרוס לכל היותר פונקציה אחת של
beforeGenerateContentופונקציה אחת שלafterGenerateContentלכל פרויקט Firebase.מיקומי ברירת מחדל: הפונקציות האלה יופעלו ב-
us-central1כברירת מחדל (מידע על מיקומים של פונקציות). עם זאת, הפונקציה תירשם כטריגר Firebase AI Logic באזורglobal, בלי קשר למיקום שבו תפרסו את הפונקציה.