- 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
- 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
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.
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.
Ç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
forqui appelle récursivement un LLM, mais comme l’industrie n’a jamais brillé par son sens du naming, je fais avec.À 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.
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.
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.
Il y a quelques domaines où j’aime bien utiliser l’IA quand je code (c’est vraiment moi qui l’écris !) :
divprécis après quelques itérations.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.
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.