Cloud Functions for Firebase'i kullanarak akışları dağıtma

Genkit, akışlarınızı Firebase için Cloud Functions'a dağıtmanıza yardımcı olan bir eklenti içerir. Dağıtılan akışlar HTTPS uç noktası olarak kullanılabilir ve Cloud Functions istemci kitaplıkları kullanılarak çağrılabilir işlevler olarak erişilebilir.

Başlamadan önce

  • Firebase CLI'yi yükleyin.
  • Genkit'in akış kavramı ve bunların nasıl yazılacağı hakkında bilgi sahibi olmanız gerekir. Bu sayfadaki talimatlarda, dağıtmak istediğiniz bazı akışların tanımlanmış olduğu varsayılır.
  • Daha önce Firebase için Cloud Functions'i kullandıysanız bu faydalı olur ancak gerekli değildir.

1. Firebase projesi oluşturma

TypeScript Cloud Functions'in ayarlandığı bir Firebase projeniz yoksa aşağıdaki adımları uygulayın:

  1. Firebase konsolunu kullanarak yeni bir Firebase projesi oluşturun veya mevcut bir projeyi seçin.

  2. Cloud Functions'i dağıtmak için gereken Blaze planına projeyi yükseltin.

  3. Firebase CLI ile oturum açın:

    firebase login
    firebase login --reauth # alternative, if necessary
    firebase login --no-localhost # if running in a remote shell
  4. Yeni bir proje dizini oluşturun:

    export PROJECT_ROOT=~/tmp/genkit-firebase-project1
    mkdir -p $PROJECT_ROOT
  5. Dizininde bir Firebase projesini başlatın:

    cd $PROJECT_ROOT
    firebase init genkit

    Bu sayfanın geri kalanında, işlevlerinizi TypeScript'te yazmayı seçtiğiniz varsayılır ancak JavaScript kullanıyorsanız Genkit akışlarınızı dağıtabilirsiniz.

2. Akış tanımlarını güncelleme

Cloud Functions ile bir Firebase projesi oluşturduktan sonra, projenin functions/src dizininde akış tanımlarını kopyalayabilir veya yazabilir ve index.ts'a aktarabilirsiniz.

Akışlarınızın dağıtılabilmesi için bunları tanımlama şeklinizde bazı küçük değişiklikler yapmanız gerekir. Temel mantık aynı kalır ancak bu işleri sorunsuz bir şekilde dağıtmak ve dağıtıldıktan sonra daha güvenli hale getirmek için bazı ek bilgiler eklersiniz.

Aşağıdaki akışa sahip olduğunuzu varsayalım:

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

Aşağıdaki bölümlerde, dağıtmadan önce yapmanız gereken değişiklikler açıklanmaktadır.

onFlow ile akışları tanımlama

Akışınızı Genkit.defineFlow() ile tanımlamak yerine Firebase eklentisinin onFlow() işlevini kullanın. Bu işlev, akış mantığınızı onCall'a benzer bir Cloud Functions istek işleyicisine sarmalar.

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

export const generatePoem = onFlow(
  ai,
  {
    // ...
  },
  async (subject: string) => {
    // ...
  }
);

onFlow'ün Genkit yöntemi değil, ilk parametresi olarak bir Genkit örneği alan bir işlev olduğunu unutmayın. Aksi takdirde söz dizimi defineFlow ile benzerdir.

Yetkilendirme politikası tanımlama

Firebase'e dağıtılmış olsun veya olmasın, dağıtılan tüm akışların bir yetkilendirme politikası olmalıdır. Aksi takdirde, pahalı olabilecek üretken yapay zeka akışlarınız herkes tarafından çağrılabilir. Yetkilendirme politikası tanımlamak için akış tanımında authPolicy parametresini kullanın:

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

export const generatePoem = onFlow(
  ai,
  {
    name: "generatePoem",
    // ...
    authPolicy: firebaseAuth((user, input) => {
      if (!user.email_verified) {
        throw new Error("Verified email required to run flow");
      }
    }),
  },
  async (subject: string) => {
    // ...
  }
);

