É possível executar seus próprios scripts de linguagem de servidor personalizados antes e depois de cada solicitação que o app envia ao Gemini API pelo Firebase AI Logic, sem mudar o código do cliente. Implemente esses scripts como funções de estilo de callback implantadas no Cloud Functions for Firebase.
Com esse recurso, é possível moderar comandos, limitar o uso de tokens, registrar gerações para análise ou ocultar o conteúdo da resposta.
Há dois tipos de evento disponíveis:
beforeGenerateContent: é executado antes que uma solicitação chegue ao Gemini API. A função pode inspecionar ou modificar a solicitação ou bloqueá-la completamente gerando um erro.afterGenerateContent: é executada depois que a resposta é enviada de volta do Gemini API e antes de ser retornada ao app cliente. A função pode inspecionar ou modificar a resposta, bloqueá-la totalmente ou apenas observá-la (como para geração de registros ou auditoria).
Depois que os scripts forem implantados como funções no Cloud Functions for Firebase, eles serão
registrados como gatilhos do Firebase AI Logic, o que significa que serão executados para
cada solicitação generateContent no seu projeto para o Gemini API via
Firebase AI Logic (incluindo solicitações feitas com
modelos de comando do servidor).
Essas funções não são acionadas por solicitações feitas ao Gemini API que não sejam por meio do Firebase AI Logic.
Pré-requisitos
Configurar o Firebase AI Logic: se ainda não tiver feito isso, conclua o guia de iniciação do Firebase AI Logic, que descreve como configurar seu projeto do Firebase, conectar seu app ao Firebase, adicionar o SDK, inicializar o serviço de back-end para o provedor Gemini API escolhido e criar uma instância do
GenerativeModel.Permissões necessárias: verifique se você tem as permissões do IAM necessárias para implantar no Cloud Functions for Firebase.
Etapa 1: configurar o projeto para o Cloud Functions for Firebase
Se você nunca usou o Cloud Functions for Firebase no seu projeto do Firebase, conclua a configuração a seguir.
Verifique se o projeto do Firebase está no plano de preços Blaze de pagamento por uso (necessário para usar o Cloud Functions for Firebase).
Instale as interfaces de linha de comando (CLIs): gcloud CLI e CLI do Firebase
Conceda à conta de serviço padrão do Compute o papel de conta de serviço do Cloud Build (
roles/cloudbuild.builds.builder) necessário para criar a função. Execute o seguinte comando gcloud CLI:gcloud projects add-iam-policy-binding PROJECT_ID \ --member="serviceAccount:PROJECT_NUMBER-compute@developer.gserviceaccount.com" \ --role="roles/cloudbuild.builds.builder"Inicialize o Cloud Functions for Firebase no seu projeto do Firebase:
Execute o seguinte comando da CLI Firebase:
firebase init functionsQuando solicitado, escolha TypeScript.
Verifique se o
firebase-functionsno seufunctions/package.jsoné a versão 6.3.0 ou mais recente. Veja como verificar sua versão:npm --prefix functions list firebase-functions
Etapa 2: escrever as funções
Escrever uma função de pré-solicitação (beforeGenerateContent)
Escrever uma função de pós-solicitação (afterGenerateContent)
Escrever uma função de pré-solicitação (beforeGenerateContent)
Com o tipo de evento beforeGenerateContent, a função é acionada quando o proxy Firebase AI Logic recebe uma solicitação generateContent. A função
é executada na solicitação antes de ser enviada para o Gemini API.
A função pode modificar ou bloquear completamente a solicitação.
Leia as seguintes informações antes de escrever sua função:
- Dados de eventos que podem ser usados na função
- Principais considerações sobre as funções de pré-solicitação
- Limitações e comportamentos das funções
Exemplo
Veja um exemplo de função de pré-solicitação que faz o seguinte:
Especifica que a função só deve ser executada quando a solicitação for para um provedor Gemini API específico.
Inspeciona o comando em busca de temas bloqueados e rejeita a solicitação gerando um erro.
Limita o máximo de tokens de saída para modelos de geração 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,
),
},
};
});
Principais considerações sobre funções de pré-solicitação
Especifique o provedor Gemini API:
event.data.requestpode ser para Gemini Developer API ou Agent Platform Gemini API (formerly Vertex AI). Os objetos de solicitação para essas APIs diferentes têm formas diferentes. Para trabalhar com segurança com o objeto de solicitação, verifiqueevent.data.api(por exemplo, compare comgeminiV1BetaouvertexV1Beta1, respectivamente).O lançamento bloqueia a solicitação: se você lançar um
HttpsError, a solicitação será rejeitada.Retornar a solicitação inteira: se a função modificar a solicitação, você precisará retornar o objeto de solicitação completo e modificado. Não retornar nada (ou
undefined) deixa a solicitação inalterada.Teste de latência: dependendo do que a função faz, ela pode adicionar latência e afetar a experiência do usuário.
Escrever uma função de pós-solicitação (afterGenerateContent)
Com o tipo de evento afterGenerateContent, a função é acionada quando o proxy Firebase AI Logic recebe uma resposta de uma solicitação generateContent. A função é executada na resposta antes que ela seja
retornada ao app cliente. A função pode registrar o uso, modificar a resposta ou
bloqueá-la completamente.
Leia as seguintes informações antes de escrever sua função:
- Dados de eventos que podem ser usados na função
- Principais considerações para funções pós-solicitação
- Limitações e comportamentos das funções
Exemplo
Confira um exemplo de função pós-solicitação que registra o uso de tokens e o motivo de encerramento:
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.
});
Principais considerações sobre funções pós-solicitação
Especifique o provedor Gemini API:
event.data.responsepode ser para Gemini Developer API ou Agent Platform Gemini API (formerly Vertex AI). Para transmitir e trabalhar com segurança com o objeto de solicitação, verifiqueevent.data.api(por exemplo, compare comgeminiV1BetaouvertexV1Beta1, respectivamente).Teste de latência: dependendo do que a função faz, ela pode adicionar latência e afetar a experiência do usuário.
Etapa 3: implantar as funções
A implantação das funções no Firebase concede ao agente de serviço do Firebase AI Logic permissão para invocar essas funções e registra cada uma como um gatilho do Firebase AI Logic.
Implante suas funções usando a CLI do Firebase:
firebase deploy --only functionsDepois da implantação, confirme se as funções foram implantadas no Firebase:
firebase functions:listSe você precisar iterar na função:
Atualize a função no diretório do projeto e execute
firebase deploy --only functionsnovamente.
Interromper a execução de uma função
Para interromper a execução de uma dessas funções, ela precisa ser excluída dos nossos servidores e ter o registro cancelado como um gatilho do Firebase AI Logic. Para isso, use a CLI Firebase com uma das seguintes opções:
Opção 1: excluir a função de maneira implícita
Remova a função da base de código do diretório do projeto.
Execute o seguinte comando da CLI Firebase:
firebase deploy --only functions
Opção 2: excluir a função explicitamente
Remova a função da base de código do diretório do projeto.
Execute o seguinte comando da CLI Firebase:
firebase functions:delete FUNCTION_NAME
Referência de dados de eventos
Tanto beforeGenerateContent quanto afterGenerateContent recebem um objeto
AIBlockingEvent
que contém contexto e metadados sobre a solicitação.
Metadados de solicitação de nível superior (AIBlockingEvent)
O objeto
AIBlockingEvent
de nível superior fornece informações sobre o autor da chamada e o ambiente de acionamento:
event.authType: estado de autenticação do autor da chamada:"app_user","unauthenticated"ou"unknown".event.authId: o UID do Firebase Authentication do autor da chamada, se ele tiver feito login.event.authClaims: as declarações de autenticação personalizadas do autor da chamada, se houver.event.appId: o ID do app do Firebase que fez a solicitação.event.androidPackageName/event.iosBundleId: o nome do pacote ou o ID do pacote do app de ligação (aplicável às plataformas Android ou Apple, respectivamente).event.data: o payload do evento, que é diferente entre as funções de pré-solicitação e pós-solicitação:- Para
beforeGenerateContent, esse é um objetoBeforeGenerateContentData. - Para
afterGenerateContent, esse é um objetoAfterGenerateContentData.
- Para
Dados de eventos de pré-solicitação (beforeGenerateContent)
Em uma função beforeGenerateContent, event.data é preenchido com um objeto
BeforeGenerateContentData:
event.data.api: o provedor Gemini API:geminiV1Beta(Gemini Developer API) ouvertexV1Beta1(Agent Platform Gemini API (formerly Vertex AI)).event.data.model: o caminho completo do recurso do modelo (por exemplo,projects/{PROJECT_ID}/locations/global/publishers/google/models/gemini-3.8-flash).event.data.template: metadados sobre o modelo de comando do servidor usado (PromptTemplateInfo), se aplicável.event.data.request: o payload da solicitação de saída. O tipo de objeto e as propriedades dependem do provedor Gemini API:- Gemini Developer API (
geminiV1Beta):GeminiV1BetaGenerateContentRequest - Agent Platform Gemini API (formerly Vertex AI) (
vertexV1Beta1):VertexV1Beta1GenerateContentRequest
- Gemini Developer API (
Dados de eventos pós-solicitação (afterGenerateContent)
Em uma função afterGenerateContent, event.data é preenchido com um objeto AfterGenerateContentData. Esse objeto estende BeforeGenerateContentData (fornecendo api,
model, template e request) e adiciona a resposta do modelo:
event.data.response: o payload de resposta do modelo. O tipo de objeto e as propriedades dependem do provedor Gemini API:- Gemini Developer API (
geminiV1Beta):GeminiV1BetaGenerateContentResponse - Agent Platform Gemini API (formerly Vertex AI) (
vertexV1Beta1):VertexV1Beta1GenerateContentResponse
- Gemini Developer API (
Limitações e comportamentos
Ao implementar essas funções, lembre-se dos seguintes comportamentos e limitações:
Somente solicitações
generateContent: essas funções só podem ser acionadas por solicitaçõesgenerateContentpara o Gemini API por meio de Firebase AI Logic.As ações a seguir não vão acionar essas funções, que serão ignoradas silenciosamente para essa solicitação:
As solicitações para
generateContentStreamnão vão acionar essas funções.As solicitações para o Gemini Live API não vão acionar essas funções.
Nenhuma mudança no código do lado do cliente: além de garantir que você use solicitações
generateContentquando quiser executar essas funções, nenhuma mudança é necessária na base de código do lado do cliente.Essas funções são implantadas nos nossos servidores e registradas como gatilhos do Firebase AI Logic para que o proxy do Firebase AI Logic possa interceptar solicitações e respostas do lado do servidor.
Escopo no nível do projeto: é possível implantar no máximo uma função
beforeGenerateContente uma funçãoafterGenerateContentpor projeto do Firebase.Locais padrão: essas funções serão implantadas em
us-central1por padrão (saiba mais sobre locais para funções). No entanto, a função será registrada como um gatilho do Firebase AI Logic na regiãoglobal, independentemente de onde você implantar a função.