Richiamare i flussi Genkit dalla tua app

Cloud Functions for Firebase dispone di un metodo onCallGenkit che ti consente di creare una funzione richiamabile con un'azione Genkit (un flusso). Queste funzioni possono essere chiamate con genkit/beta/client o con gli SDK client di Cloud Functions, che aggiungono automaticamente le informazioni di autenticazione.

Prima di iniziare

  • Dovresti conoscere il concetto di flussi di Genkit e come scriverli. Le istruzioni riportate in questa pagina presuppongono che tu abbia già definito alcuni flussi da eseguire.
  • È utile, ma non obbligatorio, se hai già utilizzato Cloud Functions for Firebase.

Configurare un progetto Firebase

  1. Crea un nuovo progetto Firebase utilizzando la console Firebase o scegline uno esistente.

  2. Esegui l'upgrade del progetto al piano Blaze, necessario per il deployment di produzione di Cloud Functions.

  3. Installa l'interfaccia a riga di comando di Firebase.

  4. Accedi con l'interfaccia a riga di comando di Firebase:

    firebase login
    firebase login --reauth # alternative, if necessary
    firebase login --no-localhost # if running in a remote shell
  5. Crea una nuova directory del progetto:

    export PROJECT_ROOT=~/tmp/genkit-firebase-project1
    mkdir -p $PROJECT_ROOT
  6. Inizializza un progetto Firebase nella directory:

    cd $PROJECT_ROOT
    firebase init functions

Il resto di questa pagina presuppone che tu abbia scelto di scrivere le funzioni in JavaScript.

Inserisci un a capo nel flusso in onCallGenkit

Dopo aver configurato un progetto Firebase con Cloud Functions, puoi copiare o scrivere le definizioni dei flussi nella directory functions del progetto. Ecco un flusso di esempio per dimostrare questo:

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;
},
);

Per eseguire il deployment di un flusso come questo, inseriscilo in onCallGenkit, disponibile in firebase-functions/https. Questo metodo di supporto ha tutte le funzionalità delle funzioni callable e supporta automaticamente sia le risposte JSON che quelle in streaming.

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,
);

Rendi disponibili le credenziali API per i flussi di cui è stato eseguito il deployment

Una volta dipesi, i flussi devono avere un modo per autenticarsi con gli eventuali servizi remoti su cui si basano. Come minimo, la maggior parte dei flussi richiede le credenziali per accedere al servizio API model che utilizza.

Per questo esempio, esegui una delle seguenti operazioni, a seconda del fornitore di modelli scelto:

Gemini (IA di Google)

  1. Assicurati che l'AI di Google sia disponibile nella tua regione.

  2. Genera una chiave API per l'API Gemini utilizzando Google AI Studio.

  3. Memorizza la chiave API in Cloud Secret Manager:

    firebase functions:secrets:set GOOGLE_GENAI_API_KEY

    Questo passaggio è importante per evitare la fuga accidentale della chiave API, che consente di accedere a un servizio potenzialmente a pagamento.

    Per ulteriori informazioni sulla gestione dei secret, consulta Archiviare e accedere a informazioni di configurazione sensibili.

  4. Modifica src/index.js e aggiungi quanto segue dopo le importazioni esistenti:

    const {defineSecret} = require("firebase-functions/params");
    // Store the Gemini API key in Cloud Secret Manager.
    const apiKey = defineSecret("GOOGLE_GENAI_API_KEY");
    

    Poi, nella definizione della funzione richiamabile, dichiara che la funzione deve accedere a questo valore segreto:

    // Bind the Gemini API key secret parameter to the function.
    secrets: [apiKey],
    

Ora, quando esegui il deployment di questa funzione, la chiave API verrà archiviata in Cloud Secret Manager e sarà disponibile nell'ambiente Cloud Functions.

Gemini (Vertex AI)

  1. Nella console Cloud, abilita l'API Vertex AI per il tuo progetto Firebase.

  2. Nella pagina IAM, assicurati che all'account di servizio Compute predefinito sia stato concesso il ruolo Utente Vertex AI.

L'unico segreto che devi configurare per questo tutorial è per il provider del modello, ma in generale devi eseguire un'operazione simile per ogni servizio utilizzato dal flusso.

(Facoltativo) Aggiungere l'applicazione forzata di App Check

Firebase App Check utilizza l'attestazione nativa per verificare che la tua API venga chiamata solo dalla tua applicazione. onCallGenkit supporta l'applicazione di App Check in modo dichiarativo.

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);

Configurare CORS (Cross-Origin Resource Sharing)

Utilizza l'opzione cors per controllare le origini che possono accedere alla funzione.

Per impostazione predefinita, le funzioni richiamabili hanno CORS configurato per consentire le richieste da tutte le origini. Per consentire alcune richieste cross-origin, ma non tutte, passa un elenco di domini o espressioni regolari specifici che devono essere consentiti. Ad esempio:

export const tellJoke = onCallGenkit({
  cors: 'mydomain.com',
}, jokeTeller);

Esempio completo

Dopo aver apportato tutte le modifiche descritte sopra, il flusso di deployment sarà simile all'esempio seguente:

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,
);

Esegui il deployment dei flussi in Firebase

Dopo aver definito i flussi utilizzando onCallGenkit, puoi eseguirne il deployment come faresti con altre funzioni:

cd $PROJECT_ROOT
firebase deploy --only functions