Cloud Functions for Firebase 提供了 onCallGenkit
方法,可让您使用 Genkit 操作(例如流程)快速创建可调用函数。您可以使用 genkit/beta/client
或 Functions 客户端 SDK 调用这些函数,后者会自动添加身份验证信息。
准备工作
- 您应该熟悉 Genkit 的流程概念以及如何编写流程。本页中的说明假定您已定义要部署的一些流程。
- 如果您之前使用过适用于 Firebase 的 Cloud Functions,将会很有帮助,但不是必需的。
1. 设置 Firebase 项目
如果您还没有设置 TypeScript Cloud Functions 的 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 genkit
本页面的其余部分假定您已决定使用 TypeScript 编写函数,但如果您使用的是 JavaScript,也可以部署 Genkit 流程。
2. 在 onCallGenkit 中封装流
使用 Cloud Functions 设置 Firebase 项目后,您可以在项目的 functions/src
目录中复制或编写流程定义,并在 index.ts
中导出这些定义。
为了能够部署流程,您需要将其封装在 onCallGenkit
中。此方法具有普通 onCall
的所有功能。它自动支持流式传输和 JSON 响应。
假设您有以下流程:
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;
}
);
您可以使用 onCallGenkit
将此流程公开为可调用函数:
import { onCallGenkit } from 'firebase-functions/https';
export generatePoem = onCallGenkit(generatePoemFlow);
定义授权政策
所有已部署的流程(无论是否部署到 Firebase)都应具有授权政策;如果没有授权政策,任何人都可以调用可能非常昂贵的生成式 AI 流程。如需定义授权政策,请使用 onCallGenkit
的 authPolicy
参数:
export const generatePoem = onCallGenkit({
authPolicy: (auth) => auth?.token?.email_verified,
}, generatePoemFlow);
此示例使用手动函数作为其身份验证政策。此外,https 库还会导出 signedIn()
和 hasClaim()
帮助程序。下面是使用其中一个帮助程序的相同代码:
import { hasClaim } from 'firebase-functions/https';
export const generatePoem = onCallGenkit({
authPolicy: hasClaim('email_verified'),
}, generatePoemFlow);
向已部署的流程提供 API 凭据
部署后,您的流程需要通过某种方式与其依赖的任何远程服务进行身份验证。大多数流程至少需要凭据才能访问其使用的模型 API 服务。
对于此示例,请根据您选择的模型提供方,执行以下操作之一:
Gemini (Google AI)
使用 Google AI Studio 为 Gemini API 生成 API 密钥。
将 API 密钥存储在 Cloud Secret Manager 中:
firebase functions:secrets:set GOOGLE_GENAI_API_KEY
此步骤非常重要,可防止意外泄露您的 API 密钥,该密钥可授予对可能按量计费的服务的访问权限。
如需详细了解如何管理 Secret,请参阅存储和访问敏感的配置信息。
修改
src/index.ts
,并将以下代码添加到现有 import 之后:import {defineSecret} from "firebase-functions/params"; const googleAIapiKey = defineSecret("GOOGLE_GENAI_API_KEY");
然后,在流程定义中声明 Cloud Functions 函数需要访问此 Secret 值:
export const generatePoem = onCallGenkit({ secrets: [googleAIapiKey] }, generatePoemFlow);
现在,当您部署此函数时,您的 API 密钥会存储在 Cloud Secret Manager 中,并可从 Cloud Functions 环境中使用。
Gemini (Vertex AI)
在 Cloud 控制台中,为您的 Firebase 项目启用 Vertex AI API。
在 IAM 页面上,确保为默认计算服务账号授予 Vertex AI User 角色。
在本教程中,您只需要为模型提供方设置 Secret,但一般来说,您必须为流水线使用的每项服务执行类似的操作。
添加 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 政策
默认情况下,Callable 函数允许任何网域调用您的函数。如果您想自定义可以执行此操作的网域,请使用 cors
选项。通过适当的身份验证(尤其是 App Check),通常不需要 CORS。
export const generatePoem = onCallGenkit({
cors: 'mydomain.com',
}, generatePoemFlow);
完整示例
完成上述所有更改后,您的可部署流程应如下例所示:
import { genkit } from 'genkit';
import { onCallGenkit, hasClaim } from 'firebase-functions/https';
import { defineSecret } from 'firebase-functions/params';
const apiKey = defineSecret("GOOGLE_GENAI_API_KEY");
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;
});
export const generateFlow = onCallGenkit({
secrets: [apiKey],
authPolicy: hasClaim("email_verified"),
enforceAppCheck: true,
}, generatePoemFlow);
3. 将流程部署到 Firebase
使用 onCallGenkit
定义流程后,您可以像部署其他 Cloud Functions 函数一样部署这些流程:
cd $PROJECT_ROOT
firebase deploy --only functions
现在,您已将该流程部署为 Cloud Functions 函数!但是,由于该流程的授权政策,您无法使用 curl
或类似工具访问已部署的端点。下一部分将介绍如何安全地访问该流程。
可选:试用已部署的流程
如需试用流程端点,您可以部署以下最小示例 Web 应用:
在 Firebase 控制台的项目设置部分中,添加一个新的 Web 应用,并选择同时设置 Hosting 的选项。
在 Firebase 控制台的 Authentication(身份验证)部分,启用此示例中使用的 Google 提供方。
在项目目录中,设置 Firebase Hosting(您将在其中部署示例应用):
cd $PROJECT_ROOT
firebase init hosting
接受所有提示的默认设置。
将
public/index.html
替换为以下代码:<!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>
部署 Web 应用和 Cloud Functions 函数:
cd $PROJECT_ROOT
firebase deploy
访问 deploy
命令输出的网址,打开 Web 应用。该应用要求您使用 Google 账号登录,然后您才能发起端点请求。
可选:在开发者界面中运行流程
您可以在开发者界面中运行使用 onCallGenkit
定义的流程,就像运行使用 defineFlow
定义的流程一样,因此在部署和开发之间无需在二者之间切换。
cd $PROJECT_ROOT/functions
npx genkit start -- npx tsx --watch src/index.ts
或
cd $PROJECT_ROOT/functions
npm run genkit:start
现在,您可以导航到 genkit start
命令输出的网址进行访问。
可选:使用 Firebase Local Emulator Suite 进行开发
Firebase 提供了一套适用于本地开发的模拟器,您可以将其与 Genkit 搭配使用。
如需将 Genkit 开发者界面与 Firebase Emulator Suite 搭配使用,请按如下方式启动 Firebase 模拟器:
npx genkit start -- firebase emulators:start --inspect-functions
此命令会在模拟器中运行您的代码,并在开发模式下运行 Genkit 框架。这会启动并公开 Genkit 反射 API(但不会公开开发者界面)。
如需在开发者界面中查看 Firestore 中的轨迹,您可以前往 Inspect 标签页,然后切换 Dev/Prod 开关。切换到prod 后,它会从 Firestore 加载轨迹。