L’idée en 30 secondes
Step limits sont un contrôle runtime qui arrête de force un run quand l’agent boucle ou ne produit pas de progrès.
Quand c’est nécessaire : quand un agent tourne en loop, interagit avec des tools, et peut répéter les mêmes actions en production.
Le problème
Sans step limits, un agent “fait quelque chose” mais n’avance pas vers le résultat. En démo, ça peut sembler normal. En production, ça devient vite du coût, de la latence et du bruit dans les logs.
Pattern typique :
- une réponse tool instable
- répétition de la même action
- encore une répétition
- puis le même cycle
Analogie : c’est comme un GPS qui boucle au même carrefour. La voiture roule, mais ne se rapproche pas de la destination.
Pour éviter un incident, les limites doivent être dans la runtime loop, pas dans l’UI ni le prompt.
La solution
La solution consiste à mettre le contrôle des steps dans une couche policy au niveau runtime. Chaque step est vérifié après la formation de l’action suivante, mais avant l’exécution.
Le policy layer renvoie une de ces décisions :
allowstop (reason=max_steps)stop (reason=loop_detected)stop (reason=no_progress)
C’est une couche système séparée, pas une partie du prompt ni de la logique du modèle.
Step limits ≠ Budget controls
Ce sont des couches de contrôle différentes :
- Step limits contrôlent le comportement de la boucle (combien et quel type de steps l’agent exécute)
- Budget controls contrôlent les ressources du run (temps, coût, nombre d’actions)
L’un sans l’autre ne suffit pas :
- sans step limits, une boucle peut tourner longtemps sans progrès
- sans budget controls, même une boucle “limitée” peut coûter cher
Exemple :
- step limits :
max_steps=18,max_repeat_action=3 - budget controls :
max_seconds=45,max_usd=1.00
Métriques de contrôle des steps
Ces vérifications travaillent ensemble à chaque step de l’agent.
| Métrique | Ce qu’elle contrôle | Mécaniques clés | Pourquoi |
|---|---|---|---|
| Step cap | Longueur maximale du run | max_stepscompteur de steps runtime | Stoppe une boucle infinie avant la hausse des coûts |
| Repeat-action control | Répétition de la même action | max_repeat_actionclé tool + args | Détecte les loops où le même appel est répété |
| No-progress control | Situations sans progrès réel | no_progress_windowcontrôle des changements d’état | Stoppe le run quand il y a des steps mais pas de progrès |
| Stop reason surfacing | Transparence de la cause d’arrêt | stop reason explicitepartial response | Utilisateur et équipe voient pourquoi le run est stoppé |
À quoi ça ressemble dans l’architecture
La couche step policy se place dans la runtime loop entre planning et exécution d’action.
Chaque décision (allow ou stop) est écrite dans l’audit log.
Chaque step de l’agent passe par ce flow avant exécution : la runtime n’exécute pas l’action suivante directement, elle passe d’abord les step-checks.
Résumé du flow :
- Runtime forme l’action suivante
- Step policy layer vérifie
max_steps, répétitions et progrès allow-> l’action suivante de l’agent est exécutéestop-> stop reason + partial response sont renvoyés- les deux décisions sont écrites dans l’audit log
Exemple
Un agent de support appelle search.docs plusieurs fois à cause d’une réponse externe instable.
Avec step limits :
max_steps = 18max_repeat_action = 3no_progress_window = 4
-> le run s’arrête avec un stop reason explicite au lieu de continuer la boucle sans fin.
Step limits stoppent l’incident au niveau runtime loop au lieu de dépendre du comportement du modèle.
En code, ça ressemble à ça
Le schéma simplifié ci-dessus montre le control flow principal. En pratique, les step-checks s’exécutent de façon centralisée avant chaque action.
Exemple de configuration step :
step_limits:
max_steps: 18
max_repeat_action: 3
no_progress_window: 4
while True:
# Ici, un step est compté comme une intention d’action, pas comme une action déjà exécutée.
state = state.with_step_increment()
action = planner.next(state) # planner forme l’action pour ce step
repeat_key = make_repeat_key(action.name, action.args) # clé normalisée tool+args
decision = step_policy.check(state, action, repeat_key=repeat_key)
if decision.outcome == "stop":
audit.log(
run_id,
decision.outcome,
reason=decision.reason,
step=state.steps,
action=action.name,
repeat_key=repeat_key,
)
return stop(decision.reason)
result = tool.execute(action.args)
state = state.apply(action, result)
decision = Decision.allow(reason="step_ok")
audit.log(
run_id,
decision.outcome,
reason=decision.reason,
step=state.steps,
action=action.name,
repeat_key=repeat_key,
result=result.status,
)
if result.final:
return result
Step policy vérifie généralement trois signaux : limite de steps, répétition des actions et absence de progrès.
Pour la loop detection, il faut une clé tool+args, pas seulement action.name.
À quoi ça ressemble pendant l’exécution
Scénario 1 : max_steps atteint
- Runtime forme le step 19 et incrémente le compteur.
- Policy détecte le dépassement de
max_steps. - Décision :
stop (reason=max_steps). - La cause d’arrêt est écrite dans l’audit log.
- L’utilisateur reçoit une partial response.
Scénario 2 : loop détectée
- Runtime forme plusieurs fois
search.docsavec les mêmes args. - Policy compte les répétitions
tool+args. - Décision :
stop (reason=loop_detected). - Le run s’arrête avant l’appel inutile suivant.
- Les logs montrent la cause exacte et l’action.
Scénario 3 : exécution normale
- Runtime forme un nouveau step.
- Policy vérifie les limites : tout est dans les bornes.
- Décision :
allow. - L’action suivante de l’agent est exécutée.
- Résultat et décision sont enregistrés dans l’audit log.
Erreurs typiques
- mettre
max_stepsseulement en UI, pas dans la runtime loop - ne pas retourner un stop reason explicite dans la réponse
- compter seulement les tool calls et ignorer les steps
- ne pas vérifier les répétitions (
tool + args) et no-progress - logger seulement les steps réussis sans décisions stop
- mettre un
max_stepstrop haut “au cas où”
Résultat : le run semble actif, mais la boucle grandit plus vite que la visibilité de l’équipe.
Auto-vérification
Vérification rapide des step limits avant mise en production :
Progression: 0/8
⚠ Les contrôles de governance de base manquent
Avant la production, il faut au minimum le contrôle d'accès, des limites, des audit logs et un arrêt d'urgence.
FAQ
Q : Quel max_steps de départ utiliser ?
A : Pour la plupart des runs synchrones, commence à 15-25. Ajuste ensuite selon la fréquence des stops en situation réelle.
Q : max_steps seul suffit ?
A : Non. Ajoute au minimum max_repeat_action et un contrôle no-progress. En production, il faut aussi des budgets (max_seconds, max_usd, max_tool_calls).
Q : Le plus important, repeat detection ou no-progress ?
A : Les deux. Repeat detection attrape les répétitions explicites, no-progress attrape les “boucles douces” où les actions changent mais le progrès est absent.
Q : Que doit voir l’utilisateur quand on stoppe ?
A : Partial response + stop reason explicite + une action suivante courte (reformuler la demande ou relancer avec un autre scope).
Q : Step limits remplacent kill switch ?
A : Non. Step limits pilotent chaque run, kill switch sert à l’arrêt global d’urgence.
Où se placent Step Limits dans le système
Step limits sont une des couches d’Agent Governance. Avec RBAC, budgets, approval et audit, ils forment un système unifié de contrôle d’exécution.
Pages liées
Suite du sujet :
- Vue d’ensemble Agent Governance — modèle global de contrôle des agents en production.
- Budget Controls — comment limiter temps, actions et coût.
- Rate limiting pour agents — comment limiter la fréquence des requêtes vers tools et API.
- Kill switch — comment arrêter un agent en urgence pendant un incident.
- Infinite loop — mode de failure classique des boucles et détection.