Plug-in Firebase

Le plug-in Firebase fournit plusieurs intégrations avec les services Firebase:

  • Indexeurs et récupérateurs utilisant le magasin de vecteurs Cloud Firestore
  • Suivre l'espace de stockage à l'aide de Cloud Firestore
  • Déploiement de flux à l'aide de Cloud Functions
  • Règles d'autorisation pour les utilisateurs de Firebase Authentication
  • Exportation des données de télémétrie vers la suite Google Cloud Operations

Installation

npm i --save @genkit-ai/firebase

Prérequis

  • Tous les produits Firebase nécessitent un projet Firebase. Vous pouvez créer un projet ou activer Firebase dans un projet Google Cloud existant à l'aide de la console Firebase.
  • De plus, si vous souhaitez déployer des flux dans Cloud Functions, vous devez mettre à niveau votre projet vers le forfait Blaze (paiement à l'usage).
  • Si vous souhaitez exécuter localement du code qui exporte des données de télémétrie, vous devez installer l'outil Google Cloud CLI.

Configuration

ID du projet

Pour utiliser ce plug-in, spécifiez-le lorsque vous initialisez Genkit:

import { genkit } from 'genkit';
import { firebase } from '@genkit-ai/firebase';

const ai = genkit({
  plugins: [firebase({ projectId: "your-firebase-project" })],
});

Le plug-in vous oblige à spécifier l'ID de votre projet Firebase. Vous pouvez spécifier l'ID de votre projet Firebase de l'une des manières suivantes:

  • Définissez projectId dans l'objet de configuration firebase().

  • Définissez la variable d'environnement GCLOUD_PROJECT. Si vous exécutez votre flux à partir d'un environnement Google Cloud (Cloud Functions, Cloud Run, etc.), GCLOUD_PROJECT est automatiquement défini sur l'ID de projet de l'environnement.

    Si vous définissez GCLOUD_PROJECT, vous pouvez omettre le paramètre de configuration : firebase()

Identifiants

Pour fournir des identifiants Firebase, vous devez également configurer les identifiants par défaut de l'application Google Cloud. Pour spécifier vos identifiants :

  • Si vous exécutez votre flux à partir d'un environnement Google Cloud (Cloud Functions, Cloud Run, etc.), cette valeur est définie automatiquement.

  • Pour les autres environnements:

    1. Générez des identifiants de compte de service pour votre projet Firebase et téléchargez le fichier de clé JSON. Pour ce faire, accédez à la page Compte de service de la console Firebase.
    2. Définissez la variable d'environnement GOOGLE_APPLICATION_CREDENTIALS sur le chemin du fichier JSON contenant votre clé de compte de service, ou définissez la variable d'environnement GCLOUD_SERVICE_ACCOUNT_CREDS sur le contenu du fichier JSON.

Télémétrie

Le plug-in dépend directement du plug-in Google Cloud et est donc conçu pour permettre l'exportation de la télémétrie vers la suite Cloud Operations de Google. Pour activer l'exportation de la télémétrie, appelez enableFirebaseTelemetry():

import { enableFirebaseTelemetry } from '@genkit-ai/firebase';

enableFirebaseTelemetry();

Consultez la documentation du plug-in Google Cloud pour connaître toutes les options de configuration et les API nécessaires à activer dans le projet.

Utilisation

Ce plug-in fournit plusieurs intégrations avec les services Firebase, que vous pouvez utiliser ensemble ou individuellement.

Stockage de vecteurs Cloud Firestore

Vous pouvez utiliser Cloud Firestore comme magasin de vecteurs pour l'indexation et la récupération des données de classification RAG.

Cette section contient des informations spécifiques au plug-in firebase et à la fonctionnalité de recherche vectorielle de Cloud Firestore. Consultez la page Génération augmentée de récupération pour en savoir plus sur l'implémentation de la génération augmentée de récupération à l'aide de Genkit.

Utiliser GCLOUD_SERVICE_ACCOUNT_CREDS et Firestore

Si vous utilisez des identifiants de compte de service en transmettant des identifiants directement via GCLOUD_SERVICE_ACCOUNT_CREDS et que vous utilisez également Firestore comme magasin de vecteurs, vous devez transmettre les identifiants directement à l'instance Firestore lors de l'initialisation. Sinon, le singleton peut être initialisé avec les identifiants par défaut de l'application, en fonction de l'ordre d'initialisation du plug-in.

import {initializeApp} from "firebase-admin/app";
import {getFirestore} from "firebase-admin/firestore";

const app = initializeApp();
let firestore = getFirestore(app);

if (process.env.GCLOUD_SERVICE_ACCOUNT_CREDS) {
  const serviceAccountCreds = JSON.parse(process.env.GCLOUD_SERVICE_ACCOUNT_CREDS);
  const authOptions = { credentials: serviceAccountCreds };
  firestore.settings(authOptions);
}

Retrievers

Le plug-in firebase fournit une fonction pratique pour définir des récupérateurs Firestore, defineFirestoreRetriever():

import {defineFirestoreRetriever} from "@genkit-ai/firebase";
import {retrieve} from "@genkit-ai/ai/retriever";

import {initializeApp} from "firebase-admin/app";
import {getFirestore} from "firebase-admin/firestore";

const app = initializeApp();
const firestore = getFirestore(app);

const yourRetrieverRef = defineFirestoreRetriever({
  name: "yourRetriever",
  firestore: getFirestore(app),
  collection: "yourCollection",
  contentField: "yourDataChunks",
  vectorField: "embedding",
  embedder: textEmbeddingGecko, // Import from '@genkit-ai/googleai' or '@genkit-ai/vertexai'
  distanceMeasure: "COSINE", // "EUCLIDEAN", "DOT_PRODUCT", or "COSINE" (default)
});

Pour l'utiliser, transmettez-le à la fonction ai.retrieve():

const docs = await ai.retrieve({
  retriever: yourRetrieverRef,
  query: "look for something",
  options: { limit: 5 },
});

Les options de récupération disponibles sont les suivantes:

  • limit: spécifiez le nombre de résultats correspondants à renvoyer.
  • where: paires champ/valeur à faire correspondre (par exemple, {category: 'food'}) en plus de la recherche vectorielle.
  • collection: remplacez la collection par défaut pour effectuer une recherche, par exemple une recherche dans une sous-collection.

Indexation et intégration

Pour renseigner votre collection Firestore, utilisez un générateur d'embeddings avec le SDK Admin. Par exemple, le script d'ingestion de menu de la page Génération avec augmentation du rappel peut être adapté à Firestore comme suit:

import { genkit } from 'genkit';
import { vertexAI, textEmbedding004 } from "@genkit-ai/vertexai";

import { applicationDefault, initializeApp } from "firebase-admin/app";
import { FieldValue, getFirestore } from "firebase-admin/firestore";

import { chunk } from "llm-chunk";
import pdf from "pdf-parse";

import { readFile } from "fs/promises";
import path from "path";

// Change these values to match your Firestore config/schema
const indexConfig = {
  collection: "menuInfo",
  contentField: "text",
  vectorField: "embedding",
  embedder: textEmbedding004,
};

const ai = genkit({
  plugins: [vertexAI({ location: "us-central1" })],
});

const app = initializeApp({ credential: applicationDefault() });
const firestore = getFirestore(app);

export async function indexMenu(filePath: string) {
  filePath = path.resolve(filePath);

  // Read the PDF.
  const pdfTxt = await extractTextFromPdf(filePath);

  // Divide the PDF text into segments.
  const chunks = await chunk(pdfTxt);

  // Add chunks to the index.
  await indexToFirestore(chunks);
}

async function indexToFirestore(data: string[]) {
  for (const text of data) {
    const embedding = await ai.embed({
      embedder: indexConfig.embedder,
      content: text,
    });
    await firestore.collection(indexConfig.collection).add({
      [indexConfig.vectorField]: FieldValue.vector(embedding),
      [indexConfig.contentField]: text,
    });
  }
}

async function extractTextFromPdf(filePath: string) {
  const pdfFile = path.resolve(filePath);
  const dataBuffer = await readFile(pdfFile);
  const data = await pdf(dataBuffer);
  return data.text;
}

Firestore dépend des index pour fournir des requêtes rapides et efficaces sur les collections. (Notez que "index" ici fait référence aux index de base de données, et non aux abstractions d'indexeur et de récupérateur de Genkit.)

L'exemple précédent nécessite que le champ embedding soit indexé pour fonctionner. Pour créer l'index:

  • Exécutez la commande gcloud décrite dans la section Créer un index vectoriel à champ unique de la documentation Firestore.

    La commande se présente comme suit :

    gcloud alpha firestore indexes composite create --project=your-project-id \
      --collection-group=yourCollectionName --query-scope=COLLECTION \
      --field-config=vector-config='{"dimension":"768","flat": "{}"}',field-path=yourEmbeddingField

    Toutefois, la configuration d'indexation correcte dépend des requêtes que vous effectuerez et du modèle d'encapsulation que vous utilisez.

  • Vous pouvez également appeler ai.retrieve(). Firestore génère alors une erreur avec la commande appropriée pour créer l'index.

En savoir plus

Cloud Functions

Le plug-in fournit le constructeur onFlow(), qui crée un flux basé sur une fonction Cloud Functions for Firebase déclenchée par HTTPS. Ces fonctions sont conformes à l'interface de fonction appelable de Firebase. Vous pouvez les appeler à l'aide des SDK client Cloud Functions.

import { onFlow, noAuth } from "@genkit-ai/firebase/functions";

export const exampleFlow = onFlow(
  ai, // Provide the Genkit instance
  {
    name: "exampleFlow",
    authPolicy: noAuth(), // WARNING: noAuth() creates an open endpoint!
  },
  async (prompt) => {
    // Flow logic goes here.

    return response;
  }
);

Déployez votre flux à l'aide de la CLI Firebase:

firebase deploy --only functions

La fonction onFlow() comporte des options qui ne sont pas présentes dans defineFlow():

  • httpsOptions: objet HttpsOptions utilisé pour configurer votre fonction Cloud:

    export const exampleFlow = onFlow(
      ai,
      {
        name: "exampleFlow",
        httpsOptions: {
          cors: true,
        },
        // ...
      },
      async (prompt) => {
        // ...
      }
    );
    
  • enforceAppCheck: lorsque true, rejetez les requêtes avec des jetons App Check manquants ou non valides.

  • consumeAppCheckToken: lorsque la valeur est true, invalidez le jeton App Check après l'avoir validé.

    Consultez la section Protection contre la relecture.

Authentification Firebase

Ce plug-in fournit une fonction d'assistance pour créer des stratégies d'autorisation autour de Firebase Auth:

import {firebaseAuth} from "@genkit-ai/firebase/auth";

export const exampleFlow = onFlow(
  ai,
  {
    name: "exampleFlow",
    authPolicy: firebaseAuth((user) => {
      if (!user.email_verified) throw new Error("Requires verification!");
    }),
  },
  async (prompt) => {
    // ...
  }
);

Pour définir une stratégie d'authentification, fournissez à firebaseAuth() une fonction de rappel qui utilise un DecodedIdToken comme seul paramètre. Dans cette fonction, examinez le jeton utilisateur et générez une erreur si l'utilisateur ne remplit pas l'un des critères que vous souhaitez exiger.

Pour en savoir plus sur ce sujet, consultez Autorisation et intégrité.