Plug-in do Firebase

O plug-in do Firebase oferece várias integrações com os serviços do Firebase:

  • Indexadores e recuperados usando o armazenamento de vetores do Cloud Firestore
  • Armazenamento de traces usando o Cloud Firestore
  • Implantação de fluxo usando o Cloud Functions
  • Políticas de autorização para usuários do Firebase Authentication

Instalação

npm i --save @genkit-ai/firebase

Pré-requisitos

  • Todos os produtos do Firebase exigem um projeto do Firebase. É possível criar um novo projeto ou ativar o Firebase em um projeto atual do Google Cloud usando a Console do Firebase
  • Além disso, se você quiser implantar fluxos no Cloud Functions, será preciso fazer upgrade do seu projeto para o plano de pagamento por utilização Blaze.

Configuração

ID do projeto

Para usar esse plug-in, especifique-o ao chamar configureGenkit():

import {configureGenkit} from "@genkit-ai/core";
import {firebase} from "@genkit-ai/firebase";

configureGenkit({
  plugins: [firebase({projectId: "your-firebase-project"})],
});

O plug-in exige que você especifique o ID do projeto do Firebase. É possível especificar o ID do projeto do Firebase de uma das seguintes maneiras:

  • Defina projectId no objeto de configuração firebase().

  • Defina a variável de ambiente GCLOUD_PROJECT. Se você estiver executando seu fluxo em um ambiente do Google Cloud (Cloud Functions, Cloud Run etc.), GCLOUD_PROJECT é definido automaticamente como o ID do projeto do ambiente.

    Se você definir GCLOUD_PROJECT, poderá omitir o parâmetro de configuração: firebase()

Credenciais

Para fornecer credenciais do Firebase, você também precisa configurar o Google Cloud Application Default Credentials. Para especificar suas credenciais:

  • Se você estiver executando seu fluxo em um ambiente do Google Cloud (Cloud Functions, Cloud Run e outros), isso é definido automaticamente.

  • Para outros ambientes:

    1. Gerar credenciais de conta de serviço para seu projeto do Firebase e faça o download do arquivo de chave JSON. Você pode fazer isso no Conta de serviço do console do Firebase.
    2. Defina a variável de ambiente GOOGLE_APPLICATION_CREDENTIALS para o arquivo caminho do arquivo JSON que contém a chave da conta de serviço. Também é possível definir a variável de ambiente GCLOUD_SERVICE_ACCOUNT_CREDS como o conteúdo do arquivo JSON.

Telemetria

O plug-in tem uma dependência direta do plug-in do Google Cloud e, portanto, tem disposições para permitir a exportação de telemetria para o pacote de operações do Google Cloud. Para ativar a exportação de telemetria, defina enableTracingAndMetrics como true e adicione uma seção de telemetria à configuração do Genkit:

import {configureGenkit} from "@genkit-ai/core";
import {firebase} from "@genkit-ai/firebase";

configureGenkit({
  plugins: [firebase()],
  enableTracingAndMetrics: true,
  telemetry: {
    instrumentation: 'firebase',
    logger: 'firebase',
  },
});

Consulte a documentação do plug-in do Google Cloud para conferir todas as opções de configuração e as APIs necessárias que precisam ser ativadas no projeto.

Uso

Esse plug-in oferece várias integrações com serviços do Firebase, que você pode para usar em conjunto ou individualmente.

Armazenamento de vetores do Cloud Firestore

É possível usar o Cloud Firestore como um armazenamento de vetores para indexação e recuperação de RAG.

Esta seção contém informações específicas para o plug-in firebase e o Cloud o recurso de pesquisa vetorial do Firestore. Consulte a página Geração aumentada de recuperação para uma discussão sobre a implementação de RAG usando o Genkit.

Como usar o GCLOUD_SERVICE_ACCOUNT_CREDS e o Firestore

Se você estiver usando credenciais de conta de serviço transmitindo credenciais diretamente pelo GCLOUD_SERVICE_ACCOUNT_CREDS e também usando o Firestore como um armazenamento vetorial, será necessário transmitir as credenciais diretamente para a instância do Firestore durante a inicialização. Caso contrário, o singleton poderá ser inicializado com as credenciais padrão do aplicativo, dependendo da ordem de inicialização do 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);
}

Recuperadores

O plug-in firebase oferece uma função conveniente para definir o Firestore. recuperar, 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 usá-lo, transmita-o para a função retrieve():

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

