میتوانید اسکریپتهای سفارشی سمت سرور خودتان را قبل و بعداز هر درخواستی که برنامهتان ازطریق Firebase AI Logic به Gemini API ارسال میکند اجرا کنید — بدون تغییر دادن کد مشتری. این اسکریپتها را بهعنوان توابع سبک فراخوانی برگشتی که در 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، افزودن کیت توسعه نرمافزار، مقداردهی اولیه سرویس پسبک برای ارائهدهنده Gemini API انتخابی، و ایجاد نمونه
GenerativeModelرا شرح میدهد.اجازههای لازم: مطمئن شوید که اجازههای لازم IAM را برای استقرار در Cloud Functions for Firebase دارید.
مرحله ۱: راهاندازی پروژه برای Cloud Functions for Firebase
اگر هرگز از Cloud Functions for Firebase در پروژه Firebase خود استفاده نکردهاید، راهاندازی زیر را تکمیل کنید.
مطمئن شوید پروژه Firebase شما در طرح قیمتگذاری Blaze پرداخت به اندازه استفاده (برای استفاده از Cloud Functions for Firebase لازم است) باشد.
میاناهای خط فرمان (CLI) را نصب کنید: gcloud CLI و Firebase CLI
به حساب سرویس محاسباتی پیشفرض، نقش حساب سرویس Cloud Build (
roles/cloudbuild.builds.builder) را که برای ساختن تابع شما نیاز دارد اعطا کنید. فرمان gcloud CLI زیر را اجرا کنید:gcloud 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 خود مقداردهی اولیه کنید:
فرمان Firebase CLI زیر را اجرا کنید:
firebase init functionsوقتی درخواست شد، TypeScript را انتخاب کنید.
مطمئن شوید
firebase-functionsدرfunctions/package.jsonشما نسخه ۶.۳.۰ یا جدیدتر باشد. در اینجا نحوه بررسی نسخه آمده است:npm --prefix functions list firebase-functions
مرحله ۲: نوشتن توابع
نوشتن تابع پیشدرخواست (beforeGenerateContent)
نوشتن تابع پسدرخواست (afterGenerateContent)
نوشتن تابع پیشدرخواست (beforeGenerateContent)
با نوع رویداد beforeGenerateContent، وقتی پراکسی Firebase AI Logic درخواست generateContent را دریافت میکند، تابع راهاندازی میشود. تابع
پیشاز ارسال درخواست به Gemini API، درخواست را اجرا میکند.
این تابع میتواند درخواست را اصلاح کند یا درخواست را بهطور کامل مسدود کند.
پیشاز نوشتن تابع، حتماً اطلاعات زیر را مرور کنید:
- دادههای رویداد که میتوانید در تابع خود استفاده کنید
- ملاحظات کلیدی برای توابع پیشدرخواست
- محدودیتها و رفتارهای توابع
مثال
در اینجا یک نمونه تابع پیشدرخواست آورده شده است که کارهای زیر را انجام میدهد:
مشخص میکند که عملکرد فقط زمانی باید اجرا شود که درخواست برای ارائهدهنده 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) باشد. اشیاء درخواست برای این میاناهای برنامهسازی کاربردی مختلف شکلهای متفاوتی دارند. برای کار کردن ایمن با شیء درخواست، بایدevent.data.apiرا بررسی کنید (برای مثال، بهترتیب باgeminiV1BetaیاvertexV1Beta1مقایسه کنید).پرتاب کردن درخواست را مسدود میکند: اگر
HttpsErrorپرتاب کنید، درخواست رد خواهد شد.برگرداندن کل درخواست: اگر تابع شما درخواست را اصلاح میکند، باید شیء درخواست کامل و اصلاحشده را برگردانید. اگر چیزی (یا
undefined) برنگردانید، درخواست بدون تغییر باقی میماند.آزمایش تأخیر: بسته به اینکه تابع شما چه کاری انجام میدهد، ممکن است تأخیر اضافه کند و بر تجربه کاربر تأثیر بگذارد.
نوشتن تابع پسدرخواست (afterGenerateContent)
با نوع رویداد afterGenerateContent، وقتی پراکسی Firebase AI Logic پاسخی از درخواست generateContent دریافت میکند، تابع راهاندازی میشود. تابع درمقابل پاسخ قبلاز برگردانده شدن پاسخ به برنامه کارخواه اجرا میشود. تابع میتواند استفاده را ثبت کند، پاسخ را اصلاح کند، یا پاسخ را کاملاً مسدود کند.
پیشاز نوشتن تابع، حتماً اطلاعات زیر را مرور کنید:
- دادههای رویداد که میتوانید در تابع خود استفاده کنید
- ملاحظات کلیدی برای توابع پساز درخواست
- محدودیتها و رفتارهای توابع
مثال
در اینجا نمونهای از تابع درخواست پست آورده شده است که استفاده از توکن و دلیل پایان را ثبت میکند:
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مقایسه کنید).آزمایش تأخیر: بسته به اینکه تابع شما چه کاری انجام میدهد، ممکن است تأخیر اضافه کند و بر تجربه کاربر تأثیر بگذارد.
مرحله ۳: استقرار توابع
استقرار توابع در 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 با یکی از گزینههای زیر انجام دهید:
گزینه ۱: حذف تابع بهطور ضمنی
تابع را از پایگاه کد دایرکتوری پروژه بردارید.
فرمان CLI Firebase زیر را اجرا کنید:
firebase deploy --only functions
گزینه ۲: حذف صریح تابع
تابع را از پایگاه کد دایرکتوری پروژه بردارید.
فرمان Firebase CLI زیر را اجرا کنید:
firebase functions:delete FUNCTION_NAME
مرجع دادههای رویداد
هر دو beforeGenerateContent و afterGenerateContent یک شیء
AIBlockingEvent
دریافت میکنند که حاوی بافت و فراداده درباره درخواست است.
فراداده درخواست سطح بالا (AIBlockingEvent)
شیء سطح بالا
AIBlockingEvent
اطلاعاتی درباره تماسگیرنده و محیط راهانداز ارائه میدهد:
event.authType: وضعیت اصالتسنجی برای تماسگیرنده:"app_user"،"unauthenticated"، یا"unknown".event.authId: شناسه Firebase Authentication تماسگیرنده، درصورت ورود به سیستم.event.authClaims: ادعاهای اصالتسنجی سفارشی تماسگیرنده، درصورت وجود.event.appId: شناسه Firebase App که درخواست را ایجاد کرده است.event.androidPackageName/event.iosBundleId: نام بسته یا شناسه بسته ترکیبی برنامه تماسگیرنده (بهترتیب برای پلاتفرمهای Android یا Apple قابلاجرا است).event.data: پایهبار رویداد که بین توابع پیشدرخواست و پسدرخواست متفاوت است:- برای
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: بار داده درخواست خروجی. نوع شیء و ویژگیها به ارائهدهنده 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: محموله پاسخ مدل. نوع شیء و خصوصیات به ارائهدهنده 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 ثبت میشوند تا پراکسی Firebase AI Logic بتواند درخواستها و پاسخها را در سمت سرور رهگیری کند.
گستره سطح پروژه: میتوانید حداکثر یک تابع
beforeGenerateContentو یک تابعafterGenerateContentرا برای هر پروژه Firebase مستقر کنید.مکانهای پیشفرض: این توابع بهطور پیشفرض در
us-central1پیادهسازی خواهند شد (با مکانهای توابع آشنا شوید). بااینحال، تابع بهعنوان Firebase AI Logic راهانداز در منطقهglobalثبت خواهد شد، صرفنظر از اینکه تابع را کجا مستقر کنید.