O Genkit inclui um plug-in que ajuda a implantar seus fluxos no Cloud Functions para Firebase. Depois de implantados, os fluxos ficam disponíveis como endpoints HTTPS e acessíveis como funções acionáveis usando as bibliotecas de cliente do Cloud Functions.
Antes de começar
- Instale a CLI do Firebase.
- Você precisa conhecer o conceito de fluxos do Genkit e saber como programá-los. As instruções nesta página pressupõem que você já tenha alguns fluxos definidos que quer implantar.
- Ter experiência com o Cloud Functions para Firebase é útil, mas não obrigatório.
1. Configurar um projeto do Firebase
Se você ainda não tiver um projeto do Firebase com o TypeScript Cloud Functions configurado, siga estas etapas:
Crie um novo projeto do Firebase usando o console do Firebase ou escolha um projeto atual.
Faça upgrade do projeto para o plano Blaze, que é necessário para implantar o Cloud Functions.
Faça login com a CLI do Firebase:
firebase login
firebase login --reauth # alternative, if necessary
firebase login --no-localhost # if running in a remote shell
Crie um novo diretório do projeto:
export PROJECT_ROOT=~/tmp/genkit-firebase-project1
mkdir -p $PROJECT_ROOT
Inicialize um projeto do Firebase no diretório:
cd $PROJECT_ROOT
firebase init genkit
O restante desta página pressupõe que você selecionou escrever suas funções em TypeScript, mas também é possível implantar seus fluxos do Genkit se você estiver usando JavaScript.
2. Atualizar definições de fluxo
Depois de configurar um projeto do Firebase com o Cloud Functions, é possível copiar ou
escrever definições de fluxo no diretório functions/src
do projeto e exportá-las
em index.ts
.
Para implantar seus fluxos, é necessário fazer algumas pequenas mudanças na forma como você os define. A lógica principal vai permanecer a mesma, mas você vai adicionar algumas informações adicionais para facilitar a implantação e aumentar a segurança.
Suponha que você tenha o seguinte fluxo:
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;
}
);
As seções a seguir descrevem as mudanças que você precisa fazer antes de implantar.
Definir fluxos com onFlow
Em vez de definir seu fluxo com Genkit.defineFlow()
, use a função onFlow()
do plug-in
do Firebase. O uso dessa função envolve a lógica do fluxo em um
gerenciador de solicitações do Cloud Functions, semelhante a
onCall
.
import { onFlow } from "@genkit-ai/firebase/functions";
export const generatePoem = onFlow(
ai,
{
// ...
},
async (subject: string) => {
// ...
}
);
onFlow
não é um método de Genkit
, mas uma função que usa
uma instância de Genkit
como o primeiro parâmetro. Caso contrário, a sintaxe é semelhante a
defineFlow
.
Definir uma política de autorização
Todos os fluxos implantados, seja no Firebase ou não, precisam ter uma política de autorização. Sem ela, seus fluxos de IA generativa potencialmente caros podem ser invocados por qualquer pessoa. Para definir uma política de autorização, use o parâmetro authPolicy
na definição do fluxo:
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) => {
// ...
}
);
Essa política usa o auxiliar firebaseAuth()
para permitir o acesso apenas a usuários
registrados do app com endereços de e-mail verificados. No lado do cliente, é necessário
definir o cabeçalho Authorization: Bearer
como um token de ID do Firebase que atenda
à sua política. Os SDKs do cliente do Cloud Functions fornecem métodos de função chamável que automatizam isso. Consulte a seção Testar o fluxo implantado para conferir um exemplo.
Disponibilizar credenciais da API para fluxos implantados
Depois de implantados, os fluxos precisam de uma forma de autenticação com os serviços remotos em que eles dependem. A maioria dos fluxos precisa, no mínimo, de credenciais para acessar o serviço de API de modelo que eles usam.
Para este exemplo, siga um destes procedimentos, dependendo do provedor de modelos escolhido:
Gemini (IA do Google)
Verifique se a IA do Google está disponível na sua região.
Gere uma chave de API para à API Gemini usando o Google AI Studio.
Armazene sua chave de API no Cloud Secret Manager:
firebase functions:secrets:set GOOGLE_GENAI_API_KEY
Essa etapa é importante para evitar o vazamento acidental da chave de API, que concede acesso a um serviço potencialmente medido.
Consulte Armazenar e acessar informações de configuração sensíveis para mais informações sobre como gerenciar secrets.
Edite
src/index.ts
e adicione o seguinte após as importações atuais:import {defineSecret} from "firebase-functions/params"; const googleAIapiKey = defineSecret("GOOGLE_GENAI_API_KEY");
Em seguida, na definição do fluxo, declare que a função do Cloud precisa ter acesso a esse valor secreto:
export const generatePoem = onFlow( { name: "generatePoem", // ... httpsOptions: { secrets: [googleAIapiKey], // Add this line. }, }, async (subject) => { // ... } );
Agora, quando você implantar essa função, a chave da API será armazenada no Cloud Secret Manager e estará disponível no ambiente do Cloud Functions.
Gemini (Vertex AI)
No console do Cloud, ative a API Vertex AI para seu projeto do Firebase.
Na página IAM, verifique se a conta de serviço padrão do Compute tem o papel de Usuário da Vertex AI.
O único secret que você precisa configurar para este tutorial é para o provedor de modelo, mas, em geral, você precisa fazer algo semelhante para cada serviço que seu fluxo usa.
Definir uma política de CORS
Se você acessar o fluxo em um app da Web (o que será feito na seção Testar o fluxo implantado), defina uma política CORS no parâmetro httpsOptions
:
export const generatePoem = onFlow(
ai,
{
name: "generatePoem",
// ...
httpsOptions: {
cors: '*',
},
},
async (subject: string) => {
// ...
}
);
Você provavelmente vai querer uma política mais restritiva para apps de produção, mas isso serve para este tutorial.
Exemplo completo
Depois de fazer todas as mudanças descritas acima, o fluxo de implantação vai ficar parecido com este exemplo:
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. Implantar fluxos no Firebase
Depois de definir os fluxos usando onFlow
, você pode implantá-los como faria com outras funções do Cloud:
cd $PROJECT_ROOT
firebase deploy --only functions
Agora você implantou o fluxo como uma função do Cloud. No entanto, não será possível
acessar o endpoint implantado com curl
ou algo semelhante devido à política de
autorização do fluxo. Continue para a próxima seção para saber como acessar o fluxo
com segurança.
Opcional: testar o fluxo implantado
Para testar o endpoint do fluxo, implante o seguinte exemplo mínimo de app da Web:
Na seção Configurações do projeto do console do Firebase, adicione um novo app da Web, selecionando a opção para configurar também a Hospedagem.
Na seção Authentication do console do Firebase, ative o provedor Google, que será usado neste exemplo.
No diretório do projeto, configure o Firebase Hosting, onde você vai implantar o app de exemplo:
cd $PROJECT_ROOT
firebase init hosting
Aceite os padrões de todas as solicitações.
Substitua
public/index.html
por:<!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>
Implante o app da Web e a função do Cloud:
cd $PROJECT_ROOT
firebase deploy
Abra o app da Web acessando o URL impresso pelo comando deploy
. O app
exige que você faça login com uma Conta do Google. Depois disso, você pode iniciar
solicitações de endpoint.
Opcional: executar fluxos na interface do desenvolvedor
É possível executar fluxos definidos usando onFlow
na interface do desenvolvedor, da mesma
forma que você executa fluxos definidos usando defineFlow
. Portanto, não é necessário alternar
entre os dois entre a implantação e o desenvolvimento.
cd $PROJECT_ROOT/functions
npx genkit start -- npx tsx --watch src/index.ts
ou
cd $PROJECT_ROOT/functions
npm run genkit:start
Agora você pode acessar o URL impresso pelo comando genkit start
.
Opcional: como desenvolver usando o Pacote de emuladores locais do Firebase
O Firebase oferece um pacote de emuladores para desenvolvimento local, que pode ser usado com o Genkit.
Para usar a interface do desenvolvedor do Genkit com o Pacote de emuladores do Firebase, inicie os emuladores do Firebase desta forma:
npx genkit start -- firebase emulators:start --inspect-functions
Isso vai executar seu código no emulador e executar o framework do Genkit no modo de desenvolvimento, que inicia e expõe a API de reflexão do Genkit (mas não a interface do desenvolvedor).
Para conferir os rastros do Firestore na interface para desenvolvedores, acesse a guia "Inspecionar" e ative a chave "Desenv./Prod.". Quando definido como "prod", ele carrega rastros do Firestore.