Journalisation des traces des étapes d’un agent
Journalisez chaque étape de raisonnement, appel d’outil et résultat pour l’analyse post-incident.
Journalisation des traces des étapes d’un agent est une leçon AI Agents gratuite sur CoddyKit. Ceci est la leçon 2 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage AI Agents, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours AI Agents comprend 4 leçons au total.
Pourquoi la journalisation des traces est essentielle pour les agents
Les journaux d’application classiques enregistrent les erreurs et les événements. Les journaux de trace des agents enregistrent le raisonnement : à quoi l’agent a-t-il pensé à chaque étape, quel outil a-t-il choisi, quels arguments a-t-il utilisés et qu’a renvoyé l’outil ?
Sans journalisation des traces, déboguer une défaillance d’agent revient à diagnostiquer un problème de voiture sans tableau de bord : vous ne pouvez que deviner.
Configurer le module de journalisation de Python
Le module intégré logging de Python est l’outil standard. Configurez-le au démarrage de votre agent avec un format qui comprend l’horodatage, le niveau et le message. Utilisez le niveau DEBUG pour les données de trace : vous pourrez le désactiver en production.
import logging
import sys
logging.basicConfig(
level=logging.DEBUG,
format='%(asctime)s [%(levelname)s] %(name)s: %(message)s',
datefmt='%H:%M:%S',
stream=sys.stdout
)
logger = logging.getLogger('myagent')
# Usage:
logger.debug('Step 1: reasoning started')
logger.info('Agent task completed in 5 steps')
logger.warning('Tool returned empty result')
logger.error('Failed to parse tool arguments')
# Output:
# 14:32:01 [DEBUG] myagent: Step 1: reasoning started
# 14:32:03 [INFO] myagent: Agent task completed in 5 stepsJournaliser chaque étape du raisonnement
Journalisez les informations essentielles au début de chaque étape : son numéro, le raisonnement produit par le LLM, l’outil sélectionné et les arguments transmis. Vous créez ainsi un relevé complet du processus de décision de l’agent.
import logging
import json
logger = logging.getLogger('myagent')
def log_step(step: int, thought: str, tool_name: str, tool_args: dict):
logger.debug(
f'Step {step}: '
f'reasoning="{thought[:100]}" '
f'tool={tool_name} '
f'args={json.dumps(tool_args, ensure_ascii=False)[:200]}'
)
# Example usage in the agent loop:
# log_step(
# step=1,
# thought='I need to find the current weather in Tokyo',
# tool_name='get_weather',
# tool_args={'city': 'Tokyo', 'unit': 'celsius'}
# )
if __name__ == '__main__':
import sys
logging.basicConfig(level=logging.DEBUG, format='%(message)s', stream=sys.stdout)
log_step(
step=1,
thought='I need to find the current weather in Tokyo',
tool_name='get_weather',
tool_args={'city': 'Tokyo', 'unit': 'celsius'}
)
Journaliser les résultats des outils
Après chaque appel d’outil, journalisez s’il a réussi ainsi qu’un aperçu du résultat. Journaliser le résultat complet peut être trop verbeux : tronquez-le aux 200 premiers caractères pour faciliter la lecture.
import logging
logger = logging.getLogger('myagent')
def log_tool_result(step: int, tool_name: str, result: str, success: bool):
status = 'OK' if success else 'ERROR'
preview = str(result)[:200].replace('\n', ' ')
logger.debug(
f'Step {step} result [{status}]: tool={tool_name} '
f'result_preview="{preview}"'
)
if not success:
logger.warning(f'Tool {tool_name} failed at step {step}')
# Log at the start of the step:
# log_step(step, thought, tool_name, tool_args)
# result = execute_tool(tool_name, tool_args)
# log_tool_result(step, tool_name, result, success=True)
if __name__ == '__main__':
import sys
logging.basicConfig(level=logging.DEBUG, format='%(message)s', stream=sys.stdout)
log_tool_result(1, 'get_weather', '{"temp_c": 18, "condition": "cloudy"}', success=True)
log_tool_result(2, 'get_weather', 'Connection timed out', success=False)
Journalisation structurée au format JSON
Les journaux en texte brut sont faciles à lire, mais difficiles à interroger. Les journaux JSON structurés peuvent être ingérés par des systèmes d’agrégation de journaux (Datadog, Splunk, CloudWatch) afin d’appliquer des filtres et de créer des tableaux de bord et des alertes.
import logging
import json
import sys
class JSONFormatter(logging.Formatter):
def format(self, record: logging.LogRecord) -> str:
log_obj = {
'timestamp': self.formatTime(record),
'level': record.levelname,
'logger': record.name,
'message': record.getMessage()
}
# Add any extra fields attached to the log record
if hasattr(record, 'step'):
log_obj['step'] = record.step
if hasattr(record, 'tool'):
log_obj['tool'] = record.tool
return json.dumps(log_obj)
handler = logging.StreamHandler(sys.stdout)
handler.setFormatter(JSONFormatter())
logger = logging.getLogger('agent_trace')
logger.addHandler(handler)
logger.setLevel(logging.DEBUG)
logger.setLevel(logging.DEBUG)
logger.debug('Step 3: tool=search_web', extra={'step': 3, 'tool': 'search_web'})
Journaliser des champs supplémentaires
Transmettez extra={} à un appel de journalisation pour ajouter des champs structurés que les formateurs JSON ou les agrégateurs de journaux pourront utiliser pour le filtrage et l’analyse.
import logging
logger = logging.getLogger('agent_trace')
def log_step_structured(step: int, tool: str, thought: str, args: dict):
logger.debug(
f'Step {step}: tool={tool}',
extra={
'step': step,
'tool': tool,
'thought': thought[:200],
'tool_args': args
}
)
# If using a JSON formatter, this produces:
# {
# 'timestamp': '14:32:01',
# 'level': 'DEBUG',
# 'message': 'Step 3: tool=search_web',
# 'step': 3,
# 'tool': 'search_web',
# 'thought': 'I need to find recent news about...',
# 'args': {'query': 'AI news 2025'}
# }
if __name__ == '__main__':
import sys
handler = logging.StreamHandler(sys.stdout)
handler.setFormatter(logging.Formatter('%(message)s | step=%(step)s tool=%(tool)s'))
logger.addHandler(handler)
logger.setLevel(logging.DEBUG)
log_step_structured(3, 'search_web', 'I need to find recent news about...', {'query': 'AI news 2025'})
Journaliser dans un fichier
Pour les agents de production, journalisez dans un fichier afin de permettre une analyse ultérieure. Utilisez RotatingFileHandler pour plafonner la taille du fichier de journal et éviter de saturer le disque.
import logging
from logging.handlers import RotatingFileHandler
import sys
logger = logging.getLogger('myagent')
logger.setLevel(logging.DEBUG)
# Console handler — INFO and above
console = logging.StreamHandler(sys.stdout)
console.setLevel(logging.INFO)
console.setFormatter(logging.Formatter('%(message)s'))
# File handler — DEBUG and above, rotates at 10MB
file_handler = RotatingFileHandler(
'agent_trace.log',
maxBytes=10 * 1024 * 1024, # 10 MB
backupCount=3
)
file_handler.setLevel(logging.DEBUG)
file_handler.setFormatter(logging.Formatter(
'%(asctime)s [%(levelname)s] %(message)s'
))
logger.addHandler(console)
logger.addHandler(file_handler)
logger.info('Agent task completed in 5 steps')
logger.debug('Step 1: reasoning started')
Journaliser les identifiants de session pour les agents multi-utilisateurs
Lorsque plusieurs utilisateurs ou tâches s’exécutent simultanément, les journaux peuvent se mélanger. Ajoutez un identifiant de session ou de tâche à chaque message de journalisation afin de pouvoir filtrer les journaux correspondant à une exécution précise.
import logging
import uuid
class SessionLogger:
def __init__(self, name: str):
self.logger = logging.getLogger(name)
self.session_id = str(uuid.uuid4())[:8]
def debug(self, msg: str, **kwargs):
self.logger.debug(f'[session={self.session_id}] {msg}', **kwargs)
def info(self, msg: str, **kwargs):
self.logger.info(f'[session={self.session_id}] {msg}', **kwargs)
def error(self, msg: str, **kwargs):
self.logger.error(f'[session={self.session_id}] {msg}', **kwargs)
# Each agent run gets its own logger with a unique session ID
# log = SessionLogger('myagent')
# log.info(f'Starting task: {query}') # [session=a3f1b290] Starting task: ...
if __name__ == '__main__':
import sys
logging.basicConfig(level=logging.INFO, format='%(message)s', stream=sys.stdout)
log = SessionLogger('myagent')
log.info(f'Starting task: summarize the quarterly report')
Mesurer la durée de chaque étape
Ajoutez des informations de durée à chaque journal d’étape afin d’identifier les goulots d’étranglement. Quel outil est le plus lent ? Combien de temps le LLM met-il à raisonner ? Ces données orientent l’optimisation.
import time
import logging
logger = logging.getLogger('myagent')
def timed_tool_call(tool_name: str, tool_fn, args: dict) -> str:
start = time.perf_counter()
try:
result = tool_fn(**args)
elapsed = time.perf_counter() - start
logger.debug(f'Tool {tool_name} completed in {elapsed:.2f}s')
return result
except Exception as e:
elapsed = time.perf_counter() - start
logger.error(f'Tool {tool_name} failed in {elapsed:.2f}s: {e}')
raise
# In the agent loop:
# result = timed_tool_call('search_web', search_web, {'query': 'Python'})
# Logs: Tool search_web completed in 1.34s
if __name__ == '__main__':
import sys
logging.basicConfig(level=logging.DEBUG, format='%(message)s', stream=sys.stdout)
def search_web(query):
return f'3 results for {query}'
result = timed_tool_call('search_web', search_web, {'query': 'Python'})
print('Tool result:', result)
Le schéma complet de trace d’une étape
Voici le schéma complet et prêt pour la production de journalisation des traces d’une étape d’agent. Chaque étape journalise son numéro, le raisonnement, le choix de l’outil, les arguments, un aperçu du résultat et la durée, ce qui vous donne une visibilité complète sur l’exécution de l’agent.
import time
import logging
import json
logger = logging.getLogger('myagent')
def trace_step(step_num: int, thought: str, tool: str, args: dict, execute_fn):
# Log decision
logger.debug(
f'Step {step_num}: thought="{thought[:80]}" tool={tool} '
f'args={json.dumps(args)[:100]}'
)
# Execute with timing
t0 = time.perf_counter()
try:
result = execute_fn(tool, args)
elapsed = time.perf_counter() - t0
preview = str(result)[:100].replace('\n', ' ')
logger.debug(f'Step {step_num} done in {elapsed:.2f}s: "{preview}"')
return result
except Exception as e:
elapsed = time.perf_counter() - t0
logger.error(f'Step {step_num} failed in {elapsed:.2f}s: {e}')
return f'ERROR: {e}'
if __name__ == '__main__':
import sys
logging.basicConfig(level=logging.DEBUG, format='%(message)s', stream=sys.stdout)
def execute_fn(tool, args):
return f'42 (from {tool})'
trace_step(1, 'I should compute the answer', 'calculator', {'expr': '6*7'}, execute_fn)
Désactiver les journaux en production
Les journaux de trace de débogage contiennent des données sensibles (requêtes, réponses d’API) et peuvent être très verbeux. En production, définissez le niveau de journalisation sur INFO ou WARNING pour supprimer les traces de débogage. Utilisez une variable d’environnement pour contrôler le niveau.
import os
import logging
import sys
# Read log level from environment variable
log_level_str = os.environ.get('LOG_LEVEL', 'INFO').upper()
log_level = getattr(logging, log_level_str, logging.INFO)
logging.basicConfig(level=log_level, stream=sys.stdout)
logger = logging.getLogger('myagent')
# Development: LOG_LEVEL=DEBUG python agent.py -> full traces
# Production: LOG_LEVEL=WARNING python agent.py -> only warnings/errors
# Default: LOG_LEVEL not set -> INFO level
logger.debug('This only appears in DEBUG mode')
logger.info('This appears in INFO and DEBUG modes')
logger.warning('This always appears')Vérification des connaissances : journalisation des traces
Testez votre compréhension de la journalisation des traces des étapes d’un agent.
Bilan : journalisation des traces des étapes d’un agent
Vous disposez désormais d’une stratégie complète de journalisation des traces pour les agents :
- Utilisez
logging.basicConfig(level=DEBUG)pour activer les journaux de niveau trace - Journalisez le numéro de l’étape, le raisonnement, le nom de l’outil et les arguments à chaque étape
- Journalisez les résultats des outils avec un aperçu et l’indication de réussite ou d’échec
- Utilisez le format JSON pour obtenir des journaux structurés et interrogeables
- Ajoutez des identifiants de session pour les agents multi-utilisateurs ou concurrents
- Ajoutez la durée pour identifier les étapes lentes
- Contrôlez la verbosité des journaux avec la variable d’environnement
LOG_LEVEL
Questions Fréquemment Posées
La leçon « Journalisation des traces des étapes d’un agent » est-elle gratuite ?
Oui — le texte complet de « Journalisation des traces des étapes d’un agent » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours AI Agents, passe à CoddyKit PRO. Le cours AI Agents comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « Journalisation des traces des étapes d’un agent » ?
Journalisez chaque étape de raisonnement, appel d’outil et résultat pour l’analyse post-incident. Tu pratiques AI Agents avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer AI Agents ?
Aucune expérience préalable n'est requise. AI Agents sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 2 sur 4.
Combien de temps prend la leçon « Journalisation des traces des étapes d’un agent » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon AI Agents ?
Oui. Chaque leçon AI Agents inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- Échecs courants des boucles d’agents
- Journalisation des traces des étapes d’un agent
- Détecter et interrompre les boucles infinies
- Techniques de débogage pas à pas