Cost Monitoring pour agents

Le cost monitoring montre la consommation de tokens et les couts API.
Sur cette page
  1. Idee en 30 secondes
  2. Probleme principal
  3. Comment ca fonctionne
  4. Metriques de cout production typiques
  5. Comment lire la cost-layer
  6. Quand l'utiliser
  7. Exemple d'implementation
  8. Investigation
  9. Erreurs typiques
  10. Il y a seulement une somme de cout journaliere
  11. Seuls les tokens sont comptes, le cout des tools est ignore
  12. Pas de segmentation par release et model
  13. Labels a forte cardinalite
  14. Pas d'alertes sur burn rate et cost_p95
  15. Auto-verification
  16. FAQ
  17. Pages liees

Idee en 30 secondes

Le cost monitoring pour les agents IA montre non seulement la depense totale, mais aussi ou elle augmente : tokens LLM, API externes et etapes repetitives de l'agent.

Sans cela, on rate facilement le moment ou le systeme "fonctionne" encore, mais devient deja trop cher pour la production.

Probleme principal

Un run peut se terminer avec succes, mais couter 2-3 fois plus que d'habitude.

Deux requetes avec la meme reponse finale peuvent avoir des couts unitaires differents : a cause d'etapes de reasoning supplementaires, de retries ou d'appels tools inutiles. Sans cost monitoring, cela apparait generalement seulement apres depassement de budget.

Voyons maintenant comment lire ces signaux et identifier ce qui rend un run couteux.

En production, cela ressemble souvent a :

  • les tokens augmentent par vagues apres une release ;
  • un outil commence discretement a consommer la majeure partie du budget ;
  • les retries augmentent les couts meme sans hausse de trafic ;
  • l'equipe voit le probleme seulement apres explosion budgetaire.

C'est pourquoi la cost-layer doit etre surveillee separement, et pas seulement via des metriques globales de run.

Comment ca fonctionne

Le cost monitoring repose sur deux types de signaux :

  • usage signals (prompt_tokens, completion_tokens, tool_calls, retries) ;
  • cost signals (llm_cost_usd, tool_cost_usd, total_cost_per_run).

Ces metriques repondent a la question "ou et pourquoi le systeme devient plus cher dans le temps". Logs et tracing sont necessaires pour expliquer un run couteux concret.

Les couts n'augmentent pas seulement a cause du volume de trafic, mais aussi a cause du comportement de l'agent. Usage != cost. Un agent peut resoudre la meme tache avec le meme resultat, mais couter plusieurs fois plus a cause des retries, de chaines de reasoning plus longues ou de tools plus couteux.

Metriques de cout production typiques

MetriqueCe qu'elle montrePourquoi elle est utile
token_usage_per_runnombre de tokens consommes par runcontrole de base de la consommation LLM
llm_cost_per_runcout LLM par runcomparaison des modeles et strategies de prompt
tool_cost_per_runcout des API/tools externes par runidentification des outils couteux
total_cost_per_runcout total du runcontrole du cout unitaire de reponse
cost_p95longue queue de runs couteuxdetection precoce d'anomalies de cout
budget_burn_ratevitesse de consommation du budgetprevision de depassement budgetaire
cost_per_1k_runscout de 1000 runscomparaison de stabilite entre releases

budget_burn_rate est generalement calcule au niveau dashboard (depense par unite de temps), pas comme compteur runtime separe.

Pour que les metriques soient utiles, elles sont souvent segmentees par release, model, tool et type de requete.

Important : ne pas ajouter de champs a forte cardinalite (run_id, request_id, user_id) dans les labels, sinon le stockage metriques se surcharge rapidement.

Comment lire la cost-layer

Ce qui est consomme -> comment l'agent se comporte -> combien cela coute reellement. Ce sont trois niveaux a lire ensemble.

Il faut suivre les tendances dans le temps et les differences entre releases, pas des valeurs isolees.

