DEV-AI
Langfuse LLMOps Python Observabilité Open Source

Publié le · Lecture : 20 min

Langfuse 2026 : observabilité LLM complète — traces, évaluations et coûts en Python

Compatibilité SDK : les exemples de cet article s'appuient sur les APIs langfuse v3/v4 (Python 3.10+). Les noms de méthodes, imports et comportements peuvent différer selon la version installée. Vérifiez votre version avec pip show langfuse, ne copiez-collez pas sans tester, et consultez le changelog officiel avant toute mise en production.
Ce que vous allez apprendre : pourquoi l'observabilité est indispensable en production LLM, comment instrumenter votre code Python avec le décorateur @observe, intégrer Langfuse à LangChain et LangGraph, versionner vos prompts, évaluer automatiquement vos réponses avec LLM-as-judge, suivre les coûts token par token, et déployer Langfuse en self-hosted avec Docker Compose.

TL;DR — L'essentiel en 30 secondes

28K+ stars GitHub · MIT (juin 2026) Largement adopté dans l'écosystème LLMOps OpenTelemetry natif

1. Pourquoi l'observabilité LLM est indispensable

Quand vous développez une application LLM en local, vous voyez tout : les prompts, les réponses, les erreurs. En production, avec des centaines d'utilisateurs simultanés et des pipelines d'agents à 10 étapes, vous êtes aveugle. Un RAG qui hallucine sur 3% des requêtes, un agent qui tourne en boucle sur certains cas, un prompt qui coûte 10× plus cher que prévu — sans observabilité, vous ne le saurez jamais.

L'observabilité LLM répond à quatre questions critiques en production :

Quoi ?
Quels prompts sont envoyés ? Quelles réponses reçues ? Quelle chaîne d'étapes dans mes agents ?
Combien ?
Combien de tokens ? Combien ça coûte par utilisateur, par feature, par jour ?
Combien vite ?
Quelle latence par étape ? Où est le goulot d'étranglement dans mon pipeline ?
Quelle qualité ?
Mes réponses sont-elles correctes, pertinentes, sans hallucination ?

Langfuse répond à ces quatre questions. C'est la plateforme LLMOps open-source la plus adoptée en 2026 — utilisée par des milliers d'équipes IA à travers le monde — de startups aux grandes entreprises comme Merck et Samsara.

2. Architecture Langfuse — traces, spans, generations

Langfuse est construit sur OpenTelemetry (OTel), le standard ouvert d'observabilité. Son modèle de données est hiérarchique :

TRACE user_id, session_id, metadata, tags — une exécution complète SPAN Unité de travail générique start_time, end_time ex: retrieve_docs, rerank GENERATION Appel LLM avec tokens + coût model, input, output usage_details (tokens) cost_details (USD) EVENT Action ponctuelle ex: user_feedback tool_call, error_caught SCORE Évaluation associée à la trace ou une observation spécifique · numérique (0-1), catégoriel (correct/incorrect), booléen Sources : LLM-as-judge · feedback utilisateur · code evaluator · annotation manuelle
Objet Rôle Champs clés Exemple
Trace Container racine d'une exécution user_id, session_id, input, output, metadata, tags Une requête utilisateur de bout en bout
Span Unité de travail générique name, start_time, end_time, input, output Retrieval, reranking, parsing
Generation Appel LLM avec métadonnées complètes model, usage_details, cost_details, prompt_version Appel GPT-4o, Claude, Mistral
Event Action ponctuelle sans durée name, input, metadata Tool call, erreur capturée
Score Évaluation qualité name, value, data_type, comment hallucination: 0.1, correctness: "correct"

3. Installation et configuration

3.1 Créer un compte et récupérer les clés

Rendez-vous sur cloud.langfuse.com (EU) — le plan Hobby est gratuit, aucune carte bancaire requise. Créez un projet, et récupérez vos clés dans Settings → API Keys.

# Installation du SDK Python
pip install langfuse

# Variables d'environnement (dans ~/.bashrc, ~/.zshrc ou .env)
export LANGFUSE_PUBLIC_KEY="pk-lf-..."      # Clé publique du projet
export LANGFUSE_SECRET_KEY="sk-lf-..."      # Clé secrète du projet
export LANGFUSE_BASE_URL="https://cloud.langfuse.com"  # EU (défaut)

