1 points par GN⁺ 4 시간 전 | 1 commentaires | Partager sur WhatsApp
  • En dehors de l’agent de code, les boucles au niveau du harnais où une file de tâches et un harnais gèrent les itérations émergent comme le nouveau motif central de l’ingénierie des agents
  • Plus un modèle fonctionne longtemps en autonomie, plus il est facile d’ajouter des défenses locales et des solutions de repli plutôt que des invariants forts, ce qui peut fragiliser la compréhension de la conception et le contrôle dans du code maintenu sur le long terme
  • À l’inverse, dans des domaines où l’on peut facilement vérifier ou jeter le résultat, comme le portage de code, les expériences de performance, les scans de sécurité ou la recherche, les itérations mécaniques fonctionnent déjà très bien
  • Quand des attaquants et des rapporteurs font tourner des boucles, les mainteneurs subissent aussi la pression d’utiliser des machines pour le triage, la reproduction et la réponse ; le cas de curl montre la charge créée par les rapports générés par l’IA
  • L’enjeu à venir n’est pas de savoir s’il faut utiliser des boucles, mais comment y préserver le jugement humain, les règles d’ingénierie, une supervision responsable et une architecture compréhensible

Les boucles qui tournent en dehors de l’agent de code

  • À l’intérieur des agents de code, il existe déjà une boucle d’agent où le modèle appelle des outils, intègre les résultats, lit et modifie des fichiers, exécute des tests puis produit une réponse
  • Le motif qui ressort désormais est la boucle au niveau du harnais qui l’entoure
    • Une tâche entre dans une file
    • Une machine la prend et essaie de la résoudre
    • Une fois arrêtée, le harnais décide si le travail est réellement terminé
    • Si ce n’est pas fini, il injecte un message dans la même session, démarre une nouvelle session avec un contexte modifié, ou confie la tâche à une autre machine
  • Cette boucle externe permet au travail de rester vivant bien après le moment où le modèle dirait en général « c’est terminé »
  • La boucle en elle-même n’est pas nouvelle, mais elle apparaît plus souvent récemment dans l’ingénierie des agents et les discussions sur Twitter
  • On en voit aussi certains aspects sur Pi, et Pi se trouve au centre de ces expérimentations précisément parce que Pi est un harnais

L’inconfort que cela crée pour du code maintenu longtemps

  • Cette approche reste peu adaptée au code auquel on tient profondément
  • Le cœur du sujet, c’est le goût et le contrôle
    • On veut comprendre le code qu’on déploie
    • Sous pression ou dans une discussion avec d’autres, il faut pouvoir expliquer le fonctionnement du système sans commencer par demander à une machine de l’expliquer
    • À ce stade, la compréhension du code reste importante
  • Le code généré sans intervention manuelle, surtout quand il vient d’une boucle, présente des problèmes récurrents
    • trop défensif
    • trop complexe
    • enfermé dans un raisonnement local
    • évite les invariants forts
    • ajoute des fallback au lieu de rendre les états erronés impossibles
    • produit du code dupliqué et de mauvaises abstractions, et recouvre une conception floue d’encore plus de mécanismes
  • Des combinaisons comme Claude Code et Fable peuvent travailler plus de 30 minutes d’affilée sur un problème, ce qui réduit le human in the loop par rapport à avant
  • À l’heure actuelle, la qualité du code produit par ces harnais fonctionnant sans intervention donne même l’impression d’être pire qu’à l’automne dernier, et au moins selon cette sensibilité, on voit peu d’amélioration

La boucle amplifie les habitudes du modèle

  • Face à un échec local, le modèle a tendance à ajouter une défense locale
  • Andrej Karpathy a déjà dit que les modèles « craignent fatalement » les exceptions
  • Dans des systèmes avec des invariants importants, en particulier les formats de données persistants ou les infrastructures critiques, « gérer tous les cas mal formés » n’est pas forcément la bonne correction
    • Une meilleure direction consiste à rendre ces cas mal formés impossibles à représenter ou impossibles à écrire dès le départ
    • Même avec beaucoup de pilotage manuel, les LLM ont du mal à produire naturellement ce type de code et peuvent chercher à gérer des erreurs qui ont justement été rendues impossibles
  • Placée derrière une boucle, cette habitude est amplifiée
    • chaque itération ajoute une petite défense de plus
    • le système paraît plus robuste, mais devient de plus en plus difficile à comprendre
    • plus on retire la main, plus cette tendance s’accentue
  • Donner ce type d’outil à un junior sans consignes claires peut lui faire apprendre de mauvaises pratiques
    • s’il faut justifier ses choix, il pourra néanmoins les défendre de manière plausible

