Puedes ejecutar tus propias secuencias de comandos personalizadas del servidor antes y después de cada solicitud que tu app envíe a Gemini API a través de Firebase AI Logic, sin cambiar el código del cliente. Implementas estas secuencias de comandos como funciones de estilo de devolución de llamada implementadas en Cloud Functions for Firebase.
Con esta capacidad, puedes realizar acciones como moderar instrucciones, limitar el uso de tokens, registrar generaciones para estadísticas o redactar contenido de respuesta.
Hay dos tipos de eventos disponibles:
beforeGenerateContent: Se ejecuta antes de que una solicitud llegue al Gemini API. La función puede inspeccionar o modificar la solicitud, o bien bloquearla por completo arrojando un error.afterGenerateContent: Se ejecuta después de que se envía la respuesta desde el Gemini API y antes de que se devuelva a la app cliente. La función puede inspeccionar o modificar la respuesta, bloquearla por completo o solo observarla (como para el registro o la auditoría).
Una vez que tus secuencias de comandos se implementen como funciones en Cloud Functions for Firebase, se
registrarán como activadores de Firebase AI Logic, lo que significa que se ejecutarán para
cada solicitud de generateContent en tu proyecto a Gemini API a través de
Firebase AI Logic (incluidas las solicitudes realizadas con
plantillas de instrucciones del servidor).
Estas funciones no se activan con las solicitudes realizadas a Gemini API que no se realizan a través de Firebase AI Logic.
Requisitos previos
Configura Firebase AI Logic: Si aún no lo hiciste, completa la guía de introducción de Firebase AI Logic, en la que se describe cómo configurar tu proyecto de Firebase, conectar tu app a Firebase, agregar el SDK, inicializar el servicio de backend para el proveedor de Gemini API que elijas y crear una instancia de
GenerativeModel.Permisos necesarios: Asegúrate de tener los permisos de IAM necesarios para implementar en Cloud Functions for Firebase.
Paso 1: Configura tu proyecto para Cloud Functions for Firebase
Si nunca usaste Cloud Functions for Firebase en tu proyecto de Firebase, completa la siguiente configuración.
Asegúrate de que tu proyecto de Firebase tenga el plan de precios Blaze de pago por uso (obligatorio para usar Cloud Functions for Firebase).
Instala las interfaces de línea de comandos (CLI): gcloud CLI y CLI de Firebase
Otorga a la cuenta de servicio de Compute predeterminada el rol de cuenta de servicio de Cloud Build (
roles/cloudbuild.builds.builder) que necesita para compilar tu función. Ejecuta el siguiente comando de gcloud CLI:gcloud projects add-iam-policy-binding PROJECT_ID \ --member="serviceAccount:PROJECT_NUMBER-compute@developer.gserviceaccount.com" \ --role="roles/cloudbuild.builds.builder"Inicializa Cloud Functions for Firebase en tu proyecto de Firebase:
Ejecuta el siguiente comando de la CLI de Firebase:
firebase init functionsCuando se te solicite, elige TypeScript.
Asegúrate de que
firebase-functionsen tufunctions/package.jsonsea la versión 6.3.0 o una posterior. Sigue estos pasos para verificar la versión:npm --prefix functions list firebase-functions
Paso 2: Escribe tus funciones
Escribir una función de solicitud previa (beforeGenerateContent)
Escribir una función de solicitud posterior (afterGenerateContent)
Escribe una función de solicitud previa (beforeGenerateContent)
Con el tipo de evento beforeGenerateContent, la función se activa cuando el proxy Firebase AI Logic recibe una solicitud generateContent. La función
se ejecuta en la solicitud antes de que se envíe a Gemini API.
La función puede modificar la solicitud o bloquearla por completo.
Asegúrate de revisar la siguiente información antes de escribir tu función:
- Datos de eventos que puedes usar en tu función
- Consideraciones clave para las funciones de solicitud previa
- Limitaciones y comportamientos de las funciones
Ejemplo
Aquí tienes un ejemplo de función de solicitud previa que hace lo siguiente:
Especifica que la función solo debe ejecutarse cuando la solicitud es para un proveedor de Gemini API específico.
Inspecciona la instrucción en busca de temas bloqueados y rechaza la solicitud arrojando un error.
Limita la cantidad máxima de tokens de salida para los modelos generativos de texto.
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,
),
},
};
});
Consideraciones clave para las funciones de solicitud previa
Especifica el proveedor de Gemini API:
event.data.requestpuede ser para Gemini Developer API o Agent Platform Gemini API (formerly Vertex AI). Los objetos de solicitud para estas diferentes APIs tienen diferentes formas. Para trabajar de forma segura con el objeto de solicitud, debes verificarevent.data.api(por ejemplo, compararlo congeminiV1BetaovertexV1Beta1, respectivamente).La generación de excepciones bloquea la solicitud: Si generas una
HttpsError, se rechazará la solicitud.Devuelve la solicitud completa: Si tu función modifica la solicitud, debes devolver el objeto de solicitud completo y modificado. Si no se devuelve nada (o se devuelve
undefined), la solicitud no se modifica.Prueba la latencia: Según lo que haga tu función, podría agregar latencia y afectar la experiencia del usuario.
Escribe una función posterior a la solicitud (afterGenerateContent)
Con el tipo de evento afterGenerateContent, la función se activa cuando el
proxy Firebase AI Logic recibe una respuesta de una solicitud
generateContent. La función se ejecuta en la respuesta antes de que se
devuelva a la app cliente. La función puede registrar el uso, modificar la respuesta o
bloquearla por completo.
Asegúrate de revisar la siguiente información antes de escribir tu función:
- Datos de eventos que puedes usar en tu función
- Consideraciones clave para las funciones posteriores a la solicitud
- Limitaciones y comportamientos de las funciones
Ejemplo
Este es un ejemplo de una función post-request que registra el uso de tokens y el motivo de finalización:
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.
});
Consideraciones clave para las funciones posteriores a la solicitud
Especifica el proveedor de Gemini API:
event.data.responsepuede ser para Gemini Developer API o Agent Platform Gemini API (formerly Vertex AI). Para transmitir y trabajar de forma segura con el objeto de solicitud, debes verificarevent.data.api(por ejemplo, compararlo congeminiV1BetaovertexV1Beta1, respectivamente).Prueba la latencia: Según lo que haga tu función, podría agregar latencia y afectar la experiencia del usuario.
Paso 3: Implementa tus funciones
Cuando implementas tus funciones en Firebase, se le otorga permiso al agente de servicio de Firebase AI Logic para que invoque estas funciones y se registra cada función como un activador de Firebase AI Logic.
Implementa tus funciones con Firebase CLI:
firebase deploy --only functionsDespués de la implementación, confirma que tus funciones se hayan implementado en Firebase:
firebase functions:listSi necesitas iterar en tu función, haz lo siguiente:
Actualiza la función en el directorio de tu proyecto y, luego, vuelve a ejecutar
firebase deploy --only functions.
Detén la ejecución de una función
Para detener la ejecución de una de estas funciones, se debe borrar de nuestros servidores y se debe cancelar su registro como activador de Firebase AI Logic. Puedes hacerlo con la CLI de Firebase con cualquiera de las siguientes opciones:
Opción 1: Borra la función de forma implícita
Quita la función de la base de código del directorio de tu proyecto.
Ejecuta el siguiente comando de la CLI de Firebase:
firebase deploy --only functions
Opción 2: Borra la función de forma explícita
Quita la función de la base de código del directorio de tu proyecto.
Ejecuta el siguiente comando de la CLI de Firebase:
firebase functions:delete FUNCTION_NAME
Referencia de datos de eventos
Tanto beforeGenerateContent como afterGenerateContent reciben un objeto AIBlockingEvent que contiene el contexto y los metadatos sobre la solicitud.
Metadatos de solicitud de nivel superior (AIBlockingEvent)
El objeto AIBlockingEvent de nivel superior proporciona información sobre el emisor y el entorno de activación:
event.authType: Es el estado de autenticación del emisor:"app_user","unauthenticated"o"unknown".event.authId: Es el UID de Firebase Authentication del emisor, si accedió.event.authClaims: Las reclamaciones de autenticación personalizadas del llamador, si las hay.event.appId: Es el ID de la app de Firebase que realizó la solicitud.event.androidPackageName/event.iosBundleId: Es el nombre del paquete o el ID del paquete de la app que realiza la llamada (aplicable para las plataformas de Android o Apple, respectivamente).event.data: Es la carga útil del evento, que difiere entre las funciones previas y posteriores a la solicitud:- Para
beforeGenerateContent, este es un objetoBeforeGenerateContentData. - Para
afterGenerateContent, este es un objetoAfterGenerateContentData.
- Para
Datos de eventos previos a la solicitud (beforeGenerateContent)
En una función beforeGenerateContent, event.data se propaga con un objeto BeforeGenerateContentData:
event.data.api: Es el proveedor de Gemini API:geminiV1Beta(Gemini Developer API) overtexV1Beta1(Agent Platform Gemini API (formerly Vertex AI)).event.data.model: Es la ruta de acceso completa del recurso del modelo (por ejemplo,projects/{PROJECT_ID}/locations/global/publishers/google/models/gemini-3.8-flash).event.data.template: Son los metadatos sobre la plantilla de instrucciones del servidor que se usó (PromptTemplateInfo), si corresponde.event.data.request: Es la carga útil de la solicitud saliente. El tipo de objeto y las propiedades dependen del proveedor de Gemini API:- Gemini Developer API (
geminiV1Beta):GeminiV1BetaGenerateContentRequest - Agent Platform Gemini API (formerly Vertex AI) (
vertexV1Beta1):VertexV1Beta1GenerateContentRequest
- Gemini Developer API (
Datos de eventos posteriores a la solicitud (afterGenerateContent)
En una función afterGenerateContent, event.data se propaga con un objeto AfterGenerateContentData. Este objeto extiende BeforeGenerateContentData (proporciona api,
model, template y request) y agrega la respuesta del modelo:
event.data.response: Es la carga útil de la respuesta del modelo. El tipo de objeto y las propiedades dependen del proveedor de Gemini API:- Gemini Developer API (
geminiV1Beta):GeminiV1BetaGenerateContentResponse - Agent Platform Gemini API (formerly Vertex AI) (
vertexV1Beta1):VertexV1Beta1GenerateContentResponse
- Gemini Developer API (
Limitaciones y comportamientos
Cuando implementes estas funciones, ten en cuenta los siguientes comportamientos y limitaciones:
Solo solicitudes
generateContent: Estas funciones solo se pueden activar con solicitudesgenerateContenta Gemini API a través de Firebase AI Logic.Las siguientes acciones no activarán estas funciones, y las funciones se omitirán de forma silenciosa para esa solicitud:
Las solicitudes a
generateContentStreamno activarán estas funciones.Las solicitudes a Gemini Live API no activarán estas funciones.
No se requieren cambios en el código del cliente: Además de asegurarte de usar solicitudes
generateContentcuando quieras ejecutar estas funciones, no se requieren cambios en la base de código del cliente.Estas funciones se implementan en nuestros servidores y se registran como activadores de Firebase AI Logic para que el proxy de Firebase AI Logic pueda interceptar solicitudes y respuestas del lado del servidor.
Permiso a nivel del proyecto: Puedes implementar, como máximo, una función
beforeGenerateContenty una funciónafterGenerateContentpor proyecto de Firebase.Ubicaciones predeterminadas: Estas funciones se implementarán en
us-central1de forma predeterminada (obtén más información sobre las ubicaciones de las funciones). Sin embargo, la función se registrará como un activador de Firebase AI Logic en la regiónglobal, sin importar dónde la implementes.