# Alternatives selon la région
# export LANGFUSE_BASE_URL="https://us.cloud.langfuse.com"   # US
# export LANGFUSE_BASE_URL="http://localhost:3000"           # Self-hosted

3.2 Vérifier la connexion

from langfuse import get_client

langfuse = get_client()

# Teste la connexion et affiche les infos du projet
langfuse.auth_check()
# Output: True si connexion OK
Pattern singleton : get_client() retourne toujours la même instance dans un processus — pas besoin de passer le client en paramètre partout. Le SDK lit les variables d'env automatiquement.

4. Le décorateur @observe — démarrer en 2 minutes

Le décorateur @observe() est l'approche la plus simple. Il wrappe automatiquement vos fonctions Python et crée des spans dans Langfuse — sans modifier la logique de votre code.

from langfuse.decorators import observe, langfuse_context
from langfuse import get_client
from openai import OpenAI

langfuse = get_client()
openai_client = OpenAI()

# Chaque fonction décorée devient un span dans Langfuse
@observe()
def retrieve_context(query: str) -> str:
    """Simule une étape de retrieval documentaire."""
    # Votre logique de retrieval (BM25, ChromaDB, etc.)
    return f"Contexte pertinent pour : {query}"

@observe()
def generate_answer(query: str, context: str) -> str:
    """Appel LLM avec le contexte récupéré."""
    response = openai_client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[
            {"role": "system", "content": "Tu es un assistant expert."},
            {"role": "user",   "content": f"{query}\n\nContexte:\n{context}"}
        ],
    )
    return response.choices[0].message.content

# Fonction principale — crée la trace racine
@observe()
def rag_pipeline(query: str) -> str:
    # Associer un utilisateur à cette trace
    langfuse_context.update_current_trace(
        user_id="user_123",
        session_id="session_456",
        tags=["production", "rag"]
    )
    context = retrieve_context(query)
    answer  = generate_answer(query, context)
    return answer

# Exécution — Langfuse trace automatiquement les 3 spans
result = rag_pipeline("Qu'est-ce que le fine-tuning LoRA ?")
print(result)

# IMPORTANT : flush avant la fin du processus (Lambda, scripts batch)
langfuse.flush()

Avec ce code, Langfuse crée automatiquement une trace rag_pipeline contenant deux spans enfants (retrieve_context et generate_answer), avec l'input/output de chaque fonction, la latence, et les tokens consommés par l'appel OpenAI.

N'oubliez pas langfuse.flush() dans les scripts Python classiques, les fonctions Lambda, et les workers batch. Sans flush, les données en buffer peuvent ne pas être envoyées si le processus se termine trop vite. Dans une API FastAPI/Django, ce n'est pas nécessaire car le serveur tourne en continu.

5. Traces manuelles — contrôle total

Quand vous avez besoin d'un contrôle précis sur la hiérarchie des spans ou d'ajouter des métadonnées dynamiques, l'API manuelle vous donne accès à chaque détail.

from langfuse import get_client
import time

langfuse = get_client()

# 1. Créer la trace racine
trace = langfuse.trace(
    name="support-ticket-resolution",
    user_id="user_789",
    session_id="ticket_001",
    metadata={"ticket_type": "billing", "priority": "high"},
    tags=["support", "billing"]
)

# 2. Span de retrieval
retrieval_span = trace.span(
    name="retrieve-knowledge-base",
    input={"query": "remboursement facturation"}
)
# ... votre logique de retrieval ...
retrieved_docs = ["doc1", "doc2"]
retrieval_span.end(output={"docs_count": len(retrieved_docs)})

# 3. Generation LLM avec métadonnées complètes
generation = trace.generation(
    name="draft-response",
    model="gpt-4o",
    input=[
        {"role": "system", "content": "Tu es un agent support."},
        {"role": "user",   "content": "Je veux un remboursement."}
    ],
    model_parameters={"temperature": 0.3, "max_tokens": 500}
)

# ... appel LLM réel ici ...
llm_response = "Voici les étapes pour votre remboursement..."
generation.end(
    output=llm_response,
    usage={"prompt_tokens": 120, "completion_tokens": 85}
)

