22 points par GN⁺ 2025-06-13 | 1 commentaires | Partager sur WhatsApp
  • Cet article est le deuxième volet consacré à l’adaptation d’une expérience de programmation classique au monde des ordinateurs conversationnels (LLM, agents)
  • La première partie, « Comment programmer avec des LLM », expliquait comment intégrer les LLM aux outils existants pour les utiliser comme autocomplétion ou comme alternative à la recherche
  • Cette fois, l’auteur partage une expérience concrète et des enseignements sur la programmation basée sur des agents, plus difficile mais aussi plus gratifiante

Définition et réalité des agents

  • Dans le contexte des LLM (grands modèles de langage), il est utile de définir ce que signifie le terme « agent »
  • Le mot circule depuis longtemps comme un buzzword de l’industrie de l’IA, mais ce n’est que récemment qu’il s’est imposé comme une structure réellement utile
  • Au fil du temps, il s’est chargé de beaucoup de rhétorique marketing et de mysticisme
  • Du point de vue d’un ingénieur, on peut désormais le définir clairement et simplement : un agent, c’est 9 lignes de code, autrement dit une boucle for incluant un appel à un LLM
  • Dans cette boucle, le LLM exécute des instructions, vérifie directement le résultat et fonctionne de manière répétée sans intervention humaine
  • Cela peut sembler simple, mais en pratique, cette structure améliore spectaculairement la capacité de programmation par rapport à l’usage d’un LLM seul

Différence entre la programmation au tableau blanc et les agents

  • Imaginons qu’on se tienne devant un tableau blanc avec un marqueur pour écrire en C une fonction qui vérifie la validité d’une chaîne UTF-8
    • (C’est une situation d’entretien que l’auteur a réellement vécue, et un exercice d’interview assez courant)
    • La réussite dépend de l’expérience du programmeur et de sa capacité à compenser le fait de ne pas pouvoir consulter de ressources externes
    • Il faut se souvenir des règles d’encodage UTF-8 et faire attention à ne pas confondre la syntaxe du C avec celle d’autres langages de la famille C (ordre nom-type, type-nom, etc.)
    • Dans le travail quotidien, on peut pourtant vérifier son code et trouver des erreurs grâce au retour du compilateur, à la recherche dans la documentation, aux printf, etc.
  • Demander à un LLM d’écrire du code sans agent, c’est un peu comme coder au tableau blanc sans aide extérieure
    • Il faut tirer de vagues souvenirs, lutter inefficacement avec la syntaxe et éviter d’imaginer des interfaces erronées
    • Le fait qu’un LLM puisse produire un programme entièrement nouveau est impressionnant sur le plan technique, mais un tableau blanc virtuel branché à des GPU ne change pas radicalement la productivité réelle en programmation
  • Mais si on donne au LLM plus qu’un tableau blanc virtuel ?
    • Par exemple, s’il peut appeler un compilateur, lire les erreurs de compilation puis se corriger lui-même ?
    • S’il peut lire les fichiers existants avec grep et cat, modifier plusieurs fichiers (y compris des tests unitaires) puis relancer les tests en boucle ?
  • Un agent, c’est précisément un LLM guidé par le feedback.

Agent = LLM opérant dans un environnement de feedback

  • Un LLM qui fonctionne bien dans un environnement de feedback, comme un humain, peut réellement programmer avec seulement quelques outils familiers
    • bash(cmd) : exécuter des commandes terminal (find, cat, grep, etc.)
    • patch(hunks) : modifier des fichiers, appliquer des changements de code
    • todo(tasks) : gérer une liste de tâches
    • web_nav(url), web_eval(script), web_logs(), web_screenshot() etc. : navigation web, exécution, logs, captures d’écran
    • keyword_search(keywords) : recherche par mots-clés
    • codereview() : revue de code
  • Grâce à l’outil bash, il explore efficacement une codebase et peut même automatiser la gestion de version avec git add ou commit
  • Contrairement à un LLM qui se contente de générer du code sans ces outils, un agent apporte plusieurs avantages décisifs
    • La précision d’usage des API augmente nettement (recherche dans la documentation et intégration directe au contexte)
    • Le feedback du compilateur réduit les erreurs de syntaxe et les confusions d’interface
    • Les capacités de gestion des dépendances et des versions s’améliorent (avec compréhension des particularités d’une version donnée)
    • Les échecs de tests aident à détecter les erreurs et renforcent l’habitude d’écrire du code de test
    • La gestion d’une codebase au-delà des limites de la fenêtre de contexte devient possible (en ne lisant que les parties nécessaires)
    • Il peut expérimenter directement sur le résultat d’exécution : lancer le code, recevoir un feedback via des captures d’écran du navigateur, ajuster automatiquement le CSS, suivre les erreurs via les logs serveur et ajouter des tests
  • Il y a aussi des inconvénients
    • Une simple demande en une phrase peut entraîner des dizaines de milliers de tokens intermédiaires (appels d’outils, recherche web, itérations de tests, etc.), ce qui fait durer le travail plusieurs minutes ou plus
    • Les appels API ont aussi un coût, même si l’évolution du matériel devrait progressivement atténuer ce problème
  • Au final, le CPU/GPU prend en charge le travail intermédiaire, économise du temps aux développeurs et leur permet d’achever davantage de programmes qu’ils avaient envie d’écrire
  • En pratique, il est facile d’introduire un agent dans un projet, de lui confier de petites tâches et de vérifier le résultat