As opções de recuperação disponíveis incluem:

  • limit: especifica o número de resultados correspondentes a serem retornados.
  • where: pares de campo/valor a serem correspondidos (por exemplo, {category: 'food'}), além da pesquisa de vetor.
  • collection: substitui o conjunto padrão para pesquisar. Por exemplo, pesquisa de subcoleção.

Indexação e incorporação

Para preencher sua coleção do Firestore, use um gerador de embedding com a SDK Admin. Por exemplo, o script de ingestão do menu da A página Geração aumentada de recuperação pode ser adaptada para o Firestore da seguinte forma:

import { configureGenkit } from "@genkit-ai/core";
import { embed } from "@genkit-ai/ai/embedder";
import { defineFlow, run } from "@genkit-ai/flow";
import { textEmbeddingGecko, vertexAI } 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 * as z from "zod";

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: textEmbeddingGecko,
};

configureGenkit({
  plugins: [vertexAI({ location: "us-central1" })],
  enableTracingAndMetrics: false,
});

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

export const indexMenu = defineFlow(
  {
    name: "indexMenu",
    inputSchema: z.string().describe("PDF file path"),
    outputSchema: z.void(),
  },
  async (filePath: string) => {
    filePath = path.resolve(filePath);

    // Read the PDF.
    const pdfTxt = await run("extract-text", () =>
      extractTextFromPdf(filePath)
    );

    // Divide the PDF text into segments.
    const chunks = await run("chunk-it", async () => chunk(pdfTxt));

    // Add chunks to the index.
    await run("index-chunks", async () => indexToFirestore(chunks));
  }
);

async function indexToFirestore(data: string[]) {
  for (const text of data) {
    const embedding = await 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;
}

O Firestore depende de índices para oferecer consultas rápidas e eficientes . Observe que “índice” aqui se refere aos índices do banco de dados, e não abstrações do indexador e do retriever do Genkit.)

O exemplo anterior exige que o campo embedding seja indexado para funcionam. Para criar o índice:

  • Execute o comando gcloud descrito no Criar um índice vetorial de campo único da documentação do Firestore.

    O comando se parece com isto:

    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
    

    No entanto, a configuração correta depende das consultas que você vai e do modelo de embedding que você está usando.

  • Como alternativa, chame retrieve(), e o Firestore vai gerar um erro com a o comando correto para criar o índice.

Saiba mais

Armazenamento de traces do Cloud Firestore

Use o Cloud Firestore para armazenar traces:

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

configureGenkit({
  plugins: [firebase()],
  traceStore: "firebase",
  enableTracingAndMetrics: true,
});

Por padrão, o plug-in armazena traces em uma coleção chamada genkit-traces em no banco de dados padrão do projeto. Para mudar uma das configurações:

firebase({
  traceStore: {
    collection: "your-collection";
    databaseId: "your-db";
  }
})

Ao usar o armazenamento de traces baseado no Firestore, ative o TTL para os documentos de trace: https://firebase.google.com/docs/firestore/ttl

Cloud Functions

O plug-in fornece o construtor onFlow(), que cria um fluxo apoiado por uma Função acionada por HTTPS do Cloud Functions para Firebase. Essas funções estão em conformidade para a interface de usuário interface de função chamável e você pode usar a SDKs de cliente do Cloud Functions de ligar para ele.

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

configureGenkit({
  plugins: [firebase()],
});

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

    return response;
  }
);

Implante seu fluxo usando a CLI do Firebase:

firebase deploy --only functions

A função onFlow() tem algumas opções que não estão presentes em defineFlow():

  • httpsOptions: um HttpsOptions objeto usado para configurar sua função do Cloud:

    export const exampleFlow = onFlow(
      {
        name: "exampleFlow",
        httpsOptions: {
          cors: true,
        },
        // ...
      },
      async (prompt) => {
        // ...
      }
    );
    
  • enforceAppCheck: quando true, rejeitar solicitações com App Check ausente ou inválido tokens.

  • consumeAppCheckToken: quando true, invalida o token do App Check depois de verificá-lo.

    Consulte Proteção contra repetição.

Firebase Auth

Este plug-in fornece uma função auxiliar para criar políticas de autorização sobre Firebase Auth:

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

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

Para definir uma política de autenticação, forneça ao firebaseAuth() uma função de callback que leva um DecodedIdToken como único parâmetro. Nessa função, examine o token do usuário e gere uma se o usuário não atender a algum dos critérios que você quer exigir.

Consulte Autorização e integridade para uma discussão mais detalhada sobre sobre este assunto.