Genkit 包含一个插件,可帮助您将流程部署到 Cloud Functions for Firebase。流程部署后,会作为 HTTPS 端点提供,并且可以使用 Cloud Functions 客户端库作为可调用函数访问。
准备工作
- 安装 Firebase CLI。
- 您应该熟悉 Genkit 的流程概念以及如何编写流程。本页中的说明假定您已定义要部署的一些流程。
- 如果您之前使用过适用于 Firebase 的 Cloud Functions,将会很有帮助,但这不是硬性要求。
1. 设置 Firebase 项目
如果您还没有设置了 TypeScript Cloud Functions 的 Firebase 项目,请按以下步骤操作:
使用 Firebase 控制台创建新的 Firebase 项目,或选择现有项目。
将项目升级为 Blaze 方案,这是部署 Cloud Functions 函数的必备条件。
使用 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. 更新流程定义
使用 Cloud Functions 设置 Firebase 项目后,您可以在项目的 functions/src
目录中复制或编写流程定义,并在 index.ts
中导出这些定义。
为了使流程可部署,您需要对其定义方式进行一些细微更改。核心逻辑将保持不变,但您需要添加一些额外信息,以便顺利部署这些模块,并提高其部署后的安全性。
假设您有以下流程:
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;
}
);
以下部分介绍了您在部署之前需要进行的更改。
使用 onFlow 定义流程
请改用 Firebase 插件的 onFlow()
函数,而不是使用 Genkit.defineFlow()
定义流程。使用此函数可将流程逻辑封装在 Cloud Functions 请求处理程序中,类似于 onCall
。
import { onFlow } from "@genkit-ai/firebase/functions";
export const generatePoem = onFlow(
ai,
{
// ...
},
async (subject: string) => {
// ...
}
);
请注意,onFlow
不是 Genkit
的方法,而是一个将 Genkit
实例作为其第一个参数的函数。否则,语法与 defineFlow
类似。
定义授权政策
所有已部署的流程(无论是否部署到 Firebase)都应具有授权政策;如果没有授权政策,任何人都可以调用您的可能非常昂贵的生成式 AI 流程。如需定义授权政策,请在流程定义中使用 authPolicy
参数:
import { firebaseAuth } from "@genkit-ai/firebase/auth";
export const generatePoem = onFlow(
ai,
{
name: "generatePoem",
// ...
authPolicy: firebaseAuth((user, input) => {
if (!user.email_verified) {
throw new Error("Verified email required to run flow");
}
}),
},
async (subject: string) => {
// ...
}
);
此政策使用 firebaseAuth()
帮助程序,仅允许拥有经过验证的电子邮件地址的应用注册用户访问。在客户端,您需要将 Authorization: Bearer
标头设置为符合您政策的 Firebase ID 令牌。Cloud Functions 函数客户端 SDK 提供了可自动执行此操作的可调用函数方法;如需查看示例,请参阅试用已部署的工作流部分。
向已部署的流程提供 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 = onFlow( { name: "generatePoem", // ... httpsOptions: { secrets: [googleAIapiKey], // Add this line. }, }, async (subject) => { // ... } );
现在,当您部署此函数时,您的 API 密钥将存储在 Cloud Secret Manager 中,并可从 Cloud Functions 环境中使用。
Gemini (Vertex AI)
在 Cloud 控制台中,为您的 Firebase 项目启用 Vertex AI API。
在 IAM 页面上,确保为默认计算服务账号授予 Vertex AI User 角色。
在本教程中,您只需要为模型提供方设置 Secret,但一般来说,您必须为流程使用的每项服务执行类似的操作。
设置 CORS 政策
如果您将通过 Web 应用访问您的流程(您将在试用已部署的流程部分中执行此操作),请在 httpsOptions
参数中设置 CORS 政策:
export const generatePoem = onFlow(
ai,
{
name: "generatePoem",
// ...
httpsOptions: {
cors: '*',
},
},
async (subject: string) => {
// ...
}
);
对于正式版应用,您可能需要采用更严格的政策,但对于本教程来说,这样就足够了。
完整示例
完成上述所有更改后,您的可部署流程将如下例所示:
const googleAIapiKey = defineSecret("GOOGLE_GENAI_API_KEY");
export const generatePoem = onFlow(
ai,
{
name: "generatePoem",
inputSchema: z.string(),
outputSchema: z.string(),
authPolicy: firebaseAuth((user, input) => {
if (!user.email_verified) {
throw new Error("Verified email required to run flow");
}
}),
httpsOptions: {
secrets: [googleAIapiKey],
cors: '*',
},
},
async (subject: string) => {
const { text } = await ai.generate(`Compose a poem about ${subject}.`);
return text;
}
);
3. 将流程部署到 Firebase
使用 onFlow
定义流程后,您可以像部署其他 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 账号登录,然后您才能发起端点请求。
可选:在开发者界面中运行流程
您可以在开发者界面中运行使用 onFlow
定义的流程,方法与运行使用 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 中的轨迹,您可以前往“检查”标签页,然后切换“开发/生产”开关。切换到“prod”后,它将从 Firestore 加载轨迹。