Bu politika, yalnızca uygulamanızın kayıtlı ve doğrulanmış e-posta adreslerine sahip kullanıcılarına erişim izni vermek için firebaseAuth() yardımcısını kullanır. İstemci tarafında, Authorization: Bearer başlığını politikanızı karşılayan bir Firebase kimlik jetonuna ayarlamanız gerekir. Cloud Functions istemci SDK'ları, bu işlemi otomatikleştiren çağrılabilir işlev yöntemleri sağlar. Örnek için Dağıtılan akışı deneme bölümüne bakın.

API kimlik bilgilerini dağıtılan akışlar için kullanılabilir hale getirme

Yayınlanan akışlarınızın, kullandıkları uzak hizmetlerle kimlik doğrulaması yapması gerekir. Çoğu akışta, kullandıkları model API hizmetine erişmek için en azından kimlik bilgileri gerekir.

Bu örnekte, seçtiğiniz model sağlayıcıya bağlı olarak aşağıdakilerden birini yapın:

Gemini (Google Yapay Zeka)

  1. Google Yapay Zeka'nın bölgenizde kullanılabildiğinden emin olun.

  2. Google AI Studio'yu kullanarak Gemini API için API anahtarı oluşturun.

  3. API anahtarınızı Cloud Secret Manager'da depolayın:

    firebase functions:secrets:set GOOGLE_GENAI_API_KEY

    Bu adım, olası ücretli bir hizmete erişim sağlayan API anahtarınızın yanlışlıkla sızmasını önlemek için önemlidir.

    Gizli bilgileri yönetme hakkında daha fazla bilgi için Hassas yapılandırma bilgilerini depolama ve bunlara erişme başlıklı makaleyi inceleyin.

  4. src/index.ts dosyasını düzenleyin ve mevcut içe aktarma işlemlerinin ardından şunları ekleyin:

    import {defineSecret} from "firebase-functions/params";
    const googleAIapiKey = defineSecret("GOOGLE_GENAI_API_KEY");
    

    Ardından, akış tanımında, bulut işlevinin bu gizli değere erişmesi gerektiğini belirtin:

    export const generatePoem = onFlow(
      {
        name: "generatePoem",
        // ...
        httpsOptions: {
          secrets: [googleAIapiKey],  // Add this line.
        },
      },
      async (subject) => {
        // ...
      }
    );
    

Artık bu işlevi dağıttığınızda API anahtarınız Cloud Secret Manager'da depolanır ve Cloud Functions ortamından kullanılabilir.

Gemini (Vertex AI)

  1. Cloud Console'da, Firebase projeniz için Vertex AI API'yi etkinleştirin.

  2. IAM sayfasında, Varsayılan Compute hizmet hesabına Vertex AI Kullanıcısı rolünün atandığından emin olun.

Bu eğitim için ayarlamanız gereken tek gizlilik, model sağlayıcı içindir ancak genel olarak akışınızın kullandığı her hizmet için benzer bir işlem yapmanız gerekir.

CORS politikası belirleme

Akışınıza bir web uygulamasından erişecekseniz (Yayınlanan akışı deneyin bölümünde bunu yapacaksınız) httpsOptions parametresinde bir CORS politikası ayarlayın:

export const generatePoem = onFlow(
  ai,
  {
    name: "generatePoem",
    // ...
    httpsOptions: {
      cors: '*',
    },
  },
  async (subject: string) => {
    // ...
  }
);

Üretim uygulamaları için daha kısıtlayıcı bir politika kullanmak isteyebilirsiniz ancak bu eğitim için bu politika yeterli olacaktır.

Tam örnek

Yukarıda açıklanan tüm değişiklikleri yaptıktan sonra dağıtılabilir akışınız aşağıdaki örneğe benzer şekilde görünür:

const googleAIapiKey = defineSecret("GOOGLE_GENAI_API_KEY");

