從應用程式叫用 Genkit 流程

Cloud Functions for Firebase 提供 onCallGenkit 方法,可讓您使用 Genkit 動作 (資料流) 建立可呼叫的函式。您可以使用 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;
},
);

如要部署這類流程,請使用 firebase-functions/https 中的 onCallGenkit 包裝它。這個輔助方法具有可呼叫函式的所有功能,並自動支援串流和 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 的 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