# 4. Scorer la trace (évaluation de qualité)
trace.score(
    name="response_quality",
    value=0.9,
    data_type="numeric",
    comment="Réponse complète et précise"
)

langfuse.flush()

6. Intégration OpenAI SDK — drop-in replacement

Langfuse propose un wrapper OpenAI qui intercepte automatiquement tous les appels. Un seul changement d'import suffit :

# AVANT (sans Langfuse)
from openai import OpenAI

# APRÈS (avec Langfuse — un seul changement)
from langfuse.openai import OpenAI

# Le reste du code est identique
client = OpenAI()

response = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "Explique le RAG en 3 points."}],
    # Métadonnées Langfuse en paramètres supplémentaires
    name="rag-explanation",          # Nom de la génération
    user_id="user_123",              # ID utilisateur
    session_id="session_456",        # ID session
    tags=["demo", "production"],      # Tags pour filtrer dans le dashboard
)

print(response.choices[0].message.content)
# Langfuse trace automatiquement : modèle, tokens, coût, latence
Compatibilité : ce wrapper fonctionne avec chat.completions.create(), embeddings.create(), et les appels en streaming. Il supporte aussi Azure OpenAI via AzureOpenAI du même module.

7. Intégration LangChain et LangGraph

Pour les applications LangChain et LangGraph, Langfuse fournit un CallbackHandler qui s'intègre dans le système de callbacks natif — sans modifier votre graph ou votre chaîne.

7.1 LangChain — CallbackHandler

from langfuse.langchain import CallbackHandler
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate

# Initialisation du handler avec contexte
langfuse_handler = CallbackHandler(
    session_id="session_001",
    user_id="user_123",
    tags=["langchain", "production"],
    metadata={"environment": "prod"}
)

# Votre chaîne LangChain habituelle
prompt = ChatPromptTemplate.from_messages([
    ("system", "Tu es un expert en IA générative."),
    ("user",   "{question}")
])
llm   = ChatOpenAI(model="gpt-4o-mini")
chain = prompt | llm

# Passer le handler dans config — un seul endroit
response = chain.invoke(
    {"question": "Explique le fine-tuning LoRA."},
    config={"callbacks": [langfuse_handler]}
)

# Récupérer l'ID de trace pour du scoring post-hoc
trace_id = langfuse_handler.get_trace_id()
print(f"Trace ID : {trace_id}")

7.2 LangGraph — agents multi-étapes

from langfuse.langchain import CallbackHandler
from langgraph.graph import StateGraph, END
from typing import TypedDict, Annotated
import operator

# Handler Langfuse — même pattern que LangChain
langfuse_handler = CallbackHandler(
    user_id="user_456",
    tags=["agent", "langgraph"]
)

# Votre graph LangGraph habituel
class AgentState(TypedDict):
    messages: Annotated[list, operator.add]

# ... définition du graph ...
graph = StateGraph(AgentState)
# ... ajout des noeuds et edges ...
agent = graph.compile()

# Exécution avec callback — Langfuse trace chaque noeud du graph
result = agent.invoke(
    {"messages": [{"role": "user", "content": "Analyse ce document."}]},
    config={"callbacks": [langfuse_handler]}
)

# Dans le dashboard, vous verrez chaque noeud du graph comme un span distinct
# avec ses inputs/outputs, latences et tokens
Agents à plusieurs niveaux : sur un agent LangGraph de 8 noeuds, Langfuse crée automatiquement une trace avec 8 spans enfants. Vous voyez exactement où le temps est passé, quels noeuds appellent des LLMs (et combien de tokens), et à quelle étape une erreur se produit.

8. Prompt Management — versionner et déployer

Le prompt management Langfuse vous permet de versionner vos prompts dans l'interface web, de les déployer sans redéployer le code, et de les lier automatiquement aux traces qui les utilisent. C'est un A/B testing de prompts en production, sans infrastructure supplémentaire.

