On parle beaucoup d’agents IA. On les branche à des outils. On les laisse appeler des API, écrire dans une base, pousser un ticket, modifier un repo. Et puis, un jour, ça casse.
Pas un crash propre. Un truc plus pénible. L’agent « a fait quelque chose », mais on ne sait pas quoi. Ou pire, il a fait la mauvaise chose, au bon endroit, et personne ne comprend la chaîne de décision.
C’est là que l’observabilité devient non négociable. Pas « avoir quelques logs ». Je parle de logs structurés, de traces distribuées, et d’un vrai mécanisme de replay des prompts, pour reproduire, expliquer, auditer, et corriger.
Sur Le Blog Tech Pro de Samyn-Antoy ABASSE (https://monblog-sa-abasse.blogspot.com), je reviens souvent sur les workflows « build, scale, sell ». L’observabilité d’agents, c’est exactement ça. Tu peux builder un agent en une soirée. Le scaler en production sans observabilité, c’est une autre histoire.
Pourquoi l’observabilité d’un agent est différente de celle d’une API classique
Une API classique, tu as une requête, un handler, une base de données. Les erreurs sont souvent localisées. Un agent, lui, c’est un système de décisions.
Il peut :
- reformuler la demande utilisateur,
- choisir un outil,
- exécuter une action,
- lire un résultat partiel,
- boucler,
- changer de plan,
- tenter un fallback,
- et au passage, consommer du contexte (mémoire, fichiers, messages, embeddings).
Donc le « chemin » n’est pas linéaire. Deux exécutions identiques en apparence peuvent diverger, juste parce qu’un tool a renvoyé un contenu un peu différent, ou parce que le modèle a pris une autre option.
Résultat : si tu logs juste « user asked X, agent answered Y », tu n’as rien. Zéro explicabilité. Zéro debug. Zéro conformité.
Ce que tu veux en vrai, c’est répondre à des questions très concrètes :
- l’agent a t il appelé un outil, lequel, avec quels paramètres, et quel retour ?
- quel prompt exact a été envoyé au modèle ?
- quelle portion du contexte a été incluse, et pourquoi ?
- combien de tokens, combien de latence, combien de tentatives ?
- où est la divergence entre deux runs ?
- et si je rejoue, est ce que je reproduis le bug ?
Les trois piliers : logs, traces, replay
Je te propose une structure simple, très opérable.
- Logs structurés pour comprendre quoi s’est passé.
- Traces distribuées pour comprendre où et dans quel ordre ça s’est passé.
- Replay de prompts pour reproduire comment l’agent a raisonné et agir sur la cause.
On détaille.
Logs : ce qu’il faut enregistrer (et ce qu’il faut éviter)
Le piège des logs texte
Le classique : print("calling tool..."). On se rassure, puis on souffre en prod. Parce que ça ne s’agrège pas, ça ne se filtre pas bien, ça ne corrèle pas.
Il faut des logs structurés (JSON), avec des champs stables.
Un schéma de log minimal pour un agent
Au minimum, à chaque événement significatif, je veux :
timestamplevelservice(ouagent_name)env(dev, staging, prod)trace_idspan_idsession_id(conversation)run_id(exécution unique de l’agent)event_type(prompt_sent, tool_called, tool_result, model_output, policy_blocked, error)duration_mstoken_usage(prompt_tokens, completion_tokens)model(ex. gpt 4.1, claude, etc.)tool_nameettool_args(si applicable)tool_result_summary(attention, pas forcément le résultat brut)error_type,error_message(si applicable)
Tu noteras que je distingue session_id et run_id. Une session peut contenir plusieurs runs, et un run peut contenir plusieurs appels modèle et outils. Si tu ne sépares pas, tu vas mélanger.
Quoi logguer sur les prompts, sans te tirer une balle dans le pied
Le sujet sensible : faut il logguer les prompts bruts ?
En pratique, oui, mais pas n’importe comment.
Bon compromis :
- logguer le prompt template (versionné),
- logguer les variables injectées, avec redaction,
- logguer un hash du prompt final (pour comparer),
- stocker le prompt final complet dans un stockage sécurisé, chiffré, avec une policy de rétention.
Parce que les prompts peuvent contenir : PII, secrets, données clients, extraits internes. Si tu balances ça dans un log central consultable par tout le monde, tu crées une fuite.
Petit exemple de log JSON
json { "timestamp": "2026-07-22T10:15:12.221Z", "level": "info", "agent_name": "support-agent", "env": "prod", "trace_id": "3b2f1f9d0f3c1a7e", "span_id": "a91c", "session_id": "sess_8f12", "run_id": "run_91a2", "event_type": "tool_called", "tool_name": "zendesk.create_ticket", "tool_args": {"subject": "Erreur 502", "priority": "high"}, "duration_ms": 38 }
Lisible, filtrable, corrélable.
Traces : la colonne vertébrale pour comprendre une exécution
Les logs te donnent des points. Les traces te donnent le film.
Un agent, c’est typiquement une suite de spans :
agent.runllm.call(un ou plusieurs)tool.call(un ou plusieurs)retrieval.search(si RAG)memory.readetmemory.writeguardrail.check(policy)
Comment découper les spans (simple et robuste)
Je recommande ce pattern :
Span racine : agent.run
Tags : agent_name, run_id, session_id, user_id (hash), tenant_id (si B2B)
Spans enfants
llm.call— tags :model,temperature,max_tokens,prompt_hashtool.call— tags :tool_name,tool_timeout,tool_retriesretrieval.query— tags :index,top_k,query_hashguardrail.check— tags :policy_version,result
Et surtout, chaque span doit capturer :
- start time et end time
- status (ok, error)
- erreurs et exceptions
Le gros gain des traces : la latence et les loops
Tu vas le voir vite : le problème numéro un des agents en prod, ce n'est pas juste « il se trompe ». C'est aussi qu'il boucle, hésite, réessaye, appelle 4 tools inutiles, et explose ton budget tokens.
Une trace te montre ça en 10 secondes. Sans trace, tu es en mode archéologie.
Replay des prompts : reproduire une exécution, vraiment
Les logs et traces expliquent. Le replay permet de rejouer.
Mais attention, replay ne veut pas forcément dire « obtenir exactement le même texte ». Les modèles ne sont pas déterministes, et même avec temperature=0, il y a des variations selon fournisseurs, versions, et paramètres internes.
Le replay sert surtout à :
- reproduire les appels tools
- reproduire la chaîne de décisions
- comparer les sorties
- tester un changement de prompt, de policy ou de retrieval
- faire un audit
Les trois niveaux de replay
1) Replay « dry run »
Tu rejoues l’exécution mais tu bloques les actions side effect.
Exemple : l’agent simule stripe.refund mais ne l’exécute pas. Très utile.
2) Replay avec stubs
Tu remplaces les retours d’API externes par des réponses enregistrées.
Tu testes le raisonnement dans des conditions identiques.
3) Replay en production contrôlée
Tu rejoues sur un environnement isolé avec des données proches prod, mais sans impact réel. Plus coûteux, mais parfois nécessaire.
Ce qu’il faut sauvegarder pour un bon replay
Si tu veux que le replay serve, tu dois capturer :
- la version de l’agent (code, config)
- la version du prompt template
- le modèle et ses paramètres
- le contexte injecté (ou un identifiant qui permet de le reconstruire)
- les résultats des tools (au moins ceux non déterministes)
- la state machine interne (si tu as un planner, un router, etc.)
- les décisions de guardrails
Sinon tu vas « rejouer » un truc qui n’a rien à voir.
RAG, mémoire, outils : les zones où l’observabilité casse souvent
Retrieval (RAG)
Le RAG a un côté traître. L’utilisateur voit une réponse. Mais la vraie question c’est : « sur quelles sources l’agent s’est appuyé ? »
Minimum à tracer et logguer :
- query générée par l’agent (et sa version)
- top k documents (ids, titres, score)
- morceaux réellement injectés dans le prompt (pas juste les ids)
- longueur totale injectée (tokens)
- raison de filtrage (si tu filtres par permission ou fraîcheur)
Et oui, ça fait beaucoup. Mais sinon, bonne chance quand on te demandera : « pourquoi l’agent a dit ça ? »
Mémoire
Deux écritures mémoire non observées, et tu te retrouves avec un agent qui hallucine… en fait il se souvient mal, ou il a stocké une mauvaise info.
Loggue :
memory.read: clés lues, taille, sourcememory.write: clés écrites, taille, validation, policy- un diff ou un résumé, pas forcément le texte brut
Outils
Chaque tool call doit être traçable comme une requête réseau.
- input
- output
- latence
- retries
- rate limit
- erreurs
Et surtout, un champ critique : est ce que l’appel a eu un side effect ?
Parce que pour le replay, tu voudras rejouer sans side effect. Il te faut donc une classification.
Guardrails et conformité : observabilité ne veut pas dire fuite de données
On veut tout voir. Mais on ne peut pas tout stocker n’importe comment.
Checklist rapide :
- redaction de PII dans les logs
- séparation des stockages : logs techniques vs archives de replay
- chiffrement at rest et in transit
- contrôle d’accès strict, audit des accès
- politique de rétention (30 jours, 90 jours, selon contexte)
- versioning des prompts et policies
- marquage des données (public, interne, confidentiel)
Un point pratique : fais une table « prompt artifacts » dédiée, avec des permissions plus dures que tes logs applicatifs. Et dans les logs, référence juste un prompt_artifact_id.
Une architecture simple que tu peux copier
Si tu es en mode builder, voilà un montage réaliste :
- Logs structurés JSON vers un collecteur (OpenTelemetry Collector ou équivalent)
- Traces via OpenTelemetry
- Stockage logs dans Loki, Elastic, ou un SaaS
- Traces dans Tempo, Jaeger, Datadog, New Relic, etc.
- Artefacts de replay (prompts, tool outputs, snapshots) dans un stockage objet chiffré (S3 compatible)
- Une petite UI interne « run viewer » qui reconstruit l’exécution run par run
Oui, tu peux faire plus sophistiqué. Mais ça, déjà, ça te sort du noir.
Indicateurs utiles (ceux que tu regardes vraiment)
Quelques métriques qui valent de l’or en prod :
- coût moyen tokens par run
- latence p95 d’un run
- taux d’échec tool par tool
- nombre moyen de loops / steps par run
- taux de fallback modèle
- taux de blocage guardrail
- taux de réponses « je ne sais pas » (parfois c’est sain)
- divergence rate entre replay et run initial (si tu compares)
Et au niveau produit :
- taux de résolution sans humain
- taux d’escalade
- satisfaction
Exemple concret : un bug typique et comment l’observabilité le rend trivial
Scénario : ton agent support doit rembourser un client si certaines conditions sont remplies. Un jour, il rembourse trop.
Sans observabilité :
- tu lis deux logs,
- tu pries,
- tu ne trouves pas.
Avec logs + traces + replay :
- Trace
agent.runmontre 3 tool calls. - Le span
retrieval.querymontre que l’agent a récupéré une policy de remboursement obsolète. - Log
prompt_sentréférence un prompt template v1 alors que tu pensais être en v3. - Replay dry run confirme que, avec v3, la décision change.
Tu corriges :
- la source RAG
- la version de prompt
- et tu ajoutes un guardrail « max refund amount »
Fin.
Comment démarrer sans tout refaire
Si tu pars de zéro, fais ça dans cet ordre :
- Ajoute
run_id,session_id,trace_idpartout. Partout. - Loggue chaque
llm.callet chaquetool.callen structuré. - Branche OpenTelemetry pour les traces.
- Ajoute un stockage d’artefacts de replay (même minimal).
- Mets une convention de versioning des prompts (
prompt_name,prompt_version). - Ajoute redaction PII dès le début.
Tu peux itérer ensuite. Mais si tu rates l’étape 1, tu vas recoder plus tard, et tu vas râler.
Conclusion : un agent sans observabilité, c’est un stagiaire invisible
Tu peux avoir le meilleur modèle. Le meilleur planner. Les meilleurs tools. Sans observabilité, tu ne sais pas ce qui se passe. Tu ne peux pas prouver. Tu ne peux pas auditer. Tu ne peux pas améliorer proprement.
Logs structurés pour les faits. Traces pour le déroulé. Replay pour la reproductibilité. Et une discipline sur la donnée, sinon tu transformes ton système en passoire.
Si tu veux, je peux publier sur Le Blog Tech Pro de Samyn-Antoy ABASSE (https://monblog-sa-abasse.blogspot.com) une checklist téléchargeable « observabilité d’agents en production » et un petit template de schéma JSON pour standardiser tes événements. Ça évite de réinventer, et tu gagnes une semaine, facile.
Questions fréquemment posées
Pourquoi l'observabilité est-elle cruciale pour les agents IA ?
L'observabilité est essentielle pour les agents IA car ces derniers prennent des décisions complexes et non linéaires qui impliquent la reformulation de demandes, le choix d'outils, l'exécution d'actions et la gestion du contexte. Sans observabilité approfondie (logs structurés, traces distribuées, replay), il est impossible de comprendre précisément ce que l'agent a fait, d'expliquer ses décisions, de déboguer efficacement ou d'assurer la conformité.
En quoi l'observabilité d'un agent IA diffère-t-elle de celle d'une API classique ?
Contrairement à une API classique où les erreurs sont souvent localisées dans un flux linéaire simple (requête-handler-base de données), un agent IA suit un chemin décisionnel complexe et non linéaire avec des boucles, changements de plans et consommation dynamique du contexte. Cela rend les logs classiques insuffisants pour tracer ses actions et comprendre ses comportements.
Quels sont les trois piliers fondamentaux pour assurer une bonne observabilité des agents IA ?
Les trois piliers sont : 1) les logs structurés qui enregistrent précisément 'quoi' s'est passé, 2) les traces distribuées qui montrent 'où' et dans quel ordre les événements se sont déroulés, et 3) le replay des prompts permettant de reproduire 'comment' l'agent a raisonné afin d'expliquer, auditer ou corriger son comportement.
Quels éléments doivent être inclus dans un log structuré pour un agent IA ?
Un log structuré minimal doit contenir : timestamp, niveau (level), nom du service ou agent (service/agent_name), environnement (env), trace_id, span_id, session_id, run_id, type d'événement (event_type), durée en ms (duration_ms), usage des tokens (prompt_tokens, completion_tokens), modèle utilisé (model), nom et arguments de l'outil appelé (tool_name/tool_args si applicable), résumé du résultat outil (tool_result_summary), type et message d'erreur si présent (error_type/error_message).
Pourquoi éviter les logs texte classiques comme print("calling tool...") en production ?
Les logs texte simples ne s'agrègent pas facilement, ne permettent pas un filtrage ou une corrélation efficace entre événements. Ils rendent le débogage complexe en production. Les logs structurés au format JSON avec champs stables facilitent l'analyse automatisée, la recherche ciblée et la compréhension fine des comportements de l'agent.
Faut-il logger intégralement les prompts envoyés aux modèles IA ?
Logger intégralement les prompts est sensible car cela peut exposer des données confidentielles ou volumineuses. Il faut trouver un équilibre en loggant suffisamment d'informations pour reproduire et comprendre le raisonnement de l'agent sans compromettre la sécurité ou la performance. Un résumé ou une version anonymisée peut être une bonne pratique.
0 Commentaires