Combien coûte une nuit d'agents

Pendant des semaines, j'ai laissé des agents Claude coder ma plateforme la nuit sans jamais savoir ce qu'ils me coûtaient. Alors j'ai posé un compteur sur chaque run. Il m'a montré trois choses gênantes : presque la moitié des cycles tournaient à vide, un ticket s'est fait relancer cent soixante-seize fois, et j'envoyais mon modèle le plus cher trier des broutilles. Récit d'une mise à la diète, sans rogner sur la qualité.

Projet rattaché Granit Golem Sur Azure, le prix d'un health-check explose : de quelques centimes à plusieurs euros pièce. Aucun outil self-hosted ne coche mes cases, alors je l'écris moi-même. Au passage, je lâche Claude Code à fond pour voir : le projet 'rikiki' vire en plateforme SaaS industrielle, et je passe un mois à éponger le bazar généré.

J’ai un daemon, Forge, qui fait coder ma plateforme par des agents Claude pendant que je dors. J’ai raconté ailleurs comment je lui ai confié ma backlog et comment je lui ai appris à se relever quand il tombe. Mais il y a une question toute bête que j’ai mis des semaines à me poser.

Combien tout ça me coûte, au juste ?

Je n’en avais aucune idée.

Je voyais le travail sortir le matin, les merge requests, les commits. Je ne voyais pas la facture. Chaque agent consomme des jetons, et chaque jeton se paie, mais ce coût-là restait abstrait, noyé quelque part dans un relevé mensuel. Un peu comme laisser tourner le chauffage toutes fenêtres ouvertes : tant qu’on ne regarde pas le compteur, on ne sent rien.

Tant que je tourne sous le quota forfaitaire, ça ne me coûte rien de plus. Mais dans quelques jours, la donne change : une facturation à l’usage débarque pour tous les claude -p.

Poser un compteur

Sur d’autres projets, j’avais déjà tâté d’une gestion de budget par tâche, mais rien d’industrialisé. Première étape, donc : rendre ce coût visible, run par run.

Chaque agent laisse derrière lui un transcript, un journal qui détaille ses échanges et ses jetons. J’y trouve quatre compteurs : les jetons d’entrée (ce que je donne au modèle), les jetons de sortie (ce qu’il me répond), et deux compteurs de cache (ce qu’il relit d’un contexte déjà vu, bien moins cher). Forge ramasse ces chiffres à la fin de chaque run, les croise avec une grille de tarifs Anthropic, et en sort un coût en dollars.

Du transcript au coût, run par run

La trace

  • le transcriptle journal de jetons que laisse chaque run
  • quatre compteursentrée, sortie, cache lu, cache écrit

Le tarif

  • la grille Anthropicun prix au million de jetons, par modèle
  • le coût du runles jetons croisés avec leur tarif

Le bilan

  • cumulé par cyclele coût d'une nuit entière, d'un coup d'œil
  • une série dans le tempspour voir si je dérive ou si je m'améliore
Chaque agent laisse un journal de ses jetons. Forge le ramasse, le tarife, et additionne tout ça par cycle.

Comment je récupère ça ?

J’ai fait au plus simple pour une première version : une base SQLite qui encaisse les mesures relevées par des hooks. Le compte de jetons sort d’une heuristique, cache compris, que je croise ensuite avec la grille de tarifs à l’usage.

Une fois ce coût calculé par run, je l’additionne par cycle. D’un coup d’œil, je vois ce que m’a coûté une nuit entière de travail, et je peux suivre la courbe dans le temps. La facture a cessé d’être abstraite. Et elle s’est mise à raconter des choses gênantes.

Trois aveux du compteur

Le premier constat, c’est le gâchis pur. Sur une période que j’ai mesurée, presque la moitié des cycles (cent quatre-vingt-quatre sur quatre cent quinze) tournaient sans le moindre ticket à traiter. Le daemon se réveillait, regardait la file vide, et faisait quand même tout son cérémonial : interroger GitLab, écrire un commit de routine, repartir. Pour rien. Quarante-quatre pour cent de mes cycles brassaient du vent.

Oui, ce n’est pas la meilleure des idées…

La deuxième, vous la connaissez déjà si vous avez lu le carnet sur les garde-fous : ce ticket relancé cent soixante-seize fois dans la nuit, toujours pour le même échec. Vu sous l’angle du coût, chacune de ces relances était un agent lancé, du contexte rechargé, des jetons brûlés, pour reproduire exactement le même mur.