Les domaines où la boucle fonctionne bien

  • Le motif de la boucle fonctionne déjà très bien dans certains domaines
  • Le portage de code en est un exemple typique
  • Cela convient aussi très bien à l’exploration des performances
    • la machine tente des expériences
    • exécute des benchmarks
    • jette les échecs
    • puis continue à explorer
  • C’est aussi naturellement adapté aux scans de sécurité et à presque toute forme de recherche
    • on peut laisser la machine explorer un espace de problèmes complexe puis en faire un rapport
    • il n’est pas nécessaire de commit du code destiné à durer longtemps
  • Les cas de réussite ont un point commun : le résultat n’a pas besoin d’être maintenu longtemps, ou bien il transforme du code existant, ou reste proche d’un proof of concept, d’une idée, d’une découverte ou d’une transformation mécanique
  • Le harnais n’a pas besoin d’un signal totalement objectif ou binaire, mais d’un signal suffisamment utile pour pousser l’itération suivante
    • dans beaucoup de cas réussis, un autre LLM sert de juge ou d’orchestrateur
    • une traduction mécanique peut être validée par des cas de test binaires, ou évaluée par un LLM
  • Claude Code devient de plus en plus compétent pour construire et exécuter des workflows expérimentaux complets
    • même si le code généré est brouillon, cela relève davantage d’un problème du modèle que de la capacité de jugement du harnais

Le passage d’un logiciel-machine à un logiciel-organisme

  • Écrire du code destiné à durer avec cette même logique de boucle reste inconfortable
  • L’idéal historique se rapprochait d’une compréhension du logiciel comme machine déterministe
    • en retirant une couche, on pouvait comprendre plus profondément
    • une machine observée de façon non déterministe n’était pas considérée comme optimale
    • il était souhaitable qu’une architecture tende vers davantage de déterminisme
    • on voyait comme une bonne conception le fait de permettre à un nouvel ingénieur d’explorer une base de code complexe
  • Dans un système bien conçu, il y avait des ingénieurs qui savaient où se trouvaient les invariants, quelles parties étaient structurellement critiques, et quels changements étaient sûrs
  • Les grands logiciels ne tiennent déjà plus entièrement dans la tête d’une seule personne, et les systèmes distribués se diagnostiquent déjà en partie comme un médecin observe des symptômes, formule des hypothèses et prescrit davantage de tests
  • Les LLM poussent encore plus vite dans cette direction
    • quand un incident de production survient, la machine lit les logs
    • propose une root cause
    • soumet un patch
    • une autre machine le relit et l’intègre parfois dans main sans supervision humaine
  • Cette manière de faire est puissante et séduisante, mais l’humain risque de ne plus comprendre le système dans son ensemble comme auparavant
    • on le manipule, on le surveille, on le stabilise, sans nécessairement le comprendre
  • Tout le code n’a pas besoin d’être écrit par des humains, et il est possible que du code pire encore ait déjà été écrit par le passé

Une pression à laquelle il sera difficile d’échapper complètement

  • Il pourrait être difficile de se retirer d’un futur entièrement piloté par des machines
  • La sécurité en est l’exemple le plus clair
    • même si l’on ne construit pas soi-même son logiciel avec des boucles, d’autres peuvent faire tourner des boucles contre ce logiciel
    • les attaquants font tourner leurs machines en continu
    • même sans être attaquants, les chercheurs en sécurité mènent un travail automatisé
    • au final, les vrais problèmes arrivent mêlés au bruit
  • Le billet de Daniel Stenberg sur curl, summer of bliss, montre déjà la pression subie par les mainteneurs
    • l’IA ne semble pas jouer un grand rôle dans le développement cœur de curl
    • pourtant les mainteneurs sont submergés de rapports, dont la plupart sont générés par l’IA
  • Si les attaquants et les rapporteurs font tourner des boucles, les défenseurs devront suivre
    • pas forcément pour écrire eux-mêmes les patchs
    • mais parce que la pression du triage, de la reproduction et de la réponse peut les obliger à utiliser des machines
  • La pression concurrentielle fonctionne de façon similaire
    • certaines équipes peuvent construire plus que d’autres simplement par la vitesse
    • un petit groupe qui orchestre bien les machines peut soudainement accélérer un projet
    • certaines startups peuvent faire à 5 ce qui demandait autrefois 50 personnes
    • quelqu’un peut aussi faire tourner une boucle sur votre produit pour lui demander de « le faire ressembler à autre chose »
  • Tous les logiciels ne seront pas affectés de la même manière
    • certains domaines punissent la négligence et exigent confiance et responsabilité
    • dans beaucoup de logiciels, la vitesse, l’expérimentation rapide et une large couverture comptent énormément

