Możesz uruchamiać własne niestandardowe skrypty po stronie serwera przed każdym żądaniem wysyłanym przez aplikację do Gemini API za pomocą Firebase AI Logic i po nim – bez zmiany kodu klienta. Te skrypty implementuje się jako funkcje w stylu wywołania zwrotnego wdrożone w Cloud Functions for Firebase.
Dzięki tej funkcji możesz m.in. moderować prompty, ograniczać wykorzystanie tokenów, rejestrować wygenerowane treści na potrzeby analizy lub redagować treści odpowiedzi.
Dostępne są 2 typy zdarzeń:
beforeGenerateContent: uruchamia się, zanim żądanie dotrze do Gemini API. Funkcja może sprawdzać lub modyfikować żądanie albo całkowicie je blokować, zgłaszając błąd.afterGenerateContent: uruchamia się po wysłaniu odpowiedzi z Gemini API i przed jej zwróceniem do aplikacji klienckiej. Funkcja może sprawdzać lub modyfikować odpowiedź, całkowicie ją blokować lub tylko ją obserwować (np. na potrzeby logowania lub kontroli).
Gdy skrypty zostaną wdrożone jako funkcje w Cloud Functions for Firebase, zostaną zarejestrowane jako wyzwalacze Firebase AI Logic, co oznacza, że będą uruchamiane przy każdym żądaniu generateContent w Twoim projekcie do Gemini API przez Firebase AI Logic (w tym żądaniach wysyłanych za pomocą szablonów promptów serwera).
Te funkcje nie są aktywowane przez żądania wysyłane do Gemini API, które nie przechodzą przez Firebase AI Logic.
Wymagania wstępne
Skonfiguruj Firebase AI Logic: jeśli jeszcze nie masz skonfigurowanej usługi, zapoznaj się z przewodnikiem dla początkujących użytkowników Firebase AI Logic, w którym opisano, jak skonfigurować projekt w Firebase, połączyć aplikację z Firebase, dodać pakiet SDK, zainicjować usługę backendu dla wybranego dostawcy Gemini API i utworzyć instancję
GenerativeModel.Wymagane uprawnienia: sprawdź, czy masz wymagane uprawnienia do wdrażania w Cloud Functions for Firebase.
Krok 1. Skonfiguruj projekt w Cloud Functions for Firebase
Jeśli nigdy nie używano Cloud Functions for Firebase w projekcie w Firebase, wykonaj te czynności konfiguracyjne.
Upewnij się, że Twój projekt w Firebase jest objęty abonamentem Blaze z płatnością według wykorzystania (wymaganym do korzystania z Cloud Functions for Firebase).
Zainstaluj interfejsy wiersza poleceń (CLI): gcloud CLI i Firebase CLI
Przypisz do domyślnego konta usługi Compute rolę konto usługi Cloud Build (
roles/cloudbuild.builds.builder), której potrzebuje do utworzenia funkcji. Uruchom to polecenie gcloud CLI:gcloud projects add-iam-policy-binding PROJECT_ID \ --member="serviceAccount:PROJECT_NUMBER-compute@developer.gserviceaccount.com" \ --role="roles/cloudbuild.builds.builder"Zainicjuj Cloud Functions for Firebase w projekcie Firebase:
Uruchom to polecenie Firebase w interfejsie wiersza poleceń:
firebase init functionsGdy pojawi się prośba, wybierz TypeScript.
Upewnij się, że
firebase-functionswfunctions/package.jsonjest w wersji 6.3.0 lub nowszej. Aby sprawdzić wersję:npm --prefix functions list firebase-functions
Krok 2. Napisz funkcje
Tworzenie funkcji przed żądaniem (beforeGenerateContent)
Tworzenie funkcji po żądaniu (afterGenerateContent)
Napisz funkcję przed żądaniem (beforeGenerateContent)
W przypadku typu zdarzenia beforeGenerateContent funkcja jest aktywowana, gdy serwer proxy Firebase AI Logic otrzymuje żądanie generateContent. Funkcja jest uruchamiana w odniesieniu do żądania przed wysłaniem żądania do Gemini API.
Funkcja może zmodyfikować żądanie lub całkowicie je zablokować.
Zanim napiszesz funkcję, zapoznaj się z tymi informacjami:
- Dane zdarzenia, których możesz użyć w funkcji.
- Najważniejsze kwestie dotyczące funkcji przed żądaniem
- Ograniczenia i zachowania funkcji
Przykład
Oto przykład funkcji pre-request, która wykonuje te czynności:
Określa, że funkcja powinna być uruchamiana tylko wtedy, gdy żądanie dotyczy konkretnego dostawcy Gemini API.
Sprawdza prompta pod kątem zablokowanych tematów i odrzuca żądanie, zgłaszając błąd.
Ogranicza maksymalną liczbę tokenów wyjściowych w modelach generujących tekst.
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,
),
},
};
});
Najważniejsze kwestie dotyczące funkcji przed wysłaniem żądania
Określ dostawcę Gemini API:
event.data.requestmoże dotyczyć Gemini Developer API lub Agent Platform Gemini API (formerly Vertex AI). Obiekty żądań dla tych różnych interfejsów API mają różne kształty. Aby bezpiecznie pracować z obiektem żądania, musisz sprawdzićevent.data.api(np. porównać odpowiednio zgeminiV1BetalubvertexV1Beta1).Zgłoszenie błędu blokuje żądanie: jeśli zgłosisz błąd
HttpsError, żądanie zostanie odrzucone.Zwróć całe żądanie: jeśli funkcja modyfikuje żądanie, musisz zwrócić cały zmodyfikowany obiekt żądania. Jeśli nic nie zwrócisz (lub zwrócisz
undefined), żądanie pozostanie niezmienione.Przetestuj pod kątem opóźnień: w zależności od tego, co robi funkcja, może ona powodować opóźnienia i wpływać na wrażenia użytkowników.
Napisz funkcję obsługującą żądanie POST (afterGenerateContent)
W przypadku typu zdarzenia afterGenerateContent funkcja jest aktywowana, gdy serwer proxy Firebase AI Logic otrzymuje odpowiedź na żądanie generateContent. Funkcja jest uruchamiana w odpowiedzi przed zwróceniem odpowiedzi do aplikacji klienckiej. Funkcja może rejestrować wykorzystanie, modyfikować odpowiedź lub całkowicie ją blokować.
Zanim napiszesz funkcję, zapoznaj się z tymi informacjami:
- Dane zdarzenia, których możesz użyć w funkcji.
- Najważniejsze kwestie dotyczące funkcji po żądaniu
- Ograniczenia i zachowania funkcji
Przykład
Oto przykład funkcji post-request, która rejestruje wykorzystanie tokenów i przyczynę zakończenia:
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.
});
Najważniejsze kwestie dotyczące funkcji po żądaniu
Określ dostawcę Gemini API:
event.data.responsemoże dotyczyć Gemini Developer API lub Agent Platform Gemini API (formerly Vertex AI). Aby bezpiecznie rzutować obiekt żądania i pracować z nim, musisz sprawdzićevent.data.api(np. porównać odpowiednio zgeminiV1BetalubvertexV1Beta1).Przetestuj pod kątem opóźnień: w zależności od tego, co robi funkcja, może ona powodować opóźnienia i wpływać na wrażenia użytkowników.
Krok 3. Wdróż funkcje
Wdrożenie funkcji w Firebase przyznaje agentowi usługi Firebase AI Logic uprawnienia do wywoływania tych funkcji i rejestruje każdą funkcję jako Firebase AI Logic aktywator.
Wdróż funkcje za pomocą interfejsu wiersza poleceń Firebase:
firebase deploy --only functionsPo wdrożeniu sprawdź, czy funkcje zostały wdrożone w Firebase:
firebase functions:listJeśli chcesz wprowadzić zmiany w funkcji:
Zaktualizuj funkcję w katalogu projektu, a następnie ponownie uruchom
firebase deploy --only functions.
Zatrzymywanie działania funkcji
Aby zatrzymać działanie jednej z tych funkcji, musisz ją usunąć z naszych serwerów oraz wyrejestrować jako wyzwalacz Firebase AI Logic. Możesz to zrobić za pomocą interfejsu wiersza poleceń Firebase, korzystając z jednej z tych opcji:
Opcja 1. Usunięcie funkcji w sposób domyślny
Usuń funkcję z bazy kodu katalogu projektu.
Uruchom to polecenie Firebase w interfejsie wiersza poleceń:
firebase deploy --only functions
Opcja 2. Usuń funkcję bezpośrednio
Usuń funkcję z bazy kodu katalogu projektu.
Uruchom to polecenie Firebase w interfejsie wiersza poleceń:
firebase functions:delete FUNCTION_NAME
Dokumentacja danych zdarzeń
Zarówno beforeGenerateContent, jak i afterGenerateContent otrzymują obiekt AIBlockingEvent zawierający kontekst i metadane dotyczące żądania.
Metadane żądania najwyższego poziomu (AIBlockingEvent)
Obiekt najwyższego poziomu AIBlockingEvent zawiera informacje o wywołującym i środowisku wyzwalającym:
event.authType: stan uwierzytelniania rozmówcy:"app_user","unauthenticated"lub"unknown".event.authId: identyfikator UID uwierzytelniania Firebase elementu wywołującego, jeśli jest zalogowany.event.authClaims: niestandardowe oświadczenia uwierzytelniające rozmówcy (jeśli występują).event.appId: identyfikator aplikacji w Firebase, która wysłała żądanie.event.androidPackageName/event.iosBundleId: nazwa pakietu lub identyfikator pakietu aplikacji wywołującej (odpowiednio w przypadku platform Android i Apple).event.data: ładunek zdarzenia, który różni się w przypadku funkcji przed żądaniem i po żądaniu:- W przypadku
beforeGenerateContentjest to obiektBeforeGenerateContentData. - W przypadku
afterGenerateContentjest to obiektAfterGenerateContentData.
- W przypadku
Dane zdarzenia przed żądaniem (beforeGenerateContent)
W funkcji beforeGenerateContent parametr event.data jest wypełniany obiektem BeforeGenerateContentData:
event.data.api: dostawca Gemini API:geminiV1Beta(Gemini Developer API) lubvertexV1Beta1(Agent Platform Gemini API (formerly Vertex AI)).event.data.model: pełna ścieżka zasobu modelu (np.projects/{PROJECT_ID}/locations/global/publishers/google/models/gemini-3.8-flash).event.data.template: metadane dotyczące użytego szablonu prompta serwera (PromptTemplateInfo), jeśli dotyczy.event.data.request: ładunek żądania wychodzącego. Typ obiektu i właściwości zależą od dostawcy Gemini API:- Gemini Developer API (
geminiV1Beta):GeminiV1BetaGenerateContentRequest - Agent Platform Gemini API (formerly Vertex AI) (
vertexV1Beta1):VertexV1Beta1GenerateContentRequest
- Gemini Developer API (
Dane zdarzenia po żądaniu (afterGenerateContent)
W funkcji afterGenerateContent parametr event.data jest wypełniany obiektem AfterGenerateContentData. Ten obiekt rozszerza BeforeGenerateContentData (zapewniając api, model, template i request) oraz dodaje odpowiedź modelu:
event.data.response: ładunek odpowiedzi modelu. Typ obiektu i właściwości zależą od dostawcy Gemini API:- Gemini Developer API (
geminiV1Beta):GeminiV1BetaGenerateContentResponse - Agent Platform Gemini API (formerly Vertex AI) (
vertexV1Beta1):VertexV1Beta1GenerateContentResponse
- Gemini Developer API (
Ograniczenia i zachowania
Podczas implementowania tych funkcji pamiętaj o tych zachowaniach i ograniczeniach:
Tylko żądania
generateContent: te funkcje mogą być aktywowane tylko przez żądaniagenerateContentwysyłane do Gemini API przez Firebase AI Logic.Te funkcje nie zostaną wywołane w przypadku poniższych żądań i zostaną po cichu pominięte:
Żądania wysyłane do
generateContentStreamnie będą wywoływać tych funkcji.Żądania wysyłane do Gemini Live API nie będą wywoływać tych funkcji.
Brak zmian w kodzie po stronie klienta: poza upewnieniem się, że używasz żądań
generateContent, gdy chcesz uruchomić te funkcje, nie musisz wprowadzać żadnych zmian w bazie kodu po stronie klienta.Te funkcje są wdrażane na naszych serwerach i rejestrowane jako wyzwalacze Firebase AI Logic, dzięki czemu serwer proxy Firebase AI Logic może przechwytywać żądania i odpowiedzi po stronie serwera.
Zakres na poziomie projektu: w każdym projekcie w Firebase możesz wdrożyć maksymalnie 1 funkcję
beforeGenerateContenti 1 funkcjęafterGenerateContent.Domyślne lokalizacje: te funkcje będą domyślnie wdrażane w regionie
us-central1(dowiedz się więcej o lokalizacjach funkcji). Funkcja zostanie jednak zarejestrowana jako aktywator Firebase AI Logic w regionieglobalniezależnie od tego, gdzie ją wdrożysz.