Comment arrêter de surveiller constamment les agents IA ?

Ashley Innocent

Ashley Innocent

24 March 2026

Comment arrêter de surveiller constamment les agents IA ?

enterprise.banner.title

enterprise.banner.feature1

enterprise.banner.feature2

enterprise.banner.feature3

enterprise.banner.ctaB

En bref

Vous cessez de surveiller les agents IA en construisant trois éléments : des garde-fous (contraintes qui empêchent les échecs catastrophiques), de l'observabilité (journaux et métriques qui vous indiquent ce qui s'est passé) et des points de contrôle (pauses automatiques où les humains vérifient les décisions). Mettez-les en place une seule fois, et vos agents pourront fonctionner de manière autonome pendant des heures au lieu de minutes. Des outils comme Apidog vous aident en vous permettant de définir des contrats d'API que les agents ne peuvent pas violer, transformant votre couche API en un filet de sécurité.

Introduction

La semaine dernière, j'ai vu un développeur passer 4 heures à superviser un agent IA qui était censé lui faire gagner du temps. Toutes les quelques minutes, il l'interrompait, corrigeait une erreur et le redémarrait. Au final, il avait fait plus de travail manuel que s'il avait écrit le code lui-même.

C'est le problème de la surveillance constante, et c'est la raison n°1 pour laquelle les agents IA ne tiennent pas leurs promesses. Les outils fonctionnent. Les modèles sont performants. Mais la plupart des équipes ne dépassent jamais la phase de supervision constante.

Voici ce qui se passe : la plupart des configurations d'agents IA traitent le LLM comme un développeur junior qui a besoin d'être guidé à chaque tâche. Mais les LLM ne sont pas des juniors. Ils ressemblent plutôt à des stagiaires extrêmement rapides, occasionnellement en proie à des hallucinations, qui feront la mauvaise chose en toute confiance si vous ne fixez pas de limites.

💡
Si vous créez des API ou travaillez avec des agents IA qui appellent des API, Apidog vous aide à définir ces limites. En spécifiant des schémas de requête/réponse exacts, vous créez des contrats que les agents ne peuvent pas violer accidentellement. C'est comme donner une carte à votre agent au lieu de le laisser errer.
bouton

Définissez des contrats d'API que vos agents IA peuvent suivre

À la fin de ce guide, vous aurez :

Pourquoi les agents ont besoin d'une supervision constante

Les agents IA échouent de manière prévisible. Comprendre ces modes d'échec est la première étape pour les corriger.

Mode d'échec 1 : Dérive du périmètre

Vous demandez à un agent d'« ajouter l'authentification au point de terminaison de l'API ». Il ajoute l'authentification. Ensuite, il ajoute la limitation de débit. Puis il refactorise le schéma de la base de données. Puis il supprime ce qu'il considère comme des fichiers « inutilisés », qui s'avèrent être importants.

L'agent a continué parce que personne ne lui avait dit de s'arrêter. Les LLM n'ont pas un sens inné de ce qui est « terminé ». Ils continueront à apporter des modifications jusqu'à ce qu'ils atteignent une limite de jetons ou que vous les interrompiez.

Mode d'échec 2 : Mauvaises abstractions

Un agent chargé d'« améliorer la gestion des erreurs » pourrait ajouter des blocs try-catch partout. Techniquement correct. Pratiquement terrible. Le code devient illisible, la journalisation est incohérente et les cas d'erreur réels ne sont pas gérés.

L'agent a compris la requête littéralement mais a manqué l'intention. Sans exemples de bonne gestion des erreurs, il s'est rabattu sur l'interprétation la plus évidente (et la pire).

Mode d'échec 3 : Défaillances en cascade

Un agent fait une petite erreur à l'étape 1. À l'étape 10, cette erreur s'est propagée à travers chaque décision ultérieure. Ce qui a commencé comme une faute de frappe dans un nom de fonction devient une API cassée, des tests cassés et un développeur confus essayant de comprendre ce qui n'a pas fonctionné.

