Trình bổ trợ Firebase

Trình bổ trợ Firebase cung cấp một số tính năng tích hợp với các dịch vụ của Firebase:

  • Trình lập chỉ mục và trình truy xuất dữ liệu sử dụng kho lưu trữ vectơ trên Cloud Firestore
  • Theo dõi bộ nhớ bằng Cloud Firestore
  • Triển khai quy trình bằng Cloud Functions
  • Chính sách ủy quyền cho người dùng tính năng Xác thực Firebase

Lắp đặt

npm i --save @genkit-ai/firebase

Điều kiện tiên quyết

  • Tất cả các sản phẩm Firebase đều yêu cầu phải có dự án Firebase. Bạn có thể tạo một dự án mới hoặc bật Firebase trong một dự án hiện có trên Google Cloud bằng cách sử dụng Bảng điều khiển của Firebase.
  • Ngoài ra, nếu muốn triển khai luồng đến Cloud Functions, bạn phải nâng cấp dự án cho gói linh hoạt trả tiền theo mức dùng.

Cấu hình

Mã dự án

Để sử dụng trình bổ trợ này, hãy chỉ định trình bổ trợ này khi bạn gọi configureGenkit():

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

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

Trình bổ trợ này yêu cầu bạn chỉ định mã dự án Firebase. Bạn có thể chỉ định mã dự án Firebase của bạn theo một trong các cách sau:

  • Đặt projectId trong đối tượng cấu hình firebase().

  • Đặt biến môi trường GCLOUD_PROJECT. Nếu bạn đang chạy quy trình từ môi trường Google Cloud (Cloud Functions, Cloud Run, v.v.), GCLOUD_PROJECT được tự động đặt thành mã dự án của môi trường.

    Nếu đặt GCLOUD_PROJECT, bạn có thể bỏ qua thông số cấu hình: firebase()

Thông tin đăng nhập

Để cung cấp thông tin đăng nhập Firebase, bạn cũng cần thiết lập Google Cloud Thông tin xác thực mặc định của ứng dụng. Để chỉ định thông tin đăng nhập của bạn:

  • Nếu bạn đang chạy quy trình từ môi trường Google Cloud (Cloud Functions, Cloud Run, v.v.), thì chế độ này sẽ được đặt tự động.

  • Đối với các môi trường khác:

    1. Tạo thông tin đăng nhập tài khoản dịch vụ cho dự án Firebase của bạn và tải tệp khoá JSON xuống. Bạn có thể làm như vậy trên Tài khoản dịch vụ của bảng điều khiển của Firebase.
    2. Đặt biến môi trường GOOGLE_APPLICATION_CREDENTIALS vào tệp đường dẫn của tệp JSON chứa khoá tài khoản dịch vụ, hoặc bạn có thể đặt biến môi trường GCLOUD_SERVICE_ACCOUNT_CREDS thành nội dung của tệp JSON.

Đo từ xa

Trình bổ trợ này phụ thuộc trực tiếp vào trình bổ trợ của Google Cloud nên có các điều khoản để cho phép xuất dữ liệu đo từ xa sang bộ công cụ vận hành Cloud của Google. Để bật tính năng xuất dữ liệu đo từ xa, hãy đặt enableTracingAndMetrics thành true rồi thêm một mục dữ liệu đo từ xa vào cấu hình Genkit:

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

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

Tham khảo tài liệu về trình bổ trợ Google Cloud để biết tất cả các lựa chọn cấu hình và các API cần thiết mà bạn cần bật trong dự án.

Cách sử dụng

Trình bổ trợ này cung cấp một số tính năng tích hợp với dịch vụ Firebase mà bạn có thể sử dụng cùng nhau hoặc riêng lẻ.

Kho lưu trữ vectơ trên Cloud Firestore

Bạn có thể sử dụng Cloud Firestore làm kho lưu trữ vectơ để lập chỉ mục và truy xuất RAG.

Phần này chứa thông tin dành riêng cho trình bổ trợ firebase và Đám mây Tính năng tìm kiếm vectơ của Firestore. Xem trang Thế hệ tăng cường truy xuất để biết thêm chi tiết thảo luận về cách triển khai RAG bằng Genkit.

Sử dụng GCLOUD_SERVICE_ACCOUNT_CREDS và Firestore

Nếu đang sử dụng thông tin xác thực tài khoản dịch vụ bằng cách truyền trực tiếp thông tin xác thực qua GCLOUD_SERVICE_ACCOUNT_CREDS, đồng thời cũng đang sử dụng Firestore làm kho lưu trữ vectơ, thì bạn sẽ phải truyền trực tiếp thông tin xác thực đến thực thể Firestore trong quá trình khởi chạy hoặc singleton có thể được khởi chạy bằng thông tin xác thực mặc định của ứng dụng, tuỳ thuộc vào thứ tự khởi chạy trình bổ trợ.

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