Exemple : développement de l’authentification Github App

  • Il s’agit d’un cas réel où un agent a servi à implémenter le flux d’authentification Github App de sketch.dev
    • Avec seulement 3 ou 4 retours, l’ensemble du flux d’authentification a été rapidement finalisé
    • Lorsqu’une erreur ou une contrainte apparaissait, une simple phrase de feedback suffisait pour qu’il améliore immédiatement le code et le comportement
    • En réduisant au minimum les tâches répétitives et fastidieuses comme l’intégration d’API, la gestion du système de build, des packages ou des bibliothèques, il aide fortement à préserver l’élan de productivité
  • Dans les exigences initiales, l’auteur avait demandé « utiliser uniquement les informations d’authentification globales de l’app sans stocker de token par utilisateur », et l’agent l’a implémenté tel quel
    • Mais cela a introduit une grave faille de sécurité (n’importe qui pouvait voir tous les dépôts)
    • Après un feedback d’une seule phrase expliquant le problème, l’agent a immédiatement ajouté une vérification des droits par utilisateur et généré un commit corrigé
  • Ensuite, un problème de performance est apparu
    • Avec une structure comme celle-ci, des appels API étaient effectués pour toutes les combinaisons utilisateur-dépôt, ce qui posait un problème de scalabilité
      for install := range allAppInstallations {  
      	for r := range install.Repositories() {  
      		if r.IsCollaborator(user) {  
      			// add to available repositories  
      		}  
      	}  
      }  
      
    • L’auteur a compris que la cause profonde venait de sa propre exigence : « ne pas stocker de token par utilisateur »
    • Une fois l’exigence modifiée (stockage des tokens par utilisateur autorisé), l’agent a repensé la solution avec une méthode d’appels API efficace
  • En réalité, le nombre de mots utilisés pour décrire ce processus dans l’article dépasse le nombre total de mots saisis dans Sketch pour obtenir le code d’authentification
  • En bref, les agents ne sont pas encore au point de remplacer les développeurs aujourd’hui, mais ils permettent d’accomplir en une journée des tâches répétitives qui prenaient traditionnellement plusieurs jours
  • L’automatisation est telle qu’un développeur peut laisser avancer le travail tout en rangeant la chambre de son enfant

Exemple : application de règles SQL basées sur JSON

  • Parmi les tâches que les agents traitent souvent, il y avait l’application d’un style SQL particulier appris chez Tailscale
    • Chaque table n’a qu’une seule vraie colonne (les données JSON), toutes les autres étant des generated columns dérivées du JSON
    • Exemple de structure de table :
      CREATE TABLE IF NOT EXISTS Cookie (  
        Cookie   TEXT    NOT NULL AS (Data->>'cookie')  STORED UNIQUE, -- PK  
        UserID   INTEGER NOT NULL AS (Data->>'user_id') STORED REFERENCES User (UserID),  
        Created  INTEGER NOT NULL AS (unixepoch(Data->>'created')) STORED,  
        LastUsed INTEGER AS (unixepoch(Data->>'last_used')) CHECK (LastUsed>0),  
        Data     JSONB   NOT NULL  
      );  
      
    • Cette approche joue un peu le rôle d’un poor man’s ORM : elle facilite l’extension du schéma et les contraintes SQL aident à valider la qualité des données JSON
    • En contrepartie, le volume stocké par ligne augmente, et tous les INSERT/UPDATE doivent se faire au niveau du JSON
  • Mais l’agent n’arrivait pas toujours à suivre ce style de façon cohérente
    • Lorsqu’il créait de nouvelles tables, il suivait généralement bien le modèle, mais dès qu’une exception apparaissait, il se perdait ou changeait le style arbitrairement
  • Solution simple : ajouter 3 phrases d’explication en haut du fichier de schéma SQL
    • Ajouter une phrase-clé du type : « chaque table ne possède qu’une vraie colonne JSON Data, et toutes les autres colonnes en sont dérivées »
    • Pour les tables qui ne suivent pas cette règle, préciser explicitement via un commentaire qu’il s’agit d’une exception
    • Après cela, le comportement de l’agent s’est nettement amélioré
  • Fait intéressant, ce type d’explication et de commentaire est souvent ignoré ou jugé peu utile par des ingénieurs humains, mais
    • les agents basés sur des LLM intègrent activement commentaires et explications dans l’écriture du code
    • de bonnes explications suffisent à améliorer visiblement la qualité du code généré