C'est le mode d'échec le plus dangereux car l'agent ne sait pas qu'il a échoué. Chaque étape semble raisonnable isolément. Seul le résultat final révèle le problème.

Mode d'échec 4 : Épuisement des ressources

Laissés sans supervision, certains agents boucleront indéfiniment. Ils retenteront indéfiniment les appels d'API échoués, généreront de nouveaux sous-agents sans limite, ou continueront à générer du code jusqu'à ce qu'ils atteignent votre plafond de facturation.

Sans contraintes de ressources, les agents ne savent pas quand s'arrêter.

Le cadre d'autonomie : garde-fous, observabilité, points de contrôle

Vous résolvez ces problèmes avec trois couches. Pensez-y comme une pyramide : les garde-fous à la base (prévention des échecs), l'observabilité au milieu (détection des échecs) et les points de contrôle au sommet (récupération après échec).

Couche 1 : Garde-fous (prévention)

Les garde-fous sont des contraintes qui empêchent les échecs catastrophiques. Ce sont des règles que votre agent ne peut pas enfreindre, appliquées par le code, et non par des invites.

Contraintes strictes via le code :

# À éviter : Faire confiance à l'agent pour suivre les instructions
agent.run("Only modify files in the src/ directory")

# À faire : Appliquer les contraintes dans le code
import os
from pathlib import Path

ALLOWED_DIRECTORIES = {"src", "tests", "docs"}

def validate_file_path(path: str) -> bool:
    """L'agent ne peut pas écrire en dehors des répertoires autorisés."""
    abs_path = Path(path).resolve()
    return any(
        str(abs_path).startswith(str(Path(d).resolve()))
        for d in ALLOWED_DIRECTORIES
    )

# Utilisation dans les opérations de fichiers de votre agent
def agent_write_file(path: str, content: str):
    if not validate_file_path(path):
        raise ValueError(f"Impossible d'écrire dans {path} : en dehors des répertoires autorisés")
    with open(path, 'w') as f:
        f.write(content)

Contraintes de schéma d'API :

Lorsque votre agent appelle des API, utilisez des schémas pour prévenir les requêtes malformées. C'est là qu'Apidog excelle. Définissez votre contrat d'API une seule fois, et votre agent ne pourra pas envoyer de données de forme incorrecte.

// apidog-schema.ts
export const CreateUserSchema = {
  type: 'object',
  required: ['email', 'name'],
  properties: {
    email: { type: 'string', format: 'email' },
    name: { type: 'string', minLength: 1, maxLength: 100 },
    role: { type: 'string', enum: ['user', 'admin', 'guest'] }
  },
  additionalProperties: false
}

// L'agent doit valider avant d'appeler l'API
function validateRequest(schema: object, data: unknown): void {
  const valid = ajv.validate(schema, data)
  if (!valid) {
    throw new Error(`Requête invalide : ${JSON.stringify(ajv.errors)}`)
  }
}

Contraintes budgétaires :

import time
from dataclasses import dataclass

@dataclass
class AgentBudget:
    max_steps: int = 50
    max_tokens: int = 100000
    max_time_seconds: int = 600  # 10 minutes
    max_api_calls: int = 100

class BudgetEnforcer:
    def __init__(self, budget: AgentBudget):
        self.budget = budget
        self.start_time = time.time()
        self.steps = 0
        self.tokens_used = 0
        self.api_calls = 0
    
    def check(self) -> bool:
        """Renvoie False si le budget est dépassé."""
        elapsed = time.time() - self.start_time
        
        if self.steps >= self.budget.max_steps:
            raise RuntimeError(f"Limite d'étapes atteinte : {self.steps}")
        if self.tokens_used >= self.budget.max_tokens:
            raise RuntimeError(f"Limite de jetons atteinte : {self.tokens_used}")
        if elapsed >= self.budget.max_time_seconds:
            raise RuntimeError(f"Limite de temps atteinte : {elapsed:.0f}s")
        if self.api_calls >= self.budget.max_api_calls:
            raise RuntimeError(f"Limite d'appels API atteinte : {self.api_calls}")
        
        return True
    
    def record_step(self, tokens: int, api_calls: int = 0):
        self.steps += 1
        self.tokens_used += tokens
        self.api_calls += api_calls
        self.check()

