Surconsommation de tokens : quand les agents dépensent trop de tokens

La surconsommation de tokens apparaît quand un agent gaspille des tokens dans des boucles longues ou du contexte inutile. Comment la limiter.
Sur cette page
  1. Problème
  2. Pourquoi cela arrive
  3. Pannes les plus fréquentes
  4. Prompt bloat
  5. Token bombs dans les tool outputs
  6. Memory/history inflation
  7. Dégradation silencieuse via truncation
  8. Comment détecter ces problèmes
  9. Comment distinguer surconsommation et tâche vraiment complexe
  10. Comment arrêter ces pannes
  11. Où c'est implémenté dans l'architecture
  12. Auto-vérification
  13. FAQ
  14. Pages liées

Problème

La demande semble simple : vérifier le statut d'un incident et fournir un résumé court.

Dans les traces, c'est autre chose : en 8 minutes, un run a consommé plus de 38k tokens, alors que des tâches similaires restaient avant autour de ~4-6k. La moitié du budget est partie non dans la réponse, mais dans le contexte : history, logs bruts et grands tool outputs.

Pour cette classe de tâche, cela peut coûter ~$2.80 au lieu des ~$0.20 habituels. Et la qualité de la réponse a à peine augmenté.

Le système ne crash pas.

Il gonfle simplement lentement le prompt, la latence et le coût.

Analogie : imagine une valise dans laquelle avant chaque voyage on ajoute "encore un objet important", sans jamais rien retirer. Au début, c'est presque invisible. Ensuite, tu dépenses plus de temps, d'argent et d'effort juste pour porter l'excès. La surconsommation de tokens chez les agents fonctionne de la même manière.

Pourquoi cela arrive

La surconsommation de tokens vient généralement non du modèle lui-même, mais d'un contrôle faible du budget de contexte dans la runtime.

En production, cela ressemble souvent à ceci :

  1. chaque nouvelle étape ajoute tout : history, retrieval, tool output ;
  2. les payloads bruts (logs, HTML, JSON) entrent dans le prompt sans compression ;
  3. sans per-source caps et summarization, le contexte grossit à chaque turn ;
  4. les tokens partent dans le "transport de l'excès", pas dans le progrès utile ;
  5. les longues reasoning loops sans vérification no-progress gonflent encore plus l'history.

Dans un trace, cela se voit généralement comme une hausse stable de prompt_tokens, où chaque nouveau turn devient plus coûteux que le précédent, même si la tâche elle-même ne devient pas plus complexe.

Sans contrôle, cette croissance commence à dégrader latence, coût et qualité.

Pannes les plus fréquentes

En production, on voit le plus souvent quatre patterns récurrents de surconsommation de tokens.

Prompt bloat

Trop de contexte est envoyé au modèle "au cas où".

Cause typique : pas de max_prompt_tokens et pas de priorisation des chunks.

Token bombs dans les tool outputs

Les outils renvoient de gros payloads (HTML, logs, stack traces), qui vont presque bruts dans le prompt.

Cause typique : pas de caps, et le payload ne passe pas par extraction ou summarization avant d'entrer dans le prompt.

Memory/history inflation

L'agent accumule l'history turn après turn, mais ne compresse pas les sections anciennes. Résultat : chaque nouvelle étape coûte plus cher. Si le run tourne longtemps sans progrès, cette inflation accélère encore.

Cause typique : memory est utilisée comme "archive", pas comme budgeted context.

Dégradation silencieuse via truncation

Quand le contexte dépasse la fenêtre réelle, les parties importantes du prompt sont coupées. Souvent, les contraintes de policy ou les instructions critiques disparaissent d'abord.

Cause typique : pas de contrôle explicite sur ce qu'il faut retirer et dans quel ordre.

Comment détecter ces problèmes

La surconsommation de tokens se voit bien via la combinaison de métriques de coût, latence et contexte.

MétriqueSignal de surconsommationAction
prompt_tokens_per_runhausse stable des tokens par runintroduire max_prompt_tokens et un budgeted context builder
tool_output_tokensgros payloads bruts dans le promptcaps + extraction/summarization avant le modèle
tokens_per_successqualité similaire mais coût en haussevérifier unit economics et limiter le contexte inutile
context_truncation_ratetroncatures fréquentes du promptprioriser policy et faits récents, compresser l'ancien
latency_p95latence en hausse avec les tokensréduire le contexte et limiter le fan-out retrieval ou tool output

Comment distinguer surconsommation et tâche vraiment complexe

Chaque grand prompt n'est pas mauvais. La question clé : les tokens additionnels apportent-ils un vrai gain de qualité ?

Normal si :

  • la requête complexe demande vraiment plus de sources et de vérifications ;
  • tokens_per_success augmente avec la précision ;
  • le contexte additionnel apporte des faits nouveaux au lieu de répéter l'existant.

Dangereux si :

  • les tokens augmentent plus vite que le success rate ;
  • une grande partie du contexte duplique d'anciens turns ou des dumps techniques bruts ;
  • latence et coût montent, mais les réponses changent à peine.

Comment arrêter ces pannes

En pratique, cela ressemble à ceci :

  1. poser des limites strictes : max_prompt_tokens + caps sur history/tool/retrieval ;
  2. ajouter un context builder à priorités (policy et faits récents au-dessus des anciens logs) ;
  3. compresser les fragments anciens ou volumineux en summarization tier ;
  4. en cas de budget dépassé, retourner stop reason ou partial, au lieu d'envoyer un prompt "saturé".

