Genkit con Firebase Cloud Functions

Firebase Genkit incluye un complemento que te ayuda a implementar tus flujos en Firebase Cloud Functions. En esta página, se explica el proceso de implementación del flujo de muestra predeterminado en Firebase.

Implementa un flujo como una Cloud Function

  1. Instala las herramientas necesarias:

    1. Asegúrate de usar Node.js 20 o una versión posterior (ejecuta node --version para verificarlo).

    2. Instala Firebase CLI.

  2. Crea un proyecto nuevo de Firebase con Firebase console o selecciona uno existente.

    Actualizar el proyecto al plan Blaze, que es necesario para implementar Cloud Functions.

  3. Accede con Firebase CLI:

    firebase login
    firebase login --reauth # alternative, if necessary
    firebase login --no-localhost # if running in a remote shell
    
  4. Crea un directorio de proyecto nuevo:

    export PROJECT_ROOT=~/tmp/genkit-firebase-project1
    mkdir -p $PROJECT_ROOT
    
  5. Inicializa un proyecto de Firebase con Genkit en la carpeta:

    cd $PROJECT_ROOT
    firebase init genkit
    
    • Selecciona el proyecto que creaste anteriormente.
    • Selecciona el proveedor de modelos que deseas usar.

    Acepta los valores predeterminados para el resto de los mensajes. La herramienta genkit creará algunos archivos fuente de muestra para que comiences a desarrollar tus propios flujos de IA. Para el resto de este instructivo, solo implementarás el flujo de muestra.

  6. Haz que las credenciales de la API estén disponibles para tu Cloud Function. Según el proveedor de modelos que hayas elegido, realiza una de las siguientes acciones:

    Gemini (IA de Google)

    1. Asegúrate de que la IA de Google esté disponible en tu región.

    2. Genera una clave de API para la API de Gemini con Google AI Studio.

    3. Establece la variable de entorno GOOGLE_GENAI_API_KEY en tu clave:

      export GOOGLE_GENAI_API_KEY=<your API key>
      
    4. Edita src/index.ts y agrega lo siguiente después de las importaciones existentes:

    import {defineSecret} from "firebase-functions/params";
    defineSecret("GOOGLE_GENAI_API_KEY");
    

    Ahora, cuando implementes esta función, tu clave de API se almacenará en Cloud Secret Manager y estará disponible en el entorno de Cloud Functions.

    Gemini (Vertex AI)

    1. En la consola de Cloud, habilita la API de Vertex AI para tu proyecto de Firebase.

    2. En la página IAM, asegúrate de que a la cuenta de servicio de procesamiento predeterminada se le otorgue el rol de Usuario de Vertex AI.

    3. Opcional: Si deseas ejecutar tu flujo de manera local, como en el siguiente paso, configura algunas variables de entorno adicionales y usa la herramienta gcloud para configurar las credenciales predeterminadas de la aplicación:

      export GCLOUD_PROJECT=<your project ID>
      export GCLOUD_LOCATION=us-central1
      gcloud auth application-default login
      

    El único secreto que debes configurar para este instructivo es el del proveedor del modelo, pero, en general, debes hacer algo similar para cada servicio que use tu flujo.

  7. Si accedes a tu flujo desde una app web (lo que crearás en la siguiente sección), en el parámetro httpsOptions, configura una política de CORS:

    export const menuSuggestionFlow = onFlow(
      {
        name: "menuSuggestionFlow",
        // ...
        httpsOptions: {cors: true}, // Add this line.
      },
      async (subject) => {
        // ...
      }
    );
    

    Es probable que quieras una política más restrictiva para las apps de producción, pero esto hará para este instructivo.

  8. Opcional: Prueba tu flujo en la IU para desarrolladores:

    1. Inicia la IU:

      cd $PROJECT_ROOT/functions
      genkit start
      
    2. En la IU del desarrollador (http://localhost:4000/), ejecuta el flujo:

      1. Haz clic en menuSugeririonFlow.

      2. En la pestaña Input JSON, proporciona un asunto para el modelo:

        "AI app developers"
        
      3. En la pestaña JSON de autenticación, proporciona un objeto auth simulado:

        {
          "uid": 0,
          "email_verified": true
        }
        
      4. Haz clic en Ejecutar.

  9. Si todo funciona como se esperaba hasta ahora, puedes implementar el flujo:

    cd $PROJECT_ROOT
    firebase deploy --only functions
    

Ya implementaste el flujo como una Cloud Function. Sin embargo, no podrás acceder al extremo implementado con curl o una versión similar, debido a la política de autorización del flujo. Continúa con la siguiente sección para aprender cómo acceder de forma segura al flujo.

Prueba el flujo implementado

Es fundamental que cada flujo que implementes establezca una política de autorización. Sin uno, cualquiera podría invocar tus flujos de IA generativa potencialmente costosos.

El flujo de muestra predeterminado tiene una política de autorización como la siguiente:

firebaseAuth((user) => {
  if (!user.email_verified) {
    throw new Error('Verified email required to run flow');
  }
});

Esta política usa el ayudante firebaseAuth() para permitir el acceso solo a los usuarios registrados de tu app con direcciones de correo electrónico verificadas. En el lado del cliente, debes configurar el encabezado Authorization: Bearer como un token de ID de Firebase que cumpla con tu política. Los SDK de cliente de Cloud Functions proporcionan métodos de funciones que admiten llamadas que automatizan este proceso.

Para probar tu extremo de flujo, puedes implementar la siguiente aplicación web mínima de ejemplo:

  1. En la sección Configuración del proyecto de Firebase console, agrega una app web nueva y selecciona la opción para configurar también Hosting.

  2. En la sección Authentication de Firebase console, habilita el proveedor de Google, que usarás en este ejemplo.

  3. En el directorio de tu proyecto, configura Firebase Hosting, donde implementarás la app de muestra:

    cd $PROJECT_ROOT
    firebase init hosting
    

    Acepta los valores predeterminados de todos los mensajes.

  4. Reemplaza public/index.html por lo siguiente:

    <!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="suggestMenuItem">Suggest a menu theme</button>
          <p id="menuItem"></p>
        </div>
        <script type="module">
          import { initializeApp } from 'https://www.gstatic.com/firebasejs/10.10.0/firebase-app.js';
          import {
            getAuth,
            onAuthStateChanged,
            GoogleAuthProvider,
            signInWithPopup,
          } from 'https://www.gstatic.com/firebasejs/10.10.0/firebase-auth.js';
          import {
            getFunctions,
            httpsCallable,
          } from 'https://www.gstatic.com/firebasejs/10.10.0/firebase-functions.js';
    
          const firebaseConfig = await fetch('/__/firebase/init.json');
          initializeApp(await firebaseConfig.json());
    
          async function generateMenuItem() {
            const menuSuggestionFlow = httpsCallable(
              getFunctions(),
              'menuSuggestionFlow'
            );
            const subject = document.querySelector('#subject').value;
            const response = await menuSuggestionFlow(subject);
            document.querySelector('#menuItem').innerText = response.data;
          }
    
          function signIn() {
            signInWithPopup(getAuth(), new GoogleAuthProvider());
          }
    
          document
            .querySelector('#signinBtn')
            .addEventListener('click', signIn);
          document
            .querySelector('#suggestMenuItem')
            .addEventListener('click', generateMenuItem);
    
          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>
    
  5. Implementa la app web y la Cloud Function:

    cd $PROJECT_ROOT
    firebase deploy
    

Para abrir la app web, visita la URL impresa por el comando deploy. La app requiere que accedas con una Cuenta de Google. Después de eso, podrás iniciar solicitudes de extremos.

Cómo desarrollar con Firebase Local Emulator Suite

Firebase ofrece un paquete de emuladores para el desarrollo local que puedes usar con Genkit.

Para usar Genkit con Firebase Emulator Suite, inicia los emuladores de Firebase de la siguiente manera:

GENKIT_ENV=dev firebase emulators:start --inspect-functions

Esto ejecutará tu código en el emulador y el framework de Genkit en modo de desarrollo, que inicia y expone la API de reflexión de Genkit (pero no la IU para desarrolladores).

Luego, inicia la IU de Genkit Dev con la opción --attach para conectarla al código que se ejecuta en el emulador de Firebase:

genkit start --attach http://localhost:3100 --port 4001

Para ver los seguimientos de Firestore en la IU para desarrolladores, puedes navegar a la pestaña Inspeccionar y activar el interruptor “Dev/Prod”. Si activas la opción “prod”, se cargarán seguimientos desde Firestore.