Agent Drift : quand les agents IA perdent progressivement le focus

Le drift d’agent apparaît quand un agent IA s’éloigne peu à peu de la tâche initiale. Pourquoi cela arrive en production et comment le limiter.
Sur cette page
  1. Le problème
  2. Pourquoi cela arrive
  3. Quels échecs arrivent le plus souvent
  4. Drift de modèle
  5. Drift de prompt
  6. Drift de contrat d'outil
  7. Drift retrieval et contexte
  8. Comment détecter ces problèmes
  9. Comment distinguer un drift d'un changement réellement utile
  10. Comment arrêter ces échecs
  11. Où c'est implémenté dans l'architecture
  12. Auto-vérification
  13. FAQ
  14. Pages liées

Le problème

Vu de l'extérieur, tout semble stable. Le monitoring ne crie pas, il n'y a pas d'incident explicite, et le taux de succès (success rate) reste presque identique.

Mais les métriques de run montrent un décalage : il y a une semaine cet agent fermait la tâche en 2-3 étapes, et après une petite mise à jour de prompt et de version de modèle, il en faut 7-9.

Le système n'a pas planté.

Il a juste dérivé lentement de côté.

Analogie : imagine une balance de magasin qui se trompe de 1-2 grammes par jour. Le premier jour c'est presque invisible. Au bout d'un mois, l'erreur impacte déjà toute la caisse. Avec un agent c'est pareil : un petit drift à chaque run crée une grosse perte à l'échelle.

Pourquoi cela arrive

Les agents LLM sont des systèmes stochastiques. Un petit changement de modèle, prompt ou données d'entrée peut modifier l'ordre des étapes. Même un faible écart dans le reasoning loop s'accumule en drift avec le temps.

En production, le drift avance généralement en silence :

  1. le modèle, prompt, tool output ou les données retrieval changent ;
  2. l'agent continue formellement de terminer les tâches ;
  3. mais il suit d'autres étapes et consomme plus de ressources ;
  4. sans comparaison au baseline, cela ressemble à "tout va bien".

Le problème n'est pas un changement isolé. Le problème est l'absence de contrôle de release qui attrape tôt les écarts par rapport au baseline.

Quels échecs arrivent le plus souvent

Pour rester pratique, en production on distingue généralement quatre types de drift.

Drift de modèle

Après un changement de version LLM, l'agent classe les étapes autrement : il "re-vérifie" plus souvent, termine plus tard, ou choisit un autre tool.

Cause typique : version de modèle mise à jour sans comparaison baseline sur un jeu de tâches golden.

Drift de prompt

Une petite modification du system prompt change les priorités de l'agent : il devient "trop prudent" ou "trop actif".

Cause typique : prompt modifié comme texte, pas comme code de production avec test et canary.

Drift de contrat d'outil

Un tool renvoie un champ nouveau, un format d'erreur différent, ou un tableau vide au lieu de null. L'agent l'interprète différemment et modifie sa boucle de décision.

En production, cela bascule facilement vers échec d'outil ou tool spam.

Drift retrieval et contexte

L'index de connaissances est mis à jour : nouveaux documents, ranking modifié, plus de chunks non pertinents dans la context window. L'agent fonctionne formellement, mais utilise plus souvent de mauvais faits.

Par symptômes, cela ressemble souvent à context poisoning.

Comment détecter ces problèmes

Le drift se voit mieux non pas via une métrique unique, mais via les écarts par rapport au baseline.

MétriqueSignal de driftQue faire
tool_calls_per_taskhausse lente mais stablecomparer candidate au baseline, ajouter des seuils d'écart
tokens_per_taskconsommation plus élevée sans gain qualitévérifier prompt et caps sur tool output
latency_p95dégradation après releasecanary + rollback automatique sur seuil
stop_reason_distributionplus de timeout ou max_steps_reachedvérifier les nouvelles boucles et changements de policy dans le prompt
task_success_ratequasi stable, mais autres métriques dégradéesne pas se fier uniquement au success rate, analyser le profil complet du run

Comment distinguer un drift d'un changement réellement utile

Tout changement de comportement n'est pas mauvais. Parfois, la nouvelle version est vraiment meilleure. La vraie question : la qualité a-t-elle progressé sans coût disproportionné.

Normal si :

  • la qualité monte et tokens_per_task + latency_p95 restent proches ;
  • le nouveau comportement est stable sur les tâches golden ;
  • le canary ne montre pas de hausse de timeout et max_steps_reached.

Dangereux si :

  • success rate est similaire, mais coût et latence augmentent ;
  • les stop reasons se déplacent vers les limites ;
  • l'agent appelle davantage les outils sans gain de précision.

Comment arrêter ces échecs

En pratique, ça ressemble à ceci :

  1. tu fais un changement (candidate) ;
  2. dans CI, le Drift gate lance les tests et compare candidate vs baseline sur quality/tokens/tool calls/latency/stop reasons ;
  3. si les seuils sont violés, release est bloquée ou rollback ;
  4. si les seuils passent, le changement part en canary puis en rollout complet.
TEXT
baseline
   ↓
candidate evaluation
   ↓
