Cloud Functions for Firebase มีเมธอด onCallGenkit
ที่ช่วยให้คุณสร้างฟังก์ชันที่เรียกใช้ได้อย่างรวดเร็วด้วยการดำเนินการ Genkit (เช่น ฟลายเวย์) เรียกใช้ฟังก์ชันเหล่านี้ได้โดยใช้ genkit/beta/client
หรือ Functions client SDK ซึ่งจะเพิ่มข้อมูลการตรวจสอบสิทธิ์โดยอัตโนมัติ
ก่อนเริ่มต้น
- คุณควรคุ้นเคยกับแนวคิดโฟลว์ของ Genkit และวิธีเขียนโฟลว์ วิธีการในหน้านี้ถือว่าคุณกําหนดขั้นตอนการทํางานบางอย่างไว้แล้วซึ่งต้องการทําให้ใช้งานได้
- ประสบการณ์การใช้งาน Cloud Functions สําหรับ Firebase มาก่อนจะเป็นประโยชน์ แต่ก็ไม่จําเป็น
1. ตั้งค่าโปรเจ็กต์ Firebase
หากยังไม่มีโปรเจ็กต์ Firebase ที่มีการตั้งค่า TypeScript Cloud Functions ให้ทําตามขั้นตอนต่อไปนี้
สร้างโปรเจ็กต์ Firebase ใหม่โดยใช้คอนโซล Firebase หรือเลือกโปรเจ็กต์ที่มีอยู่
อัปเกรดโปรเจ็กต์เป็นแพ็กเกจ Blaze ซึ่งจําเป็นต่อการติดตั้งใช้งาน Cloud Function
ติดตั้ง Firebase CLI
เข้าสู่ระบบด้วย Firebase CLI โดยทำดังนี้
firebase login
firebase login --reauth # alternative, if necessary
firebase login --no-localhost # if running in a remote shell
สร้างไดเรกทอรีโปรเจ็กต์ใหม่
export PROJECT_ROOT=~/tmp/genkit-firebase-project1
mkdir -p $PROJECT_ROOT
เริ่มต้นโปรเจ็กต์ Firebase ในไดเรกทอรีโดยทำดังนี้
cd $PROJECT_ROOT
firebase init genkit
ส่วนที่เหลือของหน้านี้จะถือว่าคุณได้ตัดสินใจเขียนฟังก์ชันเป็น TypeScript แล้ว แต่คุณยังทำให้เวิร์กโฟลว์ Genkit ใช้งานได้หากใช้ JavaScript
2. สรุปโฟลว์ใน onCallGenkit
หลังจากตั้งค่าโปรเจ็กต์ Firebase ด้วย Cloud Functions แล้ว คุณสามารถคัดลอกหรือเขียนคําจํากัดความของโฟลว์ในไดเรกทอรี functions/src
ของโปรเจ็กต์ และส่งออกใน index.ts
คุณต้องรวมโฟลว์ไว้ใน onCallGenkit
เพื่อให้นำไปใช้งานได้
วิธีนี้มีฟีเจอร์ทั้งหมดของ onCall
ปกติ โดยรองรับทั้งการตอบกลับแบบสตรีมมิงและ JSON โดยอัตโนมัติ
สมมติว่าคุณมีขั้นตอนต่อไปนี้
const generatePoemFlow = ai.defineFlow(
{
name: "generatePoem",
inputSchema: z.string(),
outputSchema: z.string(),
},
async (subject: string) => {
const { text } = await ai.generate(`Compose a poem about ${subject}.`);
return text;
}
);
คุณสามารถแสดงขั้นตอนนี้เป็นฟังก์ชันที่เรียกใช้ได้โดยใช้ onCallGenkit
ดังนี้
import { onCallGenkit } from 'firebase-functions/https';
export generatePoem = onCallGenkit(generatePoemFlow);
กําหนดนโยบายการให้สิทธิ์
ขั้นตอนการทํางานที่ติดตั้งใช้งานทั้งหมดไม่ว่าจะติดตั้งใช้งานใน Firebase หรือไม่ก็ตามควรมีนโยบายการให้สิทธิ์ หากไม่มี ทุกคนจะเรียกใช้ขั้นตอนการทํางาน Generative AI ที่อาจมีราคาแพงได้ หากต้องการกำหนดนโยบายการให้สิทธิ์ ให้ใช้พารามิเตอร์ authPolicy
ของ onCallGenkit
ดังนี้
export const generatePoem = onCallGenkit({
authPolicy: (auth) => auth?.token?.email_verified,
}, generatePoemFlow);
ตัวอย่างนี้ใช้ฟังก์ชันที่กําหนดเองเป็นนโยบายการตรวจสอบสิทธิ์ นอกจากนี้ https
library ยังส่งออกตัวช่วย signedIn()
และ hasClaim()
ด้วย ต่อไปนี้คือโค้ดเดียวกันที่ใช้ตัวช่วยดังกล่าว
import { hasClaim } from 'firebase-functions/https';
export const generatePoem = onCallGenkit({
authPolicy: hasClaim('email_verified'),
}, generatePoemFlow);
ทำให้ข้อมูลเข้าสู่ระบบ API พร้อมใช้งานสำหรับเวิร์กโฟลว์ที่ติดตั้งใช้งาน
เมื่อติดตั้งใช้งานแล้ว ขั้นตอนจะต้องมีวิธีตรวจสอบสิทธิ์กับบริการระยะไกลที่ใช้ ขั้นตอนส่วนใหญ่ต้องมีข้อมูลเข้าสู่ระบบสำหรับการเข้าถึงบริการ API ของโมเดลที่ใช้เป็นอย่างน้อย
ในตัวอย่างนี้ ให้ทําอย่างใดอย่างหนึ่งต่อไปนี้ ทั้งนี้ขึ้นอยู่กับผู้ให้บริการโมเดลที่คุณเลือก
Gemini (AI ของ Google)
ตรวจสอบว่า AI ของ Google พร้อมให้บริการในภูมิภาคของคุณ
สร้างคีย์ API สำหรับ Gemini API โดยใช้ Google AI Studio
จัดเก็บคีย์ API ใน Secret Manager ของ Cloud โดยทำดังนี้
firebase functions:secrets:set GOOGLE_GENAI_API_KEY
ขั้นตอนนี้สำคัญเพื่อป้องกันไม่ให้คีย์ API ของคุณรั่วไหลโดยไม่ตั้งใจ ซึ่งจะมอบสิทธิ์เข้าถึงบริการที่มีการวัดปริมาณได้
ดูข้อมูลเพิ่มเติมเกี่ยวกับการจัดการข้อมูลลับได้ที่จัดเก็บและเข้าถึงข้อมูลการกําหนดค่าที่มีความละเอียดอ่อน
แก้ไข
src/index.ts
และเพิ่มรายการต่อไปนี้หลังการนําเข้าที่มีอยู่import {defineSecret} from "firebase-functions/params"; const googleAIapiKey = defineSecret("GOOGLE_GENAI_API_KEY");
จากนั้นในคําจํากัดความของโฟลว์ ให้ประกาศว่าฟังก์ชันที่อยู่ในระบบคลาวด์จําเป็นต้องเข้าถึงค่าที่เป็นความลับนี้
export const generatePoem = onCallGenkit({ secrets: [googleAIapiKey] }, generatePoemFlow);
เมื่อคุณทำให้ฟังก์ชันนี้ใช้งานได้แล้ว คีย์ API จะจัดเก็บไว้ใน Cloud Secret Manager และพร้อมใช้งานจากสภาพแวดล้อม Cloud Functions
Gemini (Vertex AI)
ในคอนโซลระบบคลาวด์ ให้เปิดใช้ Vertex AI API สําหรับโปรเจ็กต์ Firebase
ในหน้า 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
เมื่อใช้การตรวจสอบสิทธิ์ที่เหมาะสม (โดยเฉพาะ App Check) คุณอาจไม่จำเป็นต้องใช้ CORS
export const generatePoem = onCallGenkit({
cors: 'mydomain.com',
}, generatePoemFlow);
ตัวอย่างที่สมบูรณ์
หลังจากทําการเปลี่ยนแปลงทั้งหมดที่อธิบายไว้ก่อนหน้านี้แล้ว ขั้นตอนที่นําไปใช้งานได้จะมีลักษณะดังตัวอย่างต่อไปนี้
import { genkit } from 'genkit';
import { onCallGenkit, hasClaim } from 'firebase-functions/https';
import { defineSecret } from 'firebase-functions/params';
const apiKey = defineSecret("GOOGLE_GENAI_API_KEY");
const generatePoemFlow = ai.defineFlow({
name: "generatePoem",
inputSchema: z.string(),
outputSchema: z.string(),
}, async (subject: string) => {
const { text } = await ai.generate(`Compose a poem about ${subject}.`);
return text;
});
export const generateFlow = onCallGenkit({
secrets: [apiKey],
authPolicy: hasClaim("email_verified"),
enforceAppCheck: true,
}, generatePoemFlow);
3. ติดตั้งใช้งานขั้นตอนใน Firebase
หลังจากกําหนดโฟลว์โดยใช้ onCallGenkit
แล้ว คุณจะทําให้โฟลว์ใช้งานได้ในลักษณะเดียวกับที่ทํากับฟังก์ชันอื่นๆ ของ Cloud ดังนี้
cd $PROJECT_ROOT
firebase deploy --only functions
ตอนนี้คุณทำให้โฟลว์ทํางานเป็น Cloud Function แล้ว แต่คุณจะเข้าถึงปลายทางที่ติดตั้งใช้งานด้วย curl
หรือที่คล้ายกันไม่ได้เนื่องจากนโยบายการให้สิทธิ์ของขั้นตอน ส่วนถัดไปจะอธิบายวิธีเข้าถึงขั้นตอนดังกล่าวอย่างปลอดภัย
ไม่บังคับ: ลองใช้ขั้นตอนที่ติดตั้งใช้งาน
หากต้องการลองใช้ปลายทางของโฟลว์ ให้ติดตั้งใช้งานเว็บแอปตัวอย่างขั้นต่ำต่อไปนี้
ในส่วนการตั้งค่าโปรเจ็กต์ของคอนโซล Firebase ให้เพิ่มเว็บแอปใหม่โดยเลือกตัวเลือกเพื่อตั้งค่าโฮสติ้งด้วย
ในส่วนการตรวจสอบสิทธิ์ของคอนโซล Firebase ให้เปิดใช้ผู้ให้บริการ Google ที่ใช้ในตัวอย่างนี้
ในไดเรกทอรีโปรเจ็กต์ ให้ตั้งค่า Firebase Hosting ซึ่งคุณจะใช้เพื่อทำให้แอปตัวอย่างใช้งานได้ โดยทำดังนี้
cd $PROJECT_ROOT
firebase init hosting
ยอมรับค่าเริ่มต้นสำหรับพรอมต์ทั้งหมด
แทนที่
public/index.html
ด้วยข้อมูลต่อไปนี้<!DOCTYPE html> <html> <head> <title>Genkit demo</title> </head> <body> <div id="signin" hidden> <button id="signinBtn">Sign in with Google</button> </div> <div id="callGenkit" hidden> Subject: <input type="text" id="subject" /> <button id="generatePoem">Compose a poem on this subject</button> <p id="generatedPoem"></p> </div> <script type="module"> import { initializeApp } from "https://www.gstatic.com/firebasejs/11.0.1/firebase-app.js"; import { getAuth, onAuthStateChanged, GoogleAuthProvider, signInWithPopup, } from "https://www.gstatic.com/firebasejs/11.0.1/firebase-auth.js"; import { getFunctions, httpsCallable, } from "https://www.gstatic.com/firebasejs/11.0.1/firebase-functions.js"; const firebaseConfig = await fetch("/__/firebase/init.json"); initializeApp(await firebaseConfig.json()); async function generatePoem() { const poemFlow = httpsCallable(getFunctions(), "generatePoem"); const subject = document.querySelector("#subject").value; const response = await poemFlow(subject); document.querySelector("#generatedPoem").innerText = response.data; } function signIn() { signInWithPopup(getAuth(), new GoogleAuthProvider()); } document.querySelector("#signinBtn").addEventListener("click", signIn); document .querySelector("#generatePoem") .addEventListener("click", generatePoem); const signinEl = document.querySelector("#signin"); const genkitEl = document.querySelector("#callGenkit"); onAuthStateChanged(getAuth(), (user) => { if (!user) { signinEl.hidden = false; genkitEl.hidden = true; } else { signinEl.hidden = true; genkitEl.hidden = false; } }); </script> </body> </html>
ติดตั้งใช้งานเว็บแอปและ Cloud Function โดยทำดังนี้
cd $PROJECT_ROOT
firebase deploy
เปิดเว็บแอปโดยไปที่ URL ที่พิมพ์โดยคำสั่ง deploy
แอปจะกำหนดให้คุณลงชื่อเข้าใช้ด้วยบัญชี Google จากนั้นคุณจะเริ่มคําขออุปกรณ์ปลายทางได้
ไม่บังคับ: เรียกใช้ขั้นตอนใน UI ของนักพัฒนาแอป
คุณสามารถเรียกใช้โฟลว์ที่กําหนดโดยใช้ onCallGenkit
ใน UI ของนักพัฒนาซอฟต์แวร์ได้เช่นเดียวกับการเรียกใช้โฟลว์ที่กําหนดโดยใช้ defineFlow
จึงไม่ต้องสลับไปมาระหว่าง 2 รายการนี้ระหว่างการติดตั้งใช้งานกับการพัฒนา
cd $PROJECT_ROOT/functions
npx genkit start -- npx tsx --watch src/index.ts
หรือ
cd $PROJECT_ROOT/functions
npm run genkit:start
ตอนนี้คุณไปยัง URL ที่พิมพ์โดยคําสั่ง genkit start
เพื่อเข้าถึงได้แล้ว
ไม่บังคับ: การพัฒนาโดยใช้ Firebase Local Emulator Suite
Firebase มีชุดโปรแกรมจำลองสําหรับการพัฒนาซอฟต์แวร์ในเครื่อง ซึ่งคุณใช้กับ Genkit ได้
หากต้องการใช้ UI สําหรับนักพัฒนา Genkit กับ Firebase Emulator Suite ให้เริ่มโปรแกรมจําลอง Firebase ดังนี้
npx genkit start -- firebase emulators:start --inspect-functions
คำสั่งนี้จะเรียกใช้โค้ดของคุณในโปรแกรมจำลอง และเรียกใช้เฟรมเวิร์ก Genkit ในโหมดการพัฒนา ซึ่งจะเปิดและแสดง Genkit reflection API (แต่ไม่ใช่ UI สําหรับนักพัฒนาซอฟต์แวร์)
หากต้องการดูร่องรอยจาก Firestore ใน UI ของนักพัฒนาซอฟต์แวร์ ให้ไปที่แท็บตรวจสอบแล้วสลับสวิตช์ Dev/Prod เมื่อสลับเป็น prod ระบบจะโหลดร่องรอยจาก Firestore