écrits/tutorial/2026/06
Tutorial1 juin 2026·30 min

Google Genkit 1.0 : Construire des Flows et Agents IA en Production avec Next.js

Apprenez à construire des applications IA prêtes pour la production avec Google Genkit 1.0, Next.js et TypeScript. Ce tutoriel couvre les flows typés, les outils personnalisés, le middleware, le streaming et le déploiement.

Prérequis

Avant de commencer, assurez-vous de disposer de :

  • Node.js 20 ou supérieur
  • Un projet Next.js 15 (ou créez-en un avec create-next-app)
  • Une clé API Google AI depuis Google AI Studio
  • Des bases en TypeScript
  • Une familiarité avec le App Router de Next.js

Ce que vous allez construire

Dans ce tutoriel, vous créerez une API d'assistant de contenu intelligent alimentée par Google Genkit 1.0. Elle comprendra :

  • Flows typés — des workflows composables et observables avec validation des entrées/sorties
  • Outils personnalisés — des fonctions que votre IA peut appeler pour récupérer des données réelles
  • Middleware — logique de réessai, basculement de modèle et interception de requêtes (nouveau en mai 2026)
  • Streaming — des réponses en temps réel pour une meilleure expérience utilisateur
  • Routes API Next.js — des endpoints prêts pour la production via @genkit-ai/next

Qu'est-ce que Google Genkit ?

Google Genkit est un framework TypeScript open source de Firebase pour construire des applications alimentées par l'IA. Il a atteint sa version stable 1.0 fin 2024 et s'est fortement développé en 2025–2026, avec notamment :

  • Une interface unifiée pour les modèles de Google, OpenAI, Anthropic, Ollama et bien d'autres
  • Un support natif des flows, pipelines RAG et agents autonomes
  • Un système de Middleware composable (annoncé en mai 2026) pour renforcer les pipelines IA
  • Une interface de développeur interactive pour tester les flows et inspecter les traces
  • Des SDK officiels pour Next.js, Angular et les plateformes mobiles

Contrairement aux frameworks d'orchestration plus lourds, Genkit est léger et conçu pour s'intégrer naturellement dans les backends Node.js existants.

Étape 1 : Initialisation du projet

Si vous n'avez pas encore de projet Next.js, créez-en un :

npx create-next-app@latest genkit-demo --typescript --tailwind --app
cd genkit-demo

Installez Genkit et ses plugins :

npm install genkit @genkit-ai/google-genai @genkit-ai/next @genkit-ai/middleware
npm install -D genkit-cli

Définissez votre clé API dans .env.local :

GOOGLE_GENAI_API_KEY=your_api_key_here

Ne committez jamais votre fichier .env.local dans votre dépôt. Vérifiez qu'il est bien présent dans votre .gitignore.

Étape 2 : Initialiser Genkit

Créez une instance Genkit partagée réutilisée dans tous vos flows. Créez lib/genkit.ts :

import { genkit } from 'genkit';
import { googleAI } from '@genkit-ai/google-genai';
 
export const ai = genkit({
  plugins: [
    googleAI({
      apiKey: process.env.GOOGLE_GENAI_API_KEY,
    }),
  ],
  model: 'googleai/gemini-2.5-flash',
});

Cela crée une instance singleton ai configurée avec le plugin Google AI. La propriété model définit le modèle par défaut pour tous les appels ai.generate() qui ne spécifient pas de modèle explicitement.

Vous pouvez basculer vers n'importe quel fournisseur supporté — @genkit-ai/openai, @genkit-ai/anthropic ou @genkit-ai/ollama — en changeant uniquement le plugin et le nom du modèle. Le code de vos flows reste identique.

Étape 3 : Définir votre premier flow

Les flows sont des fonctions typées qui encapsulent la logique IA avec observabilité, validation des types et support du streaming. Créez lib/flows/summarize.ts :

import { z } from 'genkit';
import { ai } from '../genkit';
 
