17 points par GN⁺ 2025-12-31 | 1 commentaires | Partager sur WhatsApp
  • À mesure que les agents IA occupent une place centrale dans l’écriture du code, des bonnes pratiques autrefois « facultatives » comme les tests, la documentation et le typage statique deviennent désormais indispensables
  • Une couverture de code à 100 % est exigée, afin que chaque ligne de code soit réellement vérifiée et étayée par des exemples d’exécution
  • Une structure de répertoires et un nommage de fichiers clairs facilitent l’exploration de la base de code par les LLM, et favorisent une organisation en petits fichiers
  • Des environnements de développement rapides, éphémères et exécutables en parallèle permettent à plusieurs agents de travailler simultanément
  • Le maintien d’un écosystème de code fiable pour l’IA repose sur un système de types statiques et des outils automatisés de contrôle qualité

IA et nécessité du « bon code »

  • Depuis longtemps, les développeurs considèrent les tests, la documentation, les petits modules et le typage statique comme des critères de bon code, mais dans la pratique ils sont souvent omis
  • Or, les agents IA ne sont pas très bons pour remettre eux-mêmes le code en ordre, ce qui rend ces bonnes pratiques indispensables
  • Pour empêcher un agent de partir dans la mauvaise direction, il est essentiel de mettre en place des garde-fous clairs et appliqués de façon stricte
  • Avec des garde-fous solides, les LLM convergent uniquement vers la bonne trajectoire ; dans un environnement incomplet, ils amplifient les problèmes

Couverture de code à 100 %

  • L’équipe impose une couverture de code à 100 %, non seulement pour éviter les bugs, mais surtout pour vérifier le comportement de tout le code écrit par les agents
  • Avec 95 % ou 99,99 % de couverture, l’origine du code non testé reste floue, tandis qu’à 100 %, chaque ligne non validée peut être identifiée clairement
  • Le rapport de couverture sert de liste des éléments à tester, et le LLM doit impérativement fournir un exemple exécutable lors d’une modification du code
  • Cette approche a aussi des effets bénéfiques annexes : suppression du code inatteignable, explicitation des cas limites, amélioration de l’efficacité des revues de code

Espaces de noms et structure des fichiers

  • Les agents explorent la base de code via le système de fichiers, si bien que la structure des répertoires et les noms de fichiers jouent un rôle d’interface essentiel
  • Un chemin clair comme ./billing/invoices/compute.ts transmet bien plus d’informations que ./utils/helpers.ts
  • Il faut privilégier des fichiers petits et bien délimités, afin que le LLM puisse charger l’intégralité du fichier dans son contexte et ainsi éviter une baisse de performance
  • Cette structuration permet d’améliorer la vitesse d’exploration et la précision des agents
Publicité

Des environnements de développement rapides, éphémères et parallélisables

  • Au lieu d’un environnement de développement unique, le développement basé sur des agents évolue vers une gestion parallèle de plusieurs processus
  • Fast : les procédures de test et de validation doivent s’exécuter rapidement ; l’équipe a optimisé plus de 10 000 assertions pour qu’elles soient terminées en moins d’une minute
    • La vitesse est obtenue grâce à une parallélisation poussée, une forte isolation et une couche de cache pour les appels tiers
  • Ephemeral : la commande new-feature <name> permet de créer un nouvel environnement en 1 à 2 secondes, avec configuration automatique et lancement de l’agent
    • Si une configuration manuelle est nécessaire, la fréquence d’usage chute fortement ; l’automatisation complète est donc essentielle
  • Concurrent : pour exécuter simultanément plusieurs environnements de développement, il faut éviter les conflits liés aux ports, à la base de données, au cache, etc.
    • Isolation via Docker ou via une configuration fondée sur des variables d’environnement
    Publicité

