Anti-Pattern No Stop Conditions : agents sans conditions d’arrêt

Quand un agent ne sait jamais quand arrêter l’exécution.
Sur cette page
  1. Idée en 30 secondes
  2. Exemple de l'anti-pattern
  3. Pourquoi cela arrive et ce qui se passe mal
  4. Bonne approche
  5. Test rapide
  6. Différence avec les autres anti-patterns
  7. No Monitoring vs No Stop Conditions
  8. Agents Without Guardrails vs No Stop Conditions
  9. Auto-vérification : avez-vous cet anti-pattern ?
  10. FAQ
  11. Et ensuite

Idée en 30 secondes

No Stop Conditions est un anti-pattern où un agent démarre sans conditions de fin claires.

Résultat : l'agent peut boucler et consommer du budget sans progrès réel. Cela augmente la latency, le cost et le risque d'effets secondaires (changements d'état).

Règle simple : chaque run d'agent doit avoir des stop conditions explicites pour une terminaison réussie et une sortie sûre.


Exemple de l'anti-pattern

L'équipe construit un agent support qui doit trouver une réponse dans des données internes et retourner le résultat à l'utilisateur.

Mais la boucle agent n'a pas de stop conditions claires.

PYTHON
state = init_state(user_message)

while True:
    decision = agent.next_step(state)
    result = run_tool(decision.tool, decision.args)
    state.append(result)
    # pas de has_final_answer(...)
    # pas de no_progress(...)
    # pas de vérification repeated_action(...)

Dans ce schéma, l'agent peut répéter indéfiniment des étapes similaires :

PYTHON
search_docs -> fetch_page -> summarize -> search_docs -> ...

Pour ce cas, il faut une boucle contrôlée avec des limites explicites :

PYTHON
for step in range(MAX_STEPS):
    ...
    if has_final_answer(state):
        return build_answer(state)

Ici, l'absence de stop conditions entraîne :

  • risque de runaway loop (boucle infinie)
  • appels tool et LLM inutiles
  • consommation non contrôlée du temps et du budget

Pourquoi cela arrive et ce qui se passe mal

Cet anti-pattern apparaît souvent quand l'équipe se repose sur le modèle et suppose qu'il va "comprendre" seul quand arrêter.

Causes typiques :

  • absence de max_steps, timeout ou budget limit explicite
  • pas de définition de ce qu'est une "réponse prête"
  • pas de vérification no_progress ni d'actions répétées
  • le contrôle d'arrêt reste uniquement au niveau infrastructure

Cela crée des problèmes :

  • boucles infinies ou longues - l'agent répète des étapes proches sans terminer
  • latency plus élevée - la réponse arrive beaucoup plus tard, ou n'arrive jamais
  • cost plus élevé - le nombre d'étapes LLM/tool augmente pour une demande
  • effets secondaires (changements d'état) - actions répétées pouvant créer des doublons, réappliquer un statut, dupliquer un appel API ou renvoyer une action externe
  • résultats instables - une même demande se termine différemment selon les runs

Signaux production typiques montrant que les stop conditions sont absentes ou faibles :

  • une part visible des runs finit en infrastructure timeout au lieu d'un arrêt contrôlé
  • le P95 du nombre d'étapes augmente en continu
  • les traces montrent des appels identiques répétés avec peu de changement d'arguments
  • le cost per request augmente plus vite que le success rate

Point important : chaque étape suivante fait partie de l'inference LLM. Si la boucle n'a pas de conditions de fin claires, le modèle continue à choisir "encore une étape", même quand il n'y a presque plus d'information utile nouvelle.

Quand ce schéma grossit, sans trace ni visualisation d'exécution, il devient difficile d'expliquer pourquoi un run ne s'est pas arrêté à temps. C'est pourquoi les systèmes de production ont généralement une couche d'observabilité dédiée aux runs d'agents.

Bonne approche

Commencez par la boucle contrôlée la plus simple qui couvre de façon stable la majorité des demandes actuelles. Ajoutez de nouvelles stop conditions uniquement lorsqu'il existe un échec mesurable, un risque ou une limite du design actuel.

Cadre pratique :

  • définissez une condition de fin positive (final_answer_ready)
  • définissez des garde-fous (max_steps, timeout, budget)
  • ajoutez des vérifications no_progress et des actions répétées
  • enregistrez stop reason pour chaque run et suivez les métriques (par exemple, amélioration de success rate sans forte hausse de latency et de cost per request)

En pratique, no_progress signifie souvent répétition des mêmes appels tool, changements d'état minimes, ou absence de nouvelle information utile après une étape supplémentaire.

PYTHON
MAX_STEPS = 8

def run_agent(user_message: str):
    state = init_state(user_message)

    for step in range(MAX_STEPS):  # hard limit for runaway loops
        if timed_out():
            return stop("timeout")
        if budget_exceeded():
            return stop("budget_exceeded")

        decision = agent.next_step(state)

        if decision.type == "final_answer":
            if validate_output(decision.output):  # format, required fields, no empty answer
                return decision.output
            return stop("invalid_output")

        result = run_tool(decision.tool, decision.args)
        if no_progress(state, result):  # same tool/result pattern or no meaningful state change
            return stop("no_progress")

        state.append(result)

    return stop("max_steps_exceeded")

Dans ce schéma, la boucle devient contrôlée : le système retourne soit une réponse valide, soit un arrêt avec raison transparente.

Test rapide

Si vous répondez "oui" à ces questions, vous avez un risque no-stop-conditions :

  • Une partie des runs se termine-t-elle en timeout au lieu d'un stop_reason contrôlé ?
  • Une seule demande fait-elle parfois un nombre disproportionné d'étapes sans progrès visible ?
  • Les traces montrent-elles des actions similaires répétées sans nouveau résultat ?

Différence avec les autres anti-patterns

No Monitoring vs No Stop Conditions

No MonitoringNo Stop Conditions
Problème principal : le système n'a pas assez d'observabilité pour voir ce qui se passe pendant un run.Problème principal : la boucle agent n'a pas de conditions de fin claires.
Quand il apparaît : quand logs de run, traces, métriques et stop_reason sont absents.Quand il apparaît : quand un run continue sans max_steps, timeout, budget limit ni vérification no_progress.

Agents Without Guardrails vs No Stop Conditions

Agents Without GuardrailsNo Stop Conditions
Problème principal : l'agent fonctionne sans policy boundaries ni limites système.Problème principal : l'agent peut exécuter des boucles infinies ou trop longues.
Quand il apparaît : quand il n'y a pas d'allowlist, de deny-by-default, de limites budget ou safety.Quand il apparaît : quand la logique de boucle n'a ni critère de fin explicite ni stop_reason contrôlé.

Auto-vérification : avez-vous cet anti-pattern ?

Vérification rapide de l'anti-pattern No Stop Conditions.
Cochez les points pour votre système et regardez le statut ci-dessous.

Vérifiez votre système :

Progression: 0/8

⚠ Il y a des signes de cet anti-pattern

Essayez de déplacer les étapes simples dans un workflow et de garder l'agent uniquement pour les décisions complexes.

FAQ

Q : Si on a max_steps, est-ce déjà suffisant ?
R : Non. max_steps est nécessaire, mais ne couvre pas tous les risques à lui seul. Il faut aussi timeout, budget limit, vérification du progrès et critère valide de réponse prête.

Q : Quand ajouter une nouvelle stop condition ?
R : Quand il existe un signal concret : incidents, boucles répétées, hausse de cost ou de latency que les règles actuelles ne couvrent pas sans complexité disproportionnée.

Q : Comment démarrer si les stop conditions sont presque absentes aujourd'hui ?
R : Commencez avec le minimum : max_steps, timeout, budget, stop_reason dans les logs. Ajoutez ensuite no_progress et validation de la réponse finale.


Et ensuite

Anti-patterns proches :

  • No Monitoring - quand vous ne voyez pas que l'agent boucle ou se dégrade.
  • Too Many Tools - quand l'excès d'outils augmente le nombre d'étapes inutiles.
  • Overengineering Agents - quand la complexité supplémentaire rend le contrôle de fin plus difficile.

Ce qu'il faut construire à la place :

  • Stop Conditions - modèle de base pour définir des conditions d'arrêt sûres.
  • Step Limits - comment définir des limites d'étapes au niveau gouvernance.
  • Budget Controls - comment limiter le coût d'un run.
  • Kill Switch - arrêt d'urgence quand le système sort du contrôle.
⏱️ 7 min de lectureMis à jour 16 mars 2026Difficulté: ★★★
Implémenter dans OnceOnly
Safe defaults for tool permissions + write gating.
Utiliser dans OnceOnly
# onceonly guardrails (concept)
version: 1
tools:
  default_mode: read_only
  allowlist:
    - search.read
    - kb.read
    - http.get
writes:
  enabled: false
  require_approval: true
  idempotency: true
controls:
  kill_switch: { enabled: true, mode: disable_writes }
audit:
  enabled: 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)
  • Permissions outils (allowlist / blocklist)
  • Kill switch & arrêt incident
  • Idempotence & déduplication
  • Audit logs & traçabilité
Mention intégrée : OnceOnly est une couche de contrôle pour des systèmes d’agents en prod.
Auteur

Cette documentation est organisée et maintenue par des ingénieurs qui déploient des agents IA en production.

Le contenu est assisté par l’IA, avec une responsabilité éditoriale humaine quant à l’exactitude, la clarté et la pertinence en production.

Les patterns et recommandations s’appuient sur des post-mortems, des modes de défaillance et des incidents opérationnels dans des systèmes déployés, notamment lors du développement et de l’exploitation d’une infrastructure de gouvernance pour les agents chez OnceOnly.