Plugin Firebase

Il plug-in Firebase fornisce diverse integrazioni con i servizi Firebase:

  • Indicizzatori e retriever che utilizzano l'archivio di vettori Cloud Firestore
  • Archiviazione dei dati traccianti utilizzando Cloud Firestore
  • Deployment del flusso utilizzando Cloud Functions
  • Criteri di autorizzazione per gli utenti di Firebase Authentication
  • Esportazione della telemetria nella suite operativa di Google Cloud

Installazione

npm i --save @genkit-ai/firebase

Prerequisiti

  • Tutti i prodotti Firebase richiedono un progetto Firebase. Puoi creare un nuovo progetto o attivare Firebase in un progetto Google Cloud esistente utilizzando la Console Firebase.
  • Inoltre, se vuoi eseguire il deployment dei flussi in Cloud Functions, devi eseguire l'upgrade del progetto al piano Blaze con pagamento a consumo.
  • Se vuoi eseguire localmente il codice che esporta la telemetria, devi installare lo strumento Google Cloud CLI.

Configurazione

ID progetto

Per utilizzare questo plug-in, specificalo quando avvii Genkit:

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

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

Il plug-in richiede di specificare l'ID progetto Firebase. Puoi specificare l'ID progetto Firebase in uno dei seguenti modi:

  • Imposta projectId nell'oggetto di configurazione firebase().

  • Imposta la variabile di ambiente GCLOUD_PROJECT. Se esegui il flusso da un ambiente Google Cloud (Cloud Functions, Cloud Run e così via),GCLOUD_PROJECT viene impostato automaticamente sull'ID progetto dell'ambiente.

    Se imposti GCLOUD_PROJECT, puoi omettere il parametro di configurazione: firebase()

Credenziali

Per fornire le credenziali di Firebase, devi anche configurare le credenziali predefinite dell'applicazione Google Cloud. Per specificare le credenziali:

  • Se esegui il flusso da un ambiente Google Cloud (Cloud Functions, Cloud Run e così via), questo valore viene impostato automaticamente.

  • Per altri ambienti:

    1. Genera le credenziali dell'account di servizio per il tuo progetto Firebase e scarica il file della chiave JSON. Puoi farlo nella pagina Account di servizio della Console di Firebase.
    2. Imposta la variabile di ambiente GOOGLE_APPLICATION_CREDENTIALS sul percorso del file JSON contenente la chiave dell'account di servizio oppure imposta la variabile di ambiente GCLOUD_SERVICE_ACCOUNT_CREDS sui contenuti del file JSON.

Telemetria

Il plug-in ha una dipendenza diretta dal plug-in Google Cloud e, di conseguenza, dispone di disposizioni per abilitare l'esportazione della telemetria nella suite operativa di Google Cloud. Per attivare l'esportazione della telemetria, chiama enableFirebaseTelemetry():

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

enableFirebaseTelemetry();

Fai riferimento alla documentazione del plug-in Google Cloud per tutte le opzioni di configurazione e le API necessarie da attivare nel progetto.

Utilizzo

Questo plug-in fornisce diverse integrazioni con i servizi Firebase, che puoi utilizzare insieme o singolarmente.

Spazio vettoriale Cloud Firestore

Puoi utilizzare Cloud Firestore come spazio vettoriale per l'indicizzazione e il recupero dei raggruppamenti.

Questa sezione contiene informazioni specifiche sul plug-in firebase e sulla funzionalità di ricerca di vettori di Cloud Firestore. Per una discussione più dettagliata sull'implementazione della RAG utilizzando Genkit, consulta la pagina Retrieval-Augmented Generation.

Utilizzo di GCLOUD_SERVICE_ACCOUNT_CREDS e Firestore

Se utilizzi le credenziali dell'account di servizio passandole direttamente tramite GCLOUD_SERVICE_ACCOUNT_CREDS e utilizzi anche Firestore come archivio di vettori, dovrai passare le credenziali direttamente all'istanza Firestore durante l'inizializzazione, altrimenti l'oggetto singleton potrebbe essere inizializzato con le credenziali predefinite dell'applicazione, a seconda dell'ordine di inizializzazione del 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);
}

Retriever

Il plug-in firebase fornisce una funzione di utilità per definire i recuperatori 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)
});

Per utilizzarlo, passalo alla funzione ai.retrieve():

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

Le opzioni di recupero disponibili includono:

  • limit: specifica il numero di risultati corrispondenti da restituire.
  • where: coppie di campi/valori da associare (ad es. {category: 'food'}) oltre alla ricerca di vettori.
  • collection: sostituisci la raccolta predefinita per cercare, ad esempio, una sottoraccolta.

Indicizzazione e incorporamento

Per compilare la raccolta Firestore, utilizza un generatore di embedding insieme all'SDK Admin. Ad esempio, lo script di importazione del menu della pagina Generare con recupero avanzato potrebbe essere adattato per Firestore nel seguente modo:

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 si basa sugli indici per fornire query rapide ed efficienti sulle raccolte. Tieni presente che per "indice" qui si intendono gli indici del database e non le astrattive dell'indice e del recupero di Genkit.

L'esempio precedente richiede l'indicizzazione del campo embedding per funzionare. Per creare l'indice:

  • Esegui il comando gcloud descritto nella sezione Creare un indice di vettori a campo singolo della documentazione di Firestore.

    Il comando è il seguente:

    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

    Tuttavia, la configurazione corretta dell'indicizzazione dipende dalle query che effettuerai e dal modello di incorporamento che utilizzi.

  • In alternativa, chiama ai.retrieve() e Firestore restituirà un errore con il comando corretto per creare l'indice.

Scopri di più

Cloud Functions

Il plug-in fornisce il costruttore onFlow(), che crea un flusso basato su una funzione Cloud Functions for Firebase attivata tramite HTTPS. Queste funzioni sono conformi all'interfaccia della funzione richiamabile di Firebase e puoi utilizzarle tramite gli SDK client di 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;
  }
);

Esegui il deployment del flusso utilizzando l'interfaccia a riga di comando di Firebase:

firebase deploy --only functions

La funzione onFlow() ha alcune opzioni non presenti in defineFlow():

  • httpsOptions: un oggetto HttpsOptions usato per configurare la Funzione Cloud:

    export const exampleFlow = onFlow(
      ai,
      {
        name: "exampleFlow",
        httpsOptions: {
          cors: true,
        },
        // ...
      },
      async (prompt) => {
        // ...
      }
    );
    
  • enforceAppCheck: quando true, rifiuta le richieste con token App Check mancanti o non validi.

  • consumeAppCheckToken: quando true, invalida il token App Check dopo averlo verificato.

    Consulta Protezione da replay.

Firebase Auth

Questo plug-in fornisce una funzione di supporto per creare criteri di autorizzazione per 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) => {
    // ...
  }
);

Per definire un criterio di autenticazione, fornisci a firebaseAuth() una funzione di callback che prenda un DecodedIdToken come unico parametro. In questa funzione, esamina il token utente e genera un errore se l'utente non soddisfa uno dei criteri che vuoi richiedere.

Per una discussione più approfondita su questo argomento, consulta Autorizzazione e integrità.