1 points par GN⁺ 4 시간 전 | 1 commentaires | Partager sur WhatsApp
  • Même si un LLM continue d’écrire le code à votre place, si vous fusionnez tels quels des if dupliqués et des implémentations temporaires, le code généré par la suite peut suivre cette pratique comme s’il s’agissait d’une règle du projet
  • Si vous répétez la logique de vérification des droits d’accès dans un route handler, un background job, un endpoint API ou un webhook, les tests peuvent passer, mais la charge de maintenance reste la même
  • Comme le modèle génère le code suivant en regardant les fichiers ouverts, les motifs existants et les modifications récentes, quatre conditions copiées deviennent un signal qui appelle une cinquième copie
  • Même si vous demandez plus tard un refactoring, il est difficile de garantir que le LLM nettoiera correctement toutes les copies existantes, et un mauvais motif se rapproche davantage du style de la codebase que d’une simple erreur ponctuelle
  • Quand s’accumulent des conditions dupliquées, des fonctions « god » et des fusions faites en se disant « on nettoiera plus tard », il devient difficile de revenir en arrière par simple prompt, et au final c’est un humain qui doit corriger

Ce à quoi le LLM se réfère, c’est la codebase actuelle

  • Un LLM n’écrit pas le code « dans le vide » : il lit votre codebase
    • les fichiers ouverts
    • les motifs déjà présents
    • les modifications récentes
  • Les raccourcis fusionnés dans la codebase deviennent des signaux d’apprentissage qui disent : « ici, on fait comme ça »
  • La même condition de contrôle d’accès peut être répétée à plusieurs endroits
if (user.isActive && user.hasPermission('read') &&
!user.isSuspended && account.status === 'open') {
  // do a thing
}
  • Cette condition pourrait être extraite dans un helper partagé, mais le code généré par le LLM peut être fusionné tel quel simplement parce qu’il fonctionne et que les tests passent
  • Si vous demandez un cinquième endpoint avec la même règle, le modèle aura davantage tendance à suivre les copies déjà présentes dans le dépôt plutôt qu’à repartir d’une conception propre

L’illusion de confier la maintenance au LLM

  • Penser que « le LLM s’en chargera aussi plus tard quand il faudra changer ça » pousse à laisser traîner les duplications et les code smells
  • Quelques conditions dupliquées ne sont pas forcément critiques, mais ce type de code smell continue de s’accumuler
    • conditions dupliquées
    • fonctions « god »
    • fusions faites avec l’idée de « nettoyer plus tard »
  • À mesure que les mauvais motifs se multiplient, ils influencent aussi le résultat des prompts suivants, et il devient difficile de croire que le LLM corrigera plus tard toutes les occurrences sans en oublier
  • Même si l’on pense externaliser la maintenance au LLM, on finit en réalité par créer une situation où il répète des habitudes qui se dégradent de plus en plus
  • Il faut écrire le code comme si un humain allait le maintenir, et garder en bon état les motifs de code que le LLM absorbera avant de vous les renvoyer

