Вы можете запускать собственные серверные скрипты до и после каждого запроса, который ваше приложение отправляет в Gemini API через Firebase AI Logic, не меняя код клиента. Эти скрипты реализуются как функции обратного вызова, развернутые в Cloud Functions for Firebase.
С помощью этой функции вы можете модерировать запросы, ограничивать использование токенов, регистрировать генерации для аналитики или редактировать контент ответов.
Доступно два типа событий:
beforeGenerateContent– выполняется до того, как запрос достигнет Gemini API. Функция может проверить или изменить запрос или полностью заблокировать его, выдав ошибку.afterGenerateContent– выполняется после того, как ответ отправлен обратно из Gemini API, и до того, как он возвращен клиентскому приложению. Функция может проверять или изменять ответ, полностью блокировать его или просто наблюдать за ним (например, для ведения журнала или аудита).
После развертывания скриптов в качестве функций в Cloud Functions for Firebase они регистрируются как триггеры Firebase AI Logic. Это означает, что они будут выполняться для каждого запроса generateContent в вашем проекте к Gemini API через Firebase AI Logic (включая запросы, сделанные с помощью шаблонов запросов сервера).
Эти функции не активируются запросами к Gemini API, которые не проходят через Firebase AI Logic.
Требования
Настройте Firebase AI Logic. Если вы ещё этого не сделали, ознакомьтесь с кратким руководством по началу работы с Firebase AI Logic. В нем рассказывается, как настроить проект Firebase, подключить приложение к Firebase, добавить SDK, инициализировать бэкенд-службу для выбранного поставщика Gemini API и создать экземпляр
GenerativeModel.Необходимые разрешения. Убедитесь, что у вас есть разрешения IAM, необходимые для развертывания в Cloud Functions for Firebase.
Шаг 1. Настройте проект для Cloud Functions for Firebase
Если вы никогда не использовали Cloud Functions for Firebase в проекте Firebase, выполните следующие действия.
Убедитесь, что в проекте Firebase используется тарифный план Blaze с оплатой по мере использования (требуется для работы с Cloud Functions for Firebase).
Установите интерфейсы командной строки (CLI): gcloud CLI и Firebase CLI
Назначьте сервисному аккаунту Compute Engine по умолчанию роль сервисного аккаунта 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"Инициализируйте Cloud Functions for Firebase в проекте Firebase:
Выполните следующую команду CLI Firebase:
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 получает запрос generateContent. Функция выполняется для запроса до его отправки в Gemini API.
Функция может изменить запрос или полностью заблокировать его.
Прежде чем писать функцию, ознакомьтесь со следующей информацией:
- Данные о событии, которые можно использовать в функции.
- На что обратить внимание при использовании функций предварительного запроса
- Ограничения и особенности работы функций
Пример
Ниже приведен пример функции pre-request, которая выполняет следующие действия:
Указывает, что функция должна выполняться, только когда запрос предназначен для определенного поставщика 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-request (afterGenerateContent)
При использовании типа события afterGenerateContent функция активируется, когда прокси-сервер Firebase AI Logic получает ответ на запрос generateContent. Функция выполняется для ответа до того, как он возвращается в клиентское приложение. Функция может регистрировать использование, изменять ответ или полностью его блокировать.
Прежде чем писать функцию, ознакомьтесь со следующей информацией:
- Данные о событии, которые можно использовать в функции.
- На что обратить внимание при работе с функциями, выполняемыми после запроса
- Ограничения и особенности работы функций
Пример
Ниже приведен пример функции post-request, которая регистрирует использование токенов и причину завершения.
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.
Разверните функции с помощью CLI Firebase:
firebase deploy --only functionsПосле развертывания убедитесь, что ваши функции развернуты в Firebase:
firebase functions:listЕсли вам нужно изменить функцию:
Обновите функцию в каталоге проекта и снова запустите
firebase deploy --only functions.
Как остановить выполнение функции
Чтобы остановить выполнение одной из этих функций, ее необходимо удалить с наших серверов и отменить ее регистрацию в качестве триггера Firebase AI Logic. Это можно сделать с помощью Firebase CLI одним из следующих способов:
Вариант 1. Неявное удаление функции
Удалите функцию из базы кода каталога проекта.
Выполните следующую команду CLI Firebase:
firebase deploy --only functions
Вариант 2. Удалите функцию явным образом
Удалите функцию из базы кода каталога проекта.
Выполните следующую команду CLI Firebase:
firebase functions:delete FUNCTION_NAME
Справка по данным о событиях
И beforeGenerateContent, и afterGenerateContent получают объект AIBlockingEvent, содержащий контекст и метаданные запроса.
Метаданные запроса верхнего уровня (AIBlockingEvent)
Объект верхнего уровня AIBlockingEvent содержит информацию о вызывающем объекте и среде, в которой он был активирован.
event.authType– статус аутентификации вызывающего абонента:"app_user","unauthenticated"или"unknown".event.authId– UID Firebase Authentication вызывающего абонента, если он вошел в систему.event.authClaims– специальные утверждения вызывающего абонента, если они есть.event.appId: идентификатор приложения Firebase, которое отправило запрос.event.androidPackageName/event.iosBundleId– название пакета или идентификатор пакета вызывающего приложения (для платформ 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. Эти функции могут запускаться только запросамиgenerateContentк Gemini API через Firebase AI Logic.Функции не будут активированы и будут проигнорированы для запроса в следующих случаях:
Запросы к
generateContentStreamне будут активировать эти функции.Запросы к Gemini Live API не будут активировать эти функции.
Не нужно менять клиентский код. Вам не придется вносить изменения в клиентскую базу кода. Достаточно лишь убедиться, что для выполнения этих функций вы используете запросы
generateContent.Эти функции развертываются на наших серверах и регистрируются как триггеры Firebase AI Logic, чтобы прокси-сервер Firebase AI Logic мог перехватывать запросы и ответы на стороне сервера.
Область действия на уровне проекта. В каждом проекте Firebase можно развернуть не более одной функции
beforeGenerateContentи одной функцииafterGenerateContent.Местоположения по умолчанию. Эти функции будут развернуты в
us-central1по умолчанию (подробнее о местоположениях для функций). Однако функция будет зарегистрирована как триггер Firebase AI Logic в регионеglobalнезависимо от того, где вы ее развернете.