Cloud Functions for Firebase には、Genkit アクション(Flow など)を使用して呼び出し可能な関数をすばやく作成できる onCallGenkit
メソッドがあります。これらの関数は、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 がお住まいの地域で利用可能であることを確認します。
Google AI Studio を使用して Gemini API の API キーを生成します。
API キーを Cloud Secret Manager に保存します。
firebase functions:secrets:set GOOGLE_GENAI_API_KEY
このステップは、課金対象となる可能性のあるサービスへのアクセスを許可する API キーが誤って漏洩するのを防ぐために重要です。
シークレットの管理の詳細については、機密性の高い構成情報の保存とアクセスをご覧ください。
src/index.ts
を編集し、既存のインポートの後に次を追加します。import {defineSecret} from "firebase-functions/params"; const googleAIapiKey = defineSecret("GOOGLE_GENAI_API_KEY");
次に、フロー定義で、Cloud Functions の関数にこのシークレット値へのアクセス権が必要であることを宣言します。
export const generatePoem = onCallGenkit({ secrets: [googleAIapiKey] }, generatePoemFlow);
この関数をデプロイすると、API キーは Cloud Secret Manager に保存され、Cloud Functions 環境から使用できるようになります。
Gemini(Vertex AI)
Cloud コンソールで、Firebase プロジェクトの Vertex AI API を有効にする。
[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
オプションを使用します。適切な認証(特に 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
などでデプロイされたエンドポイントにアクセスすることはできません。次のセクションでは、フローへの安全なアクセス方法について説明します。
省略可: デプロイされたフローを試す
フロー エンドポイントを試すには、次の最小限の例のウェブアプリをデプロイします。
Firebase コンソールの [プロジェクト設定] セクションで、新しいウェブアプリを追加し、ホスティングも設定するオプションを選択します。
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>
ウェブアプリと Cloud Functions の関数をデプロイします。
cd $PROJECT_ROOT
firebase deploy
deploy
コマンドで出力された URL にアクセスして、ウェブアプリを開きます。このアプリでは、Google アカウントでログインする必要があります。ログインすると、エンドポイント リクエストを開始できます。
省略可: デベロッパー UI でフローを実行する
onCallGenkit
を使用して定義されたフローは、defineFlow
を使用して定義されたフローを実行する場合とまったく同じ方法で、デベロッパー UI で実行できます。そのため、デプロイと開発の間で切り替える必要はありません。
cd $PROJECT_ROOT/functions
npx genkit start -- npx tsx --watch src/index.ts
または
cd $PROJECT_ROOT/functions
npm run genkit:start
これで、genkit start
コマンドで出力された URL に移動してアクセスできるようになりました。
省略可: Firebase Local Emulator Suite を使用した開発
Firebase には、Genkit で使用できるローカル開発用のエミュレータ スイートが用意されています。
Firebase Emulator Suite で Genkit Dev UI を使用するには、次のように Firebase エミュレータを起動します。
npx genkit start -- firebase emulators:start --inspect-functions
このコマンドは、エミュレータでコードを実行し、Genkit フレームワークを開発モードで実行します。これにより、Genkit リフレクション API が起動され、公開されます(ただし、Dev UI は公開されません)。
デベロッパー UI で Firestore のトレースを表示するには、[検査] タブに移動し、[Dev/Prod] スイッチを切り替えます。[prod] に切り替えると、Firestore からトレースが読み込まれます。