1 commentaires

 
GN⁺ 4 시간 전
Réactions sur Hacker News
  • Créer une commande /review dans .claude/commands/review.md avec un fichier Markdown vide et y placer une checklist que l’agent doit vérifier est une bonne idée
    Quand une code review est nécessaire, il suffit de saisir /review : il consulte cette checklist, planifie les points à corriger, puis pose des questions
    Mon fichier commence par « passe en mode planification. Examine la différence entre cette branche et main. Points à considérer : ... », et comme j’y ai ajouté au fil du temps les éléments découverts en review que je faisais corriger par l’agent, j’en suis maintenant à environ 200
    L’agent ne se formalise pas d’un mur de feedback générique et passe les éléments un par un ; après avoir ajouté « vérifie que les nouveaux éléments ne dupliquent pas du code existant », j’ai été surpris de le voir commencer à planifier un vrai travail de nettoyage
    On n’en est encore qu’à effleurer la surface, et il faut donner aux outils des outils pour les outils afin qu’ils deviennent meilleurs

    • Plus j’ajoutais d’éléments à la liste, plus les performances de l’agent avaient tendance à se dégrader
      Même maintenant, avec des consignes assez simples, Claude enfreint souvent les premières instructions du type « ne pas faire de commit git sans autorisation » ou « ne pas signer les messages de commit »
      Quand on lui demande, il répond « oui, cette instruction existait, mais je l’ai ignorée » ; si on le corrige poliment pendant la session, il semble comprendre, mais il peut ensuite se retrouver incapable de faire le moindre commit
      Si on lui fait revoir une checklist de 200 éléments, il y a de fortes chances qu’il en laisse passer une bonne partie sans rien dire
    • Ce qui m’a toujours frustré avec les outils d’IA, c’est justement qu’il est difficile de connaître le niveau de qualité à attendre
      Un ingénieur humain n’irait pas utiliser dans un nouveau test une bibliothèque d’assertions complètement différente de celle employée par les 200 tests existants, mais Claude l’a fait plusieurs fois
      Du coup, je continue d’ajouter des éléments comme « examiner les conventions de test avant d’écrire »
      À l’inverse, je n’ai pas besoin de préciser des bases comme ce qu’est une fonction ou le fait qu’un test doit couvrir le diff modifié ; mais comme il n’existe pas de liste claire de ce qu’il faut dire et de ce qui peut être laissé implicite, j’ai l’impression de construire une méthode utilisable par essais et erreurs
    • Je me demande si tu pourrais partager cette liste
      Dans mon cas, je fais souvent des allers-retours avec l’agent jusqu’à ce que « cela me paraisse acceptable à mes yeux et selon mes préférences », mais je n’ai pas encore constitué une telle liste
      Selon le projet, on peut tolérer des problèmes mineurs ou des magic numbers, tandis que dans d’autres projets on impose des constantes avec des noms explicites comme SECONDS_IN_A_DAY = 24 * 60 * 60, donc c’est dépendant du contexte
    • J’ai essayé open-code-review et obtenu de bons résultats
      https://github.com/alibaba/open-code-review
      https://layandreas.github.io/personal-blog/posts/beyond-vide...
    • J’utilise une compétence de review maison, et pour ajouter un point à la description : il est utile de lui demander d’examiner d’abord l’ensemble du code, puis de refaire une review multi-rôles adaptée aux changements
      Par exemple, on lui fait choisir les N rôles les plus pertinents pour les modifications parmi une longue liste comme Senior Engineer, Security Engineer, spécialiste WCAG, etc.
      Claude exécute ensuite ces reviews en parallèle puis en fusionne les retours
      Comme je fais du développement piloté par spécification, j’ajoute les problèmes détectés à la spécification afin de garder une trace des problèmes et des décisions
  • Il est presque étrange de voir autant d’ingénieurs empiler encore un autre prompt par-dessus
    D’après mon expérience, plus on le fait, plus le résultat se dégrade : on abstrait, mais on crée de mauvaises abstractions, et on ajoute trop de commentaires, au point de perturber les appels LLM suivants
    Sur une bonne base de code, ça peut plus ou moins fonctionner, mais le code se détériore peu à peu, et si on continue jusqu’au moment où ça casse, il faut alors payer le prix de ne pas l’avoir construit soi-même en le réparant
    Quand on introduit un agent dans une nouvelle base de code, on a généralement un modèle mental du code, et le code reste relativement concis, mais à mesure que les itérations s’accumulent, les deux disparaissent et les performances du LLM baissent aussi
    Donc j’utilise les LLM pour l’exploration et la revue, et j’écris le code moi-même
    Le codage ne prend pas tant de temps que ça et c’est même la partie la plus agréable ; j’ai donc du mal à comprendre pourquoi on cherche à l’éviter, et de temps en temps je lance une course de débogage avec l’IA via le prompt /bug, mais l’IA n’est pas toujours la plus rapide

    • Je suis d’accord avec l’idée : « J’écris le code moi-même. J’ai du mal à croire que tant d’ingénieurs cherchent à éviter ça »
      Ces dernières années, le travail logiciel est passé d’un des rares refuges d’ingénierie pratique pour les bricoleurs curieux et les amateurs de puzzles à une voie de carrière pour gens intelligents attirés par l’argent, comme la finance, le droit ou la médecine
      Beaucoup de personnes qui portent aujourd’hui le titre de « software engineer » n’ont en fait jamais aimé ce travail au départ ; elles sont simplement intelligentes et consciencieuses, et ont atteint les objectifs raisonnables que leur employeur leur donnait
      Ce sont précisément ces personnes qui souhaitent le plus que des agents IA leur évitent la conception rigoureuse et le travail de puzzle, afin qu’elles puissent mettre à profit leur intelligence naturelle de manière plus paresseuse
      Comme elles n’ont pas intériorisé le codage et les principes d’ingénierie, si elles sont entourées de collègues ayant le même état d’esprit, il devient difficile de prévoir ce que cette manière de faire produira à l’avenir
      Si coder a toujours été pour vous une expérience très frustrante et pleine de friction, il est facile d’avoir l’impression que l’IA va plus vite
    • Voilà aussi pourquoi, même dans un monde où les agents écrivent « mieux » le code, les gens devraient continuer à en écrire eux-mêmes
      Il ne suffit pas de lire du code ; il faut le traverser dans la douleur pour l’intérioriser
      Les agents ont souvent tendance à entourer défensivement l’ancien code au lieu de se demander si le chemin existant doit encore exister, ce qui produit une énorme quantité de code défensif empilé comme des poupées russes
      https://softwaredoug.com/blog/2026/07/09/write-code
    • Cela fait déjà un bon moment que je fais des « courses de débogage » contre l’IA, et avant Opus 4.8, dès que ça devenait un peu complexe, il n’y avait même pas de comparaison
      Opus 4.8 a été le tournant, et aujourd’hui, surtout sur des problèmes complexes, je gagne rarement face à Opus 4.8
      Si tout le monde utilisait Opus 4.8 ou mieux pour toutes les tâches et toutes les questions, l’ambiance générale serait très différente, et il ne resterait probablement pas beaucoup de sceptiques de l’IA
    • Si l’objectif est simplement de cracher du code le plus vite possible pour fermer des tickets sans se soucier de la qualité, alors l’IA sera toujours plus rapide
    • Je travaille dans une logique assez similaire
      J’écris toujours le code à la main, et Opus en génère une partie, mais pas tout
  • C’est peut-être une idée saugrenue, mais on peut aussi simplement écrire le code soi-même
    À l’ère de l’IA, cela paraît presque difficile à croire, mais si le code doit être lu et maintenu par des humains, mieux vaut l’écrire directement pour eux
    À force de lire du code excessivement verbeux, copié-collé et recopié, on finit par s’énerver, et les autres aussi
    Si on l’écrit soi-même, on le corrige soi-même et on le structure d’une manière qui a du sens pour la maintenance par d’autres
    Sinon, on peut toujours tenter d’amadouer des agents et des boucles en créant un réseau complexe de fichiers Markdown pour leur faire comprendre à quoi devrait ressembler le code qu’un futur mainteneur est en droit d’attendre
    Je ne sais pas quelle voie sera la plus simple à long terme, et je me demande si quelqu’un a déjà hérité d’une base de code pilotée par agents en boucle et a vraiment essayé de la comprendre

  • Je ne sais pas à quel point l’idée suivante est vraie : « Quand on demande ensuite au LLM un endpoint avec les mêmes règles d’accès, le modèle ne repart pas de zéro, il part des quatre copies déjà présentes dans le dépôt »
    En pratique, il semble y avoir un biais intégré en faveur de la répétition de la structure de base et d’un moindre recours à la réutilisation ou à l’abstraction
    Si le schéma existant ressemble déjà à cela, il semble le suivre, mais en réalité il aurait probablement fait pareil dans les deux cas
    Même quand on met en place à l’avance des abstractions strictes et des exemples d’usage, puis qu’on lui demande explicitement de n’utiliser que cette API d’abstraction précise et même de copier mon style, j’ai souvent vu des LLM récents ne faire ni l’un ni l’autre, réimplémenter la structure de base depuis le bas, et ignorer partiellement ou totalement l’abstraction
    Je ne sais pas exactement pourquoi, mais j’ai l’impression qu’il y a tellement de code de ce type dans les données d’entraînement que les poids « savent » mieux produire ce genre de résultat

    • C’est malheureusement bien la réalité actuelle, et pour l’éviter, il faut donner au modèle des instructions très concrètes sur la manière d’implémenter
      Cela dit, je trouve qu’utiliser un LLM comme moteur d’implémentation rapide reste tout à fait valable
      Le défi consiste à faire émerger ces décisions d’implémentation avant que le modèle parte dans la mauvaise direction
  • Après de gros changements, j’ai obtenu de bons résultats avec le prompt suivant
    « Fais maintenant une vérification finale du code. Est-ce que tout est propre et les composants respectent le principe de séparation des responsabilités ? L’ensemble est-il compréhensible et maintenable ? Repose-t-il sur des hypothèses qui ne sont peut-être plus vraies ? Du code laissé par des modifications ou des expériences précédentes s’est-il retrouvé dans la base de code ? La documentation reflète-t-elle encore l’état actuel du code ? »

    • En général, je dis plutôt quelque chose comme : « Vérifie que ce code est dans un état professionnel digne d’être livré par un ingénieur senior »
      Et en général, il en déduit l’essentiel de ce qui précède, voire davantage
      En revanche, il faut continuer à lui rappeler explicitement de supprimer tous les commentaires de « suivi d’avancement » et de ne laisser que ceux qui ont du sens pour la maintenance à long terme
      Claude laisse par exemple des commentaires du type « le clic sur le bouton déclenche désormais l’enregistrement et n’utilise plus onBlur », alors que le code n’a en réalité jamais utilisé onBlur, et que ce commentaire ne fait que garder la trace de ce que Claude comptait faire plus tôt dans la même tâche ou sur la même branche avant que je le fasse changer de direction
    • Cela ressemble surtout à une version verbeuse de « ne fais pas d’erreur », et il serait peut-être plus logique d’avoir à la place une tâche cron nocturne qui passe en revue le travail de la veille pour produire une tâche du matin du même genre
      Le modèle l’interprétera à sa manière, mais c’est malgré tout souvent mieux que de ne rien faire
    • C’est un bon exemple de pensée AI-native
      On enseigne tout à l’IA, puis on lui demande si elle a bien appris, et les résultats sont étonnamment bons
      Je suis une démarche assez proche de celle de cet article
      https://www.lucasfcosta.com/blog/backpressure-is-all-you-nee...
  • Il existe un vieil adage
    « Commente ton code en partant du principe que la prochaine personne chargée de la maintenance est un psychopathe meurtrier qui sait où tu habites. »

    • Le type de commentaire qui m’agace le plus en ce moment, ce sont les commentaires verbeux à la sauce LLM qui, juste au-dessus de la définition d’une fonction, décrivent le comportement actuel d’un appelant précis et brisent ainsi l’encapsulation.
      J’en ai encore croisé plusieurs récemment dans une revue de PR, et j’ai posté un commentaire énervé ; ça m’a moi-même surpris.
      Je ne savais pas que je pouvais réagir comme ça.
    • Quelqu’un avec qui je travaillais autrefois disait souvent : « les commentaires sont des excuses ».
      Autrement dit, s’il y a un commentaire, c’est que le code lui-même n’est pas clair ; ça arrive, mais en général je pense qu’il vaut mieux avoir plus de commentaires que pas assez.
      C’est encore mieux s’ils expliquent comment le code se rattache aux véritables exigences métier ou fonctionnelles, au lieu de simplement répéter ce que fait le code.
      Il y a quelques années, j’écrivais parfois les commentaires en premier.
      J’expliquais l’objectif global, puis je le découpais en routines et en étapes, et une fois satisfait, je remplissais les blocs de code entre les commentaires.
      C’était une forme de programmation littéraire, même si je faisais ça avant de connaître le terme, et c’était plus proche du fait de me donner à moi-même des prompts vers l’objectif visé.
      L’inconvénient, c’est que les commentaires finissent facilement par n’être qu’une explication en anglais de ce que fait le code, ce qui peut ne pas être très utile pour la personne qui en assurera la maintenance plus tard.
    • Ce qui suscite le plus de pulsions meurtrières, ce n’est pas le code sans commentaires, mais les commentaires anciens ou inexacts.
    • On dirait une prescription qui appelle à commenter à l’excès.
      Le code doit être auto-explicatif, et les commentaires sont là là où il y a des dragons.
  • Dans le même esprit, un prompt que j’aime bien est : « Passe en revue le test que tu as écrit. Est-ce que ce test vérifie vraiment ce qu’il est censé vérifier ? Si le code casse, est-ce que le test échoue aussi ? »
    Il est étonnant de voir à quelle fréquence les LLM écrivent des tests vides qui ne valident en réalité rien du tout.

    • J’ai aussi souvent vu des tests écrits par des humains qui ne valident pas le vrai code, mais seulement le framework de test.
    • Mon flux de travail consiste à écrire d’abord le test, à vérifier qu’il échoue, puis à écrire le code minimal pour le faire passer, et à vérifier qu’on est bien au vert.
  • J’ai du mal à croire qu’on doive encore discuter sérieusement de ce genre de choses.
    Après avoir autant « expérimenté » avec les LLM, on devrait maintenant l’admettre comme une évidence.
    Je me demande à quel moment on pourra à nouveau parler du code écrit à la main sans le traiter comme un tabou.
    Les LLM sont utiles de bien des façons, mais quand je vois des gens déléguer à des agents la saisie de l’intégralité du code source,
    ça me donne la même impression que quand on nous dit qu’on devrait être heureux parce que le web, c’est bien.

  • Je fais tourner en continu plusieurs modèles sur la codebase pour repérer des mauvaises odeurs comme le code dupliqué.
    Ça a été plutôt efficace, et j’ai l’impression que, si on n’entretient pas ça en permanence, ça devient un amas désordonné qui ne fait que s’accumuler avec le temps.

    • Je me demande ce que vous pensez des analyseurs statiques basés sur l’AST comme SonarQube ou Rubocop, qui repèrent de façon fiable la complexité cyclomatique ou la duplication de code.
      On peut aussi les intégrer au pipeline de build, et ils ne consomment aucun token.
    • Je me demande aussi si l’important est d’utiliser différents modèles,
      ou si c’est plutôt le processus de revue et la réinitialisation du contexte qui comptent davantage.
  • J’ai vu énormément de duplications et de choses pires encore dans du code que des gens maintenaient depuis 20 ans.
    Honnêtement, dans la plupart des cas, le code écrit et maintenu par des humains était pire que ce que produisent aujourd’hui les LLM.
    Parfois c’était par manque d’expérience, parfois par négligence délibérée, mais le plus souvent c’était à cause de délais serrés et de la pression pour terminer immédiatement.
    Les gens savent comment mieux faire, mais ils n’ont pas le temps ni le budget pour le faire réellement.
    Les LLM ont appris ça eux aussi.

    • Avant les LLM, Copilot répétait déjà beaucoup ; avant ça, il y avait le copier-coller et Stack Overflow.