Retour au blog
X24LABS

Supprimer notre classifieur regex : quand l'IA remplace votre propre abstraction

On a passé des mois à construire un moteur de regex pondéré qui classait les erreurs CI en neuf catégories avec des scores de confiance. Puis on l'a supprimé. Voici l'histoire de pourquoi il devait partir et de ce qui l'a remplacé.

La réécriture v1 vers v2 portait surtout sur la forme externe. En local au lieu de distant, TypeScript au lieu de Python, CLI au lieu de job CI. La partie qui mérite un post à elle seule est interne. v2 est parti avec beaucoup moins de code que v1, et une grande partie de ce qui manque a été volontairement supprimée.

La plus grosse suppression en un seul bloc, c’était notre classifieur d’erreurs.

Ce qu’il faisait

Le classifieur de v1 était un moteur de regex pondéré. Il lisait les logs CI, les passait à travers environ cent cinquante patterns et triait les erreurs en neuf seaux : lint, formatage, types, build, config CI, contrats de tests, types complexes, logique, et un fourre-tout appelé unknown. Chaque classification venait avec un score de confiance. Chaque seau pointait vers une stratégie de correction.

La landing page de Stitch v1 listait fièrement les neuf catégories. On pensait que c’était une fonctionnalité.

Pourquoi on l’avait construit

Le classifieur répondait à un vrai problème. Les appels aux modèles de langage coûtent des tokens. Les logs CI sont énormes. Si vous envoyez tout le log, vous gaspillez du contexte et vous obtenez de moins bons résultats parce que le modèle doit trouver le signal lui-même. Si vous prétraitez le log, retirez le bruit, isolez l’erreur pertinente et étiquetez son type, vous économisez des tokens et vous donnez une longueur d’avance au modèle.

On a donc construit un préprocesseur. Il tournait avant le modèle. Il produisait une charge utile compacte qui disait “c’est une erreur de type sur le fichier X ligne Y, voici la traceback, voici les cinq lignes autour du site d’appel”. Le modèle produisait ensuite le correctif. Ça marchait.

Pourquoi il devait partir

Deux choses ont changé.

Les modèles sont devenus meilleurs à lire des logs bruts. Claude et GPT sont devenus moins chers par token et plus aiguisés pour parser une sortie non structurée. L’écart entre “envoyer au modèle une erreur extraite chirurgicalement” et “envoyer au modèle le log et le laisser comprendre” s’est refermé. L’étape d’extraction a arrêté de rentabiliser son coût.

Notre classifieur est devenu moins bon en comparaison. On avait des patterns pour TypeScript et Python et Go. On n’avait pas de patterns pour Elixir ou Rust ou tel framework qu’un utilisateur faisait tourner cette semaine. Quand un log arrivait et que notre regex ne le reconnaissait pas, on le routait vers le seau unknown et on laissait le modèle s’en occuper quand même. C’était l’indice. Si le fallback marchait, le chemin spécialisé était optionnel. Si le chemin spécialisé était optionnel, c’était aussi une source de bugs qu’on maintenait pour rien.

La prise de conscience décisive est venue du contexte local de v2. Sur la machine d’un développeur, lancer stitch run claude voulait dire qu’on appelait Claude Code, qui est un agent pluggable avec déjà des outils pour lire des fichiers, lancer des commandes et raisonner sur des erreurs. Lui envoyer une charge utile pré-classée, c’était comme envoyer à un ingénieur senior un rapport de bug pré-rempli en insistant pour qu’il utilise notre template. Il n’en avait pas besoin. Le template ajoutait de la friction.

Ce qu’on a mis à la place

Deux choses. Une beaucoup plus simple qu’avant, une pas du tout dans la même couche.

Stitch v2 fait toujours un petit prétraitement, mais il est grossier et honnête. Il regarde les noms des jobs et décide de les lancer ou non. Un job appelé deploy-prod est infra, à sauter en local. Un job appelé lint est vérification, à lancer en local. C’est une décision d’une ligne par job. Il ne prétend pas savoir ce que seront les erreurs.

Le vrai diagnostic a déménagé dans l’agent. Quand un job échoue, Stitch passe le log à l’agent avec un prompt court et délibérément ennuyeux : voici le job, voici le log, voici le dépôt, corrige s’il te plaît. L’agent fait ce qu’il ferait dans une session interactive. Il lit des fichiers, il lance des commandes, il essaie des choses. Stitch valide le résultat en relançant le job.

Le total de code retiré se compte en milliers de lignes. La capacité totale perdue est de zéro. Les diagnostics sont meilleurs parce que l’agent avait accès à tout le dépôt au lieu d’un extrait de cinq lignes.

La leçon

La leçon est inconfortable, mais elle revient encore et encore dans les outils bâtis autour d’agents IA : les abstractions que vous construisez pour aider le modèle cessent souvent d’aider une fois que le modèle devient assez bon. Si vous possédez à la fois le préprocesseur et le prompt, vous atteindrez un point où le préprocesseur rend le prompt moins bon. Vous ne le remarquerez pas parce que vous l’avez construit.

La seule façon dont on l’a remarqué, c’est en se permettant de le supprimer et de voir ce qui se passerait. Rien ne s’est passé. C’était le but.

Prochain post de la série : Stitch 2.0 arrive. Ce que vous installez vraiment et ce qu’il fait.

Retour au blog