Plug-in Firebase

Le plug-in Firebase permet d'intégrer les services Firebase afin 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.
  • Télémétrie: exportez la télémétrie vers la suite Google Cloud Operations qui alimente la console de surveillance Firebase Genkit.

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 des fonctions Cloud, 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 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 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.

Fonctionnalités et utilisation

Télémétrie

La surveillance Firebase Genkit est fournie par la suite Google Cloud Operations. Pour ce faire, vous devez activer les API liées à la télémétrie pour votre projet. Pour en savoir plus, consultez la documentation du plug-in Google Cloud.

Attribuez les rôles suivants au compte de service Compute par défaut dans la console Google Cloud IAM:

  • Rédacteur de métriques Monitoring (roles/monitoring.metricWriter)
  • Agent Cloud Trace (roles/cloudtrace.agent)
  • Rédacteur de journaux (roles/logging.logWriter)

Pour activer l'exportation de la télémétrie, appelez enableFirebaseTelemetry():

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

enableFirebaseTelemetry({
  forceDevExport: false, // Set this to true to export telemetry for local runs
});

Ce plug-in partage des options de configuration avec le plug-in Google Cloud.

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

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 à l'autre.

  • collections.

Insérer des embeddings dans Firestore

Pour renseigner votre collection Firestore, utilisez un générateur d'embarquages 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,
    }))[0].embedding;
    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 indice 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 effectuez et du modèle d'embedding que vous utilisez.

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

En savoir plus

Déployer des flux en tant que fonctions Cloud

Pour déployer un flux avec Cloud Functions, utilisez la prise en charge intégrée de la bibliothèque Firebase Functions pour Genkit. La méthode onCallGenkit vous permet de créer une fonction appelable à partir d'un flux. Il est compatible avec le streaming et les requêtes JSON. Vous pouvez les appeler à l'aide des SDK client Cloud Functions.

import { onCallGenkit } from 'firebase-functions/https';
import { defineSecret } from 'firebase-functions/params';

export const exampleFlow = ai.defineFlow({
  name: "exampleFlow",
}, async (prompt) => {
    // Flow logic goes here.

    return response;
  }
);

// WARNING: This has no authentication or app check protections.
// See github.com/firebase/genkit/blob/main/docs/auth.md for more information.
export const example = onCallGenkit({ secrets: [apiKey] }, exampleFlow);

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

firebase deploy --only functions