Moins de tokens ne signifie pas moins cher : pourquoi les agents de codage gaspillent du temps plutôt que des tokens
La compression des résultats générés par les outils peut augmenter le coût d’une tâche de codage entière. Découvrez pourquoi il est nécessaire de mesurer le coût par tâche achevée, de prévoir un plan de récupération et de concevoir des outils adaptés aux agents.
Depuis l’apparition des agents de codage, les développeurs se concentrent sur un seul indicateur : les tokens. Combien le modèle en a générés, combien un outil en a renvoyés, quelle est la taille du contexte, combien l’agent en a consommés ? Ce raisonnement semble logique. Moins de tokens devraient signifier une facture plus faible.
L’analyse de GitHub concernant l’agent de codage Copilot montre pourquoi cette hypothèse est risquée. La suppression de parties des réponses des outils peut rendre toute la tâche plus coûteuse si le texte supprimé contenait des informations importantes. L’agent doit alors réexécuter les commandes, retrouver la sortie originale, consacrer davantage de temps à la réflexion et gérer un contexte plus volumineux pour tout ce qui suit.
Ainsi, l’interaction la moins chère n’est pas automatiquement celle qui utilise le moins de tokens. Ce que l’on cherche vraiment, c’est une tâche logicielle terminée avec le moins de travail inutile, et cela modifie la manière dont on devrait évaluer les performances des agents.
Le piège de l’optimisation locale
Supposons qu’un agent exécute une commande de test :
npm test
Cela affiche 50 000 tokens. Cela semble gaspiller des ressources, alors on écrit un enveloppeur qui réduit la sortie à 2 000 tokens. En théorie, c’est une victoire : 48 000 tokens en moins.
Supposons maintenant que ces 2 000 tokens omettent ce dont l’agent avait besoin. Il répond alors par quelque chose comme :
I need more information about the failing test.
Ainsi, il exécute à nouveau la commande, recherche le résultat enregistré, ouvre le fichier de journal, ou tente une commande plus ciblée. Le flux devient alors le suivant :
Original command
↓
Compressed output
↓
Missing information
↓
Agent searches again
↓
Command runs again
↓
More context
↓
More reasoning
La étape unique est devenue moins chère tandis que la tâche est devenue plus coûteuse. GitHub a rencontré ce problème en testant des moyens de réduire les résultats générés par Copilot. Une expérience a utilisé un outil nommé RTK pour raccourcir les sorties de la console, et les agents rouvraient ou relançaient fréquemment des commandes chaque fois que des détails manquants devenaient importants. Le résultat a été davantage d’itérations, en moyenne plus de tokens, ainsi qu’une complétion plus lente. Cela semble évident avec le recul, mais il est facile de l’ignorer lorsqu’on optimise le mauvais paramètre.
Jugez la tâche, pas l’appel
Un agent a pour but d’achever une tâche logicielle, pas de minimiser le coût d’une seule requête API. L’écart entre ces objectifs est plus grand qu’il n’y paraît. Comparez deux agents. Agent A :
Task
↓
8 tool calls
↓
100K tokens
↓
Completed in 4 minutes
et l’Agent B :
Task
↓
15 tool calls
↓
80K tokens
↓
Completed in 9 minutes
En se basant uniquement sur les jetons, B gagne. Cependant, lorsqu’il s’agit de diriger une organisation d’ingénierie, la réponse devient plus floue. Un résultat obtenu plus rapidement nécessite probablement moins de tentatives, utilise moins de ressources informatiques, peut produire un correctif de meilleure qualité et réduit le temps d’attente des développeurs. Si quelqu’un doit superviser B pendant cinq minutes de plus, son coût réel augmente encore.
C’est pourquoi GitHub affirme que le comptage des jetons par interaction ne dit pas grand-chose sur l’efficacité de l’agent. Ce qu’il faut optimiser, c’est le résultat global de la tâche.
Un modèle de coût du début à la fin
Les ingénieurs expérimentés connaissent déjà ce principe grâce à d’autres domaines. Réduire le temps d’exécution d’une requête de base de données de 200 ms à 100 ms semble être un avantage évident. Mais si cette nouvelle requête pousse un autre service à effectuer trois demandes supplémentaires, le système peut finir par être plus lent dans son ensemble. Il s’agit d’ajuster le système dans son intégralité, et non une seule opération.
Les agents suivent la même règle. Un modèle mental utile pour comprendre le coût total :
Total agent cost =
model inference
+ tool execution
+ retries
+ repeated work
+ context growth
+ developer waiting
+ infrastructure
Et un motif qui apparaît souvent :
smaller response
+
missing context
=
more recovery work
C’est pourquoi l’ingénierie de l’IA ressemble de plus en plus à l’ingénierie des systèmes.
Tous les résultats ne valent pas la même chose
On a constaté que les sorties des commandes varient en termes de densité d’information. Les journaux de déploiement, de compilation, de test et d’avancement répétitifs peuvent être remplis de bruit. En revanche, les sorties similaires à du code source et les résultats aléatoires des commandes peuvent contenir exactement ce dont l’agent a besoin. Plutôt que d’une règle de compression unique pour tout, GitHub a adopté une approche sélective. En principe, cela fonctionne comme suit :
Command output
│
▼
┌──────────────────────┐
│ What kind of output? │
└──────────┬───────────┘
│
┌─────┼─────┐
│ │ │
▼ ▼ ▼
Source Search Noise
output results logs
│ │ │
▼ ▼ ▼
Keep Reorganize Compress
all without selectively
losing
content
C’est mieux que l’alternative brutale :
if output.length > X:
truncate()
La règle brute optimise un nombre. La règle sélective optimise la capacité de l’agent à continuer de fonctionner.
Ce que git diff enseigne
Imaginez un agent qui a modifié cinq fichiers et qui exécute maintenant :
git diff
La sortie est longue. Un compresseur naïf la jugerait volumineuse et la réduirait de taille. Mais la différence peut contenir exactement ce dont l’agent a besoin pour déterminer si ses modifications sont correctes. GitHub indique que les versions précoces de son compresseur compressaient bien git diff, et les tests ont montré que les agents devaient rouvrir la sortie originale pour récupérer ces informations. C’est pourquoi ce filtre a été supprimé.
C’est une excellente leçon spécifique à l’IA : on ne peut pas qualifier quelque chose de inutile simplement parce qu’il est volumineux. Certaines sorties longues représentent un contexte de grande valeur, tandis que d’autres très courtes sont sans intérêt. Le nombre de tokens ne permet pas de les distinguer.
Concevoir ses propres outils
Si vous développez un agent de codage, vous pourriez écrire ceci :
const result = await exec(command);
suivi d’un plafond maximal :
return result.stdout.slice(0, 5000);
Cela semble raisonnable, mais cela suppose implicitement que les 5 000 premiers caractères contiennent tout ce dont l’agent a besoin. Une conception plus intelligente classe d’abord le résultat. Commencez de la même manière :
const result = await exec(command);
Ensuite, on choisit le type de sortie :
const outputType = classifyOutput(result);switch (outputType) {
case "source":
return result.stdout; case "search":
return reorganize(result.stdout); case "repetitive-log":
return compress(result.stdout); default:
return result.stdout;
}
Même cela nécessite une voie de sortie, afin que l’agent puisse récupérer l’original :
return {
summary,
compressedOutput,
fullOutputAvailable: true
};
L’agent dispose d’une vue compacte, et rien n’a vraiment disparu. Pour les systèmes autonomes, c’est une conception bien meilleure.
La compression doit différer, pas supprimer
La compression ne devrait pas signifier la suppression d’informations. Elle devrait plutôt signifier son report jusqu’à ce qu’elle soit nécessaire. Comparez les deux approches. Une mauvaise compression se présente comme ceci :
Original output
↓
Throw away 90%
↓
Agent cannot recover it
Original output
↓
Create useful summary
↓
Agent continues
↓
Needs more detail?
↓
Retrieve original
Cela correspond davantage au fonctionnement du cache dans les logiciels ordinaires. L’agent n’a pas besoin de tout immédiatement, mais il ne doit pas perdre l’accès à quoi que ce soit d’important. L’approche mise en œuvre par GitHub offre un moyen de récupération direct une fois la sortie compressée.
Parfois, plus de contexte est plus économique
Cela semble contraire à l’intuition. Les développeurs passent des années à réduire le contexte. Mais plus de contexte peut éviter plus de travail. Supposons que l’agent détecte une erreur compactée :
Test failed:
Expected 401
Received 500
La sortie complète aurait également pu afficher :
Database connection refused
JWT middleware initialized correctly
Request reached /api/auth/login
PostgreSQL timeout after 5 seconds
La version abrégée indique à l’agent qu’il y a eu une erreur. La version complète précise que la logique d’authentification n’est probablement pas en cause, mais que c’est la connexion à la base de données. La version complète coûte plus de tokens mais peut éviter cinq appels d’outils. Le contexte a un coût, tout comme son absence. Le défi technique réside dans trouver un équilibre entre les deux.
Pourquoi les agents semblent tourner en rond
Vous avez probablement déjà vu un agent agir de la sorte :
Run command
↓
Read partial output
↓
Run another command
↓
Search same file
↓
Run original command again
↓
Read more output
↓
Change code
↓
Run test
↓
Go back to original command
Cela ressemble à de la confusion, et c’est parfois le cas. Mais parfois, l’infrastructure ne fournit tout simplement pas assez d’informations au modèle, et l’agent compense une interface incomplète. Si un agent demande constamment la même chose, le problème peut résider dans la conception de l’outil plutôt que dans le modèle.
La conception des outils, c’est l’UX pour les modèles
Les développeurs évaluent généralement les API en fonction des entrées, des sorties, de la latence, des erreurs et de l’authentification. Les outils destinés à l’IA nécessitent une question supplémentaire : en quoi cette sortie affecte-t-elle la prochaine décision du modèle ? Prenons deux réponses. API A :
{
"status": "failed"
}
et API B :
{
"status": "failed",
"error": "PostgreSQL connection timeout",
"service": "auth-api",
"retryable": true,
"attempt": 2,
"duration_ms": 5040
}
B contient plus d’informations, mais il peut réduire le coût total du système, car l’agent peut prendre la bonne décision sur place. L’objectif n’est pas de disposer du JSON le plus petit possible, mais plutôt des informations qui permettent à l’agent de prendre la décision suivante correctement.
Ajustement de tout le cycle
GitHub ne considère pas cela comme un simple problème de compression. Son document décrit plusieurs modifications à apporter : conserver le contexte utile tout en réduisant les redondances, supprimer les formats qui ne sont pas utiles pour la tâche, raccourcir les instructions sans changer le comportement, et éviter des étapes de récupération inutiles pour les tâches en arrière-plan. Chaque modification a été évaluée hors ligne sur des benchmarks de codage par agents, puis validée dans des expériences en ligne contrôlées avant son déploiement.
C’est là l’ingénierie des performances pour les agents. La question passe de savoir comment rendre une réponse plus courte à savoir comment aider l’agent à terminer son travail avec moins de gaspillage, et c’est une question bien meilleure.
Observabilité pour les agents
Cela modifie ce que vous suivez en production. Pour les services ordinaires, vous surveilleriez :
Latency
Error rate
CPU
Memory
Throughput
Pour les agents, ajouter davantage :
Task completion rate
Tool-call count
Retry rate
Repeated-command rate
Context growth
Model escalation rate
Time to completion
Cost per completed task
Human intervention rate
La plupart d’entre elles sont des métriques de flux de travail, et non des métriques de tokens. Les tokens restent importants, mais ils influencent les aspects économiques plutôt que de définir l’efficacité.
Cost par tâche réussie
Le changement le plus simple à apporter est d’arrêter de suivre ce paramètre :
cost per request
et suivez plutôt ceci :
cost per successfully completed task
Ils ne sont pas équivalents. Prenons un agent avec ces chiffres :
Agent A
$0.20/task
70% success rate
par rapport à celui-ci :
Agent B
$0.35/task
95% success rate
La demande la moins chère n’est pas nécessairement le système le moins cher. Normalisez-la :
Effective cost
= inference cost / successful tasks
Pour A :
$0.20 / 0.70
≈ $0.286
Pour B :
$0.35 / 0.95
≈ $0.368
A gagne selon cette métrique simple. Mais si A nécessite beaucoup plus de supervision de la part des développeurs, les considérations économiques changent à nouveau, c’est pourquoi les équipes ont finalement besoin d’une définition plus large du coût des tâches.
La même logique s’applique au choix des modèles
Cela renvoie à l’évolution vers le routage des modèles. La version préliminaire de la recherche HydraFusion de GitHub traite déjà les workflows de codage comme un problème d’optimisation, en choisissant pour chaque tâche entre un seul modèle, une escalade vers des modèles plus puissants, ou un deuxième modèle agissant en tant que critique indépendant. Des tests hors ligne menés dans des conditions contrôlées auraient montré d’importantes économies estimées, avec une qualité sur certains benchmarks égale ou supérieure à la référence Opus 5 utilisée.
Associez cela à la leçon tirée des résultats. Un agent intelligent ne se contente pas de demander quel modèle est le moins cher. Il demande quel workflow permet d’achever cette tâche avec le moins de gaspillage. Ce workflow peut combiner :
Cheap model
+
Good context
+
Efficient tools
+
Verification
et battez celui-ci :
Expensive model
+
Poor context
+
Repeated tool calls
L’intelligence n’existe plus uniquement dans le modèle. Elle est répartie dans tout le système.
Si vous développez des produits d’IA
Il est tentant de commencer par optimiser les paramètres évidents : moins d’utilisation de tokens, des prompts plus courts, des sorties plus brèves, des modèles moins chers. Ne vous concentrez pas uniquement sur ceux-ci. Instrumentez l’ensemble du flux de travail :
User request
↓
Model inference
↓
Tool call
↓
Tool response
↓
Model reasoning
↓
Another tool call
↓
Verification
↓
Final result
Évaluez chaque étape, puis demandez-vous où l’agent effectue un travail inutile. Peut-être que l’outil de base de données fournit trop peu de contexte, ou que l’outil de recherche renvoie trop de matériel irrelevant. Peut-être que l’agent réessaie inutilement, ou que votre instruction force une planification redondante. Peut-être qu’un modèle plus puissant résoudrait le problème en la moitié des tentatives, ou qu’un modèle moins coûteux suffit amplement pour une première tentative. Ce sont des problèmes d’ingénierie logicielle.
Le futur, ce n’est pas moins de tokens
Il est tentant de réduire tout le problème de coût à :
tokens ↓
cost ↓
La véritable relation ressemble plutôt à ceci :
Useful context
↓
Better decisions
↓
Fewer retries
↓
Fewer unnecessary tool calls
↓
Shorter task duration
↓
Lower total cost
Parfois, le chemin vers des coûts plus bas commence par fournir davantage d’informations au modèle. C’est là l’aspect contre-intuitif, et c’est pourquoi l’ingénierie de l’IA devient une discipline systémique plutôt qu’un simple exercice d’élaboration de prompts.
Évaluer le travail accompli
Lorsque vous évaluez un agent, ne demandez pas seulement combien de tokens il a utilisés. Demandez plutôt quelle quantité de logiciel utile il a produit, et combien d’efforts il a gaspillés pour y parvenir. Cela implique de suivre la précision, le temps de réponse, les appels aux outils, les tentatives de réessai, la taille du contexte, le coût de l’inférence, l’intervention humaine et l’achèvement réussi.
Le système de codage gagnant n’émettra pas nécessairement le moins grand nombre de tokens. On peut s’attendre à ce que ce soit la configuration qui transforme chaque token, chaque appel d’outil et chaque choix de modèle en véritable progrès. Les dernières initiatives techniques de GitHub montrent la direction à suivre : optimiser l’ensemble de la tâche, conserver les informations nécessaires à l’agent, et ne réduire les efforts que lorsque l’on sait qu’ils ne sont d’aucune aide. Il ne s’agit pas de faire en sorte que les agents fassent moins, mais plutôt qu’ils gaspillent moins.