您可以在應用程式透過 Firebase AI Logic傳送至 Gemini API 的每個要求前後,執行自訂伺服器端指令碼,不必變更用戶端程式碼。您會將這些指令碼實作為部署至 Cloud Functions for Firebase 的回呼樣式函式。
這項功能可讓您執行多種操作,例如管理提示、限制詞元用量、記錄生成內容以供分析,或編輯回覆內容。
可用的事件類型有兩種:
beforeGenerateContent:在要求送達 Gemini API 之前執行。函式可以檢查或修改要求,也可以擲回錯誤,完全封鎖要求。afterGenerateContent:在 Gemini API 傳回回應後,以及在回應傳回給用戶端應用程式前執行。這個函式可以檢查或修改回應、完全封鎖回應,或只是觀察回應 (例如用於記錄或稽核)。
將指令碼部署為 Cloud Functions for Firebase 的函式後,系統會將其註冊為 Firebase AI Logic 觸發條件,也就是說,專案中每個傳送至 Gemini API 的 generateContent 要求都會透過 Firebase AI Logic 執行指令碼 (包括使用伺服器提示範本提出的要求)。
這些函式不會由傳送至 Gemini API 的要求觸發 (並非透過 Firebase AI Logic)。
必要條件
設定 Firebase AI Logic:如果尚未完成,請參閱Firebase AI Logic入門指南,瞭解如何設定 Firebase 專案、將應用程式連結至 Firebase、新增 SDK、為所選Gemini API供應商初始化後端服務,以及建立
GenerativeModel執行個體。必要權限:請確認您具備部署至 Cloud Functions for Firebase 的必要 IAM 權限。
步驟 1:為 Cloud Functions for Firebase 設定專案
如果您從未在 Firebase 專案中使用 Cloud Functions for Firebase,請完成下列設定。
請確認 Firebase 專案採用即付即用 Blaze 定價方案 (使用 Cloud Functions for Firebase 的必要條件)。
安裝指令列介面 (CLI): gcloud CLI 和 Firebase CLI
將Cloud Build 服務帳戶角色 (
roles/cloudbuild.builds.builder) 授予預設的 Compute 服務帳戶,讓該帳戶具備建構函式所需的權限。執行下列 gcloud CLI 指令:gcloud projects add-iam-policy-binding PROJECT_ID \ --member="serviceAccount:PROJECT_NUMBER-compute@developer.gserviceaccount.com" \ --role="roles/cloudbuild.builds.builder"在 Firebase 專案中初始化 Cloud Functions for Firebase:
執行下列 Firebase CLI 指令:
firebase init functions出現提示時,請選擇「TypeScript」。
確認
functions/package.json中的firebase-functions為 6.3.0 以上版本。如要查看版本,請按照下列步驟操作:npm --prefix functions list firebase-functions
步驟 2:編寫函式
撰寫前置要求函式 (beforeGenerateContent)
撰寫後置要求函式 (afterGenerateContent)
編寫前置要求函式 (beforeGenerateContent)
使用 beforeGenerateContent 事件類型時,函式會在 Firebase AI Logic Proxy 收到 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)。這些不同 API 的要求物件形狀各異。如要安全地使用要求物件,請務必檢查event.data.api(例如分別與geminiV1Beta或vertexV1Beta1比較)。擲回會封鎖要求:如果擲回
HttpsError,要求就會遭到拒絕。傳回整個要求:如果函式會修改要求,則必須傳回完整的修改後要求物件。如果未傳回任何內容 (或
undefined),要求就不會變更。測試延遲:視函式執行的動作而定,可能會增加延遲,進而影響使用者體驗。
撰寫要求後函式 (afterGenerateContent)
使用 afterGenerateContent 事件類型時,當 Firebase AI Logic Proxy 收到來自 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比較)。測試延遲:視函式執行的動作而定,可能會增加延遲,進而影響使用者體驗。
步驟 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:隱含刪除函式
從專案目錄程式碼集移除函式。
執行下列 Firebase CLI 指令:
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:如果呼叫端已登入,則為呼叫端的 Firebase 驗證 UID。event.authClaims:呼叫端的自訂授權聲明 (如有)。event.appId:提出要求的 Firebase 應用程式 ID。event.androidPackageName/event.iosBundleId:呼叫端應用程式的套件名稱或套件 ID (分別適用於 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要求:這些函式只能透過 Firebase AI Logic,由對 Gemini API 的generateContent要求觸發。下列情況不會觸發這些函式,且系統會自動略過該要求:
對
generateContentStream的要求不會觸發這些函式。對 Gemini Live API 的要求不會觸發這些函式。
不必變更用戶端程式碼:除了確保在執行這些函式時使用
generateContent要求之外,您不必變更用戶端程式碼集。這些函式會部署到我們的伺服器,並註冊為 Firebase AI Logic 觸發程序,以便 Firebase AI Logic Proxy 攔截伺服器端的要求和回應。
專案層級範圍:每個 Firebase 專案最多可部署一個
beforeGenerateContent函式和一個afterGenerateContent函式。預設位置:這些函式預設會部署至
us-central1(請參閱函式位置)。不過,無論您將函式部署到哪個區域,系統都會在global區域中將函式註冊為 Firebase AI Logic 觸發程序。