Cloud Functions for Firebase には、Genkit アクション(Flow)を使用して呼び出し可能関数を作成できる onCallGenkit
メソッドがあります。これらの関数は、genkit/beta/client
または Cloud Functions クライアント SDK で呼び出すことができます。この場合、認証情報が自動的に追加されます。
始める前に
- Genkit のフローのコンセプトと、フローを作成する方法を理解している必要があります。このページで説明する手順では、デプロイするフローがある程度定義されていることを前提としています。
- 以前に 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 で記述することを前提としています。
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)
Google AI がお住まいの地域で利用可能であることを確認します。
Google AI Studio を使用して Gemini API の API キーを生成します。
API キーを Cloud Secret Manager に保存します。
firebase functions:secrets:set GOOGLE_GENAI_API_KEY
このステップは、従量制となり得るサービスへのアクセスを許可する API キーが誤って漏洩するのを防ぐために重要です。
シークレットの管理の詳細については、機密性の高い構成情報の保存とアクセスをご覧ください。
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)
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
オプションを使用して、関数にアクセスできるオリジンを制御します。
デフォルトでは、すべての送信元からのリクエストを許可するように、呼び出し可能関数には 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