Couche 2 : Observabilité (détection)

Lorsque les agents fonctionnent pendant des heures, vous devez savoir ce qu'ils font sans surveiller chaque étape. L'observabilité vous fournit une chronologie des décisions.

Journalisation structurée :

import json
from datetime import datetime
from typing import Any

class AgentLogger:
    def __init__(self, log_file: str = "agent_trace.jsonl"):
        self.log_file = log_file
        self.entries = []
    
    def log(self, event: str, data: dict[str, Any] | None = None):
        entry = {
            "timestamp": datetime.utcnow().isoformat(),
            "event": event,
            "data": data or {}
        }
        self.entries.append(entry)
        
        # Ajouter au fichier immédiatement (ne pas perdre les logs en cas de crash)
        with open(self.log_file, 'a') as f:
            f.write(json.dumps(entry) + '\n')
    
    def log_decision(self, decision: str, reasoning: str, confidence: float):
        """Journalise lorsqu'un agent prend une décision importante."""
        self.log("decision", {
            "decision": decision,
            "reasoning": reasoning,
            "confidence": confidence
        })
    
    def log_action(self, action: str, params: dict, result: str):
        """Journalise les actions des agents et leurs résultats."""
        self.log("action", {
            "action": action,
            "params": params,
            "result": result[:200]  # Tronquer les résultats longs
        })
    
    def log_error(self, error: str, context: dict):
        """Journalise les erreurs avec le contexte complet."""
        self.log("error", {
            "error": error,
            "context": context
        })

# Utilisation dans l'agent
logger = AgentLogger()
logger.log_decision(
    decision="Ajouter la limitation de débit à l'API",
    reasoning="Le point de terminaison actuel n'a aucune protection contre les abus",
    confidence=0.85
)
logger.log_action(
    action="écrire_fichier",
    params={"chemin": "src/middleware/rate-limit.ts"},
    result="45 lignes écrites avec succès"
)

Tableau de bord des métriques :

Pour les agents fonctionnant plus longtemps, vous souhaitez des métriques agrégées, pas seulement des journaux individuels.

from collections import Counter
from dataclasses import dataclass, field

@dataclass
class AgentMetrics:
    actions_taken: Counter = field(default_factory=Counter)
    files_modified: list[str] = field(default_factory=list)
    api_calls: dict[str, int] = field(default_factory=dict)
    errors: list[str] = field(default_factory=list)
    decisions_by_confidence: dict[str, int] = field(default_factory=lambda: {
        "élevée (>0.9)": 0,
        "moyenne (0.7-0.9)": 0,
        "faible (<0.7)": 0
    })
    
    def record_action(self, action: str):
        self.actions_taken[action] += 1
    
    def record_file_modification(self, path: str):
        if path not in self.files_modified:
            self.files_modified.append(path)
    
    def record_api_call(self, endpoint: str):
        self.api_calls[endpoint] = self.api_calls.get(endpoint, 0) + 1
    
    def record_error(self, error: str):
        self.errors.append(error)
    
    def record_decision(self, confidence: float):
        if confidence > 0.9:
            self.decisions_by_confidence["élevée (>0.9)"] += 1
        elif confidence >= 0.7:
            self.decisions_by_confidence["moyenne (0.7-0.9)"] += 1
        else:
            self.decisions_by_confidence["faible (<0.7)"] += 1
    
    def summary(self) -> str:
        return f"""
Résumé des métriques de l'agent
=====================
Actions : {dict(self.actions_taken)}
Fichiers modifiés : {len(self.files_modified)}
Appels API : {self.api_calls}
Erreurs : {len(self.errors)}
Décisions par confiance : {self.decisions_by_confidence}
"""

Couche 3 : Points de contrôle (récupération)