export const generatePoem = onFlow(
  ai,
  {
    name: "generatePoem",
    inputSchema: z.string(),
    outputSchema: z.string(),
    authPolicy: firebaseAuth((user, input) => {
      if (!user.email_verified) {
        throw new Error("Verified email required to run flow");
      }
    }),
    httpsOptions: {
      secrets: [googleAIapiKey],
      cors: '*',
    },
  },
  async (subject: string) => {
    const { text } = await ai.generate(`Compose a poem about ${subject}.`);
    return text;
  }
);

3. Akışları Firebase'e dağıtma

onFlow kullanarak akışları tanımladıktan sonra bunları diğer Cloud Functions işlevlerini dağıttığınız gibi dağıtabilirsiniz:

cd $PROJECT_ROOT
firebase deploy --only functions

Artık akışı bir Cloud Functions işlevi olarak dağıttınız. Ancak akıştaki yetkilendirme politikası nedeniyle, dağıtılan uç noktanıza curl veya benzeri bir yöntemle erişemezsiniz. Akışa nasıl güvenli bir şekilde erişeceğinizi öğrenmek için sonraki bölüme geçin.

İsteğe bağlı: Dağıtılan akışı deneyin

Akış uç noktanızı denemek için aşağıdaki minimum örnek web uygulamasını dağıtabilirsiniz:

  1. Firebase konsolunun Proje ayarları bölümünde, Hosting'i de ayarlama seçeneğini belirleyerek yeni bir web uygulaması ekleyin.

  2. Firebase Konsolu'nun Kimlik doğrulama bölümünde, bu örnekte kullanacağınız Google sağlayıcısını etkinleştirin.

  3. Proje dizininizde, örnek uygulamayı dağıtacağınız Firebase Hosting'i ayarlayın:

    cd $PROJECT_ROOT
    firebase init hosting

    Tüm istemler için varsayılan değerleri kabul edin.

  4. public/index.html yerine aşağıdakileri kullanın:

    <!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. Web uygulamasını ve Cloud Functions işlevini dağıtın:

    cd $PROJECT_ROOT
    firebase deploy

deploy komutu tarafından yazdırılan URL'yi ziyaret ederek web uygulamasını açın. Uygulama, bir Google Hesabı ile oturum açmanızı gerektirir. Ardından uç nokta isteklerini başlatabilirsiniz.

İsteğe bağlı: Geliştirici kullanıcı arayüzünde akışları çalıştırma

Geliştirici kullanıcı arayüzünde onFlow kullanılarak tanımlanan akışları, defineFlow kullanılarak tanımlanan akışları çalıştırdığınız şekilde çalıştırabilirsiniz. Bu nedenle, dağıtım ve geliştirme arasında iki akış arasında geçiş yapmanız gerekmez.

cd $PROJECT_ROOT/functions
npx genkit start -- npx tsx --watch src/index.ts

veya

cd $PROJECT_ROOT/functions
npm run genkit:start

Artık genkit start komutu tarafından yazdırılan URL'ye giderek erişebilirsiniz.

İsteğe bağlı: Firebase Local Emulator Suite'i kullanarak geliştirme

Firebase, Genkit ile kullanabileceğiniz yerel geliştirme için bir emülatör paketi sunar.

Genkit geliştirici kullanıcı arayüzünü Firebase Emulator Suite ile kullanmak için Firebase emülatörlerini şu şekilde başlatın:

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

Bu işlem, kodunuzu emülatörde ve Genkit çerçevesini geliştirme modunda çalıştırır. Bu mod, Genkit yansıma API'sini (geliştirici kullanıcı arayüzünü değil) başlatır ve gösterir.

Geliştirici kullanıcı arayüzünde Firestore'daki izlemeleri görmek için İncele sekmesine gidebilir ve "Geliştirici/Üretim" anahtarını açabilirsiniz. "prod" olarak ayarlandığında Firestore'dan iz yükler.