Idée en 30 secondes
Budget controls = des limites runtime qui arrêtent un run quand l'agent dépasse les seuils de pas, de temps, d'appels d'outil ou de coût.
Quand c'est nécessaire : quand l'agent appelle des outils externes, peut faire des retries, et travaille avec un vrai budget en production.
Problème
Sans budgets, un agent en production entre facilement dans une boucle : plus de pas, plus d'appels d'outil, plus de coûts. En demo, on ne le voit pas car la charge est faible. En production, ce comportement devient vite un incident.
Une réponse instable d'un outil déclenche souvent une chaîne : retry -> nouvel appel d'outil -> plus de tokens -> encore un retry. S'il n'y a pas de limite runtime stricte, le run continue plus longtemps et coûte plus cher que prévu.
Analogie : c'est comme une course sans plafond sur le compte taxi de l'entreprise. Tant que la course est courte, tout semble normal. Quand le trajet s'allonge, les coûts montent discrètement jusqu'au débit.
Solution
La solution est de déplacer les vérifications budgétaires dans la couche de policy du runtime.
Chaque étape de l'agent est contrôlée avec quatre limites : max_steps, max_seconds, max_tool_calls, max_usd.
La couche de policy renvoie une décision technique : allow ou stop avec une raison explicite (max_steps, max_seconds, max_tool_calls, max_usd).
Cette décision est prise à chaque étape, pas seulement à la fin du run.
C'est une couche système séparée, pas une partie du prompt ou de la logique du modèle.
Budget Controls != Rate Limiting
Ce sont deux niveaux de contrôle différents :
- Rate limiting limite la fréquence des requêtes vers un système ou un outil.
- Budget controls limitent la dépense totale d'un seul run.
L'un sans l'autre ne fonctionne pas :
- sans budget controls, un seul run peut devenir trop coûteux
- sans rate limiting, beaucoup de runs peuvent saturer les dépendances
Exemple :
- rate limit : pas plus de 10 requêtes par minute vers
search_api - budget controls : pas plus de
max_tool_calls=12etmax_usd=1.00sur un run
Métriques de contrôle budgétaire
Ces métriques et signaux travaillent ensemble à chaque étape de l'agent.
| Métrique | Ce qu'elle contrôle | Mécaniques clés | Pourquoi |
|---|---|---|---|
| Step budget | La longueur du run en étapes | max_stepsstop reason max_steps | Arrête les boucles avant la hausse des coûts |
| Time budget | La durée du run en secondes | max_secondswall-clock timeout | Empêche les runs longs de bloquer les ressources |
| Tool-call budget | Le nombre d'appels d'outil | max_tool_callslimite d'appels par run | Limite le tool spam et les chaînes de retries |
| Spend budget | La dépense monétaire par run | max_usdcalcul du usage | Pose une frontière financière stricte |
| Observability (budget) | La visibilité sur les décisions budgétaires | audit logs alerts (Slack / PagerDuty) | Ne limite pas directement les actions, mais permet d'identifier et d'expliquer rapidement le dépassement |
Exemple d'alert :
Slack: 🛑 Agent Support-Bot hit max_usd limit ($100). Run stopped at step 12.
Comment cela se place dans l'architecture
La couche de policy budget se place entre runtime et exécution d'action et vérifie les limites avant chaque étape.
Chaque décision (allow ou stop) est enregistrée dans l'audit log.
Chaque étape de l'agent passe par ce flow avant exécution : runtime n'exécute pas directement l'action — d'abord la vérification budget, puis l'exécution.
Résumé du flow :
- Runtime met à jour le usage (étapes, temps, appels d'outil, coût)
- la couche de policy budget vérifie les limites
allow-> l'étape suivante est exécutéestop-> stop reason et partial response sont renvoyés- les deux décisions sont écrites dans l'audit log
Exemple
Un agent support traite une demande et appelle plusieurs fois refund.lookup à cause d'une API instable.
Avec budget controls :
max_tool_calls = 8max_seconds = 45max_usd = 1.00
-> le run est arrêté dès que la limite est atteinte, pas après une hausse incontrôlée des coûts.
Budget controls arrêtent l'incident au niveau exécution, sans dépendre du fait que le modèle s'arrête tout seul.
Dans le code, cela ressemble à ceci
Dans le schéma simplifié ci-dessus, le control flow principal est montré. En pratique, le budget check est souvent exécuté deux fois : avant l'exécution de l'étape et après mise à jour du usage réel. Le compteur d'étapes est mis à jour avant la vérification pour inclure l'étape courante dans le budget.
usage.update(step=1)
decision = budget.check(usage, limits)
if not decision.allowed:
audit.log(run_id, decision.outcome, reason=decision.reason, usage=usage.snapshot())
alerts.notify_if_needed(run_id, decision.reason, usage.snapshot())
return stop(decision.reason)
result = tool.execute(args)
usage.update(tool_call=1, usd=result.cost_usd)
decision = budget.check(usage, limits)
if not decision.allowed:
audit.log(run_id, decision.outcome, reason=decision.reason, usage=usage.snapshot())
alerts.notify_if_needed(run_id, decision.reason, usage.snapshot())
return stop(decision.reason)
audit.log(run_id, decision.outcome, reason=decision.reason, usage=usage.snapshot(), result=result.status)
return result
Comment cela se passe pendant l'exécution
Scénario 1 : limite atteinte (stop)
1. Runtime termine l'étape 9 et met à jour le usage réel.
2. La budget policy voit que max_usd est dépassé.
3. Décision : stop (max_usd).
4. Audit : decision=stop, reason=max_usd, step=9.
5. L'utilisateur reçoit une partial response avec stop reason.
---
Scénario 2 : limite non atteinte (allow)
1. Runtime démarre l'étape 4 et met à jour le usage.
2. La budget policy vérifie les limites : tout est dans les seuils.
3. Décision : allow.
4. L'appel d'outil est exécuté.
5. Audit : decision=allow, usage mis à jour, résultat renvoyé.
Erreurs fréquentes
- limiter seulement les tokens et ignorer
max_seconds,max_tool_callsetmax_usd - vérifier les budgets seulement "à la fin", pas avant chaque étape
- ne pas retourner un stop reason explicite à l'utilisateur
- disperser la logique budget entre runtime, tools et UI
- ne pas logguer les budget decisions (
allow/stop) dans l'audit trail - ne pas activer d'alerting sur
max_usdetmax_tool_calls
Résultat : le système semble stable, mais sous charge il perd vite sa prévisibilité.
Auto-vérification
Vérification rapide des budget controls avant lancement 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: Un token budget seul suffit-il ?
A: Non. Les tools peuvent coûter plus cher que les tokens. Minimum : max_steps, max_seconds, max_tool_calls, max_usd.
Q: Que mettre en place d'abord : max_steps ou max_usd ?
A: Commence par max_steps et max_tool_calls pour arrêter les boucles immédiatement. Puis ajoute max_usd comme limite financière.
Q: Que faut-il renvoyer à l'utilisateur lors d'un budget stop ?
A: Partial response + stop reason explicite + courte indication de suite (réduire la demande ou relancer avec un budget plus élevé).
Q: Faut-il des budgets par tenant ?
A: Oui. Différents plans ou équipes nécessitent des limites différentes, mais la mécanique de vérification doit rester identique.
Q: Les budget controls remplacent-ils le rate limiting ?
A: Non. Le rate limiting protège les dépendances des pics, alors que les budget controls protègent un run des runaway-coûts.
Où Budget Controls se place dans le système global
Budget controls est une des couches d'Agent Governance. Avec RBAC, execution limits, approval et audit, il forme un système unifié de contrôle d'exécution.
Pages liées
Pour continuer :
- Vue d'ensemble Agent Governance — modèle global de contrôle des agents en production.
- Contrôle d'accès (RBAC) — comment limiter qui peut appeler quoi.
- Rate Limiting pour agents — comment protéger outils et API des pics de charge.
- Step Limits — comment arrêter les boucles infinies via le nombre d'étapes.
- Audit logs pour agents — comment analyser les incidents via stop reasons et décisions de policy layer.