Regardons les combinaisons de signaux :

  • token_usage_per_run ↑ + llm_cost_per_run ↑ -> l'agent depense plus de tokens par run ;
  • tool_cost_per_run ↑ + total_cost_per_run ↑ -> over-tooling ou chemin tools couteux ;
  • llm_cost_per_run ↑ + tool_cost_per_run ~= stable -> probleme de prompt ou reasoning, pas de tools ;
  • budget_burn_rate ↑ + run_count ~= stable -> regression du cout unitaire ;
  • cost_p95 ↑ + budget_burn_rate ↑ -> des runs anormalement chers accelerent la depense.

Quand l'utiliser

Un cost monitoring complet n'est pas toujours necessaire.

Pour un prototype simple, token_usage de base et une limite de depense journaliere peuvent suffire.

Mais un monitoring detaille des couts devient critique quand :

  • le systeme est deja en production avec contraintes budgetaires ;
  • l'agent utilise plusieurs tools avec API payantes ;
  • les releases sont frequentes et les regressions de cout doivent etre visibles ;
  • il faut scaler le trafic sans perdre le controle budgetaire.

Exemple d'implementation

Ci-dessous un exemple simplifie d'instrumentation de cost metrics en style Prometheus. L'exemple montre le controle de base du cout LLM, du cout tools et du cout total par run.

PYTHON
import time
from prometheus_client import Counter, Histogram

RUN_TOTAL = Counter(
    "agent_run_total",
    "Total number of agent runs",
    ["status", "stop_reason", "release"],
)

LLM_COST_USD_TOTAL = Counter(
    "agent_llm_cost_usd_total",
    "Total LLM cost in USD",
    ["model", "release"],
)

TOOL_COST_USD_TOTAL = Counter(
    "agent_tool_cost_usd_total",
    "Total tool/API cost in USD",
    ["tool", "release"],
)

TOKEN_USAGE_TOTAL = Counter(
    "agent_token_usage_total",
    "Total LLM tokens",
    ["model", "token_type", "release"],
)

RUN_COST_USD = Histogram(
    "agent_run_cost_usd",
    "Cost per run in USD",
    ["release"],
    buckets=(0.001, 0.003, 0.01, 0.03, 0.1, 0.3, 1, 3),
)

BUDGET_BREACH_TOTAL = Counter(
    "agent_budget_breach_total",
    "Total runs that crossed cost budget",
    ["release"],
)

LLM_PRICING = {
    # WARNING: exemple de tarification (peut etre obsolete).
    # En production, ces valeurs doivent venir de la config ou d'une API fournisseur.
    "gpt-4.1": {
        "prompt": 0.0000015,
        "completion": 0.0000020,
    }
}


def estimate_llm_cost_usd(model, prompt_tokens, completion_tokens):
    # WARNING: replace with actual provider pricing
    pricing = LLM_PRICING.get(model)
    if not pricing:
        # WARNING: unknown model — cost will be reported as 0 (underestimated)
        return 0.0
    prompt_cost = prompt_tokens * pricing.get("prompt", 0)
    completion_cost = completion_tokens * pricing.get("completion", 0)
    return prompt_cost + completion_cost


def run_agent(agent, task, budget_limit_usd=0.25, release="2026-03-21"):
    run_status = "ok"
    stop_reason = "max_steps"
    run_cost_usd = 0.0

    try:
        for step in agent.iter(task):
            step_type = step.type
            try:
                result = step.execute()
            except Exception as error:
                run_status = "error"

                if step_type == "tool_call":
                    stop_reason = "tool_error"
                elif step_type == "llm_generate":
                    stop_reason = "llm_error"
                else:
                    stop_reason = "step_error"

                raise

            if step_type == "llm_generate":
                model = getattr(step, "model", "unknown")
                usage = getattr(result, "token_usage", {}) or {}
                prompt_tokens = usage.get("prompt_tokens", 0)
                completion_tokens = usage.get("completion_tokens", 0)

                TOKEN_USAGE_TOTAL.labels(model=model, token_type="prompt", release=release).inc(
                    prompt_tokens
                )
                TOKEN_USAGE_TOTAL.labels(
                    model=model, token_type="completion", release=release
                ).inc(completion_tokens)

                llm_cost = estimate_llm_cost_usd(model, prompt_tokens, completion_tokens)
                run_cost_usd += llm_cost
                LLM_COST_USD_TOTAL.labels(model=model, release=release).inc(llm_cost)

            if step_type == "tool_call":
                tool_name = getattr(step, "tool_name", "unknown")
                tool_cost = float(getattr(result, "cost_usd", 0.0) or 0.0)
                run_cost_usd += tool_cost
                TOOL_COST_USD_TOTAL.labels(tool=tool_name, release=release).inc(tool_cost)

            if result and result.is_final:
                stop_reason = "completed"
                break
    finally:
        RUN_COST_USD.labels(release=release).observe(run_cost_usd)
        if run_cost_usd > budget_limit_usd:
            BUDGET_BREACH_TOTAL.labels(release=release).inc()
        RUN_TOTAL.labels(status=run_status, stop_reason=stop_reason, release=release).inc()

