0Pricing
AI Agents · Leçon

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 steps

Journaliser 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

  1. Échecs courants des boucles d’agents
  2. Journalisation des traces des étapes d’un agent
  3. Détecter et interrompre les boucles infinies
  4. Techniques de débogage pas à pas
← Retour à AI Agents