Firebase 插件

Firebase 插件可与 Firebase 服务集成,让您能够构建智能且可伸缩的 AI 应用。主要功能包括:

  • Firestore 向量存储:使用 Firestore 通过向量嵌入进行索引编制和检索。
  • Cloud Functions:将流程部署为 HTTPS 触发的函数。
  • Firebase Authentication:实现授权政策。
  • 遥测:将遥测数据导出到 Google Cloud 的运维套件,并在 Firebase 控制台中查看专用视图

安装

使用 npm 安装 Firebase 插件:

npm install @genkit-ai/firebase

前提条件

Firebase 项目设置

  1. 所有 Firebase 产品都需要 Firebase 项目。您可以使用 Firebase 控制台创建新项目,也可以在现有 Google Cloud 项目中启用 Firebase。
  2. 如果您使用 Cloud Functions 部署流程,请将 Firebase 项目升级为 Blaze 方案。
  3. 如果您想在本地运行用于导出遥测数据的代码,则需要安装 Google Cloud CLI 工具。

Firebase Admin SDK 初始化

您必须在应用中初始化 Firebase Admin SDK。插件不会自动处理此操作。

import { initializeApp } from 'firebase-admin/app';

initializeApp({
  projectId: 'your-project-id',
});

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

  • initializeApp() 配置对象中设置 projectId,如上面的代码段所示。

  • 设置 GCLOUD_PROJECT 环境变量。如果您要从 Google Cloud 环境(Cloud Functions、Cloud Run 等)运行 flow,系统会自动将 GCLOUD_PROJECT 设置为该环境的项目 ID。

    如果您设置了 GCLOUD_PROJECT,则可以省略 initializeApp() 中的配置参数。

凭据

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

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

  • 对于其他环境:

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

功能和用法

遥测

该插件直接依赖于 Google Cloud 插件,因此包含用于启用遥测数据导出到 Google Cloud 运维套件的条款。如需启用遥测数据导出,请调用 enableFirebaseTelemetry()

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

enableFirebaseTelemetry();

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

您可以将 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);
}

定义 Firestore 检索器

使用 defineFirestoreRetriever() 为基于向量的 Firestore 查询创建检索器。

import { defineFirestoreRetriever } from '@genkit-ai/firebase';
import { initializeApp } from 'firebase-admin/app';
import { getFirestore } from 'firebase-admin/firestore';

const app = initializeApp();
const firestore = getFirestore(app);

const retriever = defineFirestoreRetriever(ai, {
  name: 'exampleRetriever',
  firestore,
  collection: 'documents',
  contentField: 'text', // Field containing document content
  vectorField: 'embedding', // Field containing vector embeddings
  embedder: yourEmbedderInstance, // Embedder to generate embeddings
  distanceMeasure: 'COSINE', // Default is 'COSINE'; other options: 'EUCLIDEAN', 'DOT_PRODUCT'
});

检索文档

如需使用定义的检索器检索文档,请将检索器实例和查询选项传递给 ai.retrieve

const docs = await ai.retrieve({
  retriever,
  query: 'search query',
  options: {
    limit: 5, // Options: Return up to 5 documents
    where: { category: 'example' }, // Optional: Filter by field-value pairs
    collection: 'alternativeCollection', // Optional: Override default collection
  },
});

可用的检索选项

以下选项可传递给 ai.retrieve 中的 options 字段:

  • limit(数字)
    指定要检索的文档数量上限。默认值为 10

  • where(Record<string, any>)
    根据 Firestore 字段添加其他过滤条件。示例:

    where: { category: 'news', status: 'published' }
    
  • collection(字符串)
    替换检索器配置中指定的默认集合。这对于查询子集合或在集合之间动态切换非常有用。

使用嵌入填充 Firestore

如需填充 Firestore 集合,请将嵌入生成器与 Admin SDK 搭配使用。例如,您可以按照以下方式将增强型检索生成页面中的菜单提取脚本改编为适用于 Firestore 的脚本:

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 依赖于索引来快速高效地对集合进行查询。(请注意,这里的“索引”是指数据库索引,而不是 Genkit 的索引器和检索器抽象。)

上例要求对 embedding 字段进行编制索引,才能正常运行。如需创建索引,请执行以下操作:

  • 运行 Firestore 文档的创建单字段向量索引部分中所述的 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
    

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

  • 或者,调用 ai.retrieve(),Firestore 将抛出一个错误,并附上用于创建索引的正确命令。

了解详情

将流程部署为 Cloud Functions 函数

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

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

使用 Firebase CLI 部署您的流程:

firebase deploy --only functions

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

  • httpsOptions:用于配置 Cloud Functions 函数的 HttpsOptions 对象:

    export const exampleFlow = onFlow(
      ai,
      {
        name: "exampleFlow",
        httpsOptions: {
          cors: true,
        },
        // ...
      },
      async (prompt) => {
        // ...
      }
    );
    
  • enforceAppCheck:如果为 true,则拒绝缺少或无效的 App Check 令牌的请求。

  • consumeAppCheckToken:如果为 true,则在验证 App Check 令牌后将其失效。

    请参阅重放攻击防范

Firebase Authentication

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

如需定义身份验证政策,请向 firebaseAuth() 提供一个回调函数,该函数将 DecodedIdToken 作为其唯一参数。在此函数中,检查用户令牌,如果用户不符合您要要求的任何条件,则抛出错误。

如需更详细地了解此主题,请参阅授权和完整性