Wywoływanie procesów Genkit z aplikacji

Cloud Functions for Firebase ma metodę onCallGenkit, która umożliwia tworzenie funkcji, którą można wywołać, za pomocą działania Genkit (przepływu). Te funkcje można wywoływać za pomocą genkit/beta/client lub a Cloud Functions for Firebase Client SDK, które automatycznie dodają informacje o autoryzacji.

Zanim zaczniesz

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

Konfigurowanie projektu w Firebase

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

  2. Przenieś projekt na abonament Blaze z płatnością według wykorzystania, który jest wymagany w przypadku Cloud Functions wdrożenia produkcyjnego.

  3. Zainstaluj interfejs Firebase CLI.

  4. Zaloguj się w interfejsie Firebase CLI:

    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 w Firebase w katalogu:

    cd $PROJECT_ROOT
    firebase init functions

Dalsza część tej strony zakłada, że funkcje będziesz pisać w JavaScript.

Zawijanie przepływu w onCallGenkit

Po skonfigurowaniu projektu w Firebase i zainicjowaniu Cloud Functions w nim, możesz skopiować lub napisać definicje przepływu w katalogu functions projektu. Oto przykładowy przepływ, 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 przepływ, zawij go w onCallGenkit, który jest dostępny w firebase-functions/https. Ta metoda pomocnicza ma wszystkie funkcje funkcji, które można wywołać, i automatycznie obsługuje odpowiedzi strumieniowe i 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,
);

Udostępnianie danych logowania interfejsu API wdrożonym przepływom

Po wdrożeniu przepływy muszą mieć możliwość uwierzytelniania się w usługach zdalnych, z których korzystają. Większość przepływów potrzebuje co najmniej danych logowania 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. Wygeneruj klucz interfejsu API dla Gemini Developer API za pomocą Google AI Studio.

  2. Zapisz klucz interfejsu API w Google Cloud Secret Manager:

    firebase functions:secrets:set GOOGLE_GENAI_API_KEY

    Ten krok jest ważny, aby zapobiec przypadkowemu wyciekowi klucza interfejsu API, który zapewnia dostęp do usługi potencjalnie rozliczanej według wykorzystania.

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

  3. Edytuj plik src/index.js i po istniejących importach dodaj ten kod:

    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, którą można wywołać, 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 Google Cloud Secret Manager, i będzie dostępny ze środowiska Cloud Functions.

Gemini (Vertex AI)

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

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

Jedynym obiektem tajnym, który musisz skonfigurować w tym samouczku, jest obiekt tajny dostawcy modelu, ale ogólnie musisz zrobić coś podobnego w przypadku każdej usługi, z której korzysta Twój przepływ.

(Opcjonalnie) Dodawanie egzekwowania Firebase App Check

Firebase App Check używa natywnego potwierdzenia, aby sprawdzić, czy nasz interfejs API jest wywoływany tylko przez Twoją aplikację. Metoda onCallGenkit obsługuje App Check egzekwowanie deklaratywnie.

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 mię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, które można wywołać, mają skonfigurowane CORS tak, aby zezwalać na żądania ze wszystkich źródeł. Aby zezwolić na niektóre żądania współdzielenia, 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);

Kompletny przykład

Po wprowadzeniu wszystkich zmian opisanych w tym przewodniku przepływ, który można wdrożyć, będzie wyglądać podobnie jak w tym przykładzie:

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

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