Modèle du code « actif » et « dette »

  • Une critique fréquente des outils de génération de code basés sur les LLM est que la génération de code elle-même ne représente qu’une toute petite partie du coût total du logiciel
    • En réalité, l’essentiel du temps sert à gérer les dépendances, l’enchevêtrement du code existant et les interfaces complexes
    • Pour les produits anciens, de grande taille et utilisés par beaucoup de monde, le coût de maintenance devient écrasant
    • Dans un tel contexte, demander à un LLM « écris-moi un tri à bulles en Fortran » peut donner l’impression d’un gadget ou d’une gêne inutile
    • Certains comparent cela aux notions financières d’« actif » et de « dette », sans que l’analogie soit parfaite
  • Mais toute l’ingénierie logicielle ne se résume pas à ces grands projets de long terme
    • La plupart des programmes ont peu d’utilisateurs ou une durée de vie courte
    • Il ne faut pas extrapoler l’expérience de la maintenance à grande échelle comme si elle définissait l’essence de toute l’industrie
  • La valeur des agents ne se limite pas à générer du code
    • En combinant plusieurs outils avec un LLM, ils automatisent la lecture du code, l’édition de fichiers, la suppression ou la modification de code, autrement dit le changement lui-même
    • Tout comme l’ajout de code, la suppression de code et le refactoring sont des opérations qu’ils réalisent naturellement
  • Au final, l’objectif de l’ingénieur, c’est le changement
    • Le processus de changement exige toujours un travail supplémentaire pour que le pilote comprenne ce qui a été modifié, mais les agents montrent déjà leur capacité à produire des évolutions progressives jusque sur des projets de taille intermédiaire
    • Même si ce n’est pas encore suffisant aujourd’hui, les agents progressent rapidement dans la bonne direction
  • On ajoute parfois que les langages complexes et les systèmes de build compliqués servent de barrières à l’entrée dans un projet
    • Certains craignent qu’en abaissant cette barrière avec des outils qui facilitent l’écriture du code (LLM, sûreté des types, garbage collection, gestion des packages, agents, etc.), la qualité baisse
    • Si l’objectif est de ralentir le changement ou de le contrôler, alors des outils d’automatisation comme les agents ne conviennent pas

Pourquoi les agents maintenant ?

  • Contrairement aux principes d’IA complexes comme les transformers, ajouter une boucle de feedback à un LLM est une approche intuitivement claire
    • Pour quelqu’un qui réfléchit à des outils de développement, cela ressemble à une évolution naturelle
    • D’ailleurs, la première version de sketch.dev, il y a un an, ne faisait que relier un LLM à des outils Go, mais la différence de praticité avec les agents actuels est énorme
    • Même dans le domaine du ML, l’apprentissage par renforcement (apprentissage basé sur le feedback) est un principe fondamental depuis plus de 50 ans
  • L’émergence concrète des agents est directement liée à l’évolution des LLM
    • En 2023, les LLM maîtrisaient mal les appels d’outils, ce qui limitait fortement leur rôle d’agent
    • En 2025, les LLM sont optimisés pour les appels d’outils et les tâches répétitives, ce qui rend possible un usage réel des agents
    • Les modèles Frontier (les plus avancés commercialement) sont très en avance sur les modèles ouverts dans leur capacité à utiliser les outils
    • On peut s’attendre à ce que les modèles ouverts rattrapent cela dans les 6 prochains mois
    • La grande nouveauté des LLM modernes, c’est leur capacité à effectuer des appels d’outils répétitifs réellement utiles

