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 :
- chaque nouvelle étape ajoute tout : history, retrieval, tool output ;
- les payloads bruts (logs, HTML, JSON) entrent dans le prompt sans compression ;
- sans per-source caps et summarization, le contexte grossit à chaque turn ;
- les tokens partent dans le "transport de l'excès", pas dans le progrès utile ;
- 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étrique | Signal de surconsommation | Action |
|---|---|---|
prompt_tokens_per_run | hausse stable des tokens par run | introduire max_prompt_tokens et un budgeted context builder |
tool_output_tokens | gros payloads bruts dans le prompt | caps + extraction/summarization avant le modèle |
tokens_per_success | qualité similaire mais coût en hausse | vérifier unit economics et limiter le contexte inutile |
context_truncation_rate | troncatures fréquentes du prompt | prioriser policy et faits récents, compresser l'ancien |
latency_p95 | latence en hausse avec les tokens | ré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_successaugmente 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 :
- poser des limites strictes :
max_prompt_tokens+ caps sur history/tool/retrieval ; - ajouter un context builder à priorités (policy et faits récents au-dessus des anciens logs) ;
- compresser les fragments anciens ou volumineux en summarization tier ;
- en cas de budget dépassé, retourner stop reason ou partial, au lieu d'envoyer un prompt "saturé".
Garde minimale pour token budget :
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 :
- Pourquoi les agents IA échouent - carte générale des pannes en production.
- Budget explosion - comment la surconsommation de tokens devient un incident financier.
- Tool spam - comment les appels inutiles gonflent contexte et coût.
- Context poisoning - comment un mauvais contexte dégrade les décisions de l'agent.
- Memory Layer - où séparer mémoire long terme et contexte du prompt.
- Agent Runtime - où poser limites tokens, stop reasons et fallback.