Tutoriel Langfuse 2026 : Observabilité LLM et Gestion des Prompts pour Apps Next.js

Dès que votre application IA dépasse le stade du prototype, vous découvrez vite que console.log ne suffit plus. Il faut pouvoir répondre à des questions comme : quel prompt utilisateur a déclenché cette réponse défaillante, combien a coûté cette conversation, pourquoi la latence a-t-elle explosé à 3 h du matin, et quelle version de prompt obtient les meilleurs scores d'évaluation ?
Langfuse est la plateforme d'observabilité open-source conçue spécifiquement pour les applications LLM. Elle gère le tracing, le suivi des coûts et des tokens, le versioning des prompts, les évaluations et les retours utilisateurs. Dans ce tutoriel, vous allez brancher Langfuse sur une application Next.js 15 utilisant le Vercel AI SDK, capturer chaque appel LLM avec des métadonnées riches, gérer les prompts comme des artefacts de première classe, et construire des dashboards qui vous aideront vraiment à déboguer la production.
Prérequis
Avant de commencer, assurez-vous d'avoir :
- Node.js 20 ou plus récent
- Un projet Next.js 15 (App Router) — ou vous pouvez en créer un à l'étape 1
- Une clé API OpenAI, Anthropic ou Google (n'importe quel fournisseur LLM fonctionne)
- Des bases en TypeScript et React Server Components
- Docker Desktop si vous voulez auto-héberger Langfuse (optionnel — Langfuse Cloud fonctionne aussi)
Ce que vous allez construire
À la fin de ce tutoriel, vous aurez :
- Une route de chat Next.js IA instrumentée avec des traces Langfuse
- Une capture automatique des tokens, coûts et latence pour chaque appel LLM
- Un registre de prompts où les non-développeurs peuvent éditer les prompts sans déploiement
- Un scoring de feedback utilisateur (pouces haut / bas) rattaché aux traces
- Un pipeline d'évaluation qui note les sorties avec un LLM-juge
- Des dashboards et alertes prêts pour la production
Commençons.
Étape 1 : Choisir Cloud ou Auto-hébergé
Langfuse propose deux modes de déploiement. Choisissez-en un :
Option A — Langfuse Cloud (le plus rapide) : inscrivez-vous sur cloud.langfuse.com, créez un projet et récupérez les clés API publique et secrète. L'offre gratuite couvre 50 000 observations par mois, largement suffisant pour le développement.
Option B — Auto-hébergé (plus de contrôle) : lancez la stack Docker Compose officielle en local ou sur votre VPS. Clonez le dépôt et démarrez :
git clone https://github.com/langfuse/langfuse.git
cd langfuse
docker compose up -dLangfuse sera disponible sur http://localhost:3000. Créez un compte, créez un projet, et copiez les clés depuis la page de paramètres du projet.
Pour ce tutoriel, nous supposerons l'option Cloud, mais chaque exemple de code fonctionne à l'identique en auto-hébergé — seule la variable LANGFUSE_BASEURL change.
Étape 2 : Créer l'application Next.js
Sautez cette étape si vous avez déjà un projet Next.js 15. Sinon :
npx create-next-app@latest langfuse-demo --typescript --app --tailwind
cd langfuse-demo
npm install ai @ai-sdk/openai zodAjoutez vos secrets dans .env.local :
OPENAI_API_KEY=sk-...
LANGFUSE_PUBLIC_KEY=pk-lf-...
LANGFUSE_SECRET_KEY=sk-lf-...
LANGFUSE_BASEURL=https://cloud.langfuse.comNe commitez jamais .env.local. Ajoutez-le à .gitignore s'il n'y est pas déjà.
Étape 3 : Installer le SDK Langfuse
Langfuse propose plusieurs SDK. Pour Next.js avec Vercel AI SDK, installez le SDK JS principal et l'intégration Vercel AI SDK :
npm install langfuse langfuse-vercelLe paquet langfuse-vercel fournit un exporter de télémétrie qui se branche automatiquement sur les spans OpenTelemetry du AI SDK. Aucun wrapping manuel de span requis.
Étape 4 : Initialiser le client Langfuse
Créez un client partagé dans lib/langfuse.ts :
import { Langfuse } from "langfuse";
export const langfuse = new Langfuse({
publicKey: process.env.LANGFUSE_PUBLIC_KEY!,
secretKey: process.env.LANGFUSE_SECRET_KEY!,
baseUrl: process.env.LANGFUSE_BASEURL,
flushAt: 1, // envoi immédiat pendant le développement
});
export async function flushLangfuse() {
await langfuse.flushAsync();
}Le réglage flushAt: 1 est idéal en développement, mais montez-le à 20 ou 50 en production pour batcher les appels réseau. Appelez toujours flushLangfuse() à la fin des handlers serverless — sinon, les événements peuvent être perdus lors du gel de la Lambda.
Étape 5 : Enregistrer l'exporter de télémétrie
Dans Next.js 15, l'instrumentation OpenTelemetry vit dans instrumentation.ts à la racine du projet. Créez-le :
import { registerOTel } from "@vercel/otel";
import { LangfuseExporter } from "langfuse-vercel";
export function register() {
registerOTel({
serviceName: "langfuse-demo",
traceExporter: new LangfuseExporter({
publicKey: process.env.LANGFUSE_PUBLIC_KEY,
secretKey: process.env.LANGFUSE_SECRET_KEY,
baseUrl: process.env.LANGFUSE_BASEURL,
}),
});
}Installez aussi le helper Vercel OpenTelemetry :
npm install @vercel/otel @opentelemetry/apiActivez la télémétrie dans next.config.js :
/** @type {import('next').NextConfig} */
const nextConfig = {
experimental: {
instrumentationHook: true,
},
};
module.exports = nextConfig;Sur Next.js 15.1 et plus récent, instrumentationHook est activé par défaut et ce flag devient inutile — vérifiez votre version de Next avant de l'ajouter.
Étape 6 : Construire une route de chat tracée
Créez app/api/chat/route.ts :
import { openai } from "@ai-sdk/openai";
import { streamText } from "ai";
import { after } from "next/server";
import { flushLangfuse } from "@/lib/langfuse";
export async function POST(req: Request) {
const { messages, userId, sessionId } = await req.json();
const result = streamText({
model: openai("gpt-4o-mini"),
messages,
experimental_telemetry: {
isEnabled: true,
functionId: "chat-completion",
metadata: {
langfuseUserId: userId ?? "anonymous",
langfuseSessionId: sessionId,
tags: ["production", "chat"],
},
},
});
after(async () => {
await flushLangfuse();
});
return result.toDataStreamResponse();
}Le bloc experimental_telemetry est la clé. Langfuse lit langfuseUserId, langfuseSessionId et tags depuis les métadonnées et les transforme en champs de première classe sur lesquels vous pouvez filtrer. Le helper after() de next/server déclenche le flush après l'envoi de la réponse, donc sans ralentir l'utilisateur.
Étape 7 : Tester votre première trace
Démarrez le serveur de dev et envoyez une requête :
npm run devPuis depuis un autre terminal :
curl -X POST http://localhost:3000/api/chat \
-H "Content-Type: application/json" \
-d '{
"messages": [{ "role": "user", "content": "Explique le retrieval augmented generation en un paragraphe." }],
"userId": "user-42",
"sessionId": "demo-session"
}'Ouvrez le dashboard Langfuse. En quelques secondes, vous devriez voir une nouvelle trace avec le prompt complet, la réponse streamée, le nom du modèle, le nombre de tokens et le coût total calculé depuis la table de tarification en direct. Cliquez sur la trace pour l'étendre et vous verrez tous les spans, y compris l'appel API OpenAI imbriqué à l'intérieur.
Étape 8 : Gérer les prompts comme des artefacts versionnés
Coder en dur les prompts dans le code source rend impossible leur itération sans déploiement. Langfuse résout cela avec un registre de prompts.
Allez dans Prompts sur le dashboard et créez un prompt nommé chat-system :
Tu es un assistant technique concis pour développeurs.
Réponds toujours en markdown. Pour le code, utilise des blocs avec un tag de langage.
Date actuelle : {{today}}
Langfuse stocke cela en version 1. Récupérez-le dans votre route :
import { langfuse } from "@/lib/langfuse";
async function buildSystemMessage() {
const prompt = await langfuse.getPrompt("chat-system", undefined, {
cacheTtlSeconds: 60,
});
const compiled = prompt.compile({
today: new Date().toISOString().split("T")[0],
});
return { role: "system" as const, content: compiled, promptRef: prompt };
}Puis passez la référence du prompt à experimental_telemetry pour que Langfuse lie la trace à la version exacte utilisée :
const system = await buildSystemMessage();
const result = streamText({
model: openai("gpt-4o-mini"),
messages: [{ role: "system", content: system.content }, ...messages],
experimental_telemetry: {
isEnabled: true,
functionId: "chat-completion",
metadata: {
langfusePrompt: system.promptRef.toJSON(),
},
},
});Maintenant, quand un collègue édite le prompt dans l'UI Langfuse, chaque nouvelle requête utilise la version mise à jour en moins de 60 secondes — sans déploiement. Et la page Prompts vous montre quelles versions sont actuellement en usage et comment chacune performe en latence et qualité.
Étape 9 : Capturer le feedback utilisateur
Une trace n'est que la moitié de l'histoire. Vous devez savoir si les utilisateurs ont apprécié la réponse. Ajoutez un endpoint de feedback :
// app/api/feedback/route.ts
import { langfuse } from "@/lib/langfuse";
import { after } from "next/server";
export async function POST(req: Request) {
const { traceId, value, comment } = await req.json();
langfuse.score({
traceId,
name: "user-feedback",
value: value === "up" ? 1 : 0,
dataType: "NUMERIC",
comment,
});
after(async () => {
await langfuse.flushAsync();
});
return Response.json({ ok: true });
}Côté frontend, affichez des boutons pouces haut / bas après chaque message de l'assistant et faites un POST vers /api/feedback avec le traceId que Langfuse a retourné dans les headers de réponse. Chaque trace a maintenant un signal de qualité que vous pouvez filtrer et regrouper.
Étape 10 : Ajouter des évaluations LLM-juge
Le feedback manuel est précieux mais rare. Pour scorer chaque conversation automatiquement, configurez un évaluateur LLM-juge.
Dans le dashboard Langfuse, allez dans Evaluations, créez un nouvel évaluateur et choisissez LLM-as-judge. Utilisez un template comme :
Note la réponse de l'assistant pour son utilité de 0 à 1.
Considère : répond-elle à la question ? Est-elle précise ? Est-elle concise ?
Question utilisateur : {{input}}
Réponse assistant : {{output}}
Retourne du JSON : { "score": number, "reasoning": string }
Sélectionnez les traces à scorer — par exemple, toutes les traces taguées production ces dernières 24 heures. Langfuse exécute l'évaluateur en arrière-plan et attache le score à chaque trace. Vous pouvez ensuite tracer la courbe d'utilité dans le temps, ventilée par version de prompt, pour valider que vos modifications améliorent vraiment la qualité.
Étape 11 : Construire un dashboard de production
L'onglet Dashboards permet de composer des graphiques sans écrire de SQL. Panneaux utiles à épingler :
- Coût par jour — détecter une dérive de dépenses tôt
- Latence P95 par modèle — attraper les modèles lents avant les plaintes
- Usage de tokens par userId — identifier les gros utilisateurs à rate-limiter
- Taux d'erreur par version de prompt — détecter les mauvais prompts tôt
- Score moyen d'utilité par jour — suivre la dérive de qualité
Ajoutez une alerte avec seuil sur le coût et le taux d'erreur. Langfuse peut pousser les alertes vers des webhooks Slack ou Discord quand un seuil est franchi.
Étape 12 : Utiliser les sessions pour grouper les conversations
Passer le même langfuseSessionId sur plusieurs requêtes les regroupe dans une vue unique de conversation. Inestimable pour déboguer les flux multi-tours. Dans votre frontend, générez un ID de session une fois par conversation (stockez-le dans l'état du composant ou un cookie) et incluez-le dans chaque requête /api/chat.
Langfuse affiche alors la timeline complète du fil, le coût cumulé de toute la conversation, et où la latence s'est accumulée d'un tour à l'autre.
Étape 13 : Masquer les PII avant envoi
Si votre app manipule des données personnelles, vous devez masquer les contenus sensibles avant qu'ils ne quittent votre serveur. Langfuse supporte une fonction de masquage :
import { Langfuse } from "langfuse";
export const langfuse = new Langfuse({
publicKey: process.env.LANGFUSE_PUBLIC_KEY!,
secretKey: process.env.LANGFUSE_SECRET_KEY!,
mask: (data) => {
if (typeof data !== "string") return data;
return data
.replace(/\b[\w.-]+@[\w.-]+\.\w+\b/g, "[EMAIL]")
.replace(/\b(\+?\d{1,3}[ -]?)?\(?\d{3}\)?[ -]?\d{3}[ -]?\d{4}\b/g, "[PHONE]");
},
});Le masque s'applique sur les entrées et sorties avant expédition de l'événement. Pour une conformité plus stricte, lancez un classifieur PII robuste comme Microsoft Presidio dans la fonction de masquage.
Étape 14 : Déployer en production
Quelques astuces de durcissement pour la production :
- Batcher les événements : montez
flushAtà 20 etflushIntervalà 5000 ms. Cela réduit drastiquement la charge réseau. - Gérer l'arrêt : sur Vercel, le helper
after()gère le flush. Sur un serveur Node long-running, enregistrezprocess.on("SIGTERM", flushLangfuse). - Séparation des environnements : utilisez un projet Langfuse différent par environnement (dev, staging, prod). Cela garde les dashboards propres.
- Rotation des secrets : les clés Langfuse peuvent être tournées dans les paramètres du projet sans downtime. Faites-le chaque trimestre.
- Échantillonnage : si votre volume est très élevé, utilisez
sampleRate: 0.1côté client pour ne capturer que 10 pourcent des traces. Vous pouvez toujours échantillonner plus sur des cohortes spécifiques.
Tester votre implémentation
Avant de livrer :
- Envoyez une requête de chat. Vérifiez qu'une trace apparaît avec la bonne version de prompt, le bon user id et session id.
- Soumettez un pouce haut. Vérifiez qu'un score s'attache à la trace.
- Simulez une erreur (désactivez temporairement la clé OpenAI). Vérifiez que Langfuse capture l'erreur avec la stack trace complète.
- Éditez le prompt dans l'UI Langfuse. Vérifiez que la requête suivante utilise la nouvelle version en moins de 60 secondes.
- Vérifiez que les coûts correspondent au dashboard de facturation OpenAI à quelques pourcent près.
Dépannage
Aucune trace n'apparaît dans le dashboard. Vérifiez que instrumentation.ts est à la racine du projet et que experimental_telemetry.isEnabled vaut true. Lancez avec NODE_OPTIONS=--trace-warnings pour attraper les erreurs de l'exporter.
Les événements n'apparaissent qu'après les cold starts. Vous avez oublié d'appeler flushLangfuse() dans after(). Sur Vercel, les fonctions serverless gèlent immédiatement après la réponse et les événements bufferisés ne sont jamais envoyés.
Les coûts affichent zéro. Le modèle que vous utilisez n'est pas encore dans le catalogue de pricing Langfuse. Ajoutez un pricing personnalisé dans Settings, Models ou ouvrez une PR sur le repo Langfuse.
La version de prompt ne se met jamais à jour. Vérifiez que cacheTtlSeconds n'est pas réglé trop haut dans getPrompt(). Le fallback par défaut servira la dernière version connue indéfiniment si l'API est injoignable — vérifiez la connectivité réseau de votre région de déploiement.
Prochaines étapes
- Combinez Langfuse avec les boucles d'agents Vercel AI SDK pour tracer les tool calls et handoffs
- Ajoutez Langfuse à votre projet Claude Agent SDK pour une observabilité unifiée
- Mettez en place une stack Langfuse + Next.js avec OpenTelemetry pour les traces applicatives
- Explorez les Datasets Langfuse pour construire une suite de tests de régression qui tourne à chaque changement de prompt
- Intégrez avec Inngest durable functions pour que les workflows en arrière-plan apparaissent aussi dans votre vue de traces
Conclusion
L'observabilité LLM n'est pas optionnelle dès que de vrais utilisateurs touchent à votre app IA. Langfuse vous offre traces, coûts, versioning de prompts, feedback utilisateur et évaluation automatisée dans une seule plateforme open-source qui se branche proprement sur Next.js et le Vercel AI SDK. L'installation prend moins d'une heure, et le retour sur investissement est la capacité de répondre à toutes les questions qu'un PM, ingénieur ou membre de la finance peut poser sur votre système IA — avec des données réelles plutôt que des suppositions.
Branchez-le une fois, et votre futur vous remerciera dès le premier incident en production.
Discutez de votre projet avec nous
Nous sommes ici pour vous aider avec vos besoins en développement Web. Planifiez un appel pour discuter de votre projet et comment nous pouvons vous aider.
Trouvons les meilleures solutions pour vos besoins.
Articles connexes

Guide d'Integration de Chatbot IA : Construire des Interfaces Conversationnelles Intelligentes
Un guide complet pour integrer des chatbots IA dans vos applications en utilisant OpenAI, Anthropic Claude et ElevenLabs. Apprenez a construire des chatbots textuels et vocaux avec Next.js.

Construire un Chatbot IA Local avec Ollama et Next.js : Guide Complet
Construisez un chatbot IA privé fonctionnant entièrement sur votre machine locale avec Ollama et Next.js. Ce tutoriel pratique couvre l'installation, le streaming des réponses, la sélection de modèles et le déploiement d'une interface de chat prête pour la production — le tout sans envoyer de données dans le cloud.

Construire un chatbot RAG avec Supabase pgvector et Next.js
Apprenez à construire un chatbot IA qui répond aux questions en utilisant vos propres données. Ce tutoriel couvre les embeddings vectoriels, la recherche sémantique et le RAG avec Supabase et Next.js.