Вы можете запускать собственные серверные скрипты до и после каждого запроса, который ваше приложение отправляет к API Gemini через Firebase AI Logic , — без изменения клиентского кода . Вы реализуете эти скрипты как функции обратного вызова, развернутые в Cloud Functions for Firebase .
Благодаря этой возможности вы можете, например, модерировать запросы, ограничивать использование токенов, генерировать журналы для аналитики или редактировать содержимое ответов.
Доступны два типа мероприятий:
beforeGenerateContent: Выполняется до того, как запрос достигнет API Gemini . Функция может проверить или изменить запрос, либо полностью заблокировать его, выдав ошибку.afterGenerateContent: Выполняется после отправки ответа от API Gemini и до его возврата клиентскому приложению. Функция может проверять или изменять ответ, полностью блокировать его или просто наблюдать за ним (например, для логирования или аудита).
После развертывания ваших скриптов в качестве функций в Cloud Functions for Firebase , они регистрируются как триггеры Firebase AI Logic , что означает, что они будут запускаться для каждого запроса generateContent в вашем проекте к API Gemini через Firebase AI Logic (включая запросы, сделанные с использованием шаблонов серверных подсказок ).
Эти функции не запускаются запросами к API Gemini , которые не поступают через Firebase AI Logic .
Предварительные требования
Настройка Firebase AI Logic : Если вы еще этого не сделали, пройдите руководство по началу работы с Firebase AI Logic , в котором описано, как настроить ваш проект Firebase, подключить ваше приложение к Firebase, добавить SDK, инициализировать бэкэнд-сервис для выбранного вами поставщика API Gemini и создать экземпляр
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.
Предоставьте учетной записи вычислительной службы по умолчанию роль учетной записи службы сборки облака (
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:
Выполните следующую команду Firebase CLI:
firebase init functionsПри появлении запроса выберите TypeScript .
Убедитесь, что версия
firebase-functionsв вашемfunctions/package.json— 6.3.0 или более поздняя . Вот как проверить свою версию:npm --prefix functions list firebase-functions
Шаг 2 : Напишите свои функции
Напишите функцию перед запросом ( beforeGenerateContent ) Напишите функцию после запроса ( afterGenerateContent )
Напишите функцию предварительного запроса ( beforeGenerateContent ).
При использовании типа события beforeGenerateContent функция запускается, когда прокси-сервер Firebase AI Logic получает запрос generateContent . Функция выполняется над запросом до того, как он будет отправлен в API Gemini . Функция может изменить запрос или полностью заблокировать его.
Перед написанием функции обязательно ознакомьтесь со следующей информацией:
- Данные событий , которые вы можете использовать в своей функции.
- Ключевые моменты, которые следует учитывать при выполнении функций, предшествующих запросу.
- Ограничения и особенности поведения при выполнении функций
Пример
Вот пример функции предварительного запроса , которая выполняет следующие действия:
Указывает, что функция должна выполняться только тогда, когда запрос поступает к конкретному поставщику API Gemini .
Проверяет приглашение на наличие заблокированных тем и отклоняет запрос, выдавая ошибку.
Устанавливает ограничение на максимальное количество выходных токенов для моделей генерации текста.
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,
),
},
};
});
Ключевые моменты, которые следует учитывать при выполнении функций, предшествующих запросу.
Укажите поставщика API Gemini :
event.data.requestможет относиться либо к API разработчика Gemini , либо к API платформы агентов Gemini (ранее Vertex AI) . Объекты запроса для этих разных API имеют разную структуру. Для безопасной работы с объектом запроса необходимо проверитьevent.data.api(например, сравнитеgeminiV1BetaилиvertexV1Beta1соответственно).Выбрасывание исключения блокирует запрос: если вы выбросите исключение
HttpsError, запрос будет отклонен.Возвращать весь запрос: если ваша функция изменяет запрос, то вы должны вернуть полный, измененный объект запроса. Возвращение пустого значения (или
undefined) оставляет запрос без изменений.Проверка на задержку: В зависимости от того, что делает ваша функция, она может добавлять задержку и влиять на пользовательский опыт.
Напишите функцию для обработки POST-запроса ( afterGenerateContent ).
При использовании типа события afterGenerateContent функция запускается, когда прокси-сервер Firebase AI Logic получает ответ на запрос generateContent . Функция обрабатывает ответ до того, как он будет возвращен клиентскому приложению . Функция может регистрировать использование, изменять ответ или полностью блокировать его.
Перед написанием функции обязательно ознакомьтесь со следующей информацией:
- Данные событий , которые вы можете использовать в своей функции.
- Ключевые аспекты, которые следует учитывать при выполнении функций после запроса.
- Ограничения и особенности поведения при выполнении функций
Пример
Вот пример функции обработки POST-запроса , которая регистрирует использование токена и причину завершения:
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.
});
Ключевые аспекты, которые следует учитывать при выполнении функций после запроса.
Укажите поставщика API Gemini :
event.data.responseможет быть либо для API разработчика Gemini , либо для API платформы агентов Gemini (ранее 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: UID аутентификации Firebase вызывающего пользователя, если он авторизован. -
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: Поставщик API Gemini :geminiV1Beta( Gemini Developer API ) илиvertexV1Beta1( Agent Platform Gemini API (ранее Vertex AI) ). -
event.data.model: Полный путь к ресурсу модели (например,projects/{PROJECT_ID}/locations/global/publishers/google/models/gemini-3.8-flash). -
event.data.template: Метаданные об используемом шаблоне приглашения сервера (PromptTemplateInfo), если применимо. -
event.data.request: Содержимое исходящего запроса. Тип объекта и его свойства зависят от поставщика API Gemini :- API для разработчиков Gemini (
geminiV1Beta) :GeminiV1BetaGenerateContentRequest - API платформы агентов Gemini (ранее Vertex AI) (
vertexV1Beta1) :VertexV1Beta1GenerateContentRequest
- API для разработчиков Gemini (
Данные события после запроса ( afterGenerateContent )
В функции afterGenerateContent event.data заполняется объектом AfterGenerateContentData . Этот объект наследует BeforeGenerateContentData (предоставляя api , model , template и request ) и добавляет ответ модели:
-
event.data.response: Полезная нагрузка ответа модели. Тип объекта и его свойства зависят от поставщика API Gemini :- API разработчика Gemini (
geminiV1Beta) :GeminiV1BetaGenerateContentResponse - API платформы агентов Gemini (ранее Vertex AI) (
vertexV1Beta1) :VertexV1Beta1GenerateContentResponse
- API разработчика Gemini (
Ограничения и модели поведения
При реализации этих функций следует учитывать следующие особенности и ограничения:
Только для запросов
generateContent: Эти функции могут быть запущены только запросамиgenerateContentк API Gemini через Firebase AI Logic .Следующие действия не запустят эти функции, и для данного запроса они будут пропущены без уведомления :
Запросы к
generateContentStreamне будут запускать эти функции.Запросы к Gemini Live API не будут запускать эти функции.
Никаких изменений в клиентском коде : помимо обеспечения использования запросов
generateContentпри выполнении этих функций, никаких изменений в клиентском коде не требуется.Эти функции развернуты на наших серверах и зарегистрированы как триггеры Firebase AI Logic, чтобы прокси-сервер Firebase AI Logic мог перехватывать запросы и ответы на стороне сервера.
Область применения на уровне проекта : в каждом проекте Firebase можно развернуть не более одной функции
beforeGenerateContentи одной функцииafterGenerateContent.Расположение по умолчанию : Эти функции по умолчанию будут развернуты в
us-central1(подробнее о расположении функций см. здесь). Однако функция будет зарегистрирована как триггер Firebase AI Logic вglobalрегионе независимо от того, где вы её развернете.