Les points de contrôle sont des pauses automatiques où l'agent attend la vérification humaine. Ils vous permettent de détecter les problèmes tôt sans supervision constante.

Points de contrôle automatiques :

from enum import Enum
from typing import Callable

class CheckpointTrigger(Enum):
    BEFORE_FILE_WRITE = "before_file_write"
    BEFORE_API_CALL = "before_api_call"
    BEFORE_GIT_COMMIT = "before_git_commit"
    BEFORE_DELETE = "before_delete"
    AFTER_N_STEPS = "after_n_steps"

@dataclass
class Checkpoint:
    trigger: CheckpointTrigger
    description: str
    data: dict
    requires_approval: bool = True

class CheckpointManager:
    def __init__(self, auto_approve: set[CheckpointTrigger] | None = None):
        self.auto_approve = auto_approve or set()
        self.pending: list[Checkpoint] = []
    
    def create_checkpoint(
        self, 
        trigger: CheckpointTrigger, 
        description: str, 
        data: dict
    ) -> bool:
        """Renvoie True si approuvé, False si rejeté."""
        
        # Approuver automatiquement certains déclencheurs
        if trigger in self.auto_approve:
            return True
        
        checkpoint = Checkpoint(
            trigger=trigger,
            description=description,
            data=data
        )
        self.pending.append(checkpoint)
        
        # Dans un système réel, cela notifierait l'humain et attendrait
        # Pour l'instant, nous renvoyons False pour mettre en pause l'exécution
        return False
    
    def approve(self, checkpoint_id: int) -> None:
        """L'humain approuve un point de contrôle en attente."""
        if 0 <= checkpoint_id < len(self.pending):
            self.pending.pop(checkpoint_id)
    
    def reject(self, checkpoint_id: int) -> None:
        """L'humain rejette un point de contrôle en attente."""
        raise RuntimeError(f"Point de contrôle rejeté : {self.pending[checkpoint_id]}")

# Utilisation dans l'agent
checkpoints = CheckpointManager(
    auto_approve={CheckpointTrigger.BEFORE_FILE_WRITE}  # Faire confiance aux écritures de fichiers
)

# Avant une action destructrice
if not checkpoints.create_checkpoint(
    trigger=CheckpointTrigger.BEFORE_DELETE,
    description="Sur le point de supprimer le répertoire src/legacy/",
    data={"chemin": "src/legacy/", "fichiers": ["old_handler.ts", "deprecated.ts"]}
):
    # Attendre l'approbation humaine
    agent.pause("En attente d'approbation pour supprimer des fichiers")

Construire des agents autonomes avec Apidog

Lorsque votre agent IA interagit avec des API, le plus grand risque est celui des requêtes malformées qui provoquent des échecs en aval. Apidog vous aide en vous permettant de définir des schémas d'API exacts que votre agent doit suivre.

Mise en place de contrats d'API :

  1. Importez ou définissez votre spécification OpenAPI dans Apidog
  2. Générez du code client avec validation intégrée
  3. Donnez à votre agent le client validé au lieu du HTTP brut
// Au lieu de laisser l'agent appeler directement les API
const response = await fetch('/api/users', {
  method: 'POST',
  body: JSON.stringify(data)  // Pas de validation
})

// Donner à l'agent un client validé
import { UsersApi } from './generated/apidog-client'

const usersApi = new UsersApi()
// L'agent ne peut envoyer que des requêtes valides - schéma appliqué
const response = await usersApi.createUser({
  email: 'user@example.com',
  name: 'Test User',
  role: 'user'  // Doit être une valeur d'énumération valide
})

Cela transforme votre couche API en un garde-fou. L'agent ne peut littéralement pas envoyer de données invalides car le client les rejette avant que la requête ne soit envoyée.

Générez des clients API validés pour vos agents IA

Modèles éprouvés et erreurs courantes

Modèle 1 : Le sandwich d'approbation

Pour les opérations risquées, exigez une approbation avant ET après.