Les nouvelles dépendances créées par la boucle

  • Les outils fondés sur la boucle ne créent pas seulement un coût ponctuel, mais aussi une dépendance cognitive durable
  • Le développement logiciel dépendait déjà d’outils coûteux comme les compilateurs, mais les outils actuels ressemblent davantage à des systèmes auxquels il faut accéder en permanence
  • Si une base de code est produite, relue, patchée et maintenue par des boucles, la perte d’accès à des systèmes du même niveau peut devenir problématique
    • des restrictions commerciales peuvent faire disparaître l’accès aux modèles les plus puissants
    • le coût peut devenir insoutenable
    • l’équipe peut perdre sa dernière capacité à comprendre le code sans la machine
  • On pourrait voir apparaître des bases de code qui ne sont pas seulement difficiles à maintenir pour les humains, mais qui présupposent la participation de la machine comme partie intégrante du modèle de maintenance
  • Certains changements sont déjà visibles
    • de plus en plus de personnes fusionnent du code qu’elles ne peuvent pas expliquer complètement
    • elles enrichissent ou réécrivent des rapports d’issue et des discussions en chat avec le contexte fourni par la machine
    • elles s’appuient sur la machine pour les résumés et la contextualisation
    • on voit plus souvent des personnes converser en passant par un LLM
  • Ce n’est pas nécessairement faux, mais c’est un changement majeur par rapport à l’ancienne manière de faire

Les harnais et outils qu’il faudra pour la suite

  • Orchestrer davantage de boucles ne suffira pas
  • Mieux visualiser les changements, l’orchestration et les agents ne restaurera pas automatiquement la compréhension
  • La direction nécessaire est l’une des deux suivantes
    • trouver des moyens de ramener fortement l’humain dans la boucle, et de rendre lisibles à long terme les changements produits par la boucle
    • ou trouver de meilleures façons de composer des systèmes de plus en plus complexes
  • La réflexion sur Pi évolue elle aussi
    • Pi était prudent, et cette prudence est une bonne chose
    • on ne veut pas d’un futur où chaque interaction devient une modification produite par un essaim de machines impossible à suivre
    • on ne veut pas non plus que Pi devienne un chaos ingérable juste pour gagner la course au logiciel qu’il écrit lui-même
    • on ne veut pas non plus que Pi encourage ce type d’ingénierie
  • Malgré cela, Pi reste un harnais, et les harnais sont au cœur des nouvelles expérimentations
  • Les files de tâches de codage, l’orchestration d’agents, les subagents et les sessions durables vont devenir de plus en plus importants
  • Même ceux qui ne veulent pas adopter aveuglément les boucles doivent commencer à expérimenter
    • car il faut comprendre comment rendre cet avenir supportable à l’intérieur de garde-fous

Le problème du contrôle des boucles

  • Dès lors qu’on accepte une boucle de harnais, c’est le harnais qui décide quand le travail est terminé
  • Dans une boucle d’agent, le modèle finit par dire « done » et un humain relit
    • avant cela aussi, un humain oriente généralement le travail en cours de route
    • l’humain est impliqué, et il apprend au passage
  • Dans une boucle pilotée par le harnais, le rôle humain devient flou
    • le signal « done » lui-même perd son sens et devient un message qu’une autre machine doit interpréter
    • le rôle de l’humain peut se rapprocher de celui d’un simple messager
  • À l’heure actuelle, une grande partie du code produit de cette manière ne plaît pas, et l’interaction avec des logiciels produits avec l’aide de l’IA n’est pas particulièrement agréable non plus
  • Les boucles sont puissantes, mais elles retirent progressivement la responsabilité et, pour l’instant, poussent d’une certaine façon à se soumettre à la machine
  • Malgré cela, l’avenir des boucles semble bien devoir arriver
    • on voit déjà de toutes petites équipes construire à une vitesse qui semblait impossible
    • les bases de code se transforment en organismes plus ambigus et plus chaotiques
    • ces bases de code sont à la fois utiles et désordonnées
  • La question à venir n’est donc pas « faut-il faire tourner des boucles ? », mais plutôt la suivante
    • comment ne pas abandonner son jugement au sein des boucles
    • comment préserver de bonnes règles d’ingénierie
    • comment faire en sorte que des humains responsables puissent continuer à superviser
    • comment repenser l’architecture du code pour rester sain d’esprit

