langchain-core, donc instrumenter l’un instrumente automatiquement l’autre.
Installation
failproofai-sdk[langchain].
Versions supportées : langchain-core 1.4.7 à 2.0, langgraph 1.2 à 2.0. En dehors de cette plage, l’adaptateur s’installe quand même et émet un avertissement unique.
Instrumentation
instrument() enregistre un tracer via langchain_core.tracers.context.register_configure_hook. LangChain l’injecte dans chaque gestionnaire de callbacks qu’il crée, ce qui permet de capturer graphes, outils et modèles sans modifier un seul point d’appel — y compris ceux au sein de bibliothèques tierces.
Ce qui est enregistré
Un nœud devient un hook, pas un agent imbriqué.
agent_id est la facette principale sur toutes les vues du tableau de bord — promouvoir retrieve, grade_documents et should_continue en agents noierait cette facette et étiquerait la session d’après le nœud exécuté en premier.
Les spans de hooks s’affichent de la même manière et offrent quand même une vue de latence par nœud.
Nommez vos nœuds comme vous le souhaitez. L’exécution d’un nœud est identifiée par sa forme — une exécution non-feuille portant le tag de step LangGraph — jamais par son nom.
Nommer un nœud d’après ce qu’il exécute faisait autrefois disparaître les événements de cet élément. Ce n’est plus le cas.
Streaming
.stream() et .astream() n’émettent aucun événement par token. Ils sont regroupés dans le model_response final :
Comptage de tokens sur une réponse streamée
Point distinct, facile à manquer : OpenAI n’envoie l’usage sur une réponse streamée que si on le lui demande explicitement.model_response arrive sans comptage de tokens.
Exemple
Nommer vos spans
Par défaut, le span racine prend le nom propre du graphe. Enveloppez-le pour lui attribuer le libellé de votre choix :parent_id :
agent_id à faible cardinalité. Utilisez un rôle ou un nom de nœud, jamais un UUID ou une chaîne générée à chaque exécution.
Contrôler la session
L’identifiant de session est résolu dans cet ordre, la première correspondance l’emportant :instrument("langchain", session_id=...)config={"metadata": {"failproofai_sdk_session_id": ...}}- Le scope englobant
failproofai_sdk.session() metadata["session_id"],metadata["conversation_id"], oumetadata["thread_id"]- L’identifiant de l’exécution racine
Options
capture_content=False pour les données réglementées. La structure, les timings, les comptages de tokens, les noms d’outils et les issues sont toujours enregistrés ; les corps de messages ne le sont pas.
include_chains s’applique uniquement aux exécutions imbriquées. Un runnable invoqué au niveau supérieur est la racine de la session — il devient donc le span agent plutôt qu’une paire de hooks, et le nommer ici n’a aucun effet.
Human in the loop
interrupt() produit quatre événements, et aucune paire n’est redondante :
human_wait à human_input, la paire transporte la question et la réponse (toutes deux supprimées avec capture_content=False, ainsi que les sources des documents de retrieval — le nombre de documents est conservé). La paire agent_pause vers agent_resume est la seule qui alimente le temps en pause ; sans elle, une attente humaine de dix minutes est comptabilisée comme temps actif de l’agent. Le span racine reste ouvert entre les deux appels, les maintenant dans une même session.
Problèmes courants
Un outil qui lève une exception interrompt tout le graphe
Un outil qui lève une exception interrompt tout le graphe
create_react_agent propage l’exception. Pour que le modèle voie l’échec et puisse continuer, construisez le nœud d’outil explicitement :tool_result portant une erreur dans les deux cas. Ce paramètre décide uniquement si l’exécution survit à l’erreur.Un agent portant le nom de la classe de modèle apparaît dans la trace
Un agent portant le nom de la classe de modèle apparaît dans la trace
Un appel direct
llm.invoke() en dehors de tout graphe n’a pas d’exécution parente, il ouvre donc un span racine et émet sa paire de modèle à l’intérieur. Le tableau de bord rattache les feuilles à un agent ouvert, ce span est donc intentionnel. Nommez-le :Chaque événement apparaît deux fois
Chaque événement apparaît deux fois
Vous avez passé un handler Failproof dans
config={"callbacks": [...]} tout en appelant instrument(). Supprimez-le. Le configure hook couvre déjà tous les gestionnaires de callbacks du processus.Les approbations humaines apparaissent comme des erreurs
Les approbations humaines apparaissent comme des erreurs
Ce n’est pas le cas. LangGraph lève
GraphInterrupt par le même chemin qu’une vraie exception, donc chaque pause atteint le tracer comme un callback d’erreur. Toute sous-classe de GraphBubbleUp est traitée comme un flux de contrôle, donc une approbation n’est pas marquée en rouge.Rien n'est enregistré
Rien n'est enregistré
Vérifiez dans cet ordre :
instrument() a été appelé avant l’exécution du graphe ; il y a un with failproofai_sdk.session(): autour de l’appel ; FAILPROOFAI_SDK_STRICT=1 est défini, ce qui fait qu’un hook dégradé lève une exception au lieu d’être ignoré silencieusement.Étapes suivantes
Fonctionnement interne
Paires, identifiants, cycle de vie de session et livraison.
Lire une trace
Suivez la causalité à travers la session que vous venez de capturer.
Autres frameworks
CrewAI, LlamaIndex, Pydantic AI et agents personnalisés.