Direction future : conteneurs et exécution parallèle

  • Le domaine des agents LLM reste dans une phase précoce et de changement rapide que la majorité des ingénieurs n’a pas encore réellement adoptée
  • À ce stade, les agents sont surtout utilisés dans l’IDE ou sur un dépôt local
    • On peut démarrer facilement en installant un fork de VSCode ou un outil en ligne de commande
    • Mais il existe deux limites importantes
      • Premièrement, le manque de garde-fous : risque d’exposition d’informations sensibles comme des identifiants de production stockés sur la machine réelle
        • Si l’agent exécute par erreur des commandes inattendues comme un script de déploiement, cela peut provoquer un incident de sécurité grave
        • Même si une confirmation manuelle est demandée pour chaque commande, le risque d’exposer des secrets par erreur demeure
      • Deuxièmement, les limites de l’exécution parallèle et de l’automatisation : chaque développeur ne peut lancer qu’un seul agent à la fois dans son propre environnement
        • Comme une seule exécution d’agent prend plusieurs minutes, il devient difficile et inefficace de mener plusieurs tâches en parallèle
  • Chez sketch.dev, on essaie de résoudre cela avec un environnement à base de conteneurs
    • Un conteneur de développement isolé est créé pour chaque tâche, avec duplication du code source, puis seuls les éléments externes comme les commits git sont extraits
    • Cela permet d’exécuter plusieurs agents simultanément, et d’autres solutions d’agents explorent elles aussi cette approche
  • Cas concret : pendant le travail sur l’authentification Github, une amélioration de l’interface d’un formulaire a été traitée en parallèle dans une autre session d’agent
    • Sans même passer par un suivi d’issues séparé, un simple screenshot et une courte phrase de demande ont suffi pour traiter le feedback sur le design du formulaire
    • En investissant seulement 30 secondes, on peut obtenir un résultat d’un niveau déjà satisfaisant
  • Résultat de 6 mois d’expérimentations UX :
    • pour le développement basé sur des agents, les conteneurs (environnements d’exécution isolés) apparaissent comme l’option la plus pratique

Que devient l’IDE ?

  • Dans un environnement de développement basé sur des agents, le rôle de l’IDE (environnement de développement intégré) reste une question ouverte
    • Le workflow réel pourrait consister à saisir une consigne pour l’agent, lancer l’exécution dans un conteneur, examiner les changements sous forme de diff, puis pousser vers une branche ou une PR
  • En pratique, la plupart des commits générés par un agent exigent encore un certain niveau de retouche humaine
    • Au début, presque tous les commits nécessitent des corrections manuelles, mais à mesure que l’on gagne en maîtrise dans la rédaction des prompts, la quantité de retouches diminue
    • Ces corrections vont de simples ajustements comme l’édition de commentaires ou le changement de noms de variables jusqu’à des refactorings plus complexes
    • La vraie question est donc de savoir comment effectuer efficacement ces modifications dans un environnement conteneurisé
  • Voici quelques workflows expérimentés chez sketch.dev
    • Fournir une interface de vue diff directement modifiable
      • Dans l’écran diff de Sketch, modifier directement le code dans le panneau de droite permet d’intégrer immédiatement le changement au commit puis de le pousser
      • C’est très efficace pour une petite correction d’une seule ligne
    • Fournir un accès SSH au conteneur
      • pour entrer directement dans le shell ou manipuler le code via un terminal web
      • et l’ouvrir avec une URL vscode:// pour travailler dans un IDE traditionnel
    • Laisser des commentaires de style code review directement sur le diff afin de les transmettre à l’agent comme feedback
      • En réutilisant les habitudes de code review, on peut communiquer les explications ou exigences nécessaires avec un minimum de saisie
  • Bilan général
    • L’environnement conteneurisé intègre la génération, la modification, la vérification et la revue du code, et permet ainsi un véritable développement orienté agents au-delà de la simple écriture de code
    • L’auteur n’avait pas envie autrefois de développer dans des conteneurs, mais l’expérience consistant à nettoyer et corriger dans un conteneur les diffs produits par un agent s’avère très intéressante et productive

Conclusion

  • Le processus d’apprentissage et d’expérimentation autour des technologies basées sur les LLM a été une leçon d’humilité
    • L’auteur avait déjà ressenti du plaisir lors de précédents changements qui transformaient la nature de la programmation, comme l’arrivée du multicœur, des SSD ou l’extension du réseau, mais
      les LLM, et en particulier les agents, renouvellent complètement le “processus même” du codage
    • Contrairement aux évolutions qui influençaient surtout le choix des algorithmes, des langages ou des bibliothèques,
      les agents obligent à reconsidérer fondamentalement tous les présupposés sur la manière de travailler
    • Le changement est parfois si profond qu’on en vient à penser qu’« il vaudrait peut-être mieux réapprendre depuis zéro comme si l’on ne connaissait rien à la programmation »
    • Et cette transformation est toujours en cours aujourd’hui
  • La manière dont nous travaillons actuellement est déjà complètement différente d’il y a 6 mois, et elle n’est pas encore stabilisée
    • Les standards de culture de développement, comme la collaboration d’équipe ou la revue, devraient bientôt beaucoup changer
    • Par exemple, les code reviews purement formelles ne résolvent déjà plus les vrais problèmes
      • Le moment est venu de réinventer le processus même de revue de code
    • L’IDE aussi, malgré toutes les promesses d’intégration qu’il portait jusqu’ici, doit sans doute être repensé de fond en comble
    • L’industrie a bien conscience de ce changement, mais l’approche centrée sur les agents n’en est qu’à ses débuts
    • D’autres bouleversements majeurs sont à venir, et
      la curiosité et l’humilité sont peut-être les seules bonnes façons de traverser cette période
    • Il serait même peut-être préférable, pour l’instant, de s’éloigner des forums techniques sur Internet
      et de laisser les agents se charger aussi de ce genre de discussions et de résumés

