Cloud Functions for Firebase 具有 onCallGenkit
方法,可让您使用 Genkit 操作(Flow)创建可调用函数。这些函数可以使用 genkit/beta/client
或 Cloud Functions 客户端 SDK 进行调用,后者会自动添加身份验证信息。
准备工作
- 您应该熟悉 Genkit 的 flow 概念以及如何编写 flow。本页面中的说明假定您已定义要部署的一些 flow。
- 如果您之前使用过 Cloud Functions for Firebase,那么这会有所帮助,但不是必需的。
设置 Firebase 项目
使用 Firebase 控制台创建新的 Firebase 项目,或选择现有项目。
将项目升级到 Blaze 方案,这是 Cloud Functions 正式版部署所必需的。
安装 Firebase CLI。
使用 Firebase CLI 登录:
firebase login
firebase login --reauth # alternative, if necessary
firebase login --no-localhost # if running in a remote shell
创建新的项目目录:
export PROJECT_ROOT=~/tmp/genkit-firebase-project1
mkdir -p $PROJECT_ROOT
在目录中初始化 Firebase 项目:
cd $PROJECT_ROOT
firebase init functions
本页面的其余部分假定您已选择使用 JavaScript 编写函数。
将 flow 封装在 onCallGenkit
中
使用 Cloud Functions 设置 Firebase 项目后,您可以在项目的 functions
目录中复制或编写 flow 定义。以下示例 flow 演示了这一过程:
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;
},
);
如需部署此类 flow,请使用 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,
);
向已部署的 Flow 提供 API 凭据
部署后,您的 flow 需要一种方法来对其所依赖的任何远程服务进行身份验证。大多数 flow 至少需要凭据才能访问其使用的模型 API 服务。
对于此示例,请根据您选择的模型提供方,执行以下操作之一:
Gemini (Google AI)
使用 Google AI Studio 为 Gemini API 生成 API 密钥。
将 API 密钥存储在 Cloud Secret Manager 中:
firebase functions:secrets:set GOOGLE_GENAI_API_KEY
此步骤非常重要,可防止您的 API 密钥意外泄露,从而授予对潜在按计量方式收费的服务的访问权限。
如需详细了解如何管理密钥,请参阅存储和访问敏感的配置信息。
修改
src/index.js
,并在现有 import 之后添加以下内容: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)
在 Cloud 控制台中,为您的 Firebase 项目启用 Vertex AI API。
在 IAM 页面上,确保为默认计算服务账号授予 Vertex AI User 角色。
在本教程中,您只需要为模型提供方设置 Secret,但一般来说,您必须为 flow 使用的每项服务执行类似的操作。
(可选)添加 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
选项控制哪些来源可以访问您的函数。
默认情况下,Callable 函数会将 CORS 配置为允许来自所有来源的请求。若要允许部分(而非全部)跨域请求,请传递应允许的特定网域或正则表达式的列表。例如:
export const tellJoke = onCallGenkit({
cors: 'mydomain.com',
}, jokeTeller);
完整示例
完成上述所有更改后,您的可部署 flow 将如下所示:
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,
);
将 flow 部署到 Firebase
使用 onCallGenkit
定义 flow 后,您可以像部署其他函数一样部署这些 flow:
cd $PROJECT_ROOT
firebase deploy --only functions