La troisième était plus sournoise. J’envoyais mon modèle le plus puissant, Opus, sur absolument tout. Y compris des tâches qui n’en demandent pas tant : trier un ticket, retirer une étiquette, valider qu’un déploiement répond. Le marteau-pilon pour écraser une mouche, à chaque fois.

Le bon modèle pour la bonne tâche

Faut-il vraiment Opus pour corriger la couleur d’un bouton ? Non.
Et c’est pourtant ce que je faisais, run après run, sans y penser. J’ai donc attaqué ce point en premier, le plus simple à redresser. Tous les modèles ne coûtent pas pareil : un Sonnet revient nettement moins cher qu’un Opus au million de jetons, et un Haiku, cinq fois moins. Reste, pour chaque tâche, à trouver le modèle juste : le moins cher qui fait encore le travail.

J’ai donc rangé les tâches par nature. Le vrai travail (écrire une fonctionnalité, corriger un bug, remanier) reste sur Opus, sans négociation : là, une bêtise du modèle coûte bien plus cher que le modèle lui-même. Mais tout le reste, le mécanique, le cadré (réparer une CI, débloquer un cycle, valider un déploiement), bascule sur un modèle moins cher.

À chaque tâche son modèle6 gates

Jamais bradéOpus
  • Écrire une fonctionnalité, corriger un vrai bug, remanier du code
  • Le travail où une bêtise coûte plus cher que le modèleces tâches ne descendent jamais d'un cran
Bon pour Sonnetmoins cher
  • Réparer une CI cassée, débloquer un cycle, valider un déploiement
  • Du travail mécanique, cadré, à faible enjeu de jugementtrier, classer : même logique
Le garde-fou qualitésur 10 runs
  • Si une classe de tâches rate plus d'une fois sur deux, elle remonte sur Opus toute seule
  • L'économie ne doit jamais se payer en travail bâcléil faut au moins trois runs pour juger

Tout ne mérite pas mon modèle le plus cher. Un diagnostic complexe, oui. Corrige la couleur d'un bouton, non.

Ne pas troquer la qualité contre des sous

Reste un piège évident. Si je brade un modèle sur une tâche qu’il rate sans cesse, je ne gagne rien : je paie moins par run, mais je multiplie les runs ratés. L’économie de façade tourne au gouffre.

D’où le garde-fou que j’ai posé par-dessus le routage. Forge surveille le taux d’échec de chaque classe de tâches sur ses dernières runs. Si une classe se met à rater plus d’une fois sur deux, elle remonte d’elle-même sur Opus. Il faut au moins trois runs pour juger (sinon le moindre faux pas déclenche le repli), mais passé ce seuil, le système se corrige seul.

L’idée tient en une phrase : le modèle léger reste tant qu’il fait le travail. Le jour où il commence à patiner, on remet le bon outil sans attendre que je m’en aperçoive.

La vraie surprise : le cache

En regardant les chiffres de près, un détail m’a sauté aux yeux. Sur une journée type, mes agents relisent environ trois cent cinquante-sept millions de jetons de cache, pour à peine deux millions de jetons de réponse produits. Le cache pèse près de deux cents fois la sortie.

Ça paraît énorme, et c’est précisément ce qui rend l’affaire soutenable. Un jeton relu du cache coûte un dixième d’un jeton d’entrée neuf. Tout ce contexte que les agents traînent (le code du projet, les specs, les consignes) n’est pas refacturé plein tarif à chaque run, il est relu à prix cassé (l’écriture du cache, elle, se paie un peu au-dessus de l’entrée neuve, mais je ne la paie qu’une fois). Sans ce mécanisme, faire tourner une flotte d’agents la nuit ne serait pas un loisir d’ingénieur, ce serait un luxe.

Ce que j’en retiens

Je croyais qu’une flotte d’agents, c’était surtout une affaire de prompts et de garde-fous. C’en est une. Je n’avais juste pas encore branché les compteurs.

Le compteur n’a rien réparé.
Il a juste éclairé où partait vraiment l’argent : dans les nuits sans rien à faire, où mes robots faisaient quand même semblant.

Alors, combien ?

Reste la question du début, celle qui a tout déclenché : combien me coûte une nuit d’agents ? Le chiffre exact, je ne l’ai pas encore. Pas au centime près, et je ne vais pas en inventer un (certains connaissent mon aversion pour les moyennes en plus). Ce que j’ai, en revanche, ce sont les instruments : les thermomètres sont plantés, un par run, et le compteur tourne chaque nuit.

La suite au prochain relevé.