1 commentaires

 
GN⁺ 2025-06-13
Commentaires sur Hacker News
  • Comme je code surtout pour mes propres outils, je vois mal l’intérêt qu’une autre personne, ou autre chose, écrive le code à ma place pour que je doive ensuite le lire, le comprendre et le corriger ; en revanche, demander à un LLM de trouver dans une doc d’API la partie que je cherche est très utile et fait gagner du temps. Donc, indépendamment de l’amélioration future des performances des LLM, je n’aime simplement pas trop lire le code des autres.

    • Il y a quand même des cas où les LLM m’aident : par exemple, sur du code très formalisé, ils peuvent remplacer des macros ou des générateurs de code. C’est plus lent, et plus difficile de faire une mise à jour globale d’un coup comme avec des macros, mais pour des structures répétitives avec de petites variations, un LLM peut être plus utile. De même, quand j’utilise une API familière sans connaître le code par cœur, je peux avancer directement sans passer par Google ni fouiller la documentation. Comme j’utilise des langages typés, si le LLM raconte n’importe quoi, le vérificateur de types ou les tests le détectent, donc je ne m’inquiète pas trop. Et lorsqu’un changement touche plus de 10 fichiers, lui faire préparer un plan de modification en Markdown est un vrai gain de temps. Enfin, quand je suis fatigué, je laisse facilement passer le style ou les conventions de nommage, alors que le LLM maintient assez bien le style existant du projet.
    • J’aime de plus en plus travailler ainsi ces temps-ci : je planifie d’abord l’ensemble du design, puis j’explique les étapes concrètes au LLM. Pendant que je lis, comprends et corrige le code, et que je prépare l’étape suivante, le LLM travaille déjà sur la section suivante. En quelque sorte, le LLM et moi travaillons en parallèle. C’est comme un chef de restaurant qui, dès qu’une commande arrive, pense immédiatement à l’ensemble des étapes du plat et, pendant qu’un steak cuit, n’attend pas sans rien faire mais prépare autre chose en parallèle. Le LLM ressemble davantage à un outil de cuisine, comme un four ou un robot ménager. On peut râper du fromage à la main, par exemple, mais le mettre dans un robot fait gagner quelques minutes. Les cuisiniers professionnels utilisent divers outils pour gagner en efficacité via le multitâche ; je pense qu’à l’avenir, le codage pourrait lui aussi passer d’un travail ligne par ligne à une structure plus multitâche.
    • À la question « quel est l’avantage de déléguer l’écriture de mon code à autre chose, pour ensuite devoir le relire, le comprendre et le corriger moi-même ? », j’emploie le mot « friction ». Beaucoup de gens ont du mal à se lancer dans une nouvelle tâche, un peu comme le syndrome de la page blanche ; avoir une solution déjà produite par quelqu’un d’autre réduit fortement la barrière d’entrée pour la remodeler à sa façon et la modulariser. Parmi mes collègues et moi, beaucoup ressentent un vrai poids lorsqu’il faut configurer la toolchain et initialiser un projet depuis zéro. Un LLM, avec assez de contexte et de ressources, peut parcourir rapidement tout un codebase et remarquer des choses du genre : « il y a déjà deux mécanismes d’audit dans ce code, on pourrait extraire la partie commune ». Il peut même repérer automatiquement des points que j’aurais ratés moi-même.
    • Dans l’un des codebases sur lesquels je travaille, il y a beaucoup de tâches qui consistent à faire de petits changements répétitifs dans plusieurs fichiers. Ce n’est pas vraiment de la créativité ni un défi, juste du travail répétitif à ouvrir des fichiers et les modifier. Avant, cela me prenait 3 à 4 heures ; si j’explique la tâche à un agent IA, il s’en charge à 99 % tout seul, et cela ne prend plus que 3 à 4 minutes.
    • Certaines personnes ne savent rien faire sans outils. Ce sont elles qui deviennent les early adopters et les power users, et qui diffusent de nouvelles découvertes. La valeur de GitHub venait du fait qu’il offrait à des développeurs ordinaires un environnement où ils pouvaient avoir l’air productifs avec des PR, des reviews, des green squares, des listes de todo, etc. Les LLM plaisent aussi aux managers parce qu’ils permettent à des développeurs ordinaires de donner une apparence de productivité en lançant des outils et des agents pas si importants que ça.
  • Je suis entièrement d’accord avec l’auteur quand il dit que la revue de code est médiocre et fonctionne rarement vraiment bien. À l’ère des agents qui écrivent le code, le vrai goulot d’étranglement n’est plus l’écriture mais la lecture du code. Si les gens bâclent les reviews ou s’en servent juste pour afficher leurs préférences personnelles, les agents peuvent très facilement introduire de graves problèmes de sécurité ou de performance. Franchement, le vrai problème, c’est que beaucoup de choses ne se voient pas simplement en lisant le code : il faut déboguer soi-même ou vérifier les hypothèses manuellement.

    • Je me demande toujours comment le code agentique/IA est censé résoudre clairement ce problème de « review bâclée ». Les gens n’aiment déjà pas faire de revue de code et trouvent ça ennuyeux. J’ai peur qu’on finisse par confier la partie amusante — écrire du code — à l’IA, pour se retrouver à devoir faire à la place une lecture et une vérification interminables.
    • Ce qui manque le plus aujourd’hui sur le marché, c’est un moyen de lire, reviewer et comprendre efficacement le code, les diff et les codebases entiers générés par les LLM. S’il n’y a que très peu de personnes dans un projet, je m’inquiète de savoir si celles qui restent lisent réellement le code, ou si elles se contentent de le laisser passer.
    • Le point clé des agents, c’est que si la couverture de tests est suffisante, l’IA peut écrire le code et obtenir en retour des signaux sur la sécurité et les performances. Et cette même IA peut aussi aider à écrire les tests.
  • Ça fait du bien de voir enfin une analyse réaliste des LLM. Le terme « agent » m’agace un peu, parce qu’au fond on a surtout donné un nom à une boucle for qui appelle récursivement un LLM, mais comme l’industrie n’a jamais brillé par son sens du naming, je fais avec.

    • Je ne partage pas tout à fait la même définition de « agent » que l’auteur. Pour moi, c’est réellement une structure où un LLM appelle de façon itérative des outils et des ressources en boucle. La nuance est subtile, mais elle touche à la question de savoir où se situe réellement l’agentivité.
    • J’ai bien aimé la formule « un agent, c’est un outil dans une boucle ». Il me semble que Simon l’a formulée ainsi.
    • J’ai un léger désaccord avec la définition d’agent de l’OP. Le trait distinctif n’est pas simplement qu’un LLM tourne en boucle, mais que ses actions sont contraintes ou orientées par d’autres composants logiques. Certains sont déterministes, d’autres reposent sur du ML, y compris des LLM. Autrement dit, on peut obtenir une utilité supplémentaire en forçant le LLM, dans un système conçu pour cela, à établir un plan d’une certaine façon, ou en déclenchant automatiquement une build et l’exécution des tests après l’édition du code. Dire qu’« un agent se met en mouvement à partir de ses propres entrées » n’est pas faux, mais l’essentiel est plutôt l’intention de superviser et de guider en permanence le comportement du LLM via plusieurs composants.
    • Le nom « Agent » me paraît acceptable parce qu’il est intuitif pour les gens, mais je me suis demandé si une alternative comme LoopGPT ne serait pas envisageable.
  • À propos du passage « nous sommes d’accord sur le fait que les conteneurs sont utiles et nécessaires en programmation », cela explique pourquoi Solomon Hykes, le créateur de Docker, a récemment publié en open source un projet appelé Container Use : pour permettre aux agents de s’exécuter en parallèle de manière sûre. Certaines plateformes comme Sketch intègrent des environnements de développement local isolés, mais beaucoup d’autres agents de code ne le font pas. En complément, je recommande aussi cette vidéo YouTube.

  • Les boucles agentiques ressemblent à un cerveau dans la machine, ou en pratique à un remplacement des moteurs de règles. Elles ont encore des inconvénients propres, mais je trouve que plusieurs personnes ont bien mis le doigt sur l’essentiel : « brancher des outils d’agent, les piloter par prompt à partir d’une demande utilisateur, les laisser tourner en boucle, et faire évoluer dynamiquement le prompt selon le contexte ». Sans même chercher à imiter l’interaction humaine ou la manière humaine de résoudre les problèmes, c’est déjà très utile pour l’orchestration, les workflows multi-étapes, ou l’automatisation de tâches floues. Avant, il fallait coder explicitement cette ambiguïté ; peut-être que ce ne sera plus nécessaire. En production, il y a toujours des inquiétudes à exécuter tout cela sans dry run, mais je pense que les outils et les services vont évoluer. Si plus de 100 services similaires se connectent au monde extérieur via des interfaces cohérentes — par exemple SMS, mail, météo, réseaux sociaux, etc. — on pourrait obtenir des assistants bien plus puissants qu’aujourd’hui, voire davantage.

    • Il existe un projet jouet intéressant qui relie un agent à plusieurs services, comme un calendrier et la météo, pour créer une interface de jeu : lien
    • Si l’abstraction devient unifiée pour tous les outils utilisés, on pourrait avoir quelque chose de bien supérieur aux assistants actuels, mais il faudrait aussi accepter un niveau énorme de pannes et de possibilités d’erreur. L’ingénierie de fiabilité, l’assurance qualité, la gestion des autorisations, la sécurité et la protection des données deviendront de plus en plus importantes. Je me demande d’ailleurs si c’est précisément pour gérer ces risques qu’Apple n’a pas encore sorti un assistant vocal moderne capable de dépasser les limites de Siri.
  • Lire du code a toujours été aussi important qu’en écrire, mais c’est en train de devenir encore plus vrai. C’est mon cauchemar. Écrire du code peut parfois être agréable ; le lire est toujours un travail pénible.

    • Cela dit, il est possible que « le plaisir de corriger » reste présent, voire augmente.
  • Je me demande combien de personnes qui utilisent des agents aiment réellement la « programmation » au sens du plaisir de réfléchir à une manière de résoudre un problème et de l’exprimer en code. Quand je vois beaucoup de travaux récents avec des agents, ce processus a quasiment disparu : on décrit simplement des exigences en langage naturel, puis on espère juste que le LLM n’introduira pas de bugs.

    • Moi, j’aime coder en soi, et quand un LLM me génère d’un coup un parseur que j’aurais trouvé amusant à écrire, cela me laisse parfois un sentiment de vide. En revanche, cela me permet de me concentrer sur des objectifs plus ambitieux au lieu de passer du temps sur l’écriture d’un parseur. Le fait de pouvoir définir uniquement les types ou les signatures de fonctions souhaités, puis laisser le LLM remplir les détails d’implémentation pour passer tout de suite à l’étape suivante, m’a beaucoup marqué. Avant, des modifications globales du genre « ce serait bien de le corriger, mais c’est trop pénible » représentaient une vraie charge ; maintenant, le LLM m’aide sur le polissage du code, la génération de tests, la synchronisation du README et même des idées de refactorisation, ce qui augmente au contraire l’ambition et la qualité finale du projet. Avec le bon état d’esprit, cela peut être le paradis pour les builders qui aiment créer du logiciel.
    • À l’inverse, pour des problèmes déjà résolus des milliers de fois, je n’ai pas spécialement envie d’implémenter le code moi-même. Dans ces cas-là, j’utilise un dictionnaire, je ne réécris pas une table de hachage. Si je pouvais demander « écris-moi ce compilateur pour ce langage » ou « résous-le avec un DFS » et obtenir un résultat parfait, cela ne réduirait pas forcément le plaisir de programmer. Le langage naturel a certes des limites : à un certain niveau de complexité, il devient facile d’être imprécis ou de produire des contradictions quand on décrit un processus de calcul. Mais dans tous les cas, personne ne recommande d’utiliser les LLM sans réfléchir, et au final la responsabilité du résultat m’incombe toujours.
    • Comme argument sur le fait que le langage naturel n’est pas adapté à la programmation, on peut consulter EWD667. En pratique, les LLM sont utiles pour des questions-réponses de style Stack Overflow, mais si les données de SO diminuent à l’avenir, cela pourrait même devenir une limite pour cet usage.
    • Pour ma part, je ne suis pas d’accord. La plupart de ce que font les LLM relève d’implémentations répétitives et ennuyeuses. Je garde toujours les parties amusantes : l’architecture du projet, ou la conception directe des morceaux créatifs ou difficiles que même les LLM peinent à traiter. La situation sera peut-être différente dans un an, mais pour l’instant je suis satisfait de pouvoir me concentrer uniquement sur les aspects qui demandent une vraie réflexion.
    • C’est l’auteur du billet : j’aime la programmation, et j’aime aussi les agents.
  • Il y a quelques domaines où j’aime bien utiliser l’IA quand je code (c’est vraiment moi qui l’écris !) :

    • CSS : je détestais travailler le CSS sur n’importe quel site web, mais l’IA se souvient de toutes les astuces CSS complexes, ce qui accélère le travail. Par exemple, même dans un WordPress compliqué, elle peut assez vite aider à centrer un div précis après quelques itérations.
    • Tests unitaires : quand les données de code intégrées par l’IA ne sont pas trop anciennes, générer des tests est aussi une expérience agréable.
    • Résumés de commit : pour un premier jet, c’est tout à fait utilisable.
    • Même des exercices très simples de niveau première année peuvent être traités rapidement.
    • Fait intéressant, de mon côté j’ai parfois trouvé que l’IA écrivait plutôt mal le CSS, donc cela m’a semblé inutile. Mais je comprends tout à fait l’idée qu’elle puisse prendre en charge des tâches qu’on n’aime pas ; dans mon cas, ce serait plutôt la rédaction de descriptions de tickets, qu’elle fait bien mieux que moi.
    • Désolé si j’ai mal compris, mais si vous n’êtes pas familier des tendances CSS récentes, le CSS moderne est aujourd’hui bien moins complexe et plus facile à maintenir qu’avant. Cela vaut peut-être le coup d’y consacrer quelques heures pour se mettre à jour. Cela dit, moi aussi j’utilise beaucoup l’IA pour le styling.
  • Le passage sur les « actifs » et les « dettes » m’a paru intéressant, mais je ne suis pas d’accord. Beaucoup de programmes commencent pour un tout petit nombre d’utilisateurs, puis deviennent soudain de gros projets. J’ai trop souvent vu dans le passé des codes scientifiques écrits à la va-vite pour un usage ponctuel finir par s’étendre involontairement sur une longue durée et à une plus grande échelle. Du coup, j’écris mon code en pensant qu’il servira bien plus longtemps et dans un périmètre bien plus large, par égard pour moi-même comme pour les autres. Si vous avez déjà vu le side project personnel d’un collègue être promu en projet d’équipe par un manager, vous comprendrez le problème.

    • Il reste quand même la question : « quelle est l’alternative ? » Les gens prédisent mal ce qui sera adopté à grande échelle. Bien souvent, un projet soigneusement élaboré ne sert à rien, alors qu’un projet bricolé mais rapide rencontre le succès parce que la pression évolutive favorise ce cas-là. Sur ce point, on peut citer le classique « worse is better » (lien).
  • J’ai l’impression que le véritable killer feature des LLM ne sera pas l’écriture ou la conception du code, mais la revue de code. Aujourd’hui, la code review est cassée à bien des égards, et à l’avenir j’imagine un usage important des LLM pour revérifier la sécurité, les comportements indéfinis, les mauvais usages fonctionnels ou encore les avertissements du compilateur. Personnellement, j’utilise surtout les LLM comme des moteurs de recherche pour diagnostiquer des erreurs ou déboguer, avec un taux de réussite d’environ 50 %, ce qui me satisfait déjà largement.

    • ChatGPT est déjà très bon pour le débogage dès lors qu’il s’agit de problèmes largement discutés sur le web. Comme il résume et agrège les connaissances de Stack Overflow, cela fait gagner beaucoup de temps par rapport à la recherche de cas individuels. En revanche, les réponses des LLM contiennent encore des hallucinations, donc il reste du bruit. Si on leur demande de revoir un code entier, ils peuvent assez bien repérer certains types d’erreurs ou des fonctions/appels problématiques, mais il y aura aussi forcément beaucoup de faux positifs. Je me demande comment les gens utilisent concrètement les LLM pour automatiser la revue de code.
    • Quand on demande à plusieurs reprises à un chatbot « peux-tu relire ce code ? », on finit par voir des situations où il remplace X par Y, puis un peu plus tard rechange Y en X. Cela a une certaine utilité en revue de code, mais il faut soi-même décider quoi accepter et quoi rejeter. Pour quelqu’un qui a suffisamment de discernement, cela peut vraiment servir à proposer de manière productive des changements candidats.
    • Je me demande pourquoi ce sujet n’est pas davantage discuté. Parmi les développeurs autour de moi, le degré d’intérêt pour la technologie varie beaucoup ; en général, plus ils sont juniors, plus ils utilisent activement ces outils, et plus ils sont seniors, moins cela les intéresse. J’entends presque jamais parler d’usage de l’IA pour la revue ou la vérification de code ; il faudrait peut-être des fonctions qui le fassent automatiquement au moment du commit.
    • Au-delà de la code review/design, des LLM spécialisés pour la code review existent déjà dans GitHub Copilot avec un mode reviewer. Ce n’est pas encore le top absolu, mais la qualité est déjà suffisamment bonne pour l’intégrer dans la boucle.
    • D’accord, c’est justement le genre de choses sur lesquelles nous travaillons chez sourcery.ai.