threshold gate
   ↓
canary
   ↓
production

Barrière minimale anti-drift dans runtime CI :

PYTHON
from dataclasses import dataclass


@dataclass(frozen=True)
class Thresholds:
    max_tool_calls_delta: int = 2
    max_tokens_delta_pct: float = 0.30
    max_latency_delta_pct: float = 0.30
    allow_stop_reason_change: bool = False


def violates_thresholds(baseline: dict, candidate: dict, t: Thresholds) -> list[str]:
    errors: list[str] = []

    if candidate["tool_calls"] > baseline["tool_calls"] + t.max_tool_calls_delta:
        errors.append("tool_calls_delta_exceeded")

    if candidate["tokens"] > baseline["tokens"] * (1 + t.max_tokens_delta_pct):
        errors.append("tokens_delta_exceeded")

    if candidate["latency_ms"] > baseline["latency_ms"] * (1 + t.max_latency_delta_pct):
        errors.append("latency_delta_exceeded")

    if (not t.allow_stop_reason_change) and candidate["stop_reason"] != baseline["stop_reason"]:
        errors.append("stop_reason_changed")

    return errors

Cette barrière ne fait pas de magie. Elle évite juste de shipper une régression plus lente et plus coûteuse, déguisée en release "réussie".

Où c'est implémenté dans l'architecture

Le contrôle du drift est généralement réparti entre deux couches.

Agent Runtime capture les signaux de drift pendant l'exécution : stop_reason_distribution, steps_per_task, tokens_per_task. Sans ces métriques, un threshold gate ne peut rien comparer.

Tool Execution Layer est une source d'une partie du drift : changement de format de tool output, nouvelle retry policy, ou contrat d'erreur différent modifient en silence le comportement de l'agent. C'est ici qu'il faut versionner les contrats d'outils.

Auto-vérification

Vérification rapide avant release. Coche les points et regarde le statut ci-dessous.
C'est un sanity-check court, pas un audit formel.

Progression: 0/7

⚠ Il y a des signaux de risque

Il manque des contrôles de base. Fermez les points clés de la checklist avant release.

FAQ

Q : Drift veut toujours dire que le modèle est devenu pire ?
R : Non. Drift veut dire que le comportement a changé. C'est mauvais quand ce changement n'est ni mesuré ni contrôlé.

Q : Peut-on détecter le drift uniquement via success rate ?
R : Non. Success rate arrive souvent en retard. tool_calls, tokens, latence et stop reasons bougent avant.

Q : Canary est nécessaire pour de petites modifs de prompt ?
R : Pour les systèmes high-traffic, oui. Même une phrase peut changer les choix d'action de l'agent.

Q : Que faire si drift existe mais qualité un peu meilleure ?
R : Calcule les unit economics : coût par run réussi en baseline et candidate. Si la qualité monte et que le coût reste dans le budget, ship et fixe le nouveau baseline.


Agent drift ressemble rarement à un crash. C'est une régression lente visible uniquement par comparaison au baseline. C'est pourquoi les agents de production demandent non seulement de meilleurs modèles, mais aussi un contrôle strict des releases.

Pages liées

Pour mieux couvrir le drift en production, regarde :

⏱️ 7 min de lectureMis à jour 12 mars 2026Difficulté: ★★☆
Implémenter dans OnceOnly
Guardrails for loops, retries, and spend escalation.
Utiliser dans OnceOnly
# onceonly guardrails (concept)
version: 1
budgets:
  max_steps: 25
  max_tool_calls: 12
  max_seconds: 60
  max_usd: 1.00
policy:
  tool_allowlist:
    - search.read
    - http.get
controls:
  loop_detection:
    enabled: true
    dedupe_by: [tool, args_hash]
  retries:
    max: 2
    backoff_ms: [200, 800]
stop_reasons:
  enabled: true
logging:
  tool_calls: { enabled: true, store_args: false, store_args_hash: true }
Intégré : contrôle en productionOnceOnly
Ajoutez des garde-fous aux agents tool-calling
Livrez ce pattern avec de la gouvernance :
  • Budgets (steps / plafonds de coût)
  • Kill switch & arrêt incident
  • Audit logs & traçabilité
  • Idempotence & déduplication
  • Permissions outils (allowlist / blocklist)
Mention intégrée : OnceOnly est une couche de contrôle pour des systèmes d’agents en prod.
Exemple de policy (concept)
# Example (Python — conceptual)
policy = {
  "budgets": {"steps": 20, "seconds": 60, "usd": 1.0},
  "controls": {"kill_switch": True, "audit": True},
}

Auteur

Nick — ingénieur qui construit une infrastructure pour des agents IA en production.

Focus : patterns d’agents, modes de défaillance, contrôle du runtime et fiabilité des systèmes.

🔗 GitHub: https://github.com/mykolademyanov


Note éditoriale

Cette documentation est assistée par l’IA, avec une responsabilité éditoriale humaine pour l’exactitude, la clarté et la pertinence en production.

Le contenu s’appuie sur des défaillances réelles, des post-mortems et des incidents opérationnels dans des systèmes d’agents IA déployés.