您可以在應用程式透過 Firebase AI Logic 傳送至 Gemini API 的每個要求前後,執行自訂伺服器端指令碼,無須變更用戶端程式碼。您會將這些指令碼實作為回呼樣式函式,並部署至 Cloud Functions for Firebase。
這項功能可讓您控管提示、限制詞元用量、記錄生成內容以進行分析,或遮蓋回覆內容。
可用的事件類型有兩種:
beforeGenerateContent:在要求到達 Gemini API 之前執行。函式可以檢查或修改要求,也可以擲回錯誤,完全封鎖要求。afterGenerateContent:在 Gemini API 傳回回應後,以及回應傳回用戶端應用程式前執行。這個函式可以檢查或修改回應、完全封鎖回應,或只是觀察回應 (例如記錄或稽核)。
指令碼以函式形式部署至 Cloud Functions for Firebase 後,會註冊為 Firebase AI Logic 觸發條件,也就是說,專案中每個透過 Firebase AI Logic 傳送至 Gemini API 的 generateContent 要求,都會執行這些指令碼 (包括使用伺服器提示詞範本傳送的要求)。
如果對 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) 授予預設運算服務帳戶。執行下列 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) 則不會變更要求。測試延遲時間:視函式執行的作業而定,可能會增加延遲時間並影響使用者體驗。
編寫 POST 要求函式 (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 觸發條件。