Chó tha mồi

Trình bổ trợ firebase cung cấp một hàm tiện lợi để định nghĩa Firestore chó săn tha mồi, 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)
});

Để sử dụng, hãy truyền hàm này vào hàm retrieve():

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

Các tuỳ chọn truy xuất hiện có bao gồm:

  • limit: Chỉ định số lượng kết quả trùng khớp cần trả về.
  • where: Các cặp trường/giá trị cần khớp (ví dụ: {category: 'food'}) ngoài tìm kiếm vectơ.
  • collection: Ghi đè tập hợp mặc định để tìm kiếm, chẳng hạn như tìm kiếm bộ sưu tập con.

Lập chỉ mục và nhúng

Để điền sẵn bộ sưu tập Firestore của bạn, hãy dùng một trình tạo nhúng cùng với SDK dành cho quản trị viên. Ví dụ: tập lệnh nhập thực đơn từ Có thể điều chỉnh trang tạo tăng cường truy xuất cho phù hợp với Firestore theo cách sau:

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 phụ thuộc vào các chỉ mục để truy vấn nhanh và hiệu quả bộ sưu tập. (Xin lưu ý rằng "chỉ mục" ở đây đề cập đến chỉ mục cơ sở dữ liệu, chứ không phải bản tóm tắt trình lập chỉ mục và dữ liệu tóm tắt của Genkit.)

Ví dụ trước yêu cầu trường embedding phải được lập chỉ mục để cơ quan. Cách tạo chỉ mục:

  • Chạy lệnh gcloud được mô tả trong Tạo chỉ mục vectơ một trường của phần "Tài liệu về Firestore".

    Lệnh có dạng như sau:

    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
    

    Tuy nhiên, cấu hình lập chỉ mục chính xác phụ thuộc vào các truy vấn mà bạn sẽ và mô hình nhúng mà bạn đang dùng.

  • Ngoài ra, hãy gọi retrieve() và Firestore sẽ báo cáo một lỗi chính xác để tạo chỉ mục.

Tìm hiểu thêm

Bộ nhớ theo dõi trên Cloud Firestore

Bạn có thể sử dụng Cloud Firestore để lưu trữ dấu vết:

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

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

Theo mặc định, trình bổ trợ này lưu trữ dấu vết trong một bộ sưu tập có tên là genkit-traces trong cơ sở dữ liệu mặc định của dự án. Để thay đổi một trong hai chế độ cài đặt này, hãy làm như sau:

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

Khi sử dụng bộ nhớ theo dõi dựa trên Firestore, bạn cần bật TTL cho các tài liệu theo dõi: https://firebase.google.com/docs/firestore/ttl

Cloud Functions

Trình bổ trợ này cung cấp hàm khởi tạo onFlow(), giúp tạo ra một luồng được hỗ trợ bởi một Hàm được kích hoạt bằng HTTPS của Firebase Functions. Các hàm này tuân thủ vào Firebase giao diện hàm có thể gọi. Bạn có thể sử dụng SDK ứng dụng Cloud Functions để gọi cho họ.

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

Triển khai quy trình bằng giao diện dòng lệnh (CLI) của Firebase:

firebase deploy --only functions

Hàm onFlow() có một số tuỳ chọn không có trong defineFlow():

  • httpsOptions: HttpsOptions đối tượng dùng để định cấu hình Chức năng đám mây của bạn:

    export const exampleFlow = onFlow(
      {
        name: "exampleFlow",
        httpsOptions: {
          cors: true,
        },
        // ...
      },
      async (prompt) => {
        // ...
      }
    );
    
  • enforceAppCheck: khi true, từ chối các yêu cầu có Kiểm tra ứng dụng bị thiếu hoặc không hợp lệ mã thông báo.

  • consumeAppCheckToken: khi true, hãy vô hiệu hoá mã thông báo Kiểm tra ứng dụng sau khi xác minh.

    Hãy xem bài viết Chống phát lại.

Firebase Auth

Trình bổ trợ này cung cấp chức năng trợ giúp để tạo chính sách uỷ quyền xung quanh Xác thực 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) => {
    // ...
  }
);

Để xác định chính sách xác thực, hãy cung cấp cho firebaseAuth() một hàm callback mất một DecodedIdToken làm tham số duy nhất. Trong hàm này, hãy kiểm tra mã thông báo người dùng và gửi một lỗi nếu người dùng không đáp ứng được bất kỳ tiêu chí nào bạn muốn yêu cầu.

Xem Uỷ quyền và tính toàn vẹn để thảo luận kỹ hơn về chủ đề này.