Système de types de bout en bout et contrôle qualité automatisé

  • Il faut automatiser autant de bonnes pratiques que possible afin de réduire la marge de liberté du LLM et de maintenir une qualité constante
  • Configurer des linters et formatters automatiques de manière stricte, afin que des corrections automatiques soient appliquées chaque fois que le LLM termine une tâche
  • Il est recommandé d’utiliser un langage à typage statique, en s’appuyant notamment sur TypeScript et son système de types puissant
    • Des noms de types porteurs de sens comme UserId, WorkspaceSlug, SignedWebhookPayload rendent l’intention du code plus explicite
  • OpenAPI permet de maintenir la cohérence des types entre le frontend et le backend
  • Le système de types et les triggers de Postgres garantissent l’intégrité des données, tandis que Kysely génère un client type-safe
  • Tous les clients tiers doivent eux aussi disposer de définitions de types précises, ou être utilisés via des wrappers

Conclusion : redéfinir la qualité du code à l’ère de l’IA

  • Les agents sont des codeurs infatigables et performants, mais leur niveau dépend de la qualité de l’environnement
  • Le « bon code » n’est plus un choix, mais une condition préalable au bon fonctionnement de l’IA
  • La mise en place initiale peut sembler lourde, mais il s’agit d’un investissement indispensable longtemps repoussé
  • Avec le soutien du leadership technique, il faut viser la construction d’une base de code adaptée à l’IA

