Firebase용 Cloud Functions에는 Genkit 작업(플로우)으로 호출 가능한 함수를 만들 수 있는 onCallGenkit
메서드가 있습니다. 이러한 함수는 genkit/beta/client
또는 인증 정보를 자동으로 추가하는 Cloud Functions 클라이언트 SDK를 사용하여 호출할 수 있습니다.
시작하기 전에
- Genkit의 플로우 개념과 이를 작성하는 방법을 숙지해야 합니다. 이 페이지의 안내에서는 배포하려는 일부 플로우를 이미 정의했다고 가정합니다.
- 이전에 Firebase용 Cloud Functions를 사용한 적이 있다면 도움이 되지만 필수는 아닙니다.
Firebase 프로젝트 설정
Firebase Console을 사용하여 새 Firebase 프로젝트를 만들거나 기존 프로젝트를 선택합니다.
Cloud Functions 프로덕션 배포에 필요한 Blaze 요금제로 프로젝트를 업그레이드합니다.
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 키를 생성합니다.
Cloud Secret Manager에 API 키를 저장합니다.
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 사용자 역할이 부여되었는지 확인합니다.
이 튜토리얼에서 설정해야 하는 유일한 보안 비밀은 모델 제공업체이지만, 일반적으로 플로우에서 사용하는 각 서비스에 대해 유사한 작업을 수행해야 합니다.
(선택사항) 앱 체크 적용 추가
Firebase 앱 체크는 네이티브 증명을 사용하여 API가 애플리케이션에서만 호출되는지 확인합니다.
onCallGenkit
는 선언적으로 앱 체크 적용을 지원합니다.
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