ปลั๊กอิน Firebase

ปลั๊กอิน Firebase ผสานรวมบริการ Firebase หลายอย่าง ดังนี้

  • ผู้จัดทำดัชนีและรีทรีฟเวอร์โดยใช้ที่เก็บเวกเตอร์ Cloud Firestore
  • ติดตามพื้นที่เก็บข้อมูลโดยใช้ Cloud Firestore
  • การทำให้โฟลว์ใช้งานได้โดยใช้ Cloud Functions
  • นโยบายการให้สิทธิ์สำหรับผู้ใช้การตรวจสอบสิทธิ์ Firebase

การติดตั้ง

npm i --save @genkit-ai/firebase

สิ่งที่ต้องดำเนินการก่อน

  • ผลิตภัณฑ์ Firebase ทั้งหมดต้องมีโปรเจ็กต์ Firebase คุณจะสร้างโปรเจ็กต์ใหม่หรือเปิดใช้ Firebase ในโปรเจ็กต์ Google Cloud ที่มีอยู่ได้โดยใช้คอนโซล Firebase
  • นอกจากนี้ หากต้องการทำให้โฟลว์ใช้งานได้กับ Cloud Functions คุณต้องอัปเกรดโปรเจ็กต์เป็นแพ็กเกจแบบจ่ายเมื่อใช้ของ Blaze

การกำหนดค่า

หากต้องการใช้ปลั๊กอินนี้ ให้ระบุเมื่อเรียกใช้ configureGenkit():

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

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

ปลั๊กอินจะกำหนดให้คุณระบุรหัสโปรเจ็กต์ Firebase ของคุณ คุณระบุรหัสโปรเจ็กต์ Firebase ได้ด้วยวิธีใดวิธีหนึ่งต่อไปนี้

  • ตั้งค่า projectId ในออบเจ็กต์การกำหนดค่า firebase()

  • ตั้งค่าตัวแปรสภาพแวดล้อม GCLOUD_PROJECT หากคุณกำลังเรียกใช้โฟลว์จากสภาพแวดล้อม Google Cloud (Cloud Functions, Cloud Run เป็นต้น) ระบบจะตั้งค่า GCLOUD_PROJECT เป็นรหัสโปรเจ็กต์ของสภาพแวดล้อมโดยอัตโนมัติ

    หากตั้งค่า GCLOUD_PROJECT ไว้ คุณสามารถข้ามพารามิเตอร์การกําหนดค่าได้ ดังนี้ firebase()

หากต้องการระบุข้อมูลเข้าสู่ระบบ Firebase คุณจะต้องตั้งค่าข้อมูลเข้าสู่ระบบเริ่มต้นของแอปพลิเคชัน Google Cloud ด้วย วิธีระบุข้อมูลเข้าสู่ระบบ

  • หากเรียกใช้โฟลว์จากสภาพแวดล้อม Google Cloud (Cloud Functions, Cloud Run เป็นต้น) ระบบจะตั้งค่านี้โดยอัตโนมัติ

  • สำหรับสภาพแวดล้อมอื่นๆ

    1. สร้างข้อมูลเข้าสู่ระบบของบัญชีบริการสำหรับโปรเจ็กต์ Firebase แล้วดาวน์โหลดไฟล์คีย์ JSON ซึ่งทำได้ในหน้าบัญชีบริการของคอนโซล Firebase
    2. ตั้งค่าตัวแปรสภาพแวดล้อม GOOGLE_APPLICATION_CREDENTIALS ให้กับเส้นทางไฟล์ของไฟล์ JSON ที่มีคีย์บัญชีบริการ

การใช้งาน

ปลั๊กอินนี้มีการผสานรวมหลายอย่างกับบริการ Firebase ซึ่งคุณจะใช้ด้วยกันหรือแยกกันก็ได้

ที่เก็บเวกเตอร์ใน Cloud Firestore

คุณใช้ Cloud Firestore เป็นที่เก็บเวกเตอร์สำหรับการจัดทำดัชนีและการดึงข้อมูล RAG ได้

ส่วนนี้ประกอบด้วยข้อมูลเฉพาะเกี่ยวกับปลั๊กอิน firebase และฟีเจอร์การค้นหาเวกเตอร์ของ CloudFirestore ดูรายละเอียดเพิ่มเติมเกี่ยวกับการใช้ RAG โดยใช้ Genkit ได้ในหน้า Retrieval-augmented Generation

ปลั๊กอิน 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 เช่น สคริปต์การส่งผ่านข้อมูลเมนูจากหน้า Retrieval-augmented Generation สามารถปรับเปลี่ยนสำหรับ 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 จะขึ้นอยู่กับดัชนีเพื่อให้การค้นหาคอลเล็กชันได้อย่างรวดเร็วและมีประสิทธิภาพ (โปรดทราบว่า "index" ในที่นี้จะหมายถึงดัชนีฐานข้อมูล ไม่ใช่ตัวจัดทำดัชนีและ Recaller ของ Genkit)

ตัวอย่างก่อนหน้านี้กำหนดให้มีการจัดทำดัชนีช่อง embedding เพื่อให้ทำงานได้ วิธีสร้างดัชนี

  • เรียกใช้คำสั่ง gcloud ที่อธิบายไว้ในส่วนสร้างดัชนีเวกเตอร์ช่องเดียวของเอกสาร Firestore

    คำสั่งมีลักษณะดังต่อไปนี้

    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() ซึ่งจะสร้างโฟลว์ที่สนับสนุนโดยฟังก์ชันที่ทริกเกอร์ด้วย HTTPS ของ Firebase ฟังก์ชันเหล่านี้สอดคล้องกับอินเทอร์เฟซฟังก์ชันที่เรียกใช้ได้ของ Firebase และคุณใช้ SDK ของไคลเอ็นต์ 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;
  }
);

ทำให้โฟลว์ใช้งานได้โดยใช้ Firebase CLI ดังนี้

firebase deploy --only functions

ฟังก์ชัน onFlow() มีตัวเลือกบางอย่างที่ไม่มีใน defineFlow():

  • httpsOptions: ออบเจ็กต์ HttpsOptions ที่ใช้เพื่อกำหนดค่า Cloud Function: js export const exampleFlow = onFlow( { name: "exampleFlow", httpsOptions: { cors: true, }, // ... }, async (prompt) => { // ... } );

  • enforceAppCheck: เมื่อtrue ให้ปฏิเสธคำขอที่ไม่มีโทเค็นการตรวจสอบแอปหรือไม่ถูกต้อง

  • consumeAppCheckToken: เมื่อ true ให้เลิกใช้โทเค็น App Check หลังจากยืนยัน

    ดูการป้องกันการเล่นซ้ำ

Firebase Auth

ปลั๊กอินนี้มีฟังก์ชันตัวช่วยในการสร้างนโยบายการให้สิทธิ์เกี่ยวกับ Firebase Auth

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

หากต้องการกำหนดนโยบายการตรวจสอบสิทธิ์ ให้ระบุฟังก์ชัน Callback ที่ใช้ DecodedIdToken เป็นพารามิเตอร์เดียวให้กับ firebaseAuth() ในฟังก์ชันนี้ ให้ตรวจสอบโทเค็นผู้ใช้ และแสดงข้อผิดพลาดหากผู้ใช้ไม่ตรงตามเกณฑ์ที่คุณต้องการ

โปรดดูการให้สิทธิ์และความถูกต้องสำหรับการสนทนาเกี่ยวกับหัวข้อนี้ที่ละเอียดขึ้น