從應用程式叫用 Genkit 流程

Cloud Functions for Firebase 具有 onCallGenkit 方法,可讓您使用 Genkit 動作 (流程) 建立可呼叫函式。您可以使用 genkit/beta/clientCloud Functions for Firebase Client SDK 呼叫這些函式,系統會自動新增驗證資訊。

事前準備

  • 您應熟悉Genkit流程的概念,以及如何編寫流程。本頁的操作說明假設您已定義要部署的流程。
  • 如果您曾使用 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/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 (Google AI)

  1. 產生 API 金鑰,以供 Gemini Developer API 使用 Google AI Studio

  2. Google Cloud Secret Manager 中儲存 API 金鑰:

    firebase functions:secrets:set GOOGLE_GENAI_API_KEY

    這個步驟非常重要,可避免 API 金鑰意外外洩,因為這類金鑰可能會授予存取計量服務的權限。

    如要進一步瞭解如何管理密鑰,請參閱「儲存及存取機密設定資訊」。

  3. 編輯 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 金鑰會儲存在 Google Cloud Secret Manager 中,並可從 Cloud Functions 環境取得。

Gemini (Vertex AI)

  1. Google Cloud 控制台中,為 Firebase 專案啟用 Vertex AI API

  2. 在「IAM」頁面中,確認「預設運算服務帳戶」已獲授「Vertex AI 使用者」角色。

在本教學課程中,您只需要為模型供應商設定密鑰,但一般來說,您必須為流程使用的每項服務執行類似操作。

(選用) 新增Firebase 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/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