Garde minimale pour token budget :

PYTHON
from dataclasses import dataclass


@dataclass(frozen=True)
class TokenLimits:
    max_prompt_tokens: int = 7000
    max_history_tokens: int = 1800
    max_tool_tokens: int = 2500
    max_retrieval_tokens: int = 2200


class TokenBudgetGuard:
    def __init__(self, limits: TokenLimits = TokenLimits()):
        self.limits = limits
        self.total_prompt_tokens = 0
        self.by_source = {
            "history": 0,
            "tool": 0,
            "retrieval": 0,
        }

    def _cap_for(self, source: str) -> int:
        if source == "history":
            return self.limits.max_history_tokens
        if source == "tool":
            return self.limits.max_tool_tokens
        if source == "retrieval":
            return self.limits.max_retrieval_tokens
        return self.limits.max_prompt_tokens

    def add_chunk(self, source: str, tokens: int) -> str | None:
        if self.by_source.get(source, 0) + tokens > self._cap_for(source):
            return f"token_overuse:{source}_cap"

        if self.total_prompt_tokens + tokens > self.limits.max_prompt_tokens:
            return "token_overuse:prompt_budget_exceeded"

        self.by_source[source] = self.by_source.get(source, 0) + tokens
        self.total_prompt_tokens += tokens
        return None

C'est une garde de base. En production, on la complète en général avec un comptage de tokens précis côté provider, un summarization tier pour les anciens chunks et des stop reasons séparés pour truncation. add_chunk(...) est appelé avant d'ajouter un fragment dans le prompt, pour que le budget agisse comme gate et non comme vérification post-factum.

Où c'est implémenté dans l'architecture

En production, le contrôle de la surconsommation de tokens est presque toujours réparti entre trois couches du système.

Memory Layer gère ce qu'il faut stocker à long terme et ce qu'il faut injecter dans le prompt courant. Si memory = "tout montrer", les coûts augmentent inévitablement.

Tool Execution Layer est responsable de la normalisation et de la compression des gros payloads avant leur entrée dans le contexte du modèle. C'est ici qu'on pose des output caps, qu'on extrait les faits utiles des gros payloads et qu'on les compresse avant le prompt.

Agent Runtime tient les execution budgets : max_prompt_tokens, stop reasons, fin contrôlée et fallback en cas de dépassement de limites. C'est ici que le budget tokens devient une règle de production, pas un souhait.

Auto-vérification

Vérification rapide avant release. Coche les points et regarde le statut ci-dessous.
C'est un sanity-check court, pas un audit formel.

Progression: 0/8

⚠ Il y a des signaux de risque

Il manque des contrôles de base. Fermez les points clés de la checklist avant release.

FAQ

Q : Peut-on juste passer à un modèle avec une fenêtre de contexte plus grande ?
R : Oui, mais c'est généralement plus lent et plus cher. Sans contrôle de budget, le problème ne disparaît pas, il est juste déplacé vers une limite plus haute.

Q : Par quoi commencer : tokens ou caractères ?
R : Le mieux est le comptage de tokens du provider. Si ce n'est pas disponible, commence avec des char caps conservateurs puis passe aux tokens.

Q : Que compresser en premier quand le budget est dépassé ?
R : En général, les anciens turns et les gros tool outputs bruts. Policy et faits les plus récents doivent rester.

Q : Que montrer à l'utilisateur quand le prompt budget est épuisé ?
R : La raison de l'arrêt, ce qui a déjà été traité, et la prochaine étape sûre : résultat partiel, requête plus ciblée ou nouveau run avec moins de contexte.


La surconsommation de tokens ressemble rarement à une panne bruyante. C'est une dégradation lente qui gonfle latence et coût, sans crash de service explicite. C'est pourquoi les agents de production ont besoin non seulement de meilleurs modèles, mais aussi d'un contrôle strict du budget de contexte.

Pages liées

Si ce problème apparaît en production, il est aussi utile de voir :

⏱️ 8 min de lectureMis à jour 12 mars 2026Difficulté: ★★☆
Implémenter dans OnceOnly
Guardrails for loops, retries, and spend escalation.
Utiliser dans OnceOnly
# onceonly guardrails (concept)
version: 1
budgets:
  max_steps: 25
  max_tool_calls: 12
  max_seconds: 60
  max_usd: 1.00
policy:
  tool_allowlist:
    - search.read
    - http.get
controls:
  loop_detection:
    enabled: true
    dedupe_by: [tool, args_hash]
  retries:
    max: 2
    backoff_ms: [200, 800]
stop_reasons:
  enabled: true
logging:
  tool_calls: { enabled: true, store_args: false, store_args_hash: 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)
  • Kill switch & arrêt incident
  • Audit logs & traçabilité
  • Idempotence & déduplication
  • Permissions outils (allowlist / blocklist)
Mention intégrée : OnceOnly est une couche de contrôle pour des systèmes d’agents en prod.
Exemple de policy (concept)
# Example (Python — conceptual)
policy = {
  "budgets": {"steps": 20, "seconds": 60, "usd": 1.0},
  "controls": {"kill_switch": True, "audit": True},
}

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.