Aller au contenu principal

Budgets de session Managed Agents

Avancé
What you'll learn
  • Plafonner ce qu'une seule session Managed Agents peut dépenser, en cents entiers US, avant son démarrage
  • Lire la séquence d'événements en quatre étapes qui se déclenche quand une session se met en pause à budget_reached
  • Comprendre le dépassement d'une requête — pourquoi un plafond de 0,50 $ peut s'arrêter à 0,53 $, et comment le dimensionner
  • Reprendre une session en pause en augmentant ou supprimant le plafond — et savoir pourquoi la suppression est à sens unique
  • Poser un plafond par exécution sur un déploiement planifié pour que les runs récurrents ne dérivent pas en dépenses incontrôlées
  • Distinguer les budgets de session des budgets de tâche de l'API Messages (indicatifs, en tokens, sur une seule boucle)

Une session Managed Agents autonome peut se réveiller à 3 h du matin, tomber sur un résultat d'outil coriace et se mettre à boucler. Sans plafond, le seul garde-fou est la limite de débit de votre organisation ou une alerte de monitoring lue après le café. Les budgets de session sont le correctif natif d'Anthropic : un plafond ferme en dollars, défini à la création de la session, appliqué par la plateforme entre les requêtes au modèle.

Deux choses les distinguent de toute « alerte de coût » que vous avez pu construire :

  • Le plafond est appliqué avant chaque requête au modèle côté plateforme, et non par votre webhook après coup. Une session budgétée se met en pause d'elle-même.
  • Le plafond est en cents entiers US, tarifé aux tarifs publics affichés d'Anthropic — pas votre tarif négocié. Si votre organisation bénéficie d'une remise, la session atteint son plafond en dollars affichés et votre dépense facturée est plus basse.

Budgets de session vs budgets de tâche — ne les confondez pas

Deux primitives « budget » existent maintenant sur la plateforme Claude. Elles résolvent des problèmes différents.

Budgets de session (cette page)Budgets de tâche (API Messages)
SurfaceSession / déploiement Managed AgentsBoucle agentique unique de l'API Messages
UnitéDollars US, cents entiersTokens
ApplicationFerme — la plateforme met la session en pauseIndicative — le modèle s'auto-régule
Qui la litLe comptable de coût de la plateformeLe modèle, à titre d'orientation
Que se passe-t-il au plafondstop_reason: "budget_reached", la session devient inactiveLe modèle termine et rend la main

Si vous voulez un arrêt ferme sur un run non surveillé, c'est un budget de session. Si vous voulez que le modèle s'auto-limite dans une boucle, c'est un budget de tâche. Ils se composent — une session Managed Agents peut porter un budget de session pendant qu'un appel d'outil imbriqué de l'API Messages porte son propre budget de tâche.

Définir un budget à la création de la session

Passez le champ optionnel budget sur POST /v1/sessions :

Créer une session plafonnée à 25,00 $

curl -fsSL https://api.anthropic.com/v1/sessions \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "anthropic-beta: managed-agents-2026-04-01" \
-H "content-type: application/json" \
-d '{
  "agent": "'"$AGENT_ID"'",
  "environment_id": "'"$ENVIRONMENT_ID"'",
  "budget": {
    "type": "limit",
    "max_list_cost": {"amount": "2500", "currency": "USD"}
  }
}'

L'objet budget a exactement deux champs :

  • type vaut toujours "limit". Il n'existe pas d'autre variante aujourd'hui ; le champ est là pour que les futures formes d'application ne cassent pas les clients existants.
  • max_list_cost est le plafond lui-même. amount est un entier de cents US sous forme de chaîne"2500" vaut 25,00 $, "50" vaut 50 cents, "1" vaut un cent. Les formes décimales comme "25.00" sont rejetées avec un 400. La forme chaîne est délibérée : les arrondis flottants ne touchent jamais votre plafond. currency est un code ISO-4217 en majuscules, et aujourd'hui USD est la seule valeur supportée.
Watch out
  • Un budget ne peut être attaché qu'à la création de la session. Ajouter un budget à une session déjà en cours d'exécution créée sans en avoir un renvoie 400 — prévoyez-le dès le départ.
  • Amount est une chaîne de cents entiers. "25.00" est rejeté. "0" est rejeté. "-1" est rejeté.

