Complemento de Firebase

El complemento de Firebase proporciona varias integraciones con los servicios de Firebase:

  • Indexadores y recuperadores que usan el almacén de vectores de Cloud Firestore
  • Almacenamiento de registros con Cloud Firestore
  • Implementación de flujos con Cloud Functions
  • Políticas de autorización para usuarios de Firebase Authentication
  • Exportación de telemetría a Google Cloud's operations suite

Instalación

npm i --save @genkit-ai/firebase

Requisitos previos

  • Todos los productos de Firebase requieren un proyecto de Firebase. Puedes crear un proyecto nuevo o habilitar Firebase en un proyecto de Google Cloud existente con Firebase console.
  • Además, si deseas implementar flujos en Cloud Functions, debes actualizar tu proyecto al plan Blaze de pago por uso.
  • Si quieres ejecutar código de forma local que exporte la telemetría, debes tener instalada la herramienta Google Cloud CLI.

Configuración

ID del proyecto

Para usar este complemento, especifícalo cuando inicialices Genkit:

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

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

El complemento requiere que especifiques el ID de tu proyecto de Firebase. Puedes especificar el ID de tu proyecto de Firebase de las siguientes maneras:

  • Establece projectId en el objeto de configuración firebase().

  • Configura la variable de entorno GCLOUD_PROJECT. Si ejecutas tu flujo desde un entorno de Google Cloud (Cloud Functions, Cloud Run, etc.), GCLOUD_PROJECT se establece automáticamente en el ID del proyecto del entorno.

    Si configuras GCLOUD_PROJECT, puedes omitir el parámetro de configuración: firebase()

Credenciales

Para proporcionar credenciales de Firebase, también debes configurar las credenciales predeterminadas de la aplicación de Google Cloud. Para especificar tus credenciales, haz lo siguiente:

  • Si ejecutas tu flujo desde un entorno de Google Cloud (Cloud Functions, Cloud Run, etc.), esto se configura automáticamente.

  • Para otros entornos, haz lo siguiente:

    1. Genera credenciales de cuenta de servicio para tu proyecto de Firebase y descarga el archivo de claves JSON. Puedes hacerlo en la página Cuenta de servicio de Firebase console.
    2. Configura la variable de entorno GOOGLE_APPLICATION_CREDENTIALS en la ruta del archivo JSON que contiene la clave de tu cuenta de servicio, o bien puedes configurar la variable de entorno GCLOUD_SERVICE_ACCOUNT_CREDS en el contenido del archivo JSON.

Telemetría

El complemento tiene una dependencia directa del complemento de Google Cloud y, por lo tanto, tiene disposiciones para habilitar la exportación de telemetría a la suite de operaciones de Google Cloud. Para habilitar la exportación de telemetría, llama a enableFirebaseTelemetry():

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

enableFirebaseTelemetry();

Consulta la documentación del complemento de Google Cloud para conocer todas las opciones de configuración y las APIs necesarias que se deben habilitar en el proyecto.

Uso

Este complemento proporciona varias integraciones con los servicios de Firebase, que puedes usar en conjunto o de forma individual.

Tienda de vectores de Cloud Firestore

Puedes usar Cloud Firestore como un almacén de vectores para el indexado y la recuperación de RAG.

Esta sección contiene información específica del complemento firebase y la función de búsqueda de vectores de Cloud Firestore. Consulta la página de generación mejorada de recuperación para ver un debate más detallado sobre la implementación de RAG con Genkit.

Usa GCLOUD_SERVICE_ACCOUNT_CREDS y Firestore

Si usas credenciales de cuenta de servicio pasando credenciales directamente a través de GCLOUD_SERVICE_ACCOUNT_CREDS y también usas Firestore como un almacén de vectores, deberás pasar las credenciales directamente a la instancia de Firestore durante la inicialización o el singleton se puede inicializar con las credenciales predeterminadas de la aplicación según el orden de inicialización del complemento.

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

Recuperadores

El complemento firebase proporciona una función conveniente para definir los recuperadores de 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)
});

Para usarlo, pásalo a la función ai.retrieve():

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

Entre las opciones de recuperación disponibles, se incluyen las siguientes:

  • limit: Especifica la cantidad de resultados coincidentes que se mostrarán.
  • where: Son pares de campos o valores que deben coincidir (p.ej., {category: 'food'}) además de la búsqueda de vectores.
  • collection: Anula la colección predeterminada para buscar, p.ej., una búsqueda de subcolección.

Indexación y incorporación

Para propagar tu colección de Firestore, usa un generador de incorporaciones junto con el SDK de Admin. Por ejemplo, la secuencia de comandos de transferencia de menús de la página Generación con recuperación mejorada se podría adaptar para Firestore de la siguiente manera:

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 depende de los índices para proporcionar consultas rápidas y eficientes en las colecciones. (Ten en cuenta que "índice" aquí se refiere a los índices de la base de datos y no a las abstracciones del indexador y el recuperador de Genkit).

El ejemplo anterior requiere que el campo embedding esté indexado para que funcione. Para crear el índice, sigue estos pasos:

  • Ejecuta el comando gcloud que se describe en la sección Cómo crear un índice vectorial de campo único de la documentación de Firestore.

    El comando se ve de la siguiente manera:

    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

    Sin embargo, la configuración de indexación correcta depende de las consultas que harás y del modelo de incorporación que uses.

  • Como alternativa, llama a ai.retrieve() y Firestore mostrará un error con el comando correcto para crear el índice.

Más información

Cloud Functions

El complemento proporciona el constructor onFlow(), que crea un flujo respaldado por una función activada por HTTPS de Cloud Functions para Firebase. Estas funciones cumplen con la interfaz de función que admite llamadas de Firebase y puedes usar los SDK de cliente de Cloud Functions para llamarlas.

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

Implementa tu flujo con Firebase CLI:

firebase deploy --only functions

La función onFlow() tiene algunas opciones que no están presentes en defineFlow():

  • httpsOptions: Es un objeto HttpsOptions que se usa para configurar tu Cloud Function:

    export const exampleFlow = onFlow(
      ai,
      {
        name: "exampleFlow",
        httpsOptions: {
          cors: true,
        },
        // ...
      },
      async (prompt) => {
        // ...
      }
    );
    
  • enforceAppCheck: Cuando true, rechaza las solicitudes con tokens de verificación de apps faltantes o no válidos.

  • consumeAppCheckToken: Cuando true, invalida el token de Verificación de aplicaciones después de verificarlo.

    Consulta Protección contra la repetición.

Firebase Auth

Este complemento proporciona una función de ayuda para crear políticas de autorización en 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) => {
    // ...
  }
);

Para definir una política de autenticación, proporciona a firebaseAuth() una función de devolución de llamada que tome un DecodedIdToken como su único parámetro. En esta función, examina el token del usuario y muestra un error si el usuario no cumple con ninguno de los criterios que deseas exigir.

Consulta Autorización e integridad para obtener un análisis más detallado de este tema.