Wywoływanie procesów Genkit z aplikacji

Cloud Functions dla Firebase ma metodę onCallGenkit, która umożliwia utworzenie funkcji wywoływanej z działaniem Genkit (Flow). Te funkcje można wywoływać za pomocą genkit/beta/client lub pakietów SDK klienta Cloud Functions, które automatycznie dodają informacje o autoryzacji.

Zanim zaczniesz

  • Powinieneś(-aś) znać koncepcję przepływów w Genkit i wiedzieć, jak je tworzyć. Instrukcje na tej stronie zakładają, że masz już zdefiniowane przepływy, które chcesz wdrożyć.
  • Jest to przydatne, ale nie jest wymagane, jeśli wcześniej korzystałeś(-aś) z Cloud Functions dla Firebase.

Konfigurowanie projektu Firebase

  1. Utwórz nowy projekt Firebase w konsoli Firebase lub wybierz istniejący.

  2. Przenieś projekt na abonament Blaze, który jest wymagany w przypadku wdrożenia produkcyjnego Cloud Functions.

  3. Zainstaluj wiersz poleceń Firebase.

  4. Zaloguj się za pomocą wiersza poleceń Firebase:

    firebase login
    firebase login --reauth # alternative, if necessary
    firebase login --no-localhost # if running in a remote shell
  5. Utwórz nowy katalog projektu:

    export PROJECT_ROOT=~/tmp/genkit-firebase-project1
    mkdir -p $PROJECT_ROOT
  6. Zainicjuj projekt Firebase w katalogu:

    cd $PROJECT_ROOT
    firebase init functions

W dalszej części tej strony zakładamy, że funkcje zostały napisane w JavaScript.

Umieść proces w tagu onCallGenkit

Po skonfigurowaniu projektu Firebase z Cloud Functions możesz skopiować lub napisać definicje przepływu w katalogu functions projektu. Oto przykładowy proces, który to ilustruje:

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;
},
);

Aby wdrożyć taki proces, umieść go w onCallGenkit, które jest dostępne w firebase-functions/https. Ta metoda pomocnicza ma wszystkie funkcje funkcji wywoływanych i automatycznie obsługuje odpowiedzi strumieniowe oraz odpowiedzi w formacie JSON.

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

Udostępnianie danych logowania interfejsu API w przypadku wdrożonych przepływów

Po wdrożeniu przepływy muszą mieć możliwość uwierzytelniania w dowolnych usługach zdalnych, z których korzystają. Większość procesów wymaga co najmniej danych logowania umożliwiających dostęp do usługi interfejsu API modelu, z której korzystają.

W tym przykładzie wykonaj jedną z tych czynności w zależności od wybranego dostawcy modelu:

Gemini (AI od Google)

  1. Sprawdź, czy AI od Google jest dostępna w Twoim regionie.

  2. Wygeneruj klucz interfejsu API dla Gemini API za pomocą Google AI Studio.

  3. Zapisz klucz interfejsu API w Cloud Secret Manager:

    firebase functions:secrets:set GOOGLE_GENAI_API_KEY

    Ten krok jest ważny, aby zapobiec przypadkowemu ujawnieniu klucza interfejsu API, który zapewnia dostęp do usługi, za którą możesz płacić.

    Więcej informacji o zarządzaniu obiektami tajnymi znajdziesz w artykule Przechowywanie poufnych informacji o konfiguracji i uzyskiwanie do nich dostępu.

  4. Edytuj plik src/index.js i po istniejących instrukcjach importu dodaj te instrukcje:

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

    Następnie w definicji funkcji wywoływanej zadeklaruj, że funkcja potrzebuje dostępu do tej wartości tajnej:

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

Teraz, gdy wdrożysz tę funkcję, klucz interfejsu API zostanie zapisany w usłudze Cloud Secret Manager i będzie dostępny w środowisku Cloud Functions.

Gemini (Vertex AI)

  1. W konsoli Cloud włącz interfejs Vertex AI API w projekcie Firebase.

  2. Na stronie Uprawnienia sprawdź, czy domyślne konto usługi Compute ma przypisaną rolę Użytkownik Vertex AI.

W tym samouczku musisz skonfigurować tylko klucz tajny dostawcy modelu, ale ogólnie musisz zrobić coś podobnego w przypadku każdej usługi używanej w przepływie.

(Opcjonalnie) Dodawanie wymuszania sprawdzania aplikacji

Sprawdzanie aplikacji Firebase wykorzystuje natywną atestację, aby sprawdzić, czy interfejs API jest wywoływany tylko przez Twoją aplikację. onCallGenkit obsługuje deklaratywne egzekwowanie weryfikacji aplikacji.

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);

Konfigurowanie CORS (współdzielenia zasobów pomiędzy serwerami z różnych domen)

Użyj opcji cors, aby określić, które źródła mogą uzyskiwać dostęp do Twojej funkcji.

Domyślnie funkcje wywoływalne mają skonfigurowane CORS, aby zezwalać na żądania ze wszystkich źródeł. Aby zezwolić na niektóre żądania z innych domen, ale nie na wszystkie, przekaż listę konkretnych domen lub wyrażeń regularnych, które powinny być dozwolone. Przykład:

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

Pełny przykład

Po wprowadzeniu wszystkich opisanych powyżej zmian wdrożony proces będzie wyglądać podobnie jak w tym przykładzie:

const {onCallGenkit} = require("firebase-functions/v2/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,
);

Wdrażanie przepływów w Firebase

Po zdefiniowaniu przepływów za pomocą onCallGenkit możesz je wdrożyć tak samo jak inne funkcje:

cd $PROJECT_ROOT
firebase deploy --only functions