Plug-in Firebase

Le plug-in Firebase permet d'intégrer les services Firebase, ce qui vous permet de créer des applications d'IA intelligentes et évolutives. Principales fonctionnalités :

  • Firestore Vector Store: utilisez Firestore pour l'indexation et la récupération avec des embeddings de vecteurs.
  • Cloud Functions: déployez des flux en tant que fonctions déclenchées par HTTPS.
  • Firebase Authentication: implémentez des règles d'autorisation.
  • Télémétrie: exportez la télémétrie vers la suite d'opérations Google Cloud et affichez des vues spécialisées dans la console Firebase.

Installation

Installez le plug-in Firebase avec npm:

npm install @genkit-ai/firebase

Prérequis

Configuration du projet Firebase

  1. 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.
  2. Si vous déployez des flux avec Cloud Functions, passez au forfait Blaze pour votre projet Firebase.
  3. 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.

Initialisation du SDK Admin Firebase

Vous devez initialiser le SDK Firebase Admin dans votre application. Cette opération n'est pas gérée automatiquement par le plug-in.

import { initializeApp } from 'firebase-admin/app';

initializeApp({
  projectId: 'your-project-id',
});

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 initializeApp(), comme indiqué dans l'extrait de code ci-dessus.

  • 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 dans initializeApp().

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 d'accès au 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.

Fonctionnalités et utilisation

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 d'opérations Cloud 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.

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. Pour en savoir plus sur l'implémentation de la génération augmentée de récupération à l'aide de Genkit, consultez la page Génération augmentée de récupération.

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

Définir un récupérateur Firestore

Utilisez defineFirestoreRetriever() pour créer un récupérateur pour les requêtes Firestore basées sur des vecteurs.

import { defineFirestoreRetriever } from '@genkit-ai/firebase';
import { initializeApp } from 'firebase-admin/app';
import { getFirestore } from 'firebase-admin/firestore';

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

const retriever = defineFirestoreRetriever(ai, {
  name: 'exampleRetriever',
  firestore,
  collection: 'documents',
  contentField: 'text', // Field containing document content
  vectorField: 'embedding', // Field containing vector embeddings
  embedder: yourEmbedderInstance, // Embedder to generate embeddings
  distanceMeasure: 'COSINE', // Default is 'COSINE'; other options: 'EUCLIDEAN', 'DOT_PRODUCT'
});

Récupérer des documents

Pour récupérer des documents à l'aide du récupérateur défini, transmettez l'instance du récupérateur et les options de requête à ai.retrieve.

const docs = await ai.retrieve({
  retriever,
  query: 'search query',
  options: {
    limit: 5, // Options: Return up to 5 documents
    where: { category: 'example' }, // Optional: Filter by field-value pairs
    collection: 'alternativeCollection', // Optional: Override default collection
  },
});

Options de récupération disponibles

Les options suivantes peuvent être transmises au champ options dans ai.retrieve:

  • limit: (nombre)
    Spécifiez le nombre maximal de documents à récupérer. La valeur par défaut est 10.

  • where: (Record<chaîne, tout>)
    Ajoutez des filtres supplémentaires en fonction des champs Firestore. Exemple :

    where: { category: 'news', status: 'published' }
    
  • collection: (chaîne)
    Remplace la collection par défaut spécifiée dans la configuration du récupérateur. Cela est utile pour interroger des sous-collections ou passer dynamiquement d'une collection à une autre.

Insérer des embeddings dans Firestore

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 récupération 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 le terme "index" fait ici référence aux index de base de données, et non aux abstractions d'indexeur et de récupérateur de Genkit.)

Pour fonctionner, l'exemple précédent nécessite que le champ embedding soit indexé. 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 appropriée dépend des requêtes que vous allez effectuer 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

Déployer des flux en tant que fonctions Cloud

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.

Firebase Authentication

Ce plug-in fournit une fonction d'assistance pour créer des règles 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é.