從應用程式叫用 Genkit 流程

Cloud Functions for Firebase 具有 onCallGenkit 方法,可讓您使用 Genkit 動作 (Flow) 建立可呼叫函式。您可以使用 genkit/beta/clientCloud Functions 用戶端 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

使用 Cloud Functions 設定 Firebase 專案後,您可以在專案的 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 (Google AI)

  1. 確認 Google AI 是否支援你的所在地區

  2. 使用 Google AI Studio 產生 Gemini API 金鑰

  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 控制台中,為 Firebase 專案啟用 Vertex AI API

  2. 在「IAM」頁面中,確認「預設運算服務帳戶」已獲派「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