เรียกใช้เวิร์กโฟลว์ Genkit จากแอป

Cloud Functions for Firebase มีเมธอด onCallGenkit ที่ช่วยให้คุณ สร้างฟังก์ชันที่เรียกใช้ได้ด้วยการดำเนินการ Genkit (โฟลว์) เรียกใช้ฟังก์ชันเหล่านี้ได้ด้วย genkit/beta/client หรือ SDK ไคลเอ็นต์ของ Cloud Functions ซึ่งจะเพิ่มข้อมูลการให้สิทธิ์โดยอัตโนมัติ

ก่อนเริ่มต้น

  • คุณควรคุ้นเคยกับแนวคิดของ Flow ใน Genkit และวิธีเขียน Flow วิธีการในหน้านี้ถือว่าคุณได้กำหนดโฟลว์บางอย่างที่ต้องการ นำไปใช้แล้ว
  • หากคุณเคยใช้ Cloud Functions for Firebase มาก่อน ก็จะเป็นประโยชน์ แต่ไม่จำเป็น

ตั้งค่าโปรเจ็กต์ Firebase

  1. สร้างโปรเจ็กต์ Firebase ใหม่โดยใช้คอนโซล Firebase หรือเลือกโปรเจ็กต์ที่มีอยู่

  2. อัปเกรดโปรเจ็กต์เป็นแพ็กเกจ Blaze ซึ่งจำเป็นสำหรับการติดตั้งใช้งานเวอร์ชันที่ใช้งานจริงของ Cloud Functions

  3. ติดตั้ง Firebase CLI

  4. เข้าสู่ระบบด้วย Firebase CLI โดยทำดังนี้

    firebase login
    firebase login --reauth # alternative, if necessary
    firebase login --no-localhost # if running in a remote shell
  5. สร้างไดเรกทอรีโปรเจ็กต์ใหม่

    export PROJECT_ROOT=~/tmp/genkit-firebase-project1
    mkdir -p $PROJECT_ROOT
  6. เริ่มต้นโปรเจ็กต์ Firebase ในไดเรกทอรี

    cd $PROJECT_ROOT
    firebase init functions

ส่วนที่เหลือของหน้านี้จะถือว่าคุณเลือกเขียนฟังก์ชันใน JavaScript

ห่อหุ้มโฟลว์ใน onCallGenkit

หลังจากตั้งค่าโปรเจ็กต์ Firebase ด้วย Cloud Functions แล้ว คุณจะคัดลอกหรือเขียนคำจำกัดความโฟลว์ในไดเรกทอรี functions ของโปรเจ็กต์ได้ ตัวอย่างโฟลว์เพื่อแสดงให้เห็นถึงวิธีการนี้มีดังนี้

const ai = genkit({
  plugins: [googleAI()],
  model: gemini15Flash,
});

const jokeTeller = ai.defineFlow({
  name: "jokeTeller",
  inputSchema: z.string().nullable(),
  outputSchema: z.string(),
  streamSchema: z.string(),
}, async (jokeType = "knock-knock", {sendChunk}) => {
  const prompt = `Tell me a ${jokeType} joke.`;

  // Call the `generateStream()` method to
  // receive the `stream` async iterable.
  const {stream, response: aiResponse} = ai.generateStream(prompt);

  // Send new words of the generative AI response
  // to the client as they are generated.
  for await (const chunk of stream) {
    sendChunk(chunk.text);
  }

  // Return the full generative AI response
  // to clients that may not support streaming.
  return (await aiResponse).text;
},
);

หากต้องการติดตั้งใช้งานโฟลว์เช่นนี้ ให้ห่อหุ้มด้วย onCallGenkit ซึ่งมีอยู่ใน firebase-functions/https เมธอดตัวช่วยนี้มีฟีเจอร์ทั้งหมดของฟังก์ชันที่เรียกใช้ได้ และรองรับทั้งการสตรีมและการตอบกลับ JSON โดยอัตโนมัติ

const {onCallGenkit} = require("firebase-functions/v2/https");
exports.tellJoke = onCallGenkit({
  // Bind the Gemini API key secret parameter to the function.
  secrets: [apiKey],
},
// Pass in the genkit flow.
jokeTeller,
);

ทำให้ข้อมูลเข้าสู่ระบบ API พร้อมใช้งานกับโฟลว์ที่ใช้งานจริง

เมื่อติดตั้งใช้งานแล้ว โฟลว์ของคุณจะต้องมีวิธีตรวจสอบสิทธิ์กับบริการระยะไกลที่ใช้ โดยส่วนใหญ่แล้ว โฟลว์ต้องมีข้อมูลเข้าสู่ระบบสำหรับการเข้าถึงบริการ API ของโมเดลที่ใช้

สำหรับตัวอย่างนี้ ให้ทำอย่างใดอย่างหนึ่งต่อไปนี้ ขึ้นอยู่กับผู้ให้บริการโมเดลที่คุณเลือก