export const summarizeFlow = ai.defineFlow(
  {
    name: 'summarize',
    inputSchema: z.object({
      text: z.string().min(1).describe('Texte à résumer'),
      maxWords: z.number().optional().default(150),
    }),
    outputSchema: z.object({
      summary: z.string(),
      keyPoints: z.array(z.string()),
    }),
  },
  async (input) => {
    const result = await ai.generate({
      prompt: `Résumez le texte suivant en au plus ${input.maxWords} mots.
Retournez un objet JSON avec :
- summary : un paragraphe concis
- keyPoints : un tableau de 3 à 5 points clés
 
Texte : ${input.text}`,
      output: {
        schema: z.object({
          summary: z.string(),
          keyPoints: z.array(z.string()),
        }),
      },
    });
 
    return result.output!;
  }
);

Points importants à noter :

  • inputSchema et outputSchema utilisent Zod pour l'inférence de types TypeScript
  • Le flow est autonome et facilement testable de manière isolée
  • Genkit trace automatiquement chaque appel ai.generate() à l'intérieur d'un flow
  • Le hint .describe() sur text est transmis à l'interface de développeur

Étape 4 : Créer des outils personnalisés

Les outils permettent à votre IA d'appeler des fonctions externes — APIs REST, bases de données, ou tout code Node.js. Le modèle décide quand appeler un outil en fonction de sa description, et Genkit gère automatiquement la boucle d'exécution.

Créez lib/tools/weather.ts :

import { z } from 'genkit';
import { ai } from '../genkit';
 
export const weatherTool = ai.defineTool(
  {
    name: 'getWeather',
    description: "Récupère les conditions météo actuelles pour une ville donnée",
    inputSchema: z.object({
      city: z.string().describe('Nom de la ville'),
    }),
    outputSchema: z.object({
      temperature: z.number().describe('Température en Celsius'),
      condition: z.string().describe('Description des conditions météo'),
      humidity: z.number().describe('Taux d\'humidité en pourcentage'),
    }),
  },
  async ({ city }) => {
    const response = await fetch(
      `https://wttr.in/${encodeURIComponent(city)}?format=j1`
    );
    const data = await response.json();
    const current = data.current_condition[0];
    return {
      temperature: parseInt(current.temp_C),
      condition: current.weatherDesc[0].value,
      humidity: parseInt(current.humidity),
    };
  }
);

Créez maintenant un flow qui utilise cet outil dans lib/flows/weather-agent.ts :

import { z } from 'genkit';
import { ai } from '../genkit';
import { weatherTool } from '../tools/weather';
 
export const weatherAgentFlow = ai.defineFlow(
  {
    name: 'weatherAgent',
    inputSchema: z.object({
      query: z.string().describe('Question météo en langage naturel'),
    }),
    outputSchema: z.string(),
  },
  async (input) => {
    const result = await ai.generate({
      prompt: input.query,
      tools: [weatherTool],
    });
    return result.text;
  }
);

Lorsque ce flow s'exécute, Genkit gère l'intégralité de la boucle d'appel d'outils : le modèle demande les données météo, Genkit exécute l'outil, puis renvoie le résultat au modèle jusqu'à obtenir une réponse finale en langage naturel.

Étape 5 : Ajouter le Middleware

Le package @genkit-ai/middleware (annoncé en mai 2026) ajoute une couche d'interception composable autour de vos pipelines IA. Il supporte trois types de hooks :

  • hooks generate — logique au niveau de la conversation
  • hooks model — réessais et basculements pour chaque appel de modèle
  • hooks tool — approbations et sandboxing avant l'exécution des outils

Mettez à jour lib/genkit.ts pour ajouter la logique de réessai, le basculement automatique et la journalisation :

import { genkit } from 'genkit';
import { googleAI } from '@genkit-ai/google-genai';
import { withRetry, withFallback, withLogging } from '@genkit-ai/middleware';
 
export const ai = genkit({
  plugins: [
    googleAI({ apiKey: process.env.GOOGLE_GENAI_API_KEY }),
  ],
  model: 'googleai/gemini-2.5-flash',
  middleware: [
    withLogging({ logLevel: 'info' }),
    withRetry({
      maxAttempts: 3,
      backoff: 'exponential',
      initialDelayMs: 500,
    }),
    withFallback({
      fallbackModel: 'googleai/gemini-flash-latest',
      onError: (error) => error.code === 'QUOTA_EXCEEDED',
    }),
  ],
});