1 commentaires

 
GN⁺ 4 시간 전
Commentaires de Hacker News
  • Loop fonctionne quand on a passé du temps à bien comprendre ce qu’on veut à l’avance. La condition préalable, c’est la clarté, et il faut être capable d’écrire une spécification suffisamment soignée pour pouvoir la confier à un collègue junior
    En général, il faut passer par 5 ou 6 versions bancales avant d’arriver à cette compréhension. Ces 5 ou 6 itérations d’essais-erreurs ne peuvent pas être accélérées, et aucune technologie d’agent ne peut éviter au cerveau humain le temps nécessaire pour réfléchir. Du coup, on passe l’essentiel du temps à faire l’aller-retour entre « je ne sais pas ce que je veux, il faut que je lise, écrive et tripote du code » et « maintenant, je crois que j’ai enfin assez avancé pour savoir ce que je veux ». Il est très facile de se mentir à soi-même, mais on ne peut utiliser Loop qu’une fois qu’on sait vraiment ce qu’on veut. Beaucoup pensent pouvoir griller les étapes avec des agents, mais la compréhension et la clarté ne se simulent pas, et ceux qui sautent cette étape se repèrent de façon douloureusement évidente

    • J’ai fait créer à Codex un outil pour extraire toutes mes sessions pi. J’ai dû filtrer les prompts et les conversations des sous-agents, puis je lui ai fait analyser les schémas que je produisais pour les transformer en organigramme du prompt de génération de guide externe
      Je n’ai pas eu besoin de réfléchir longtemps à ce que je voulais, je voulais simplement qu’il fasse ça. Le résultat reste mitigé, et je ne lui fais pas encore assez confiance pour lui confier une base de code délicate, mais sur le jeu que je développe, le temps passé à vérifier a chuté à un cinquième de ce qu’il était avant. Ce n’est pas forcément une bonne chose. Il y a de fortes chances que je rate de bonnes idées en y consacrant moins de temps. Avant, les prompts étaient devenus mécaniques, du style #now-do-this, #now-review-that, et ils stagnaient avec 90 % des propositions correctes. Maintenant, il me rappelle automatiquement de « commencer par les choses difficiles, puis faire le tri et refactoriser en avançant », puis, après le premier retour, de « revoir le travail », de sorte qu’il expose les problèmes restants ; ensuite, il suffit d’injecter cela dans le prompt de génération de guide pour lancer une nouvelle série de tâches
    • Je suis totalement d’accord sur le fait qu’il faut passer par 5 ou 6 versions cassées. En revanche, une fois que j’ai trouvé un harnais (prompt + skill + modèle) auquel je peux faire confiance pour traiter la plupart des choses de la manière que j’aime, la partie codage/exploration de ce processus est devenue plus rapide
      L’itération s’est accélérée, mais l’effort nécessaire pour traverser ces versions brouillonnes reste à peu près le même. Il faut toujours comprendre quelles idées, quels principes ou quelle conception correspondent à la solution, ce qu’il faut essayer ensuite, et ajuster mon modèle mental. Au final, j’ai l’impression de dépenser davantage d’effort mental dans un laps de temps plus court, avec juste un léger gain sur l’écriture du code. Une fois expérimenté, taper le code n’a jamais représenté une grande part du travail. On a l’impression de « juste » écrire des prompts et lire du code, mais on finit tout aussi épuisé, voire plus, à cause du cycle d’itération compressé
  • Je vis ça tous les jours maintenant, et c’est décourageant et inquiétant. À mon avis, si on fusionne davantage de code qu’on est incapable d’expliquer complètement, c’est parce qu’on délègue désormais aux revues de code le modèle mental qu’on construisait autrefois en écrivant le code et via une planification technique collaborative
    La revue de code n’est pas adaptée à cet objectif. Cela dit, je pense qu’en y ajoutant des exercices structurés inspirés de la pédagogie, on pourrait mieux équilibrer friction et compréhension. Je cherche de l’aide pour tester ce type d’exercices

    • La capacité à faire une revue de code efficacement est bien plus difficile à acquérir que celle d’écrire du code. Sans bonne carte de l’impact d’un changement sur les autres parties du système, cela ressemble presque à un rituel consistant à apposer un tampon
      L’interface PR famélique de GitHub n’aide pas non plus. Les outils sont limités pour explorer les zones de la base de code qui n’ont pas changé directement mais qui sont affectées, afin d’y repérer et de mettre en évidence des problèmes
    • https://pages.cs.wisc.edu/~remzi/Naur.pdf
    • Je suis curieux de voir quel est votre produit. J’aimerais vraiment voir à quoi ressemble un produit développé par un essaim d’agents à un niveau 100 fois supérieur à l’humain. Ça a l’air impressionnant
    • Ce genre de code est souvent rempli de failles de sécurité. C’est du bricolage empilé sur du bricolage, et on finit avec 100 000 lignes de code pleines de chemins de repli étranges pour accomplir quelque chose qu’on aurait pu faire de manière plus robuste en 1 000 lignes
      Ce que dit le texte original, à savoir qu’il faut préférer des systèmes qui rendent impossibles les mauvaises conditions aux limites plutôt que de les gérer avec des chemins de repli, est très important. L’approche par chemins de repli pousse à implémenter encore plus de chemins de repli par-dessus, et chacun d’eux augmente exponentiellement la quantité de code tout en créant presque toujours de nouveaux problèmes. On pourrait presque appeler cela une « loi générale de la conception des systèmes ». Les chemins de repli réduisent le risque d’échec, mais quand l’échec se produit réellement, ils le rendent plus complexe et plus nuisible. En tant qu’ingénieur logiciel, j’aime bien le nouvel environnement de codage produit par l’IA. Les big tech m’ont créé une quantité infinie de travail. Les développeurs humains sont devenus un élément clé de l’exécution du code, et doivent rester en permanence en attente pour traiter une quantité presque infinie d’exceptions difficiles non gérées qui finissent inévitablement par survenir. Désormais, l’ingénieur logiciel ressemble moins à un travailleur qu’à un agent de sécurité qui passe le plus clair de son temps assis à son bureau à boire du café, puis intervient quand un problème rare surgit
  • Cela prolonge ce que je dis depuis des mois. Les LLM excellent pour achever des tâches, mais sont faibles en matière d’esthétique et de goût
    Il existe deux types de travail. Le premier est le travail orienté objectif : il y a un but à atteindre, et la manière d’y parvenir importe peu. La sécurité en est un exemple parfait. Si vous voulez exploiter un système, vous vous souciez rarement de savoir si l’exploit est élégant ; vous voulez simplement accéder à un programme nucléaire top secret. La recherche est similaire : bien avant l’ère de l’IA, le code de « qualité recherche » était déjà notoirement désastreux. L’autre type est le travail orienté goût. Quand on ajoute une fonctionnalité à une grande base de code, on croit que l’objectif est d’ajouter cette fonctionnalité, mais souvent ce n’est pas le cas. Maintenir une base de code capable d’absorber correctement les changements futurs est bien plus important que cette fonctionnalité précise, et cela exige du goût. La maintenabilité et la qualité du code ne sont pas synonymes, et la qualité du code n’est qu’un moyen ; sa finalité, c’est la maintenabilité

    • Beaucoup d’organisations évoluent rapidement vers un monde où la qualité du code et la maintenabilité ne sont plus du tout des priorités. Si c’est Claude qui va écrire le code, est-ce vraiment important que ce code soit « maintenable » ou « de bonne qualité » ? Selon ce point de vue, non. Il suffit que ça fonctionne et que ce soit rapide
  • Le problème des LLM qui essaient de gérer même les cas erronés de façon naturelle est un sujet contre lequel on s’est souvent battu dans les revues de PR. En particulier, une fois que c’est déjà écrit, il est très difficile de convaincre que des vérifications de nullité excessives sont nuisibles
    À moins d’avoir une meilleure modélisation, et un langage qui autorise les types somme, je n’ai pas encore trouvé de contre-argument universellement efficace contre ce genre de « parsing au fusil à pompe ». Peut-être que ce n’est pas vraiment un gros problème. Mais lorsqu’on lit et refactorise réellement une base de code, devoir gérer ces vérifications inutiles a toujours été frustrant. Une fois qu’elles sont là, il est parfois presque impossible de les supprimer en toute sécurité sans d’abord ajouter du logging ou mener une enquête plus large

    • Un argument qui fonctionne souvent est que les valeurs optionnelles fragmentent en pratique l’espace des états possibles d’un programme. Plus cet espace des états grandit, plus il devient difficile de raisonner sur le code et de le maintenir
      C’est précisément le cœur de l’idée selon laquelle il faut rendre les états indésirables impossibles à représenter
    • Les revues de code par IA encouragent une paranoïa défensive excessive et délirante. Faire une triple vérification de nullité au fond d’une fonction peut être, techniquement, un risque réel, mais en pratique c’est souvent un cas qui ne devrait jamais être atteignable, parce que la nullité a déjà été vérifiée dans tous les appels à cette fonction, ou dans toutes les fonctions qui peuvent l’appeler, et cela ne vaut peut-être pas la peine de s’en prémunir
    • L’important, c’est jusqu’à quel point on parle de cas impossibles. Je fais moi-même pas mal de programmation défensive
      Même si aujourd’hui rien n’envoie de valeur négative à cette fonction, à quel point serait-il difficile qu’un futur changement de code fasse sauter cette hypothèse ? J’ai toujours pensé qu’une erreur explicite était préférable. Même quelqu’un qui ne connaît pas bien le code peut ainsi voir quelles hypothèses existent sur la plage de validité des entrées, et n’a pas besoin de tenir compte d’anomalies impossibles
  • Mon goulot d’étranglement, c’est la spécification. La boucle d’agent est désormais un problème moins important pour moi
    Si je formule l’objectif comme obtenir une compréhension claire de ce que je veux construire, puis écrire une spécification exploitable dans le mode plan de Claude Code, l’agent produit généralement de très bons résultats quand il passe à l’implémentation. Mais cette stratégie efficace me fait porter une lourde charge d’écriture des spécifications. L’agent traite généralement chaque spécification de façon excellente, et le suivi basé sur les revues de code prend en général seulement 2 ou 3 itérations, mais on revient vite à une étape qui nécessite à nouveau une spécification. De plus, quand je ne suis pas là, même si l’agent a terminé une tâche et pourrait commencer une spécification existante sans conflit parce que les fichiers ne se chevauchent pas, il ne sait pas qu’il peut créer une nouvelle branche et démarrer. Avant d’aller me coucher, je lui dis souvent « fais la tâche X, puis une fois terminée et poussée, commence la tâche Y », mais au-delà de ça, ça marche mal. Souvent, il commence Y, une question survient, puis l’agent reste bloqué tout le temps restant. Le dernier problème, combiné à ce qui précède, est la dépendance. Par exemple, aujourd’hui j’ai écrit un worker de traitement des tâches en arrière-plan, et bien sûr les jobs des tâches suivantes dépendent de ce système. Ce genre de situation arrive assez souvent. Il faut aussi mettre à jour la spécification elle-même après l’implémentation pour refléter les détails décidés en cours de route. Malgré tout, on est maintenant juste avant le moment où une boucle externe devient nécessaire. Le point de passage est presque entièrement au niveau de la rédaction des spécifications et de la revue de PR. Là où ce point de passage n’est pas important, je veux que l’agent continue à tourner. J’ajoute que je crois fermement qu’il faut commencer à utiliser des outils meilleurs pour les LLM, même s’ils sont pires pour nous. Par exemple, Rust est agaçant pour moi parce que le compilateur est trop strict, mais c’est excellent pour les LLM

    • C’est exactement comme ça que ça devrait fonctionner. Excellent. C’est la partie la plus importante de l’ingénierie système, celle qui a été réduite au cours des 20 dernières années sous la pression de livrer vite
      Maintenant que la construction est davantage automatisée, la spécification et la conception système peuvent à nouveau reprendre un rôle de premier plan. L’ingénierie et la qualité reviendront peut-être
    • Cela correspond aussi à mon expérience de développement, et aux attentes que j’exprime depuis des années quand je dis que l’IA est encore loin d’avoir résolu le codage. La partie difficile de la programmation, ce n’est pas d’appuyer sur des touches pour mettre du code dans un fichier, c’est de comprendre le problème et d’imaginer une bonne solution, propre et extensible
      L’IA est excellente pour produire des solutions correctes qui fonctionnent techniquement, mais elle reste assez faible pour avoir une bonne vision de la solution. Elle est toujours très utile pour échanger des idées, explorer et approfondir la compréhension, mais écrire une bonne spécification que le LLM pourra implémenter n’est pas beaucoup plus facile que d’écrire soi-même le code
    • Ce qui suit pourrait résoudre ce problème
      https://www.aihero.dev/skills-handoff
      /handoff est mon nouveau skill préféré
      https://www.youtube.com/watch?v=dtAJ2dOd3ko
    • Je me demande comment on définit des « très bons résultats ». Est-ce que la définition du succès inclut un code propre et maintenable ? Moi, je dois rester dans la boucle. Mon code est déployé auprès de milliers d’utilisateurs, donc le moindre problème est amplifié
    • La complexité essentielle de la programmation, c’est « l’écriture de spécifications ». En fin de compte, cela revient à dire qu’il n’existe pas de balle en argent
      Avec ou sans agent, avec des cartes perforées ou un interpréteur, au bout du compte, programmer reste programmer
  • Le plus gros code smell des LLM, c’est qu’ils essaient de « gérer tous les cas erronés », et maintenant ils tentent même de gérer des erreurs impossibles. Je ne sais pas pourquoi ils s’y accrochent autant
    En Python, ça se voit souvent dans un codebase entièrement vérifié par les types, sous la forme d’un test hasattr sur un type dont l’attribut est déjà défini comme existant. Pourquoi faire ça ? Je me demande si ça vient du préentraînement ou du reinforcement learning. Si c’est le second, j’aimerais que les labos corrigent ça

    • Ils choisissent probablement de se tromper du côté du traitement d’erreurs inutile plutôt que du côté d’une gestion d’erreurs manquante. Il est probable que les erreurs d’exécution soient fortement pénalisées pendant l’entraînement
    • À mon avis, c’est surtout à cause des données d’entraînement. Moi aussi, je suis dans l’équipe « rendons les états invalides impossibles à représenter »
      On en parle beaucoup sur HN, mais je suis encore surpris quand je vois un codebase, open source ou en entreprise, que je n’ai pas écrit et qui fait vraiment bien ça. La plupart des programmeurs ne raisonnent pas en empêchant les erreurs de se produire et en faisant refléter ce fait par les données ; ils ramassent plutôt les morceaux là où les messages d’erreur surgissent et corrigent à cet endroit. Si je dis « la plupart », c’est parce qu’à mes yeux l’IA actuelle a aussi ce problème de mode de pensée. Il est difficile de donner aux IA le niveau de compréhension qu’un humain a d’un codebase en bout de chaîne, c’est-à-dire une compréhension globale du flux des garanties. Au niveau du code brut, ces garanties s’étendent souvent sur suffisamment de code pour faire exploser facilement la fenêtre de contexte. Essayer de résumer ça dans des fichiers de mémoire pose aussi problème. Ce n’est pas parce qu’un texte sur les garanties est écrit quelque part que l’IA en extraira la bonne information ; chez les humains aussi, lire seulement le code mène au même problème. Je ne dirais pas qu’il est « impossible » de donner ce type de compréhension à une IA, mais même si on y parvenait, la manière dont l’IA travaille va souvent à l’encontre de cette compréhension. Ma solution a surtout consisté à renoncer à attendre que l’IA comprenne ça. Je transforme généralement l’approche de résolution du problème en prompt, comme le feraient la plupart des gens, et si je veux rendre certains mauvais états invalides impossibles à représenter, je fais suivre à l’IA le processus de refactoring nécessaire étape par étape. Si c’est très petit, je le fais moi-même. Si on lui demande progressivement de typer plus rigoureusement un code rempli de maps/dictionnaires, de tableaux, de chaînes et d’entiers, elle s’en sort en fait plutôt bien. Même avec un prompt très détaillé, j’ai rarement obtenu une bonne conception en une seule fois. Il vaut mieux traiter ça comme deux tâches séparées. Et il faut surveiller attentivement les différences de types. L’IA adore glisser en douce des méthodes du genre .JustSetItAndIgnoreAllThePreAndPostConditions(string). Je soupçonne qu’il y a beaucoup de données d’entraînement issues du terrain où, à des types bien structurés conçus pour rendre les états d’erreur impossibles à représenter, un mainteneur venu plus tard a ajouté une méthode JustEffingDoIt qui casse tout. L’une des meilleures défenses consiste à mettre ce genre de types dans leurs propres fichiers pour pouvoir parcourir facilement toutes les méthodes ajoutées et corriger immédiatement ce genre de dérive. J’ai essayé de blinder la documentation avec des avertissements disant de ne pas faire ça et avec plein de préconditions et postconditions à préserver, mais ça n’a presque rien changé
    • C’est parce que l’écrasante majorité des codebases du jeu d’entraînement n’étaient pas entièrement vérifiés par les types, ou n’étaient tout simplement pas propres. Ou alors il s’agissait d’extraits Stack Overflow sans contexte existant, où on ne peut pas supposer qu’une vérification de nullité soit invalide
    • Je compatis totalement. Utiliser getattr sur chaque dataclass, c’est un choix étrange
    • Parce que ça correspond aux patterns appris. L’IA ne comprend pas le code. Elle ne peut pas raisonner sur le véritable flux logique ; elle ne manipule que des patterns
  • Le code fait partie d’une compréhension partagée et accumulée d’un système d’information
    Si ce genre de boucle nous fait tous avancer dans la vague continue de logiciel qui nous submerge, alors, au plus haut niveau de conception logique d’un système d’information, tout finit par se résumer au jugement humain et à l’équilibre avec les exigences métier. Pour s’adapter à une niche précise d’une entreprise ou d’un marché, chaque programmeur doit devenir analyste métier, chercheur de marché et entrepreneur. Sauf, bien sûr, dans certaines niches spécifiques où les outils d’IA ne « cliquètent » pas bien, ou si l’époque des tokens IA subventionnés se termine et que toutes ces boucles deviennent trop coûteuses. Cela donne l’impression d’une répétition des systèmes experts et des machines Lisp de Symbolics. Pendant un moment, le fait auquel nous avons été confrontés était que ce n’est pas tant que le code lui-même ne peut pas faire quelque chose, mais plutôt que la structure organisationnelle d’une entreprise finit par s’imprimer telle quelle dans le logiciel ; si l’on ne peut pas changer l’organisation de l’entreprise, alors la flexibilité du logiciel a elle aussi ses limites. Les flux de données, la connaissance du domaine, la modélisation du domaine et le langage ubiquitaire peuvent devenir le métalangage avec lequel nous définissons la qualité, les fonctionnalités et les standards et conventions non fonctionnels. Il faut faire en sorte que les « clankers en boucle » respectent les contrats de données, de comportement et de performance avant de pouvoir dire « terminé ». Désormais, « terminé » ne signifie plus seulement du code qui compile, du code qui build, du code qui se déploie, ni même du code en production. Il faut du code qui satisfasse aussi les exigences des utilisateurs, des opérateurs et des mainteneurs. Ainsi, le langage utilisé pourrait nous rapprocher davantage du rôle d’analyste métier et d’architecte logiciel que de celui de simple personne connaissant la syntaxe. Est-ce la revanche d’UML et le retour de la conception déclarative, logique et du BDD ?
    La vérification des fautes a été faite avec gemma4-12b, mais sans le laisser modifier le message

  • Je continue à me demander à partir de quand je n’aurai plus besoin d’être de force dans la boucle. En tant que développeur, j’aime vraiment affiner la structure du code, le rendre plus clair, réfléchir à de bonnes abstractions et le découper en modules
    J’y prends du plaisir, mais je comprends aussi qu’à un certain point je deviens le facteur limitant. Si le but du logiciel est d’apporter un bénéfice aux gens, est-ce que je dois encore me soucier de l’apparence du code ? Pour l’instant, je pense que la réponse est « oui », mais dans 3 ans ? Dans 10 ans ?

    • Si vous voulez que le logiciel continue à apporter un bénéfice aux gens, la réponse est oui
    • Cela peut être difficile si vous êtes dans un endroit où rien n’a vraiment de sens en dehors de la technique. J’ai l’impression qu’un tournant existentiel vers un travail plus épanouissant va bientôt arriver. C’est peut-être naïf, ou simplement ce dont j’ai l’impression d’avoir besoin pour moi-même
    • On peut toujours confier le refactoring à un agent. Il peut même réaliser des refactorings si vastes qu’on se sent fatigué rien qu’à y penser
  • Si quelque chose exige beaucoup de jugement et qu’il s’agit de « code auquel je tiens profondément », alors j’ai du mal à adhérer à l’orientation décrite ici. Il ne faut pas essayer de déléguer des décisions auxquelles on tient vraiment.
    J’aime bien la distinction entre la boucle d’agent et la boucle de harnais, mais il ne faut déléguer que ce qu’on peut spécifier précisément à l’avance. Dans mon cas, ce sont le plus souvent des tâches répétables, par exemple « regarde comment X a été fait, puis fais pareil pour Y », et c’est par nature prévisible. Si, sans mon jugement, on aboutit finalement à quelque chose auquel je dirais « non », alors il faut redescendre vers une collaboration dans la boucle d’agent dont parle Armin. Et c’est tout à fait acceptable. C’est rapide et sûr. Même avant les assistants de code IA, il arrivait déjà parfois qu’un ingénieur incroyablement productif rejoigne une équipe. Les collègues étaient jaloux en disant : « Vous avez réussi tout ça parce que vous avez X dans l’équipe ! » Mais ils n’avaient pas subi la malédiction d’avoir ce genre de personne à leurs côtés. Si l’alignement n’est pas parfait, ils foncent dans la mauvaise direction à une vitesse folle.

    • Il ne faut pas déléguer les décisions auxquelles on tient profondément. Ou alors, il faut trouver une méthode déterministe pour y intégrer cette décision.
    • Exactement. Si vous ne sous-traiteriez pas cela à quelqu’un que vous considérez comme très compétent, pourquoi le sous-traiter à une machine ?
  • Je ne vois pas ce que cela signifie concrètement. On dirait juste un texte verbeux qui enchaîne des concepts abstraits conçus pour suggérer une vision plus large, alors qu’au fond il s’agit simplement de laisser l’IA écrire du code.
    C’est donc ça, l’avenir ? En réalité, nous ne devenons pas des leaders de la pensée, mais des pseudo-enseignants essayant de guider une bande d’idiots IA vers la bonne réponse, tout en devant mystifier notre rôle pour avoir encore l’air de leaders intellectuels ? Sans que l’on découvre que tout cela n’est que de la frime technique ?

    • Ce n’est ni un texte verbeux ni un texte abstrait. Le sujet ici, ce sont les effets de second ordre du fait de « laisser l’IA écrire du code » avec moins de supervision.
      L’auteur aurait certes pu le rendre plus concis, mais ce n’est pas parce qu’un lecteur ne comprend pas le propos dans sa forme actuelle qu’il y a mystification.
    • C’est le genre de discours qu’on tient quand on adhère au battage médiatique autour de l’IA. Yegge est un cas encore pire.
    • Je suis convaincu que le génie logiciel est en train de se scinder en deux. Ce sont de vraies préoccupations, et c’est un raisonnement cohérent pour les développeurs qui utilisent la boucle d’agent et des workflows fortement assistés par l’IA.
      Je vois exactement de quoi parle le texte original, à la fois au travail et sur mes projets personnels, et le fait que certains y voient « un texte verbeux qui enchaîne des concepts abstraits » me fait peur. J’ai l’impression que la majorité ne comprend absolument pas ce qui est en train de se passer.
    • Avant, les blogs techniques se lisaient comme des guides README immédiatement actionnables. En lisant cet article, je n’ai cessé de me demander : « Qu’est-ce que je suis censé faire de cette information ? », au point de ne pas réussir à aller jusqu’au bout.
      Dans le domaine de l’IA, la durée de vie des techniques de pointe les plus récentes est d’environ deux semaines. Je n’avais déjà pas réussi à suivre la boucle Ralph Wiggum, et maintenant j’ai l’impression d’avoir bien fait de ne même pas essayer.
      https://news.ycombinator.com/item?id=46682325
    • Concrètement, cela veut dire : utiliser plus de tokens.