def risky_operation(agent, operation):
    # Pré-approbation
    if not agent.checkpoint(f"Sur le point de : {operation.description}"):
        return "Annulé par l'utilisateur"
    
    # Exécuter l'opération
    result = operation.execute()
    
    # Post-approbation (vérifier le résultat)
    if not agent.checkpoint(f"Vérifier le résultat de : {operation.description}"):
        operation.rollback()
        return "Annulé par l'utilisateur"
    
    return result

Modèle 2 : Seuils de confiance

Ne laissez pas les agents agir sur des décisions à faible confiance.

MIN_CONFIDENCE = 0.75

def agent_decide(options: list[dict]) -> dict:
    best = max(options, key=lambda x: x.get('confidence', 0))
    
    if best['confidence'] < MIN_CONFIDENCE:
        # Transférer à l'humain
        return {
            'action': 'escalate',
            'reason': f"La meilleure option a une confiance de {best['confidence']:.2f} < {MIN_CONFIDENCE}",
            'options': options
        }
    
    return best

Modèle 3 : Opérations idempotentes

Concevez les actions de votre agent de manière à ce qu'elles soient reproductibles sans effets secondaires.

import hashlib

def idempotent_write(path: str, content: str) -> bool:
    """Écrit uniquement si le contenu a changé."""
    content_hash = hashlib.sha256(content.encode()).hexdigest()
    
    existing_hash = None
    if os.path.exists(path):
        with open(path, 'r') as f:
            existing_hash = hashlib.sha256(f.read().encode()).hexdigest()
    
    if content_hash == existing_hash:
        logger.log_action("écrire_fichier", {"chemin": path}, "Ignoré - pas de modifications")
        return False
    
    with open(path, 'w') as f:
        f.write(content)
    logger.log_action("écrire_fichier", {"chemin": path}, f"Écrit {len(content)} octets")
    return True

Erreurs courantes à éviter

Faire confiance aux invites comme contraintes. « Ne pas supprimer de fichiers » dans une invite n'est pas une contrainte. Les permissions de fichiers sont des contraintes.

Pas de plan de retour arrière. Lorsqu'un agent fait une erreur, vous devez l'annuler. Si vous n'utilisez pas Git ou des sauvegardes, vous confiez à l'agent des actions irrécupérables.

Ignorer les scores de confiance. La plupart des LLM produisent un score de confiance ou peuvent être invités à le faire. Faible confiance = pause et interrogation humaine.

Sur-surveillance. Si vous surveillez chaque étape, vous n'avez pas construit un système autonome. Vous avez construit un système manuel lent.

Sous-spécification du succès. L'agent doit savoir quand il a terminé. « Corriger le bug » n'a pas de condition de fin. « Corriger le bug ET tous les tests passent » en a une.


Alternatives et comparaisons

Approche Autonomie Risque Idéal pour
Codage manuel Nulle Faible Travail complexe et critique
Programmation en binôme avec l'IA Faible Faible Apprentissage, exploration
Agents supervisés Moyenne Moyenne Tâches routinières
Agents autonomes avec garde-fous Élevée Contrôlé Opérations en masse, migrations
Agents entièrement autonomes Très élevée Élevée Workflows fiables et bien testés

La plupart des équipes devraient viser l'« autonomie avec garde-fous ». C'est le juste milieu où vous obtenez 80 % des gains de temps avec 10 % du risque.


Cas d'utilisation réels

Migration de codebase. Une équipe a utilisé un agent autonome pour migrer 200 points de terminaison d'API de REST vers GraphQL. Les garde-fous ont empêché les modifications de schéma. Les points de contrôle exigeaient une approbation avant de supprimer les anciens points de terminaison. La migration a pris 3 jours au lieu de 3 semaines, sans aucun incident de production.

Génération de documentation. Un agent génère automatiquement la documentation API à partir du code. Les garde-fous garantissent qu'il ne lit que dans des répertoires spécifiques. Les points de contrôle se mettent en pause avant la publication. L'équipe révise une fois par semaine au lieu de rédiger la documentation manuellement.

