Firebase 插件

Firebase 插件提供多种与 Firebase 服务的集成:

  • 使用 Cloud Firestore 矢量存储区的索引器和检索器
  • 使用 Cloud Firestore 跟踪存储情况
  • 使用 Cloud Functions 进行流部署
  • Firebase Authentication 用户的授权政策

安装

npm i --save @genkit-ai/firebase

前提条件

  • 所有 Firebase 产品都需要一个 Firebase 项目。你可以创建新项目 或使用 Firebase 控制台
  • 此外,如果您想要将数据流部署到 Cloud Functions, 升级您的项目 升级为 Blaze 随用随付方案。

配置

项目 ID

如需使用此插件,请在调用 configureGenkit() 时指定它:

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

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

该插件要求您指定 Firebase 项目 ID。您可以指定 通过以下任一方式创建 Firebase 项目 ID:

  • firebase() 配置对象中设置 projectId

  • 设置 GCLOUD_PROJECT 环境变量。如果您正在运行流 从 Google Cloud 环境(Cloud Functions、Cloud Run 等)调用, GCLOUD_PROJECT 会自动设置为环境的项目 ID。

    如果您设置了 GCLOUD_PROJECT,则可以省略配置参数: firebase()

凭据

如需提供 Firebase 凭据,您还需要设置 Google Cloud 应用默认凭据。如需指定凭据,请按照以下所述操作:

  • 如果您从 Google Cloud 环境(Cloud Functions、 Cloud Run 等),则系统会自动进行此设置。

  • 对于其他环境:

    1. 为您的 Firebase 项目生成服务账号凭据,并 下载 JSON 密钥文件。您可以在 服务账号 页面
    2. 将环境变量 GOOGLE_APPLICATION_CREDENTIALS 设置为该文件 包含您的服务账号密钥的 JSON 文件的路径,或者您可以将环境变量 GCLOUD_SERVICE_ACCOUNT_CREDS 设置为 JSON 文件的内容。

遥测

该插件直接依赖于 Google Cloud 插件,因此具有支持将遥测数据导出到 Google Cloud 运维套件的配置。如需启用遥测数据导出,请将 enableTracingAndMetrics 设置为 true,并在 Genkit 配置中添加遥测部分:

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

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

请参阅 Google Cloud 插件文档,了解需要在项目上启用的所有配置选项和必要的 API。

用法

此插件提供多种与 Firebase 服务的集成, 您可以搭配使用,也可以单独使用

Cloud Firestore 矢量存储

您可以使用 Cloud Firestore 作为 RAG 索引和检索的矢量存储区。

本部分包含特定于 firebase 插件和 Cloud Firestore 的矢量搜索功能。 如需了解详情,请参阅检索增强生成页面 关于如何使用 Genkit 实施 RAG 的讨论。

使用 GCLOUD_SERVICE_ACCOUNT_CREDS 和 Firestore

如果您使用服务账号凭据直接通过 GCLOUD_SERVICE_ACCOUNT_CREDS 传递凭据,并且还使用 Firestore 作为矢量存储,则需要在初始化期间将凭据直接传递给 Firestore 实例,或者根据插件初始化顺序,使用应用默认凭据来初始化单例。

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

检索器

firebase 插件提供了一个用于定义 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)
});

如需使用它,请将其传递给 retrieve() 函数:

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

可用的检索选项包括:

  • limit:指定要返回的匹配结果数量。
  • where:除了矢量搜索之外,还要匹配的字段/值对(例如 {category: 'food'})。
  • collection:替换默认集合以进行搜索,例如子集合搜索。

索引和嵌入

要填充 Firestore 集合,请使用嵌入生成器和 Admin SDK。例如,来自 API 的 检索增强型生成页面可针对 Firestore 进行调整 具体如下:

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 依赖索引来提供快速、高效的查询 。(请注意,这里的“索引”是指数据库索引, Genkit 的索引器和检索器抽象。)

前面的示例要求将 embedding 字段编入索引, 工作。如需创建索引,请执行以下操作:

  • 运行gcloud 创建单字段向量索引 部分。

    该命令如下所示:

    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
    

    不过,正确的索引编制配置取决于您要执行的查询 品牌和使用的嵌入模型

  • 或者,您也可以调用 retrieve(),此时 Firestore 会抛出一个错误, 正确的命令来创建索引。

了解详情

Cloud Firestore 跟踪记录存储空间

您可以使用 Cloud Firestore 来存储跟踪记录:

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

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

默认情况下,插件将跟踪记录存储在名为 genkit-traces 的集合中, 项目的默认数据库。如需更改任一设置,请执行以下操作:

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

使用基于 Firestore 的轨迹存储时,您需要为轨迹文档启用 TTL:https://firebase.google.com/docs/firestore/ttl

Cloud Functions

插件提供了 onFlow() 构造函数,用于创建一个由 Cloud Functions for Firebase HTTPS 触发的函数。这些函数符合 Firebase 应用的 Callable 函数接口,并且您可以使用 Cloud Functions 客户端 SDK 调用它们。

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

使用 Firebase CLI 部署您的流程:

firebase deploy --only functions

onFlow() 函数有一些 defineFlow() 中不存在的选项:

  • httpsOptions:一个 HttpsOptions 对象来配置 Cloud Functions 函数:

    export const exampleFlow = onFlow(
      {
        name: "exampleFlow",
        httpsOptions: {
          cors: true,
        },
        // ...
      },
      async (prompt) => {
        // ...
      }
    );
    
  • enforceAppCheck:当 true 时,拒绝 App Check 缺失或无效的请求 词元。

  • consumeAppCheckToken:当 true 时,在验证 App Check 令牌后使其失效。

    请参阅重放攻击防范

Firebase Auth

此插件提供了一个辅助函数,用于围绕 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) => {
    // ...
  }
);

如需定义身份验证政策,请向 firebaseAuth() 提供一个回调函数, 接受 DecodedIdToken 作为其唯一的参数。在此函数中,检查用户令牌并抛出 错误。

如需深入了解以下内容的讨论,请参阅授权和完整性