1. Créer le prompt dans l'interface Langfuse
Allez dans Prompts → New Prompt. Donnez un nom (rag-system-prompt), rédigez votre prompt avec des variables template entre doubles accolades, et publiez en production.
2. Récupérer et utiliser le prompt en Python
Le SDK fetch le prompt depuis l'API, le cache localement (faible latence), et le lie automatiquement à la trace en cours.
from langfuse import get_client
from openai import OpenAI

langfuse      = get_client()
openai_client = OpenAI()

# Récupérer le prompt depuis Langfuse (label "production" par défaut)
prompt_obj = langfuse.get_prompt("rag-system-prompt")

# Compiler avec les variables template (doubles accolades dans l'interface)
compiled_prompt = prompt_obj.compile(
    expertise_level="expert",
    language="français"
)

# Utiliser le prompt — Langfuse trace automatiquement la version utilisée
response = openai_client.chat.completions.create(
    model="gpt-4o",
    messages=[
        {"role": "system", "content": compiled_prompt},
        {"role": "user",   "content": "Qu'est-ce que le RAG ?"}
    ],
    langfuse_prompt=prompt_obj,  # Lie la trace au prompt (version, label)
)

# Version spécifique pour tests A/B
prompt_v2 = langfuse.get_prompt("rag-system-prompt", version=2)
prompt_staging = langfuse.get_prompt("rag-system-prompt", label="staging")

Avantages du Prompt Management

Versioning
Historique complet de vos prompts, rollback en un clic
Sans redéploiement
Modifier un prompt en prod sans toucher au code
A/B Testing
Comparer latence, coût et qualité par version
Traçabilité
Chaque trace sait quelle version de prompt a été utilisée

9. Évaluations — LLM-as-judge et scoring

L'évaluation automatique est la fonctionnalité qui différencie vraiment les équipes qui "font du LLM" de celles qui "font du LLM en production". Sans évaluation systématique, vous ne savez pas si vos changements améliorent ou dégradent la qualité.

9.1 Scoring manuel

from langfuse import get_client

langfuse = get_client()

# Score numérique (hallucination : 0 = aucune, 1 = totale)
langfuse.score(
    trace_id="trace_abc123",
    name="hallucination",
    value=0.05,
    data_type="numeric",
    comment="Réponse factuelle vérifiée"
)

# Score catégoriel (correctness)
langfuse.score(
    trace_id="trace_abc123",
    name="correctness",
    value="correct",
    data_type="categorical"
)

# Score sur une generation spécifique (pas la trace entière)
langfuse.score(
    trace_id="trace_abc123",
    observation_id="gen_xyz789",
    name="relevance",
    value=0.92,
    data_type="numeric"
)

9.2 LLM-as-judge — évaluation automatique

Le pattern LLM-as-judge utilise un modèle "juge" pour évaluer automatiquement les outputs d'un autre modèle. Voici comment l'implémenter proprement :

from langfuse.decorators import observe, langfuse_context
from langfuse import get_client
from openai import OpenAI
import json

langfuse      = get_client()
openai_client = OpenAI()

JUDGE_PROMPT = """Tu es un évaluateur objectif de réponses IA.

Question posée : {question}
Réponse générée : {answer}
Contexte fourni : {context}

Évalue sur trois critères (score de 0 à 1) :
- faithfulness : la réponse est-elle fidèle au contexte ?
- relevance    : la réponse répond-elle à la question ?
- conciseness  : la réponse est-elle concise et claire ?

Réponds uniquement en JSON : {{"faithfulness": 0.9, "relevance": 0.8, "conciseness": 0.7}}"""

@observe()
def evaluate_with_llm_judge(question: str, answer: str, context: str, trace_id: str):
    """Évalue une réponse RAG avec un LLM juge."""
    response = openai_client.chat.completions.create(
        model="gpt-4o-mini",  # Modèle juge (plus rapide = moins cher)
        messages=[{
            "role": "user",
            "content": JUDGE_PROMPT.format(
                question=question, answer=answer, context=context
            )
        }],
        response_format={"type": "json_object"}
    )

    scores = json.loads(response.choices[0].message.content)

    # Envoyer les scores à la trace principale (pas celle du juge)
    for metric_name, score_value in scores.items():
        langfuse.score(
            trace_id=trace_id,
            name=metric_name,
            value=score_value,
            data_type="numeric",
            comment="LLM-as-judge : gpt-4o-mini"
        )

    return scores

