Firebase용 Cloud Functions에는 Genkit 작업 (예: Flow)으로 호출 가능한 함수를 빠르게 만들 수 있는 onCallGenkit
메서드가 있습니다. 이러한 함수는 genkit/beta/client
또는 인증 정보를 자동으로 추가하는 Functions 클라이언트 SDK를 사용하여 호출할 수 있습니다.
시작하기 전에
- Genkit의 흐름 개념과 이를 작성하는 방법을 숙지해야 합니다. 이 페이지의 안내는 배포하려는 흐름이 이미 정의되어 있다고 가정합니다.
- 이전에 Firebase용 Cloud Functions를 사용한 적이 있으면 도움이 되지만 필수는 아닙니다.
1. Firebase 프로젝트 설정
TypeScript 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 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 키를 생성합니다.
Cloud Secret Manager에 API 키를 저장합니다.
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 함수가 이 보안 비밀 값에 액세스해야 한다고 선언합니다.
export const generatePoem = onCallGenkit({ secrets: [googleAIapiKey] }, generatePoemFlow);
이제 이 함수를 배포하면 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 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 함수로 배포했습니다. 하지만 흐름의 승인 정책으로 인해 curl
등으로 배포된 엔드포인트에 액세스할 수 없습니다. 다음 섹션에서는 흐름에 안전하게 액세스하는 방법을 설명합니다.
선택사항: 배포된 흐름 사용해 보기
흐름 엔드포인트를 사용해 보려면 다음과 같은 최소한의 웹 앱 예시를 배포하면 됩니다.
Firebase Console의 프로젝트 설정 섹션에서 새 웹 앱을 추가하고 호스팅도 설정하는 옵션을 선택합니다.
Firebase Console의 인증 섹션에서 이 예에서 사용된 Google 제공업체를 사용 설정합니다.
프로젝트 디렉터리에서 샘플 앱을 배포할 Firebase 호스팅을 설정합니다.
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 함수를 배포합니다.
cd $PROJECT_ROOT
firebase deploy
deploy
명령어로 출력된 URL을 방문하여 웹 앱을 엽니다. 앱을 사용하려면 Google 계정으로 로그인해야 하며, 로그인한 후 엔드포인트 요청을 시작할 수 있습니다.
선택사항: 개발자 UI에서 흐름 실행
defineFlow
를 사용하여 정의된 흐름을 실행하는 것과 정확히 동일한 방식으로 개발자 UI에서 onCallGenkit
를 사용하여 정의된 흐름을 실행할 수 있으므로 배포와 개발 간에 두 가지 간에 전환할 필요가 없습니다.
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 로컬 에뮬레이터 도구 모음을 사용한 개발
Firebase는 Genkit과 함께 사용할 수 있는 로컬 개발용 에뮬레이터 모음을 제공합니다.
Firebase 에뮬레이터 모음에서 Genkit Dev UI를 사용하려면 다음과 같이 Firebase 에뮬레이터를 시작합니다.
npx genkit start -- firebase emulators:start --inspect-functions
이 명령어는 에뮬레이터에서 코드를 실행하고 개발 모드에서 Genkit 프레임워크를 실행합니다. 이렇게 하면 Genkit 반사 API가 실행되고 노출되지만 개발자 UI는 노출되지 않습니다.
개발 UI에서 Firestore의 트레이스를 보려면 검사 탭으로 이동하여 Dev/Prod 스위치를 전환하면 됩니다. prod로 전환하면 Firestore에서 트레이스를 로드합니다.