Vous vous réveillez avec cinq rapports de bugs critiques un lundi matin. Votre outil de surveillance a fait son travail. Il a capturé chaque rapport de crash, chaque avis une étoile en colère, chaque « l'application freeze quand j'appuie sur enregistrer ». Vous savez exactement ce qui est cassé. Ce que vous ne savez pas, c'est où chercher.

C'est le mur contre lequel j'ai buté après avoir construit mon premier pipeline. Il surveillait les avis sur l'application et les journaux de crash entrants sans problème, triant chaque retour dans des catégories bien nettes : bugs, crashs ou demandes de fonctionnalités. Le tableau de bord semblait sain. Le processus de débogage réel ne l'était pas.

Savoir qu'un bug existe n'est que le tout début du processus. Je devais encore ouvrir l'IDE, chercher via grep dans les modules, croiser les stack traces avec la base de code actuelle et reconstruire le chemin de l'échec dans ma tête. Lorsque les tickets s'accumulent et que le café est encore chaud, cette archéologie manuelle consomme un temps que vous n'avez pas. J'avais besoin que le pipeline fasse plus que signaler les problèmes. J'avais besoin qu'il les enquête.

J'ai donc reconstruit le système autour d'un objectif unique : prendre un rapport de bug brut et renvoyer un diagnostic validé. Pas un paragraphe de réflexions d'un LLM. Une conclusion structurée qui nomme le fichier, pointe la ligne, estime le risque et suggère un correctif. Voici comment tout cela s'est mis en place.

Pourquoi la structure l'emporte sur un journal de chat

J'ai conçu l'agent d'investigation avec PydanticAI. La raison était simple. Lorsque vous demandez à un modèle de langage de raisonner sur du code, sa sortie par défaut est un flux de texte amical. Cela peut aider un lecteur humain, mais c'est inutile pour un script en aval. J'avais besoin d'un contrat lisible par une machine.

L'agent renvoie un modèle de données validé avec quatre champs spécifiques : la cause racine, les fichiers affectés, les modifications proposées, et une évaluation de la complexité et du risque. Si le modèle manque un champ ou hallucine un chemin de fichier, la validation échoue et je le détecte immédiatement. Cette rigueur garantit l'honnêteté du pipeline.

Pour effectuer le véritable travail de détective, l'agent dispose de quatre outils en lecture seule et rien d'autre. Il peut rechercher du code via grep, lire des plages de lignes spécifiques dans un fichier, lister le contenu d'un répertoire et localiser des symboles tels que des classes ou des fonctions. Le mode lecture seule est l'élément crucial. Je ne voulais pas d'un agent avec un accès en écriture errant dans mon dépôt à 2 heures du matin. Comprendre d'abord, éditer ensuite.

La carte du dépôt : le contexte avant les outils

La première version de l'agent était précise, mais extrêmement coûteuse. Elle consommait des tokens comme un touriste marchant en rond. Le modèle appelait list-dir, puis grep, puis lisait un fichier, puis listait à nouveau le répertoire, assemblant lentement un modèle mental de la structure du projet, un token coûteux après l'autre.

La solution a été de générer une carte compacte du dépôt avant même que l'agent ne commence. Cette carte est un aperçu distillé du dépôt : les fichiers clés, leurs fonctions ou classes principales, et la manière dont les modules majeurs sont connectés. Considérez cela comme si vous remettiez un GPS à l'agent au lieu de lui demander de découvrir les routes par essais et erreurs.

Avec cette carte dans sa fenêtre de contexte, l'agent ne gaspille pas d'appels pour découvrir que src/utils/parser.ts existe. Il connaît déjà le terrain. Il se dirige directement vers la crête d'où s'élève la fumée. Ce seul changement a totalement supprimé la phase d'errance.

L'entonnoir d'outils : imposer une conclusion

Même avec une carte, l'agent pouvait hésiter. Il trouvait un fichier suspect, puis doutait de lui-même, puis cherchait à nouveau, puis lisait un autre fichier, piégé dans une boucle sans fin de « juste une dernière vérification ». J'avais besoin d'un moyen de forcer l'élan.

J'ai mis en place un entonnoir d'outils en trois phases qui restreint ce que l'agent peut faire à mesure qu'il progresse.

La première phase est l'exploration. L'agent a un accès complet aux quatre outils. Il peut rechercher, parcourir et lire tout ce dont il a besoin pour reproduire le bug dans son raisonnement.

La deuxième phase est l'immersion profonde. Une fois que l'agent a identifié les lignes de faille probables, il perd ses outils de découverte. Il ne peut plus que lire des fichiers. Plus de grep, plus de listage de répertoires. À ce stade, il doit étudier le code qu'il a déjà trouvé et construire sa chaîne de preuves.

La troisième phase est la production. Tous les outils sont verrouillés. L'agent ne peut plus interroger la base de code. Il doit s'asseoir et rédiger le rapport. Cela évite la spirale sans fin du « laissez-moi vérifier une dernière chose ».

Cet entonnoir a réduit le nombre moyen d'appels d'outils de plus de quarante par analyse à environ dix. L'agent est devenu plus rapide, moins coûteux et, paradoxalement, plus sûr de lui, car il devait s'engager vers une conclusion.

Garder le backend interchangeable

Je ne voulais pas coder le système en dur pour un seul fournisseur de modèle. J'utilise différents moteurs selon la tâche. Parfois Claude Code, parfois Grok Build, parfois ce qui est le moins cher à l'instant T. Pour que la logique de base soit indépendante du fournisseur, j'ai divisé le travail en deux étapes.

La première étape est l'exploration. L'agent de codage, qui peut être n'importe quel modèle performant, lit la carte du dépôt, utilise les outils et produit un rapport markdown brut. C'est la partie réflexion, la plus coûteuse.

La deuxième étape est la structuration. Un LLM peu coûteux et rapide prend ce markdown et le reformate selon le modèle Pydantic strict. Cette étape ne nécessite presque aucune réflexion. Il s'agit simplement d'extraction et de formatage, elle peut donc s'exécuter sur du matériel léger.

Comme la séparation est nette, je peux changer le backend sans toucher à la logique de validation. Le rapport markdown agit comme un adaptateur universel entre le cerveau exploratoire et la sortie structurée que j'utilise réellement.

Ce qui a réellement fonctionné

Cette configuration a changé ma façon de gérer les tickets entrants. La couche de classification trie toujours les bugs des demandes de fonctionnalités, mais la couche d'analyse prend désormais le relais immédiatement après. Le temps que j'ouvre mon éditeur, j'ai déjà un chemin de fichier, une plage de lignes et une modification proposée qui m'attendent. Je révise toujours tout manuellement. C'est de l'assistance, pas du pilote automatique. Mais la collecte de contexte qui...