# Usage dans un pipeline RAG
@observe()
def rag_with_evaluation(question: str) -> str:
    context = "Langfuse est une plateforme open-source LLMOps..."
    answer  = "Langfuse permet de monitorer vos LLMs."  # Réponse de votre LLM

    trace_id = langfuse_context.get_current_trace_id()

    # Évaluation asynchrone après génération
    scores = evaluate_with_llm_judge(question, answer, context, trace_id)
    print(f"Scores : {scores}")

    return answer

10. Cost & Latency tracking

Langfuse calcule automatiquement les coûts pour tous les modèles majeurs. Lorsque vous utilisez le wrapper OpenAI ou le CallbackHandler LangChain, aucune configuration supplémentaire n'est nécessaire — les tokens et coûts sont extraits des réponses de l'API.

Méthode Tokens auto Coût auto Configuration
Wrapper langfuse.openai Automatique Automatique Aucune
CallbackHandler LangChain Automatique Automatique Aucune
Traces manuelles Manuel Auto si tokens fournis Passer usage_details
Ollama / LLM local Via LiteLLM 0$ (local) LiteLLM Proxy configuré
# Accéder aux métriques de coût dans le dashboard Langfuse :
# Dashboard → Cost → Filtrer par modèle, utilisateur, date, tag

# Dans les traces manuelles, passer les tokens explicitement
generation = trace.generation(
    name="llm-call",
    model="gpt-4o",
    usage={
        "input":  1250,   # tokens input
        "output": 420,    # tokens output
        "unit":   "TOKENS"
    }
    # Langfuse calcule le coût USD automatiquement via son catalogue de prix
)

11. Cas réel : pipeline RAG complet avec monitoring

Voici un pipeline RAG production-ready avec Langfuse intégré à chaque étape — retrieval, reranking, génération et évaluation automatique.

from langfuse.decorators import observe, langfuse_context
from langfuse.openai import OpenAI
from langfuse import get_client
import chromadb
import json

langfuse = get_client()
client   = OpenAI()

# ChromaDB comme vector store
chroma = chromadb.Client()
collection = chroma.get_or_create_collection("knowledge-base")

@observe()
def embed_query(query: str) -> list[float]:
    """Génère l'embedding de la requête."""
    response = client.embeddings.create(
        model="text-embedding-3-small",
        input=query
    )
    return response.data[0].embedding

@observe()
def retrieve_documents(query: str, n_results: int = 5) -> list[str]:
    """Retrieval vectoriel depuis ChromaDB."""
    embedding = embed_query(query)
    results   = collection.query(query_embeddings=[embedding], n_results=n_results)

    # Logger les métadonnées du retrieval dans le span
    langfuse_context.update_current_observation(
        metadata={
            "n_results":  n_results,
            "distances":  results["distances"][0][:3] if results["distances"] else []
        }
    )
    return results["documents"][0] if results["documents"] else []

@observe()
def generate_response(query: str, context_docs: list[str]) -> str:
    """Génère la réponse finale avec le contexte récupéré."""
    # Récupérer le prompt depuis Langfuse Prompt Management
    prompt_obj     = langfuse.get_prompt("rag-system")
    system_prompt  = prompt_obj.compile(
        context="\n\n".join(context_docs),
        language="français"
    )

    response = client.chat.completions.create(
        model="gpt-4o",
        messages=[
            {"role": "system", "content": system_prompt},
            {"role": "user",   "content": query}
        ],
        langfuse_prompt=prompt_obj,   # Lie la trace à la version du prompt
        temperature=0.2,
        max_tokens=800
    )
    return response.choices[0].message.content

@observe()
def rag_query(query: str, user_id: str, session_id: str) -> dict:
    """Pipeline RAG complet avec monitoring Langfuse."""
    # Associer utilisateur et session à la trace racine
    langfuse_context.update_current_trace(
        user_id=user_id,
        session_id=session_id,
        input={"query": query},
        tags=["rag", "production"]
    )

    # Pipeline RAG
    docs   = retrieve_documents(query, n_results=5)
    answer = generate_response(query, docs)

    # Évaluation LLM-as-judge
    trace_id = langfuse_context.get_current_trace_id()
    evaluate_faithfulness(query, answer, docs, trace_id)

    # Mettre à jour l'output de la trace racine
    langfuse_context.update_current_trace(output={"answer": answer})

    return {"answer": answer, "trace_id": trace_id, "sources": len(docs)}

