Wtyczka Firebase

Wtyczka Firebase umożliwia integrację z usługami Firebase na kilka sposobów:

  • Indeksatory i moduły pobierania danych korzystające z magazynu wektorów Cloud Firestore
  • Śledź miejsce na dane za pomocą Cloud Firestore
  • Wdrażanie przepływu za pomocą Cloud Functions
  • Zasady autoryzacji dla użytkowników Uwierzytelniania Firebase

Instalacja

npm i --save @genkit-ai/firebase

Wymagania wstępne

  • Wszystkie usługi Firebase wymagają projektu Firebase. Możesz utworzyć nowy projekt lub włączyć Firebase w istniejącym projekcie Google Cloud, korzystając z konsoli Firebase.
  • Ponadto, jeśli chcesz wdrożyć przepływy w Cloud Functions, musisz przenieść swój projekt na abonament Blaze z płatnością według wykorzystania.

Konfiguracja

Aby używać tej wtyczki, określ ją, gdy wywołujesz configureGenkit():

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

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

Wtyczka wymaga podania identyfikatora projektu Firebase. Identyfikator projektu Firebase możesz określić na jeden z tych sposobów:

  • Ustaw projectId w obiekcie konfiguracji firebase().

  • Ustaw zmienną środowiskową GCLOUD_PROJECT. Jeśli uruchamiasz przepływ ze środowiska Google Cloud (Cloud Functions, Cloud Run itp.), wartość GCLOUD_PROJECT jest automatycznie ustawiona na identyfikator projektu tego środowiska.

    Jeśli ustawisz GCLOUD_PROJECT, możesz pominąć parametr konfiguracji: firebase()

Aby podać dane logowania do Firebase, musisz też skonfigurować domyślne dane logowania do aplikacji Google Cloud. Aby podać dane logowania:

  • Jeśli uruchamiasz przepływ ze środowiska Google Cloud (Cloud Functions, Cloud Run itp.), ustawienie to jest ustawiane automatycznie.

  • W przypadku innych środowisk:

    1. Wygeneruj dane logowania do konta usługi dla projektu Firebase i pobierz plik klucza JSON. Możesz to zrobić na stronie Konto usługi w konsoli Firebase.
    2. Ustaw zmienną środowiskową GOOGLE_APPLICATION_CREDENTIALS na ścieżkę pliku JSON zawierającego klucz konta usługi.

Wykorzystanie

Zapewnia ona kilka integracji z usługami Firebase, których można używać razem lub osobno.

Magazyn wektorów Cloud Firestore

Cloud Firestore może być używany jako magazyn wektorowy na potrzeby indeksowania i pobierania RAG.

Ta sekcja zawiera informacje dotyczące wtyczki firebase i funkcji wyszukiwania wektorowego w Cloud Firestore. Na stronie generowania rozszerzonego przez wyszukiwanie znajdziesz bardziej szczegółowe omówienie wdrażania RAG za pomocą Genkit.

Wtyczka firebase zapewnia wygodną funkcję definiowania źródeł pobierania 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)
});

Aby go użyć, przekaż go do funkcji retrieve():

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

Dostępne opcje pobierania:

  • limit: określ liczbę pasujących wyników do zwrócenia.
  • where: pary pole/wartość do dopasowania (np. {category: 'food'}) oprócz wyszukiwania wektorowego.
  • collection: zastąp kolekcję domyślną, aby wyszukać np. wyszukiwanie w kolekcji podrzędnej.

Aby wypełnić kolekcję Firestore, użyj generatora umieszczania oraz pakietu Admin SDK. Na przykład skrypt przetwarzania menu ze strony Generowanie rozszerzonego przez wyszukiwanie może zostać dostosowany do Firestore w następujący sposób:

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

Firestore zależy od indeksów, aby umożliwić szybkie i sprawne wykonywanie zapytań dotyczących kolekcji. (Zwróć uwagę, że słowo „index” odnosi się w tym miejscu do indeksów baz danych, a nie do abstrakcyjnych indeksów i mechanizmów zbierających dane z Genkita).

Poprzedni przykład wymaga zindeksowania pola embedding. Aby utworzyć indeks:

  • Uruchom polecenie gcloud opisane w sekcji Tworzenie indeksu wektorów z jednym polem w dokumentach Firestore.

    Polecenie wygląda tak:

    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
    

    Prawidłowa konfiguracja indeksowania zależy jednak od wykonywanych zapytań i używanego modelu umieszczania.

  • Możesz też wywołać metodę retrieve(), a Firestore zgłosi błąd z prawidłowym poleceniem utworzenia indeksu.

Więcej informacji

Miejsce na dane logu w Cloud Firestore

W Cloud Firestore możesz przechowywać logi czasu:

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

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

Domyślnie wtyczka przechowuje logi czasu w kolekcji o nazwie genkit-traces w domyślnej bazie danych projektu. Aby zmienić któreś z tych ustawień:

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

Jeśli korzystasz z pamięci śledzenia bazującej na Firestore, włącz wartość TTL dla dokumentów śledzenia: https://firebase.google.com/docs/firestore/ttl

Cloud Functions

Wtyczka udostępnia konstruktor onFlow(), który tworzy przepływ wspierany przez funkcję wyzwalaną przez HTTPS w Cloud Functions dla Firebase. Funkcje te są zgodne z wywoływanym interfejsem funkcji Firebase i możesz je wywoływać za pomocą pakietów SDK klienta Cloud Functions.

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

Wdróż przepływ za pomocą interfejsu wiersza poleceń Firebase:

firebase deploy --only functions

Niektóre opcje funkcji onFlow() są niedostępne w defineFlow():

  • httpsOptions: obiekt HttpsOptions używany do konfigurowania funkcji w Cloud Functions: js export const exampleFlow = onFlow( { name: "exampleFlow", httpsOptions: { cors: true, }, // ... }, async (prompt) => { // ... } );

  • enforceAppCheck: gdy true odrzuca żądania z brakującymi lub nieprawidłowymi tokenami Sprawdzania aplikacji.

  • consumeAppCheckToken: gdy true, unieważni token Sprawdzania aplikacji po jego zweryfikowaniu.

    Zobacz Zabezpieczenie przed ponownym odtworzeniem.

Uwierzytelnianie Firebase

Udostępnia ona funkcję pomocniczą do tworzenia zasad autoryzacji związanych z Uwierzytelnianiem Firebase:

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) => {
    // ...
  }
);

Aby zdefiniować zasadę uwierzytelniania, podaj w firebaseAuth() funkcję wywołania zwrotnego, która jako jedyny parametr przyjmuje DecodedIdToken. W tej funkcji sprawdza się token użytkownika. Jeśli użytkownik nie spełni któregokolwiek z wymagań, zgłasza błąd.

Więcej informacji na ten temat znajdziesz w artykule Autoryzacja i integralność.