1 commentaires

 
GN⁺ 2025-12-31
Avis sur Hacker News
  • Le piège quand on atteint 100 % de couverture, c’est que si le code et les tests sont écrits par le même agent, on peut tomber dans une validation auto-contradictoire
    Si l’agent produit une logique erronée et écrit aussi des tests erronés pour la valider, les tests passent mais le code reste faux en pratique
    Cette couverture n’a de sens que si les tests sont écrits avant le code, ou si un humain les vérifie rigoureusement
    Sinon, cela ne fait que créer une illusion de fiabilité

    • Tu as raison, mais la solution n’est pas simplement de dire « laissons faire les humains » ou « écrivons les tests avant le code »
      Le point clé, c’est que plusieurs personnes avec des façons de penser différentes vérifient mutuellement leurs angles morts
      Même avec plusieurs modèles d’IA, il faut au final les considérer comme un seul « esprit »
      L’idéal, c’est des tests IA sur du code humain, des tests humains sur du code IA, ou encore des revues croisées
      Cela dit, même entre humains, les rapports de pouvoir font parfois qu’une seule opinion l’emporte, et l’IA n’empêche pas ça
    • C’est pour ça qu’il faut tester les tests
      Il faut insérer volontairement des bugs et vérifier qu’ils échouent bien
      Ce n’est pas un problème propre à l’IA, c’est pareil avec les humains
      Malgré tout, c’est une bonne chose que grâce à l’IA beaucoup de développeurs apprennent enfin de vrais principes d’ingénierie
    • Il semble que le changement se produise non pas à 100 % de couverture, mais à 100 % de couverture MC/DC
      SQLite ou les logiciels aéronautiques visent ce niveau
      Cela dit, ce n’est pas encore une hypothèse validée académiquement
    • Les tests unitaires écrits à la main ont exactement le même problème
      C’est pour ça qu’il faut valider les scénarios réels d’utilisation avec des tests d’intégration ou des tests automatisés d’interface utilisateur
      Des données issues de la production ou des tests en environnement miroir peuvent aussi aider
    • Il existe déjà de bonnes solutions fondées sur le code, comme BDD ou les tests d’acceptation
      Avant les LLM, leur mise en place était fastidieuse, mais maintenant le ROI s’est amélioré
      Comme le soulignait Uncle Bob, il est important d’investir dans la structuration des tests
      Les LLM écrivent volontiers des tests répétitifs, mais si on le leur demande, ils appliquent aussi très bien le principe DRY ou le pattern factory
  • C’est une méthode que j’essaie depuis hier : j’écris d’abord les spécifications en TLA+/PlusCal, puis je demande à Codex de les implémenter telles quelles
    Je lui demande de s’en tenir strictement aux specs, sans créativité
    Le code obtenu est laid mais correct, et bien plus rapide à produire que si je le traduisais moi-même
    En revanche, quand l’optimisation manque ou que c’est trop brouillon, je corrige certaines parties
    En particulier, j’expérimente des structures de données sans verrou, mais Codex essaie encore d’utiliser des verrous, donc je dois le corriger moi-même
    Au final, je me concentre sur la logique mathématique et l’IA prend en charge les détails d’implémentation
    C’est exactement le flux idéal : « spécifications d’abord, code ensuite »

    • Je développe de manière similaire moi aussi
      Je me retrouve dans le billet de Martin Kleppmann
    • J’ai récemment tenté des itérations avec Haskell ou Prolog, et j’aimerais qu’il existe un groupe qui travaille à la fois sur les LLM et la modélisation/vérification
    • Les gains sont encore plus importants si on fait aussi participer le LLM à la rédaction des specs
      Avec les modèles récents, cela fonctionne réellement bien, et la rentabilité est 10 à 100 fois meilleure
  • Ça ressemble à une hallucination ou à un argumentaire commercial
    Si les bugs en production et le coût de maintenance ne suffisent pas à imposer du bon code, l’IA n’y arrivera pas non plus
    Au niveau actuel, l’IA risque au contraire d’aggraver la qualité du code

    • Le problème, c’est l’hypothèse selon laquelle « tout le monde sait ce qu’est un bon code »
      Alors qu’on n’arrive même pas à se mettre d’accord sur la longueur d’une méthode, il n’existe pas de critère universel de qualité
      Même des indicateurs comme la couverture de tests se manipulent facilement et, mal appliqués, peuvent devenir nuisibles
    • La couverture de tests n’est pas un substitut à du bon code
      Surtout quand c’est l’IA qui écrit les tests, cela peut donner une fausse impression de confiance
    • Comme l’auteur du billet original est CEO d’une société d’IA, il y a peut-être un biais /s
  • Je pense que le développement logiciel est peut-être la seule application vraiment concrète des LLM
    On peut y créer des boucles de feedback bien plus rapides que dans d’autres domaines
    On établit un plan avec le LLM, puis quelques heures plus tard on constate l’échec, et le LLM dit : « voilà pourquoi il ne fallait pas faire comme ça »
    C’est comme construire une maison aux normes électriques américaines puis découvrir un problème au moment d’installer un lave-vaisselle canadien

    • C’est justement pour cela que les autres disciplines d’ingénierie ont des règles strictes et des systèmes de qualification
      Le logiciel était relativement sûr, ce qui permettait le développement anonyme, mais une culture de la signature responsable est en train d’émerger
      À l’avenir, seules les personnes qui écrivent du code innovant à haut risque seront peut-être très bien payées
    • Mais je ne vois pas pourquoi ce genre d’expérience mène à la conclusion que les LLM sont utiles
      L’IA continue de produire du code absurde, nous le déboguons, puis elle produit encore autre chose d’absurde : on tombe juste dans une boucle infinie
    • On peut quand même installer un lave-vaisselle canadien
      Il suffit simplement que les spécifications de courant soient compatibles pour que ce soit sûr
    • Si on pense aux simulateurs ou aux jumeaux numériques, on peut créer des boucles de feedback sans construire quoi que ce soit dans le monde réel
      Cela dit, je trouve rassurant de garder un point de contact avec le réel via les tests unitaires
    • Dire qu’« en dehors du logiciel il n’existe pas d’application concrète » est une affirmation arrogante
      Moi, j’utilise les LLM pour étudier des circuits RLC et des inerters
  • Beaucoup de gens sont impressionnés par la vitesse à laquelle les LLM génèrent du code, mais la vitesse ou le volume ne sont pas le goulet d’étranglement de la qualité
    La vraie révolution arrivera quand l’IA produira du code plus exact que les humains

    • Utiliser les LLM éloigne les ingénieurs de la compréhension réelle de l’implémentation d’un système
      La vraie valeur vient du fait de savoir comment le code fonctionne
      Dans une réunion remplie d’ingénieurs qui ne font que supposer, le moment le plus précieux est celui où l’un d’eux ouvre le vrai code et le montre
  • Le « bon code » est peut-être simplement du code optimisé pour la mémoire de travail limitée des humains
    Les modèles peuvent voir tout le contexte d’un seul coup, ils n’ont donc pas cette contrainte
    Si la fenêtre de contexte devient 100 fois plus grande, ce débat perdra peut-être de son importance

  • J’ai peur qu’exiger 100 % de couverture d’un LLM fige de mauvaises hypothèses
    Mais s’il y a une revue humaine, on peut toujours dire : « c’est faux, supprimons ces tests et réécrivons-les », non ?

    • Exactement, il y a toujours une revue humaine des cas de test
      On rédige aussi le PRD avec le LLM, comme dans un entretien, afin de clarifier le périmètre et les attentes
    • En pratique, les LLM produisent souvent beaucoup de tests dénués de sens, du genre « 1=1 ? »
  • Les « best practices » changent selon l’environnement technique
    Maintenant qu’écrire du code est devenu plus facile, une couverture à 100 % peut être plus utile aux LLM
    Les tests donnent au LLM un objectif clair et rendent les interactions suivantes plus sûres

    • Dans les systèmes qui évoluent sur le long terme, les tests sont une ligne de vie
      Chaque test renvoie à d’anciens tickets de bug et garantit que les correctifs restent en place
    • Les « best practices » ont beau varier dans leur implémentation, les patterns se ressemblent
      Si on donne un scénario à un LLM, il produira dans la plupart des cas un code d’une qualité similaire
      Contrairement à l’art créatif, le logiciel est une industrie particulièrement adaptée à l’automatisation
  • En voyant le titre, je pensais que l’article allait expliquer que pour que l’IA soit efficace, il faut que nous écrivions du bon code
    En pratique, Claude se trompe souvent face à des noms de variables ambigus ou à du code illogique
    Si une variable s’appelle « iteration_count » mais contient une somme, l’IA se fait piéger
    Au final, du code propre aide autant l’IA que les humains

    • Grâce à l’IA, l’équipe accorde davantage d’attention à la documentation et à la maintenance des commentaires
      Comme l’IA utilise la documentation interne comme ressource d’apprentissage, une documentation à jour est désormais considérée comme indispensable
      Avant, c’était une faible priorité, mais aujourd’hui cela affecte directement la qualité du modèle
    • Les humains se souviennent du contexte d’un code déjà vu, tandis que l’IA doit réapprendre à chaque session
      Cela dit, ce point s’améliorera probablement avec le temps
    • Une méthode efficace consiste à indiquer clairement l’intention et la logique via les signatures de méthodes et les commentaires
      Cela augmente les chances qu’un LLM produise directement une implémentation correcte
  • Cet article révèle la compréhension superficielle de l’ingénierie qu’ont les entreprises du prompt
    Une couverture à 100 % ne vérifie pas toutes les combinaisons d’entrée
    Elle signifie seulement que toutes les lignes ont été exécutées avec quelques exemples
    Au final, il faut des preuves formelles, mais leur coût est astronomique et les LLM n’y servent à rien

    • Alors quelle est la solution ? Voir un senior commenter « LGTM » sur une PR ne relève que du test émotionnel
      À l’inverse, bâtir un environnement de développement réactif grâce aux tests pourrait ouvrir un nouvel âge d’or
      Si la couverture pose problème, on pourra l’étendre plus tard
      Le mieux est de mettre en place dès le départ des tests aussi complets que possible
    • Dire que les LLM sont inutiles pour la vérification formelle est exagéré
      Il existe déjà de nombreuses tentatives de connexion avec des proof assistants
      Même quand les spécifications contiennent quelques erreurs, ils produisent dans la plupart des cas des résultats exploitables