@observe(as_type="generation")
def evaluate_faithfulness(query, answer, docs, trace_id):
    """LLM-as-judge pour évaluer la fidélité au contexte."""
    context_str = "\n".join(docs[:3])
    response = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[{"role": "user", "content":
            f"Contexte: {context_str}\nRéponse: {answer}\n"
            f"La réponse est-elle fidèle au contexte ? Score 0-1 en JSON: {{'score': 0.9}}"
        }],
        response_format={"type": "json_object"}
    )
    score = json.loads(response.choices[0].message.content)["score"]
    langfuse.score(trace_id=trace_id, name="faithfulness", value=score)

12. Self-hosted avec Docker Compose

Le self-hosting est la solution pour les données sensibles ou les budgets serrés. La stack Langfuse v3 comprend PostgreSQL, ClickHouse (pour les traces), Redis et MinIO. Un seul fichier Docker Compose suffit.

# 1. Cloner le dépôt officiel
git clone https://github.com/langfuse/langfuse.git
cd langfuse

# 2. Éditer docker-compose.yml — remplacer TOUS les secrets marqués # CHANGEME
#    Utiliser des mots de passe longs et aléatoires (openssl rand -base64 32)

# 3. Lancer la stack complète
docker compose up -d

# 4. Accéder à l'interface web
open http://localhost:3000

# 5. Configurer votre SDK Python pour pointer vers le self-hosted
export LANGFUSE_BASE_URL="http://localhost:3000"  # ou votre domaine

Configuration minimale requise

CPU
4+ cores
RAM
≥8 GB (dev) / ≥16 GB (prod)
Stockage
100 GB+ SSD
Ports
3000 (web)
Sécurité : ne jamais déployer avec les mots de passe par défaut du docker-compose. Générez des secrets forts avec openssl rand -base64 32 pour chaque service (PostgreSQL, ClickHouse, Redis, MinIO, NextAuth). Placez Langfuse derrière un reverse proxy HTTPS (Nginx, Traefik) avant de l'exposer en production.

13. Langfuse vs LangSmith vs Arize vs Helicone

Critère Langfuse LangSmith Arize Phoenix Helicone
Licence MIT Open Source Propriétaire ELv2 Propriétaire
Self-hosted Oui, 1ère classe Enterprise requis Local seulement Via proxy
Framework-agnostic Oui (OTel) LangChain-first Oui Via proxy
Prompt Management Complet Complet Non Non
Évaluations LLM-judge, code, human LLM-judge, rules Riche (templates) Basique
Alerting production Non Oui Partiel Via gateway
Coût cloud relatif (voir tarifs officiels) Économique Significativement plus élevé Gratuit (local) Intermédiaire
Idéal pour La plupart des équipes Équipes 100% LangChain Expérimentation offline Proxy simple et rapide
Verdict 2026 : Langfuse est généralement le choix le plus économique et le plus flexible pour la plupart des équipes — open-source, auto-hébergeable, framework-agnostic. Choisissez LangSmith si vous êtes 100% dans l'écosystème LangChain et avez besoin d'alertes de production. Choisissez Arize Phoenix si vous faites beaucoup d'expérimentation offline. Les tarifs évoluant régulièrement, consultez directement langfuse.com/pricing et langsmith avant de décider.

14. Limites et points de vigilance

