استقرار جریان ها با استفاده از توابع ابری برای Firebase

Cloud Functions برای Firebase دارای یک روش onCallGenkit است که به شما امکان می دهد به سرعت یک تابع قابل فراخوانی را با یک کنش Genkit (مثلاً یک Flow) ایجاد کنید. این توابع را می توان با استفاده از genkit/beta/client یا Functions client SDK فراخوانی کرد که به طور خودکار اطلاعات احراز هویت را اضافه می کند.

قبل از شروع

  • شما باید با مفهوم جنکیت از جریان ها و نحوه نوشتن آنها آشنا باشید. دستورالعمل‌های موجود در این صفحه فرض می‌کنند که شما قبلاً برخی از جریان‌ها را تعریف کرده‌اید که می‌خواهید آن‌ها را اجرا کنید.
  • اگر قبلاً از Cloud Functions برای Firebase استفاده کرده باشید، مفید است، اما ضروری نیست.

1. یک پروژه Firebase راه اندازی کنید

اگر قبلاً پروژه Firebase با توابع ابری TypeScript راه‌اندازی نکرده‌اید، این مراحل را دنبال کنید:

  1. با استفاده از کنسول Firebase یک پروژه Firebase جدید ایجاد کنید یا یک پروژه موجود را انتخاب کنید.

  2. پروژه را به پلان Blaze ارتقا دهید، که برای استقرار توابع ابری لازم است.

  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 genkit

    بقیه این صفحه فرض می کند که شما تصمیم گرفته اید توابع خود را در TypeScript بنویسید، اما اگر از جاوا اسکریپت استفاده می کنید می توانید جریان های Genkit خود را نیز مستقر کنید.

2. Flow را در onCallGenkit بپیچید

پس از راه‌اندازی یک پروژه Firebase با توابع Cloud، می‌توانید تعاریف جریان را در فهرست 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 مستقر شده باشند یا نه، باید دارای یک خط‌مشی مجوز باشند. بدون آن، هر کسی می‌تواند جریان‌های هوش مصنوعی مولد بالقوه گران قیمت شما را فراخوانی کند. برای تعریف یک خط مشی مجوز، از پارامتر authPolicy onCallGenkit استفاده کنید:

export const generatePoem = onCallGenkit({
  authPolicy: (auth) => auth?.token?.email_verified,
}, generatePoemFlow);

این نمونه از یک تابع دستی به عنوان خط مشی تأیید اعتبار خود استفاده می کند. علاوه بر این، کتابخانه https کمک کننده های signedIn() و hasClaim() را صادر می کند. در اینجا همان کد با استفاده از یکی از آن کمک کننده ها وجود دارد:

import { hasClaim } from 'firebase-functions/https';

export const generatePoem = onCallGenkit({
  authPolicy: hasClaim('email_verified'),
}, generatePoemFlow);

اعتبارنامه های API را برای جریان های مستقر در دسترس قرار دهید

پس از استقرار، جریان های شما به روشی برای احراز هویت با هر سرویس راه دوری که به آن تکیه می کنند نیاز دارد. اکثر جریان‌ها برای دسترسی به سرویس API مدلی که استفاده می‌کنند، حداقل به اعتبار نیاز دارند.

برای این مثال، بسته به ارائه دهنده مدلی که انتخاب کرده اید، یکی از موارد زیر را انجام دهید:

جمینی (گوگل هوش مصنوعی)

  1. مطمئن شوید که Google AI در منطقه شما در دسترس است.

  2. با استفاده از Google AI Studio یک کلید API برای Gemini API ایجاد کنید .

  3. کلید API خود را در Cloud Secret Manager ذخیره کنید:

    firebase functions:secrets:set GOOGLE_GENAI_API_KEY

    این مرحله برای جلوگیری از نشت تصادفی کلید API شما که امکان دسترسی به یک سرویس بالقوه اندازه‌گیری شده را می‌دهد، مهم است.

    برای اطلاعات بیشتر در مورد مدیریت اسرار، به ذخیره و دسترسی به اطلاعات پیکربندی حساس مراجعه کنید.

  4. 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)

  1. در کنسول Cloud، Vertex AI API را برای پروژه Firebase خود فعال کنید .

  2. در صفحه IAM ، اطمینان حاصل کنید که به حساب پیش‌فرض خدمات محاسباتی نقش Vertex AI User اعطا شده است.

تنها رازی که باید برای این آموزش راه اندازی کنید، مربوط به ارائه دهنده مدل است، اما به طور کلی، باید برای هر سرویسی که جریان شما استفاده می کند، کاری مشابه انجام دهید.

افزودن اجرای بررسی برنامه

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 تعریف کردید، می‌توانید آنها را به همان روشی که سایر توابع ابری را استقرار می‌دهید اجرا کنید:

cd $PROJECT_ROOT
firebase deploy --only functions

شما اکنون جریان را به عنوان یک تابع ابری به کار گرفته اید! اما به دلیل خط مشی مجوز جریان، نمی توانید با curl یا موارد مشابه به نقطه پایانی مستقر شده خود دسترسی پیدا کنید. بخش بعدی نحوه دسترسی ایمن به جریان را توضیح می دهد.

اختیاری: جریان مستقر را امتحان کنید

برای امتحان نقطه پایانی جریان خود، می‌توانید نمونه حداقل برنامه وب زیر را اجرا کنید:

  1. در بخش تنظیمات پروژه کنسول Firebase، یک برنامه وب جدید اضافه کنید و گزینه تنظیم میزبانی را انتخاب کنید.

  2. در بخش Authentication کنسول Firebase، ارائه‌دهنده Google را که در این مثال استفاده شده است، فعال کنید.

  3. در فهرست پروژه خود، میزبانی Firebase را راه‌اندازی کنید، جایی که برنامه نمونه را در آنجا مستقر خواهید کرد:

    cd $PROJECT_ROOT
    firebase init hosting

    پیش فرض ها را برای همه درخواست ها بپذیرید.

  4. 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>
    
  5. استقرار برنامه وب و عملکرد ابری:

    cd $PROJECT_ROOT
    firebase deploy

با مراجعه به URL چاپ شده توسط دستور deploy برنامه وب را باز کنید. این برنامه از شما می‌خواهد که با یک حساب Google وارد شوید، پس از آن می‌توانید درخواست‌های نقطه پایانی را آغاز کنید.

اختیاری: جریان‌ها را در رابط کاربری توسعه‌دهنده اجرا کنید

می‌توانید جریان‌های تعریف‌شده با استفاده از onCallGenkit را در رابط کاربری توسعه‌دهنده اجرا کنید، دقیقاً به همان روشی که جریان‌های تعریف‌شده با استفاده از defineFlow را اجرا می‌کنید، بنابراین نیازی به جابجایی بین این دو بین استقرار و توسعه نیست.

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 از آنها استفاده کنید.

برای استفاده از Genkit Dev UI با Firebase Emulator Suite، شبیه سازهای Firebase را به صورت زیر راه اندازی کنید:

npx genkit start -- firebase emulators:start --inspect-functions

این دستور کد شما را در شبیه ساز اجرا می کند و فریم ورک Genkit را در حالت توسعه اجرا می کند. با این کار Genkit Reflection API (اما نه Dev UI) راه اندازی و در معرض دید قرار می گیرد.

برای مشاهده ردپای Firestore در Dev UI، می توانید به برگه Inspect بروید و سوئیچ Dev/Prod را تغییر دهید. هنگامی که برای برانگیختن آن جابه‌جا می‌شود، آثاری از فایر استور بارگیری می‌شود.