Vous savez construire un agent qui raisonne, agit et se souvient. Une question reste : comment savoir ce qu’il fait vraiment ? En développement, on lit la console. En production, avec des milliers d’exécutions, des outils qui s’enchaînent et des coûts qui s’accumulent, la console ne suffit plus. Il faut de l’observabilité — et c’est le rôle de LangFuse.

Ce chapitre clôt le parcours d’initiation par la brique qui sépare un agent-jouet d’un agent qu’on peut exploiter sérieusement.

Ce qu’est une trace

Une trace LangFuse est l’enregistrement complet d’une exécution de l’agent, sous forme d’arbre. Chaque étape devient un nœud de cet arbre :

  • l’appel LLM qui décide (avec ses messages, son modèle, ses tokens, son coût) ;
  • l’exécution d’un outil (avec ses arguments et son résultat) ;
  • les éventuels sous-appels imbriqués.

Là où la console vous donne des lignes de log éparses, la trace vous donne la structure de ce qui s’est passé, chronométrée et chiffrée.

Mise en place : trois informations

LangFuse fonctionne en SaaS (cloud) ou auto-hébergé. Dans les deux cas, vous récupérez trois variables d’environnement depuis votre projet :

export LANGFUSE_PUBLIC_KEY="pk-lf-..."
export LANGFUSE_SECRET_KEY="sk-lf-..."
export LANGFUSE_HOST="https://cloud.langfuse.com"   # ou votre instance

On installe le SDK :

pip install langfuse

Brancher LangFuse sur l’agent

L’instrumentation se fait par un callback : un observateur qui s’attache à l’exécution et enregistre chaque étape, sans modifier la logique de l’agent.

from langfuse.langchain import CallbackHandler

langfuse_handler = CallbackHandler()

agent.invoke(
    {"messages": [{"role": "user", "content": "Météo à Lyon, et 21 + 21 ?"}]},
    config={"callbacks": [langfuse_handler]},
)

C’est tout. À l’exécution, chaque appel LLM et chaque outil est capturé et envoyé à LangFuse, où il devient une trace consultable.

Fig.01 · Instrumentation passive
appel invoke() + callbacks=[lf]
inchangé Agent exécute normalement
passif CallbackHandler observe chaque étape
store LangFuse trace consultable
Le callback s'attache à l'invocation et observe sans rien modifier. L'agent ignore qu'il est tracé ; LangFuse reçoit chaque étape en parallèle.

Lire sa première trace

Ouvrez LangFuse, section Traces, et cliquez sur la dernière. Vous lisez, de haut en bas :

NiveauCe que vous voyez
TraceL’exécution entière, sa durée totale, son coût total
GenerationUn appel LLM : messages d’entrée, réponse, modèle, tokens, coût
SpanUne opération non-LLM : l’exécution d’un outil, ses entrées/sorties

Pour notre requête, l’arbre ressemble à ceci — la boucle ReAct, rendue visible :

Fig.02 · Arbre de trace
TRACE · agent.invoke() 2.4 s · $0.0031 GENERATION · décision gpt-4o-mini · 412 tok SPAN · chercher_doc() 84 ms GENERATION · réponse finale 356 tok
Une trace racine contient l'arbre des étapes : appels LLM (generations) et outils (spans), chacun chronométré et chiffré. C'est l'unité de base de l'observabilité agentique.

On y lit d’un coup d’œil : une première generation (le modèle décide d’appeler un outil), un span outil, puis une seconde generation (la réponse finale) — avec, sur chacune, les tokens, le coût et la durée.

Ce que la trace vous apprend immédiatement

Trois lectures sautent aux yeux dès la première trace :

  1. Le raisonnement — quels outils l’agent a appelés, dans quel ordre, avec quels arguments. Un mauvais argument se repère d’un coup d’œil.
  2. Le coût — chaque generation affiche ses tokens d’entrée/sortie et le coût estimé. Vous savez enfin combien coûte réellement une réponse.
  3. La latence — chaque étape est chronométrée. Vous voyez si la lenteur vient du modèle, d’un outil, ou de leur enchaînement.

Ajouter du contexte à ses traces

Pour exploiter les traces à l’échelle, on les enrichit de métadonnées — de quoi les filtrer et les regrouper ensuite :

agent.invoke(
    {"messages": [msg]},
    config={
        "callbacks": [langfuse_handler],
        "metadata": {
            "langfuse_session_id": "ticket-4821",   # regroupe une conversation
            "langfuse_user_id": "lea-001",           # rattache à un utilisateur
            "langfuse_tags": ["support", "demo"],    # filtres
        },
    },
)

Avec session_id, toutes les interactions d’une même conversation se lisent comme un fil unique. Avec user_id et tags, vous segmentez vos analyses. Ces trois clés transforment un tas de traces en données exploitables.

La suite : mesurer la qualité

Voir ce que fait l’agent est la première marche. La suivante est d’en mesurer la qualité : la réponse était-elle bonne ? fidèle à la source ? LangFuse permet d’attacher des scores aux traces — manuels, automatiques, ou produits par un LLM-juge — et de suivre leur évolution. C’est précisément ce qu’on met en œuvre, de bout en bout, dans le cas pratique de l’agent de support tracé.

Ce qu’il faut retenir

  • Sans observabilité, un agent en production est une boîte noire.
  • Une trace LangFuse est l’arbre complet d’une exécution : appels LLM (generations) et outils (spans), chronométrés et chiffrés.
  • L’instrumentation est passive : un simple callback, aucune modification de l’agent.
  • Les métadonnées (session_id, user_id, tags) rendent les traces exploitables à l’échelle.

Bravo — vous avez bouclé le parcours d’initiation. Vous savez concevoir un agent, lui donner des outils, une mémoire, et l’observer. La suite se passe dans l’espace deep-dive, où l’on pousse chacune de ces briques au niveau de la production.

#langfuse#observabilite#trace#fondamentaux