Pas d'alerting natif
Langfuse ne peut pas vous prévenir si un seuil de coût ou de latence est dépassé. Pour des alertes de production, il faut intégrer un outil externe (PagerDuty, Grafana, Slack webhook). C'est la principale limitation par rapport à LangSmith.
Overhead de latence SDK
Le SDK envoie les traces en asynchrone (buffer + flush), l'impact latence est minimal (<5ms). Mais sur des appels très rapides (<50ms), utilisez le mode batch et ajustez les paramètres flush_at et flush_interval selon votre volume.
Plan Hobby limité à 50k unités/mois
En production avec plusieurs utilisateurs, 50k traces sont vite atteintes. Planifiez le passage au plan Core (29$/mois, 100k unités) dès le lancement, ou utilisez le self-hosted pour un usage illimité.
Self-hosted : infrastructure non triviale
La stack v3 (PostgreSQL + ClickHouse + Redis + MinIO) a des besoins qui varient selon le volume de traces et la rétention. Comptez 8 GB RAM pour un environnement de développement léger, 16 GB+ pour une charge de production modérée — consultez les recommandations officielles de dimensionnement avant de choisir votre infrastructure. Les mises à jour de version nécessitent de gérer les migrations ClickHouse.

FAQ

Qu'est-ce que Langfuse ?

Langfuse est une plateforme open-source (MIT) d'observabilité pour applications LLM. Elle permet de tracer chaque appel LLM, monitorer les coûts et latences, versionner les prompts, évaluer automatiquement les réponses et déboguer les pipelines d'agents en production. largement adopté dans l'écosystème LLMOps mondial.

Comment installer Langfuse en Python ?

pip install langfuse, puis configurez trois variables d'environnement : LANGFUSE_PUBLIC_KEY, LANGFUSE_SECRET_KEY (obtenus dans Settings → API Keys sur cloud.langfuse.com) et LANGFUSE_BASE_URL (URL de votre instance cloud ou self-hosted). Le SDK les détecte automatiquement.

Langfuse est-il gratuit ?

Oui, Langfuse est open-source (MIT) et se déploie gratuitement en self-hosted. Le plan cloud Hobby est gratuit avec 50 000 unités/mois, 30 jours de rétention et 2 utilisateurs — suffisant pour développer et tester. Le plan Core à 29$/mois monte à 100 000 unités/mois avec utilisateurs illimités.

Quelle est la différence entre Langfuse et LangSmith ?

Langfuse est 100% open-source (MIT), framework-agnostic via OpenTelemetry, self-hostable gratuitement, et significativement moins cher en cloud. LangSmith est propriétaire, optimisé pour LangChain, et propose de meilleures alertes de production. Pour la plupart des équipes en 2026, Langfuse est le meilleur choix sauf si vous êtes 100% LangChain et avez besoin d'alertes avancées.

Langfuse fonctionne-t-il avec Ollama et les LLMs locaux ?

Oui. Via LiteLLM Proxy (qui expose Ollama comme une API OpenAI-compatible), via le décorateur @observe pour une instrumentation manuelle, ou via OpenTelemetry. Le coût est 0$ (LLM local), mais Langfuse trace latences, inputs/outputs et évaluations. Idéal pour monitorer des pipelines RAG locaux sans coût API.

Conclusion

Langfuse comble le fossé entre "ça marche en local" et "ça tient en production". Avec le décorateur @observe(), vous passez d'une application LLM opaque à un système entièrement observable en quelques lignes — sans restructurer votre code. Le prompt management vous donne le contrôle sur vos prompts sans redéploiement. Les évaluations LLM-as-judge automatisent ce qui était autrefois une revue manuelle fastidieuse.

Pour une équipe qui passe en production — pipeline RAG, agent multi-étapes, chatbot à forte charge — Langfuse n'est pas un bonus : c'est l'infrastructure de base qui vous permettra de déboguer rapidement, d'optimiser les coûts, et de livrer des améliorations en confiance.

Pour démarrer : créez un compte sur cloud.langfuse.com (gratuit), installez pip install langfuse, ajoutez @observe() sur votre fonction principale et exécutez-la. Votre première trace apparaîtra dans le dashboard en moins de 30 secondes.
Envie d'aller plus loin ? Consultez notre guide sur LangGraph pour construire des agents IA stateful et notre tutoriel MCP en Python pour connecter vos agents à des outils externes — puis instrumentez tout avec Langfuse.

Articles liés

LANGGRAPH
LangGraph 2026 — agents stateful
Construire des agents IA avec mémoire, cycles et outils.
RAG
RAG avec Ollama en Python
Pipeline RAG local complet — LangChain, Chroma, embeddings.
MCP
Model Context Protocol
Connecter vos LLMs aux outils du monde réel.