Как вызывать потоки Genkit из приложения

У Cloud Functions for Firebase есть метод onCallGenkit, который позволяет создать вызываемую функцию с действием Genkit (потоком). Эти функции можно вызывать с помощью genkit/beta/client или Cloud Functions for Firebase Client SDK, которые автоматически добавляют информацию об авторизации.

Подготовка

  • Вы должны быть знакомы с концепцией Genkit потоков и знать, как их создавать. Инструкции на этой странице предполагают, что у вас уже определены некоторые потоки, которые вы хотите развернуть.
  • Если вы уже пользовались Cloud Functions for Firebase, это поможет нам, но не является обязательным условием.

Как настроить проект Firebase

  1. Создайте новый проект Firebase в Firebaseконсоли или выберите существующий.

  2. Перейдите на тарифный план Blaze с оплатой по мере использования, который необходим для развертывания в рабочей среде Cloud Functions.

  3. Установите Firebase CLI.

  4. Войдите в интерфейс командной строки Firebase:

    firebase login
    firebase login --reauth # alternative, if necessary
    firebase login --no-localhost # if running in a remote shell
  5. Создайте каталог проекта:

    export PROJECT_ROOT=~/tmp/genkit-firebase-project1
    mkdir -p $PROJECT_ROOT
  6. Инициализируйте проект Firebase в каталоге:

    cd $PROJECT_ROOT
    firebase init functions

Далее на этой странице предполагается, что вы решили написать функции на JavaScript.

Оберните поток в onCallGenkit

После того как вы настроите проект Firebase и инициализируете Cloud Functions, вы сможете копировать или писать определения потоков в каталоге functions проекта. Вот пример того, как это может выглядеть:

const ai = genkit({
  plugins: [googleAI()],
  model: gemini15Flash,
});

const jokeTeller = ai.defineFlow({
  name: "jokeTeller",
  inputSchema: z.string().nullable(),
  outputSchema: z.string(),
  streamSchema: z.string(),
}, async (jokeType = "knock-knock", {sendChunk}) => {
  const prompt = `Tell me a ${jokeType} joke.`;

  // Call the `generateStream()` method to
  // receive the `stream` async iterable.
  const {stream, response: aiResponse} = ai.generateStream(prompt);

  // Send new words of the generative AI response
  // to the client as they are generated.
  for await (const chunk of stream) {
    sendChunk(chunk.text);
  }

  // Return the full generative AI response
  // to clients that may not support streaming.
  return (await aiResponse).text;
},
);

Чтобы развернуть такой поток, оберните его в onCallGenkit, доступный в firebase-functions/https. Этот вспомогательный метод обладает всеми функциями вызываемых функций и автоматически поддерживает как потоковую передачу, так и ответы в формате JSON.

const {onCallGenkit} = require("firebase-functions/https");
exports.tellJoke = onCallGenkit({
  // Bind the Gemini API key secret parameter to the function.
  secrets: [apiKey],
},
// Pass in the genkit flow.
jokeTeller,
);

Как сделать учетные данные API доступными для развернутых процессов

После развертывания потокам необходимо предоставить способ аутентификации в любых удаленных сервисах, на которые они опираются. Как минимум, большинству процессов нужны учетные данные для доступа к сервису API модели, которую они используют.

В этом примере выполните одно из следующих действий в зависимости от выбранного поставщика модели:

Gemini (ИИ от Google)

  1. Сгенерируйте ключ API для Gemini Developer API, используя Google AI Studio.

  2. Храните ключ API в Google Cloud Secret Manager:

    firebase functions:secrets:set GOOGLE_GENAI_API_KEY

    Это важно, чтобы случайно не раскрыть ключ API, который предоставляет доступ к сервису с платной подпиской.

    Подробнее о том, как хранить конфиденциальную информацию о конфигурации и получать к ней доступ…

  3. Измените src/index.js и добавьте после существующих импортов следующее:

    const {defineSecret} = require("firebase-functions/params");
    // Store the Gemini API key in Cloud Secret Manager.
    const apiKey = defineSecret("GOOGLE_GENAI_API_KEY");

    Затем в определении вызываемой функции укажите, что ей нужен доступ к этому секретному значению:

    // Bind the Gemini API key secret parameter to the function.
    secrets: [apiKey],

Теперь, когда вы развернете эту функцию, ваш ключ API будет храниться в Google Cloud Secret Manager и доступен из среды Cloud Functions.

Gemini (Vertex AI)

  1. В консоли Google Cloud включите Vertex AI API для проекта Firebase.

  2. На странице IAM убедитесь, что сервисному аккаунту Compute по умолчанию назначена роль пользователя Vertex AI.

В этом руководстве вам нужно задать секрет только для поставщика модели, но в целом вам нужно будет сделать что-то подобное для каждого сервиса, который используется в вашем потоке.

Добавьте принудительное применение Firebase App Check (необязательно)

Firebase App Check использует встроенное подтверждение, чтобы убедиться, что наш API вызывается только вашим приложением. Метод onCallGenkit позволяет декларативно применять правило App Check.

export const generatePoem = onCallGenkit({
  enforceAppCheck: true,
  // Optional. Makes App Check tokens only usable once. This adds extra security
  // at the expense of slowing down your app to generate a token for every API
  // call
  consumeAppCheckToken: true,
}, generatePoemFlow);

Как настроить CORS (совместное использование ресурсов между разными источниками)

Используйте параметр cors, чтобы указать, каким источникам разрешен доступ к вашей функции.

По умолчанию для вызываемых функций настроена технология CORS, которая разрешает запросы из всех источников. Чтобы разрешить некоторые междоменные запросы, но не все, передайте список определенных доменов или регулярных выражений, которые должны быть разрешены. Пример:

export const tellJoke = onCallGenkit({
  cors: 'mydomain.com',
}, jokeTeller);

Полный пример

После того как вы внесете все изменения, описанные в этом руководстве, развертываемый поток будет выглядеть примерно так, как в примере ниже:

const {onCallGenkit} = require("firebase-functions/https");
const {defineSecret} = require("firebase-functions/params");

// Dependencies for Genkit.
const {gemini15Flash, googleAI} = require("@genkit-ai/googleai");
const {genkit, z} = require("genkit");

// Store the Gemini API key in Cloud Secret Manager.
const apiKey = defineSecret("GOOGLE_GENAI_API_KEY");

const ai = genkit({
  plugins: [googleAI()],
  model: gemini15Flash,
});

const jokeTeller = ai.defineFlow({
  name: "jokeTeller",
  inputSchema: z.string().nullable(),
  outputSchema: z.string(),
  streamSchema: z.string(),
}, async (jokeType = "knock-knock", {sendChunk}) => {
  const prompt = `Tell me a ${jokeType} joke.`;

  // Call the `generateStream()` method to
  // receive the `stream` async iterable.
  const {stream, response: aiResponse} = ai.generateStream(prompt);

  // Send new words of the generative AI response
  // to the client as they are generated.
  for await (const chunk of stream) {
    sendChunk(chunk.text);
  }

  // Return the full generative AI response
  // to clients that may not support streaming.
  return (await aiResponse).text;
},
);

exports.tellJoke = onCallGenkit({
  // Bind the Gemini API key secret parameter to the function.
  secrets: [apiKey],
},
// Pass in the genkit flow.
jokeTeller,
);

Как развернуть цепочки в Firebase

После того как вы определите последовательности с помощью функции onCallGenkit, их можно будет развернуть так же, как и другие функции:

cd $PROJECT_ROOT
firebase deploy --only functions