Installation
Instrumentation
session_id et agent_id. Les portées lient l’identité sur des variables de contexte et chaque appel d’événement la récupère, vous n’avez donc jamais besoin de propager les ids à travers vos fonctions.
Les trois fonctionnent avec async with comme avec with.
L’imbrication d’agents construit l’arbre. parent_id et la profondeur sont calculés à partir de la pile :
Comment une portée se ferme
agent() gère les exceptions pour vous :
agent_end, car le tableau de bord ferme le span à agent_end et tout ce qui suit ne serait attribué à rien. Une annulation n’est pas un échec, donc les exécutions annulées ne polluent pas la surface des erreurs. L’exception est toujours re-levée : une portée n’avale jamais les exceptions.
Les méthodes d’événements
Quinze méthodes en six familles. La plupart vont par paires — vous émettez l’ouverture, puis la fermeture, et le SDK mesure le span entre les deux.Exemple
Une boucle d’appel d’outils contre l’API OpenAI, sans framework d’agent :docs/manual/examples/.
Threads et async
Les variables de contexte se propagent automatiquement dans les tâches asyncio. Elles ne se propagent pas dans les nouveaux threads, car un thread démarre avec un contexte vide.propagate(), les événements du worker lèvent une TypeError indiquant le correctif plutôt que d’atterrir sans session. C’est délibéré : un événement sans session est ignoré à l’ingestion avec une réponse 200, ce qui constitue l’échec silencieux que la couche d’identité existe précisément pour éviter.
Instrumenter un framework sans adaptateur
Tout framework d’agent vous expose les mêmes trois points d’insertion. Mappez-les et vous avez une trace complète — les quatre adaptateurs fournis ne font rien de plus que cela.Encadrer l'exécution
Encadrer chaque outil
Appairer chaque appel de modèle
Pourquoi il n'existe pas d'adaptateur AutoGen
Pourquoi il n'existe pas d'adaptateur AutoGen
autogen-coren’est plus maintenu depuis septembre 2025.- AG2 n’expose aucun point d’enregistrement global équivalent aux hooks des autres frameworks, ce qui fait qu’instrumenter AG2 implique d’envelopper chaque agent à chaque site de construction.
Aller plus loin
Comment l’enregistrement fonctionne réellement. Rien de tout cela n’est nécessaire pour démarrer.À quoi ressemble un enregistrement, par framework
À quoi ressemble un enregistrement, par framework
- LangGraph
- CrewAI
- LlamaIndex
- Pydantic AI
- Custom agents
Comment une session commence et se termine
Comment une session commence et se termine
Identité : session_id, agent_id, et qui les crée
Identité : session_id, agent_id, et qui les crée
session_id et agent_id sont optionnels sur chaque méthode d’événement. S’ils sont omis, ils sont résolus depuis la portée englobante :TypeError indiquant le correctif plutôt que d’émettre un événement sans session, que l’ingestion ignorerait tout en répondant 200.Les portées lient l’identité sur des variables de contexte. Celles-ci se propagent automatiquement dans les tâches asyncio mais pas dans les nouveaux threads — enveloppez un worker dans failproofai_sdk.propagate().Qui crée quel identifiant
Comment les adaptateurs résolvent session_id
Le premier match gagne :- Une option
session_idexplicite - Des métadonnées par appel
- La portée
session()englobante - Les métadonnées du framework
- Le propre id d’exécution du framework
Gardez agent_id à faible cardinalité
C’est la facette principale sur chaque surface du tableau de bord, et une colonne LowCardinality(String). Une valeur par exécution dégrade la colonne et remplit le menu déroulant de filtre avec une entrée par exécution.Les adaptateurs défendent cette colonne pour vous :fw_agent_id / fw_run_id, où il reste interrogeable sans être une facette.Types d'événements, regroupés — et quel framework enregistre quoi
Types d'événements, regroupés — et quel framework enregistre quoi
human_pause et human_interrupt décrivent une personne agissant sur l’agent, ce qu’aucun framework ne signale — émettez-les vous-même.Paires, corrélation et durée
Paires, corrélation et durée
Règles de corrélation
- Réutilisez le même
tool_call_id,hook_id,pause_idouinput_idpour l’événement de complétion correspondant. - Le SDK calcule
duration_mspourtool_result,hook_completed,agent_resumeethuman_input. Le passer à ces méthodes lève uneValueError. duration_msest accepté surmodel_response, car seul l’appelant connaît la vraie latence du fournisseur. Il doit être un entier — un flottant lève uneValueErrorau site d’appel, car le serveur lit la colonne comme un entier non signé 32 bits et stockerait NULL pour tout autre valeur.- Les clés de corrélation sont délimitées par type et session, donc un appel d’outil et un hook peuvent partager un id en toute sécurité, et deux sessions concurrentes peuvent réutiliser les mêmes ids sans collision. Elles ne sont pas délimitées par agent : une paire ouverte sous un agent et fermée sous un autre se corrèle quand même, ce qui est le cas ordinaire dans les frameworks multi-agents.
request_idappariemodel_requestavecmodel_response. Sans lui, les événements de modèle sont appariés dans l’ordre par agent, donc les appels concurrents sont mal appariés.- Une paire répartie sur plusieurs processus se corrèle toujours en aval, mais le SDK ne peut pas calculer sa durée en cours de processus.
- La map des événements en attente contient au maximum 10 000 entrées et expulse la plus ancienne quand elle est pleine.
Ce que contient le package, et comment instrument() trouve votre framework
Ce que contient le package, et comment instrument() trouve votre framework
failproofai-sdk installe tout, les quatre adaptateurs inclus. Les extras tirent le framework, pas l’adaptateur.import failproofai_sdk est contractuellement sans dépendance, vérifié par un test qui installe la wheel construite avec --no-deps et un autre qui prouve qu’aucun framework n’atteint sys.modules.sys.modules, pas la liste des packages installés, donc un framework installé mais jamais importé n’est pas instrumenté et n’est jamais importé à votre place. Pour voir ce qui est câblé :instrument("crewai") sur une machine sans CrewAI ne lève pas d’exception. Il enregistre un avertissement et retourne (), donc un framework manquant ne fait jamais tomber un processus qui instrumente d’autres frameworks.L’avertissement porte l’ImportError sous-jacent, et ce message indique la commande d’installation exacte — le correctif est donc dans vos logs, pas caché.FAILPROOFAI_SDK_STRICT=1 pour qu’il lève une exception à la place. Ce flag est lu une seule fois et mis en cache, exportez-le donc avant le démarrage de votre processus plutôt que de le définir en cours d’exécution.Comment les événements parviennent au Cloud
Comment les événements parviennent au Cloud
.tmp d’abord, puis fsync, puis un renommage atomique :.jsonl, il ne peut donc jamais lire un fichier à moitié écrit. Le nom de fichier porte un timestamp, un id de processus et un numéro de séquence, donc deux processus flushing dans la même milliseconde ne peuvent pas entrer en collision. La file d’attente est limitée à 10 000 événements ; au-delà, elle supprime les plus anciens et enregistre un log.Le daemon envoie vos batches. Il ne les ouvre ni ne les réécrit.ls est en concurrence avec le collecteur et ne montre qu’une fraction de ce que vous avez émis — impossible à distinguer d’un SDK qui n’a rien enregistré.Pour confirmer que les événements sont bien arrivés, consultez le tableau de bord. Pour observer le remplissage du spool, arrêtez d’abord le daemon.Quand l'instrumentation échoue
Quand l'instrumentation échoue
try et tout ce que fait le SDK se passe en dehors.FAILPROOFAI_SDK_STRICT=1 pour rendre visible un échec avalé.Problèmes courants
Un span ne se termine jamais
Un span ne se termine jamais
model_request sans model_response, ou un tool_use sans tool_result. Utilisez les portées, qui garantissent la paire même si le corps lève une exception. Si vous appelez les méthodes d’événements directement, utilisez try et finally.Passer duration_ms lève une ValueError
Passer duration_ms lève une ValueError
tool_result, hook_completed, agent_resume et human_input. Il est accepté sur model_response, car seul vous connaissez la vraie latence du fournisseur, et il doit être un entier.Les événements d'un thread worker lèvent une TypeError
Les événements d'un thread worker lèvent une TypeError
failproofai_sdk.propagate(). Voir Threads et async.Un champ supplémentaire a disparu ou en a écrasé un autre
Un champ supplémentaire a disparu ou en a écrasé un autre
model ou outcome l’écraserait et modifierait une colonne stockée. Préfixez les vôtres ; les adaptateurs utilisent le préfixe fw_.Le filtre d'agent contient des milliers d'entrées
Le filtre d'agent contient des milliers d'entrées
agent_id est une facette à faible cardinalité et vous y avez mis un id d’exécution. Utilisez un nom de rôle ou de nœud et mettez le vrai id dans un champ de payload.

session_id.Le statut est dérivé de la forme de la trace :ongoingpausedagent_pausen’a pas deagent_resumecorrespondanterrordoneagent_endpour vous, et au moment du teardown ils ferment tout ce qui est encore ouvert en le marquant incomplet — une exécution ayant planté se stabilise endoneavec un écart visible plutôt que de rester suspendue.interrupt()LangGraph met l’exécution en pause, le span racine reste délibérément ouvert, et l’appel de reprise le ferme. Les deux appels forment une seule session.