Comment le list cost est mesuré

La plateforme tarife continuellement ce que la session consomme, aux tarifs publics affichés, et appelle le total courant le list cost de la session. Trois éléments entrent en jeu :

  • Les tokens du modèle, au tarif affiché de chaque modèle servi. Dans une session multiagent, les tokens de chaque thread sont tarifés au tarif du modèle propre à ce thread.
  • Les recherches web, à 10 $ pour 1 000 requêtes (soit un cent par recherche).
  • Le temps d'exécution de session, à 0,08 $ par heure de temps de session actif.

Les requêtes web fetch sont neutres au compteur : elles apparaissent dans les compteurs server_tool_use mais ne portent pas de coût par requête et n'alimentent pas le budget.

Deux détails comptables à intérioriser :

  1. L'application utilise le list cost exact, non arrondi. Le list_cost que vous voyez sur les objets session et event est arrondi au cent entier, donc une valeur rapportée peut être à un demi-cent près de la valeur que lit le contrôle d'application. Ne comparez jamais deux lectures arrondies pour conclure que la plateforme a « oublié » un cent.
  2. Dans les sessions multiagent, active_seconds au niveau session compte l'activité chevauchante des threads une seule fois (afin de ne pas surfacturer le temps d'exécution pour le travail parallèle). Le active_seconds par thread est tarifé par thread et exclut le coût de temps d'exécution de la session, donc additionner les list_cost de threads n'égalera pas le list_cost de la session. Faites confiance au chiffre de la session — c'est celui contre lequel le plafond est appliqué.

Le dépassement d'une requête

C'est la chose la plus surprenante des budgets de session, et celle autour de laquelle construire vos alertes.

Le plafond est vérifié entre les requêtes au modèle, pas en cours de requête. Avant chaque requête, la plateforme lit le list cost consommé de la session ; dès qu'il atteint le plafond, chaque thread se met en pause avant sa prochaine requête. La requête qui a fait franchir le plafond au total avait été admise pendant que la session était encore sous le plafond et s'exécute jusqu'à sa fin.

Conséquence : une session plafonnée à "50" (50 cents) peut se mettre en pause avec un list_cost de "53". Ce n'est pas un bug de facturation. Le dépassement est borné à une requête au modèle par thread — mais sur un roster multiagent avec plusieurs threads concurrents, ce « un » se multiplie.

Pro tip

Traitez max_list_cost comme une borne sur le nouveau travail, pas comme un point d'arrêt exact. Si vous devez garantir que la dépense ne dépasse jamais X $, réglez le plafond à X - (max_request_cost * concurrent_threads). Sur une session multiagent à 25 threads avec des appels Opus coûteux, la marge peut être significative.

Ce qui se passe quand une session atteint son budget

Une session à son budget ne meurt pas — elle devient inactive, avec son historique et son sandbox préservés. Sur le flux d'événements vous verrez, dans cet ordre :

Guided walkthrough1 of 4
  1. Dès que chaque thread termine sa requête en cours, il émet un événement idle avec stop_reason: "budget_reached". Un thread dont la requête finale a également terminé son tour rapporte stop_reason: "end_turn" sur son propre événement — mais l'événement au niveau session rapporte quand même budget_reached. Faites confiance au signal de niveau session.

Quels événements la session accepte encore

En pause au plafond, la session n'accepte que les événements qui règlent un travail déjà en cours :

  • user.tool_confirmation
  • user.tool_result
  • user.custom_tool_result
  • user.interrupt