Couverture de test. Un agent analyse le code et écrit les tests manquants. Les contraintes budgétaires empêchent la génération de tests incontrôlée. Des seuils de confiance signalent les tests incertains pour examen humain. La couverture est passée de 60 % à 85 % en un mois.

En résumé

Voici ce que vous avez appris :

bouton

Vos prochaines étapes :

  1. Identifiez votre tâche assistée par IA la plus répétitive
  2. Définissez les garde-fous : qu'est-ce que l'agent ne doit jamais faire ?
  3. Ajoutez une journalisation structurée pour voir ce qui se passe
  4. Créez des points de contrôle pour les opérations à haut risque
  5. Laissez-le fonctionner pendant 30 minutes et vérifiez les journaux

L'objectif n'est pas de retirer les humains de la boucle. C'est de placer les humains au bon endroit dans la boucle : prendre des décisions de haut niveau au lieu de corriger des erreurs de bas niveau.

Construisez des garde-fous API pour vos agents IA - gratuit

FAQ

Quelle est la différence entre un agent IA et un assistant IA ?Un assistant répond à vos requêtes et attend votre prochaine instruction. Un agent prend un objectif et planifie et exécute de manière autonome des étapes pour l'atteindre. Les assistants ont besoin de vous à chaque étape. Les agents fonctionnent jusqu'à ce qu'ils atteignent un point de contrôle ou terminent.

Comment savoir si mon agent est prêt à fonctionner de manière autonome ?Exécutez-le en mode supervisé pendant 10 sessions. Suivez chaque fois que vous avez dû intervenir. Si les interventions tombent en dessous de 2 par session et qu'elles étaient toutes mineures (clarifications, pas corrections), il est prêt. Si les interventions sont fréquentes ou nécessitent d'annuler le travail, ajoutez davantage de garde-fous.

Quel est le plus grand risque avec les agents autonomes ?Les défaillances en cascade que l'agent ne reconnaît pas. Une petite erreur précoce devient un gros problème plus tard, et l'agent continue parce que chaque étape semble raisonnable isolément. Les points de contrôle brisent ces cascades en imposant une vérification.

Puis-je utiliser ces modèles avec n'importe quel LLM ?Oui. Les modèles (garde-fous, observabilité, points de contrôle) sont agnostiques au modèle. Ils fonctionnent avec Claude, GPT-4, Gemini ou tout autre modèle. Les détails d'implémentation spécifiques peuvent varier, mais les concepts se transfèrent.

À quel point l'observabilité ralentit-elle l'agent ?Négligeable. Écrire dans un fichier journal prend des microsecondes. Le ralentissement provient des points de contrôle qui attendent l'entrée humaine. Pour des exécutions véritablement autonomes, vous ne définissez des points de contrôle que lors des moments à haut risque, pas à chaque étape.

Que se passe-t-il si l'agent prend une décision avec laquelle je ne suis pas d'accord ?C'est à cela que servent les points de contrôle. Lorsque vous voyez une décision avec laquelle vous n'êtes pas d'accord, rejetez le point de contrôle. L'agent annule ou essaie une approche différente. Mieux : incluez vos préférences dans les instructions de l'agent afin qu'il apprenne votre style au fil du temps.

Dois-je commencer par des agents supervisés ou autonomes ?Commencez toujours en mode supervisé. Exécutez l'agent avec des points de contrôle sur chaque action significative jusqu'à ce que vous lui fassiez confiance. Supprimez progressivement les points de contrôle pour les actions à faible risque. Cela renforce la confiance de manière incrémentale au lieu de risquer une défaillance catastrophique lors de votre première exécution autonome.

Comment Apidog aide-t-il spécifiquement avec les agents IA ?Apidog génère des clients API validés à partir de vos schémas. Lorsqu'un agent utilise ces clients, les requêtes malformées sont rejetées avant d'atteindre votre backend. Cela empêche toute une catégorie de défaillances où l'agent envoie une forme de données incorrecte ou des valeurs invalides.

Pratiquez le Design-first d'API dans Apidog

Découvrez une manière plus simple de créer et utiliser des API