Cette configuration vous apporte :

  1. Des logs structurés pour chaque requête et réponse IA
  2. Jusqu'à 3 réessais automatiques avec backoff exponentiel sur les erreurs transitoires
  3. Un basculement transparent vers gemini-flash-latest en cas de dépassement de quota

Le middleware s'applique globalement à tous les flows qui utilisent cette instance ai. Pour un middleware spécifique à un flow, passez un tableau middleware directement à ai.defineFlow().

Étape 6 : Intégration des routes API Next.js

Le package @genkit-ai/next fournit appRoute, un helper qui transforme un flow Genkit en handler Next.js App Router sans boilerplate.

Créez app/api/summarize/route.ts :

import { appRoute } from '@genkit-ai/next';
import { summarizeFlow } from '@/lib/flows/summarize';
 
export const POST = appRoute(summarizeFlow);

Créez app/api/weather/route.ts :

import { appRoute } from '@genkit-ai/next';
import { weatherAgentFlow } from '@/lib/flows/weather-agent';
 
export const POST = appRoute(weatherAgentFlow);

Le handler appRoute gère automatiquement :

  • L'analyse et la validation du corps JSON par rapport à inputSchema
  • Le retour d'un JSON valide correspondant à outputSchema
  • Le streaming des réponses quand le flow utilise streamingCallback
  • Les réponses d'erreur HTTP appropriées en cas d'échec de validation

Testez l'endpoint avec curl :

curl -X POST http://localhost:3000/api/summarize \
  -H "Content-Type: application/json" \
  -d '{
    "text": "L'\''intelligence artificielle transforme le développement logiciel à une vitesse sans précédent...",
    "maxWords": 80
  }'

Étape 7 : Streaming des réponses

Pour les flows longs ou les interactions de type chat, vous pouvez diffuser la sortie vers le client en temps réel. Créez lib/flows/stream-chat.ts :

import { z } from 'genkit';
import { ai } from '../genkit';
 
export const streamChatFlow = ai.defineFlow(
  {
    name: 'streamChat',
    inputSchema: z.object({
      message: z.string().describe('Message utilisateur'),
    }),
    outputSchema: z.string(),
    streamSchema: z.string(),
  },
  async (input, streamingCallback) => {
    const result = await ai.generate({
      prompt: input.message,
      onChunk: (chunk) => {
        if (streamingCallback && chunk.text) {
          streamingCallback(chunk.text);
        }
      },
    });
    return result.text;
  }
);

Créez app/api/chat/route.ts :

import { appRoute } from '@genkit-ai/next';
import { streamChatFlow } from '@/lib/flows/stream-chat';
 
export const POST = appRoute(streamChatFlow, { streaming: true });

Côté client, consommez le stream :

async function streamChat(message: string, onChunk: (text: string) => void) {
  const response = await fetch('/api/chat', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ message }),
  });
 
  const reader = response.body?.getReader();
  const decoder = new TextDecoder();
 
  while (reader) {
    const { done, value } = await reader.read();
    if (done) break;
    onChunk(decoder.decode(value, { stream: true }));
  }
}

Étape 8 : Interface de développeur et traçage

Genkit est livré avec une interface de développeur interactive pour tester les flows, inspecter les traces et comparer les sorties des modèles sans toucher au frontend.

Ouvrez un second terminal en parallèle de npm run dev :

npx genkit start -- npx tsx --watch lib/genkit.ts

L'interface s'ouvre sur http://localhost:4000 et propose :

  • Flow Runner — exécutez n'importe quel flow enregistré avec des entrées personnalisées
  • Model Playground — envoyez des prompts directement à n'importe quel modèle configuré
  • Trace Explorer — inspectez chaque appel generate() avec entrées/sorties, latences et compteurs de tokens
  • Tool Inspector — testez les schémas des outils et simulez leurs réponses