Gemini (AI ของ Google)

  1. ตรวจสอบว่า Google AI พร้อมใช้งานใน ภูมิภาคของคุณ

  2. สร้างคีย์ API สำหรับ Gemini API โดยใช้ Google AI Studio

  3. จัดเก็บคีย์ API ใน Cloud Secret Manager

    firebase functions:secrets:set GOOGLE_GENAI_API_KEY

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

    ดูข้อมูลเพิ่มเติมเกี่ยวกับการจัดการข้อมูลลับได้ที่จัดเก็บและเข้าถึงข้อมูลการกำหนดค่าที่ละเอียดอ่อน

  4. แก้ไข src/index.js และเพิ่มรายการต่อไปนี้หลังจากการนำเข้าที่มีอยู่

    const {defineSecret} = require("firebase-functions/params");
    // Store the Gemini API key in Cloud Secret Manager.
    const apiKey = defineSecret("GOOGLE_GENAI_API_KEY");

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

    // Bind the Gemini API key secret parameter to the function.
    secrets: [apiKey],

ตอนนี้เมื่อคุณติดตั้งใช้งานฟังก์ชันนี้ ระบบจะจัดเก็บคีย์ API ไว้ใน Cloud Secret Manager และพร้อมใช้งานจากสภาพแวดล้อมของ Cloud Functions

Gemini (Vertex AI)

  1. ในคอนโซล Cloud ให้เปิดใช้ Vertex AI API สำหรับโปรเจ็กต์ Firebase

  2. ในหน้า IAM ให้ตรวจสอบว่าบัญชีบริการ Compute เริ่มต้นได้รับบทบาทผู้ใช้ Vertex AI

ความลับเดียวที่คุณต้องตั้งค่าสำหรับบทแนะนำนี้คือความลับสำหรับผู้ให้บริการโมเดล แต่โดยทั่วไป คุณต้องทำสิ่งที่คล้ายกันสำหรับแต่ละบริการที่โฟลว์ใช้

(ไม่บังคับ) เพิ่มการบังคับใช้ App Check

Firebase App Check ใช้การรับรองเนทีฟเพื่อยืนยันว่าแอปพลิเคชันของคุณเท่านั้นที่เรียก API onCallGenkit รองรับการบังคับใช้ App Check โดยการประกาศ

export const generatePoem = onCallGenkit({
  enforceAppCheck: true,
  // Optional. Makes App Check tokens only usable once. This adds extra security
  // at the expense of slowing down your app to generate a token for every API
  // call
  consumeAppCheckToken: true,
}, generatePoemFlow);

กำหนดค่า CORS (การแชร์ทรัพยากรแบบข้ามต้นทาง)

ใช้ตัวเลือก cors เพื่อควบคุมว่าต้นทางใดบ้างที่เข้าถึงฟังก์ชันได้

โดยค่าเริ่มต้น ฟังก์ชันที่เรียกใช้ได้จะมี CORS ที่กำหนดค่าไว้เพื่ออนุญาตคำขอจากต้นทางทั้งหมด หากต้องการอนุญาตคำขอข้ามต้นทางบางรายการ แต่ไม่อนุญาตทั้งหมด ให้ส่งรายการ โดเมนที่เฉพาะเจาะจงหรือนิพจน์ทั่วไปที่ควรได้รับอนุญาต เช่น

export const tellJoke = onCallGenkit({
  cors: 'mydomain.com',
}, jokeTeller);

ตัวอย่างที่สมบูรณ์

หลังจากทำการเปลี่ยนแปลงทั้งหมดตามที่อธิบายไว้ข้างต้นแล้ว โฟลว์ที่พร้อมใช้งานจะมีลักษณะคล้ายกับตัวอย่างต่อไปนี้

const {onCallGenkit} = require("firebase-functions/v2/https");
const {defineSecret} = require("firebase-functions/params");

// Dependencies for Genkit.
const {gemini15Flash, googleAI} = require("@genkit-ai/googleai");
const {genkit, z} = require("genkit");

// Store the Gemini API key in Cloud Secret Manager.
const apiKey = defineSecret("GOOGLE_GENAI_API_KEY");

const ai = genkit({
  plugins: [googleAI()],
  model: gemini15Flash,
});

const jokeTeller = ai.defineFlow({
  name: "jokeTeller",
  inputSchema: z.string().nullable(),
  outputSchema: z.string(),
  streamSchema: z.string(),
}, async (jokeType = "knock-knock", {sendChunk}) => {
  const prompt = `Tell me a ${jokeType} joke.`;

  // Call the `generateStream()` method to
  // receive the `stream` async iterable.
  const {stream, response: aiResponse} = ai.generateStream(prompt);

  // Send new words of the generative AI response
  // to the client as they are generated.
  for await (const chunk of stream) {
    sendChunk(chunk.text);
  }

  // Return the full generative AI response
  // to clients that may not support streaming.
  return (await aiResponse).text;
},
);

exports.tellJoke = onCallGenkit({
  // Bind the Gemini API key secret parameter to the function.
  secrets: [apiKey],
},
// Pass in the genkit flow.
jokeTeller,
);

ทําให้โฟลว์ใช้งานได้กับ Firebase

หลังจากกำหนดโฟลว์โดยใช้ onCallGenkit แล้ว คุณจะนำโฟลว์ไปใช้งานได้เช่นเดียวกับ การนำฟังก์ชันอื่นๆ ไปใช้งาน

cd $PROJECT_ROOT
firebase deploy --only functions