Un user.message — tout ce qui démarrerait un nouveau travail — est rejeté avec une erreur 400 qui nomme exactement la liste ci-dessus. user.interrupt envoyé à une session entièrement en pause est accepté et silencieusement ignoré (il n'apparaît même pas dans la liste des événements). Régler les outils en cours ne déclenche pas de nouvelle requête au modèle ; la session reste en pause.

Reprise : changer ou supprimer le budget

Il y a exactement deux leviers.

Changer le budget

Envoyez un PATCH (ou l'update du SDK) avec un nouveau max_list_cost. La nouvelle valeur peut être plus haute ou plus basse que l'ancien plafond — mais elle doit être strictement supérieure au list cost consommé de la session, sinon vous obtenez :

400 budget.max_list_cost must be greater than the session's consumed list cost
Watch out

Comme le coût consommé se trouve généralement une fraction au-delà de l'ancien plafond quand la session s'est mise en pause, basez la nouvelle valeur sur le usage.list_cost rapporté par la session, pas sur l'ancien max_list_cost. Réglez le nouveau plafond au moins un cent au-dessus de la valeur rapportée — la valeur rapportée est arrondie et peut se trouver à un poil sous le coût consommé exact utilisé par le contrôle.

Relever le plafond à 40,00 $

curl -sS --fail-with-body "https://api.anthropic.com/v1/sessions/$SESSION_ID" \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "anthropic-beta: managed-agents-2026-04-01" \
-H "content-type: application/json" \
-d '{"budget": {"type": "limit", "max_list_cost": {"amount": "4000", "currency": "USD"}}}'

Une mise à jour acceptée reprend automatiquement le travail en pause. Vous n'envoyez rien d'autre.

Supprimer le budget

Réglez budget à null et le plafond disparaît. La session reprend et l'événement session.updated résultant porte budget: null.

{"budget": null}
Watch out

La suppression est à sens unique. Une session dont le budget a été supprimé ne peut pas en recevoir un nouveau — c'est la même règle que « budget uniquement à la création » appliquée à la suppression. Si vous voulez garder un plafond sur la session, changez-le toujours. Ne supprimez que quand vous rendez consciemment la session aux limites de dépense normales de votre organisation.

Budgets sur les déploiements — par exécution, pas cumulatifs

Un déploiement planifié accepte le même objet budget :

{
"budget": {
"type": "limit",
"max_list_cost": {"amount": "2000", "currency": "USD"}
}
}

Le plafond est copié sur chaque session que le déploiement démarre. Il borne chaque exécution séparément — pas la dépense cumulative du déploiement sur toutes les exécutions. Un budget de déploiement de 20 $ avec un cron quotidien et 30 runs par mois peut donc consommer jusqu'à ~600 $ de list cost, pas 20 $.

Deux différences supplémentaires avec les budgets de session :

  • Changer le budget du déploiement s'applique aux sessions que le déploiement démarre par la suite — les sessions déjà en cours gardent le budget avec lequel elles ont été créées.
  • Contrairement à une session, le budget d'un déploiement peut être effacé avec null puis redéfini plus tard. La règle de suppression à sens unique est une règle de niveau session, pas de niveau déploiement.

Multiagent, advisors et le plafond partagé

Une session multiagent a un seul budget partagé entre tous ses threads — il n'y a pas de plafonds par thread. La consommation de chaque thread est tarifée à son propre modèle servi ; les threads se mettent en pause indépendamment à mesure que le plafond partagé est atteint. Un thread peut être en pause à budget_reached pendant qu'un autre finit encore sa requête en cours.

Les consultations Advisor comptent contre le même budget, tarifées aux tarifs du modèle advisor. Donc un advisor Opus-5 consulté par un exécuteur Sonnet-5 sur une session budgétée à 10 $ puise dans le même pool. Si vous utilisez le pattern advisor pour l'optimisation de coût, dimensionnez le plafond pour les deux niveaux, pas seulement pour l'exécuteur.

Il y a un départage important : une demande en attente surclasse le plafond. Si un thread attend sur requires_action (un user.tool_confirmation, disons) et un autre est en pause à budget_reached, la session rapporte requires_action au niveau supérieur — car répondre à cette demande est un événement de règlement que le budget ne bloque pas. Votre UI opérateur doit afficher l'invite requires-action en premier.

Modèles sans tarif affiché

Un budget ne peut suivre que la consommation que la plateforme peut tarifer. Deux modes d'échec :

  • À la création : créer une session budgétée dont l'agent — ou n'importe quel agent ou advisor de son roster multiagent — utilise un modèle sans tarif public affiché renvoie 400 avec un message qui dit exactement no list price is available for the model. Cela inclut les modèles preview/research-preview qui n'ont pas encore été tarifés.
  • Après création : si l'usage d'une session budgétée en vient à inclure un modèle non tarifé (par exemple via une entrée de roster ajoutée par une surcharge de niveau session), le budget ne peut plus mesurer la dépense. La session peut encore se mettre en pause avec stop_reason: "budget_reached", et toute tentative de changer le budget sera rejetée. La seule reprise est de supprimer le budget — qui est à sens unique, par la règle ci-dessus. Concevez le roster pour que cela ne puisse pas arriver en cours de run.

Référence des erreurs

La liste complète des conditions 400 liées au budget :

ConditionStatut
Un événement démarrant un travail (par exemple user.message) envoyé pendant que la session est à ou au-delà de son budget400 (l'erreur nomme les événements de règlement acceptés)
Le budget est fixé à une valeur à ou en dessous du list cost consommé de la session400
Un budget est ajouté à une session créée sans, ou rajouté après suppression400
amount n'est pas un nombre entier de cents (par exemple "25.00"), est zéro ou négatif, ou currency n'est pas USD400
Un create budgété référence un modèle sans tarif public affiché400

La checklist ops

Six choses à mettre dans votre runbook le jour où vous activez les budgets de session :

Guided walkthrough1 of 6
  1. Donnez-vous de la marge pour le dépassement d'une requête et pour un run plus long que la normale. Cents entiers seulement — pas de "25.00".

Note cross-AI : comment les autres plateformes gèrent cela

Aucune des grandes plateformes d'agents hébergés n'a livré une primitive équivalente avant la sortie du 7 août d'Anthropic. Ce que vous pouvez approcher ailleurs au 2026-08-11 :

  • OpenAI : des limites de dépense mensuelles au niveau organisation et des limites d'usage par projet existent, mais elles ne sont pas par run et ne peuvent pas mettre en pause une session Assistants / Responses API en cours de boucle. Vous compensez avec votre propre webhook surveillant le flux de tokens.
  • Google Vertex AI (Gemini) : les quotas au niveau projet et les budgets de facturation (via Cloud Billing) sont asynchrones — ils alertent, ils ne mettent pas un agent en pause en ligne.
  • AWS Bedrock : les quotas d'invocation de modèle sont des plafonds fermes par seconde/par minute, pas des plafonds en dollars par session. Le gating de dépense au niveau session est de votre responsabilité.
  • Passerelles tierces (LiteLLM, OpenRouter, Portkey) : toutes offrent des plafonds de budget par clé qui renvoient une erreur HTTP quand ils sont atteints — plus proche en forme des budgets de session, mais le comportement « pause and resume » n'est pas une primitive de première classe.

Si le coût est la raison pour laquelle vous évaluez Managed Agents vs une boucle maison avec une passerelle, le plafond ferme par session avec pause gracieuse est un vrai point de différentiation cette semaine.

Key takeaways
  • Les budgets de session sont des plafonds USD fermes, appliqués par la plateforme, sur une session Managed Agents, tarifés aux tarifs publics affichés et définis à la création de la session uniquement
  • Le stop_reason est budget_reached. Attendez-vous à un session.thread_status_idle, puis session.usage, puis session.status_idle — construisez votre handler sur cet ordre
  • Le coût consommé peut se trouver une fraction au-delà du plafond (jusqu'à une requête complète par thread) — dimensionnez le plafond en tenant compte de ce dépassement
  • Changez le plafond à une valeur strictement supérieure au list_cost actuel pour reprendre ; supprimez-le entièrement avec budget: null — mais la suppression est à sens unique
  • Les budgets de déploiement sont par run, pas cumulatifs. Un job quotidien avec un plafond de 20 $ par run n'est pas un plafond mensuel de 20 $
  • Ne confondez pas les budgets de session (fermes, USD, appliqués par la plateforme) avec les budgets de tâche de l'API Messages (indicatifs, tokens, appliqués par le modèle)

Testez-vous

Testez-vous

0/4
  1. Vous créez une session avec max_list_cost de "50" (50 cents). La session se met en pause avec usage.list_cost affichant "53". Que s'est-il passé ?
  2. Une session créée sans budget tourne depuis une heure. Vous réalisez que vous voulez la plafonner. Que pouvez-vous faire ?
  3. Vous avez un déploiement avec un budget de 20 $ par run sur un cron quotidien. Quel est le list cost maximum que le déploiement peut engager sur un mois de 30 jours ?
  4. Une session budgétée est en pause à budget_reached. Vous envoyez un user.message lui demandant de continuer. Que se passe-t-il ?

Ensuite