Utilisez le Trace Explorer pendant le développement pour comprendre la consommation de tokens de chaque flow. Cela vous aide à optimiser les prompts avant de déployer en production où les coûts sont réels.

Étape 9 : Déploiement en production

Vercel

Ajoutez la variable d'environnement dans les paramètres de votre projet Vercel :

GOOGLE_GENAI_API_KEY=your_production_key

Puis déployez normalement :

npx vercel --prod

Firebase App Hosting ou Cloud Run

Pour une intégration approfondie avec le monitoring, ajoutez le plugin Firebase :

import { firebaseApp } from '@genkit-ai/firebase';
 
export const ai = genkit({
  plugins: [
    googleAI({ apiKey: process.env.GOOGLE_GENAI_API_KEY }),
    firebaseApp(),
  ],
});

Le plugin Firebase envoie automatiquement les traces vers Cloud Logging et active le tableau de bord de monitoring dans la console Firebase, vous donnant les volumes de requêtes, les percentiles de latence et les taux d'erreur pour chaque flow.

Tester votre implémentation

Les flows Genkit sont de simples fonctions asynchrones, ce qui les rend faciles à tester unitairement. Créez __tests__/summarize.test.ts :

import { describe, it, expect } from 'vitest';
import { summarizeFlow } from '@/lib/flows/summarize';
 
describe('summarizeFlow', () => {
  it('retourne un résumé et des points clés', async () => {
    const result = await summarizeFlow({
      text: "L'IA transforme chaque industrie, de la santé à la finance.",
      maxWords: 50,
    });
 
    expect(result.summary).toBeTruthy();
    expect(result.keyPoints).toBeInstanceOf(Array);
    expect(result.keyPoints.length).toBeGreaterThanOrEqual(1);
  });
});

Exécutez les tests :

npx vitest run

Résolution des problèmes courants

GOOGLE_GENAI_API_KEY introuvable au démarrage

Vérifiez que la clé est définie dans .env.local pour le développement local. Sur Vercel, consultez la section Environment Variables dans les paramètres du projet.

La sortie du flow ne correspond pas au schéma

Activez output.strict: true dans ai.generate() pour lever une exception quand le modèle retourne un JSON malformé. Ajoutez des hints .describe() à vos champs Zod pour guider le modèle.

La boucle d'appel d'outils ne se termine pas

Définissez maxTurns dans ai.generate() pour limiter le nombre d'itérations :

const result = await ai.generate({
  prompt: input.query,
  tools: [weatherTool],
  maxTurns: 5,
});

Le streaming ne fonctionne pas sur Vercel

Ajoutez export const dynamic = 'force-dynamic' dans votre fichier de route pour empêcher Vercel de l'optimiser statiquement, et assurez-vous d'être sur un plan Pro ou supérieur qui supporte le streaming.

Prochaines étapes

Avec Genkit en place, vous pouvez étendre votre application dans plusieurs directions :

  • Pipelines RAG — utilisez ai.defineRetriever avec Pinecone ou Cloud Firestore pour ajouter une recherche documentaire à vos flows
  • Agents multi-étapes — enchaînez des flows pour des tâches de raisonnement complexes
  • Évaluation — utilisez @genkit-ai/evaluation pour noter automatiquement les sorties des flows
  • Gestion des prompts — stockez des prompts versionnés dans Firestore via ai.definePrompt
  • Extension Genkit pour Gemini CLI — déboguez et exécutez des flows directement depuis votre terminal

Conclusion

Google Genkit 1.0 offre une base solide et prête pour la production pour construire des applications alimentées par l'IA en TypeScript. Sa combinaison de flows typés, du nouveau système de Middleware composable et de l'intégration native avec Next.js en fait l'un des frameworks IA les plus pratiques disponibles pour les développeurs JavaScript aujourd'hui. Que vous construisiez un simple endpoint de résumé ou un agent multi-étapes complexe avec appels d'outils, Genkit vous donne l'observabilité et la structure nécessaires pour livrer avec confiance et itérer rapidement.