Firebase 外掛程式

Firebase 外掛程式可與 Firebase 服務整合,讓您建構智慧且可擴充的 AI 應用程式。主要功能包括:

  • Firestore 向量儲存庫:使用 Firestore 搭配向量嵌入項目建立索引和擷取資料。
  • Cloud Functions:將流程部署為 HTTPS 觸發函式。
  • Firebase 驗證:實作授權政策。
  • 遙測:將遙測資料匯出至 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 等) 執行流程,GCLOUD_PROJECT 會自動設為該環境的專案 ID。

    如果您設定 GCLOUD_PROJECT,可以省略 initializeApp() 中的設定參數。

憑證

如要提供 Firebase 憑證,您也必須設定 Google Cloud 應用程式預設憑證。如要指定憑證,請按照下列步驟操作:

  • 如果您是透過 Google Cloud 環境 (Cloud Functions、Cloud Run 等) 執行流程,系統會自動設定這項屬性。

  • 適用於其他環境:

    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 會擲回錯誤,並提供建立索引的正確指令。

瞭解詳情

  • 如要進一步瞭解 Genkit 中的索引器和取用器,請參閱「檢索增強生成」頁面。
  • 如要進一步瞭解向量搜尋功能,請參閱 Cloud Firestore 說明文件中的「使用向量嵌入搜尋」。

將流程部署為 Cloud Functions

外掛程式會提供 onFlow() 建構函式,可建立由 Cloud Functions for Firebase HTTPS 觸發函式所支援的流程。這些函式符合 Firebase 的可呼叫函式介面,您可以使用 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 函式的 HttpsOptions 物件:

    export const exampleFlow = onFlow(
      ai,
      {
        name: "exampleFlow",
        httpsOptions: {
          cors: true,
        },
        // ...
      },
      async (prompt) => {
        // ...
      }
    );
    
  • enforceAppCheck:當 true 時,拒絕缺少或無效的 App Check 權杖要求。

  • consumeAppCheckToken:當 true 時,請在驗證後使 App Check 權杖失效。

    請參閱「重播攻擊防護措施」。

Firebase 驗證

這個外掛程式提供輔助函式,可針對 Firebase 驗證建立授權政策:

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 做為唯一參數。在這個函式中,請檢查使用者權杖,如果使用者未符合您要要求的任何條件,就擲回錯誤。

如要進一步瞭解這個主題,請參閱「授權和完整性」。