# cost_per_1k_runs est generalement calcule au niveau dashboard :
# (sum(agent_run_cost_usd) / run_count) * 1000
# budget_burn_rate est generalement calcule au niveau dashboard :
# depense par unite de temps (par ex. USD/hour), pas en counter separe dans le code.

Voici a quoi ces metriques peuvent ressembler ensemble sur un dashboard reel :

Segmentcost_per_runcost_p95burn_rate (hour)Statut
gpt-4.1 + tools$0.084$0.29$42/hcritical: budget risk
mini-model + cache$0.021$0.07$11/hok
research workflow$0.136$0.41$58/hwarning: p95 augmente

Investigation

Quand une alerte de cout se declenche :

  1. trouver le segment anormal (model, tool, release) ;
  2. regarder les runs couteux dans le tracing ;
  3. verifier retries, stop_reason et tool-path dans les logs ;
  4. trouver la root cause (prompt, logique agent, API couteuse, routing incorrect).

Erreurs typiques

Meme lorsque les cost metrics existent, elles donnent souvent peu de valeur a cause des erreurs ci-dessous.

Il y a seulement une somme de cout journaliere

La somme journaliere ne montre pas quel run ou segment est devenu plus cher. Sans cost_per_run et cost_p95, le probleme est souvent detecte trop tard.

Seuls les tokens sont comptes, le cout des tools est ignore

Dans de nombreux systemes agents, les appels API externes sont la partie la plus couteuse. Sans tool_cost_per_run, on manque facilement les premiers signes d'explosion budgetaire.

Pas de segmentation par release et model

Sans segmentation, il est difficile de prouver qu'une nouvelle release ou un nouveau modele a degrade le cout unitaire.

Labels a forte cardinalite

Ajouter run_id, request_id ou session_id dans les labels surcharge vite le backend metriques. Mieux vaut garder ces donnees dans logs et tracing.

Pas d'alertes sur burn rate et cost_p95

Sans alertes, les problemes s'accumulent silencieusement jusqu'a impacter le budget. Cela apparait souvent avec surconsommation de tokens.

Auto-verification

Ci-dessous une checklist courte du cost monitoring de base avant release.

Progression: 0/9

⚠ L'observability de base manque

Le système sera difficile à déboguer en production. Commencez par run_id, structured logs et tracing des tool calls.

FAQ

Q : Quelle difference entre cost monitoring et monitoring des tokens ?
R : Les tokens ne sont qu'une partie du cout. Le cost monitoring inclut tokens LLM, appels tool/API payants et cout unitaire total du run.

Q : Quel minimum de cost metrics faut-il au demarrage ?
R : Commencer avec token_usage_per_run, total_cost_per_run, cost_p95 et budget_burn_rate.

Q : Comment calculer cost_per_run avec plusieurs fournisseurs ?
R : Normaliser tous les couts d'etapes dans une meme devise (souvent USD) et sommer les couts LLM + tools dans un run.

Q : Comment separer hausse de trafic et regression de cout unitaire ?
R : Regarder run_count et cost_per_run ensemble. Si le trafic est stable mais que cost_per_run monte, c'est une regression de cout unitaire.

Pages liees

Suite du sujet :

⏱️ 9 min de lectureMis à jour 22 mars 2026Difficulté: ★★★
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

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.