J'ai construit une application avec un agent IA : retour d'expérience honnête
Les démonstrations où une IA construit une application complète à partir d'une phrase sont partout. Et les commentaires se rangent toujours dans les deux mêmes camps : « les développeurs sont finis » d'un côté, « c'est de la poudre aux yeux, ce code est truffé de failles » de l'autre. Aucun des deux camps ne mesure quoi que ce soit. Alors j'ai fait l'expérience proprement : un vrai brief, un chrono, et surtout un banc d'essai méthodique du code livré, piège par piège.
Précision de méthode habituelle sur ce blog : tout ce qui suit a été exécuté et mesuré pendant la rédaction, le 31 août 2026. L'agent est Claude Code, l'outil en ligne de commande d'Anthropic, avec le modèle Claude le plus récent à cette date. Les tests ont été faits dans Chrome 151 (interface en français), piloté par Playwright pour pouvoir relever précisément valeurs et messages. Toutes les citations de sorties, de messages d'erreur et de durées sont exactes.
Le dispositif : un vrai brief, un chrono, des règles
Je voulais reproduire la situation d'un débutant qui confie un petit projet à un agent, pas celle d'un expert qui optimise ses prompts. J'ai donc écrit la demande comme on l'écrirait spontanément, sans vocabulaire technique, et je l'ai envoyée telle quelle :
Je veux une petite application web de suivi de dépenses personnelles, en HTML,
CSS et JavaScript, sans framework. Je dois pouvoir ajouter une dépense
(libellé, montant en euros, catégorie), voir la liste des dépenses, le total,
et supprimer une dépense. Tout doit être conservé quand je ferme la page.
Design simple et propre. Trois fichiers : index.html, style.css, script.js.Trois règles pour que l'expérience vaille quelque chose. Un : je ne corrige jamais le code moi-même, toute retouche passe par une demande en français à l'agent, comme le ferait quelqu'un qui ne sait pas encore coder. Deux : je teste chaque livraison dans un vrai navigateur, avec une liste de pièges préparée à l'avance. Trois : je raconte ce qui s'est passé, même quand ça ne m'arrange pas.
52 secondes plus tard
L'agent a rendu la main au bout de 52 secondes. Trois fichiers, 446 lignes en tout : 70 de HTML, 227 de CSS, 149 de JavaScript. L'application s'ouvre, le formulaire est propre, le design tient la route (carte blanche sur fond gris, accent bleu, formulaire qui passe en colonne sous 480 pixels de large). Son compte-rendu annonçait aussi une série de précautions : validation des données rechargées, aucune injection HTML possible, montants formatés à la française, virgule normalisée à la saisie.
Un agent annonce toujours ses précautions avec beaucoup d'aplomb. La question intéressante, c'est de savoir si elles existent vraiment. Dans le code livré, oui : la liste est reconstruite avec createElement et textContent, jamais avec innerHTML, ce qui neutralise mécaniquement l'injection de balises par le libellé. L'extrait exact :
var label = document.createElement("span");
label.className = "expense-label";
label.textContent = expense.label;Même sérieux à la soumission du formulaire : la valeur est normalisée (virgule remplacée par un point), refusée si elle n'est pas un nombre strictement positif, puis arrondie à deux décimales. Le commentaire est de l'agent, pas de moi :
var amount = parseFloat(String(amountInput.value).replace(",", "."));
if (!label || !isFinite(amount) || amount <= 0) {
return; // La validation HTML gère déjà les messages, on sécurise juste
}
// Arrondi à 2 décimales pour éviter les flottants baladeurs
amount = Math.round(amount * 100) / 100;Le banc d'essai : onze scénarios, dont neuf hostiles
J'ai d'abord vérifié le nominal : trois dépenses ajoutées (12,50 + 45,00 + 9,80), total affiché « 67,30 € », données retrouvées intactes après rechargement de la page. Puis j'ai déroulé ma liste de pièges, ceux qui font tomber la plupart des premiers projets de débutant. Résultats mesurés :
- La virgule française. J'ai tapé « 12,50 » au clavier, touche par touche, dans le champ montant. Sur mon Chrome en français, le champ l'accepte et expose « 12.50 » au JavaScript : la dépense est enregistrée à 12,50 €, pas à 1 250 €.
- Des lettres à la place d'un nombre. En tapant « abc », le champ refuse les caractères un à un (sa valeur reste vide) et la soumission est bloquée avec le message « Veuillez renseigner ce champ. ».
- Trois décimales. « 12.345 » est refusé : « Veuillez saisir une valeur valide. Les deux valeurs valides les plus proches sont "12,34" et "12,35". »
- Montant négatif ou nul. « -5 » et « 0 » sont refusés tous les deux : « Cette valeur doit être supérieure ou égale à 0,01. »
- La notation scientifique. « 1e3 » passe, et c'est normal : c'est un nombre valide, la dépense s'affiche « 1 000,00 € ». Amusant, pas dangereux.
- Le libellé piégé. J'ai nommé une dépense
<img src=x onerror="...">, l'attaque classique par injection. La balise s'affiche comme du texte inerte : zéro élément injecté dans la page, le code malveillant n'est jamais exécuté. - Les centimes qui s'accumulent. Trois dépenses de 0,10 € : le total affiche bien « 0,30 € ». J'y reviens plus bas, car la réalité est plus subtile.
- Le stockage corrompu. J'ai remplacé les données enregistrées par du JSON invalide et rechargé : pas de plantage, pas de page blanche, l'application repart sur une liste vide.
Ces messages de refus ne viennent pas du JavaScript de l'agent : ils viennent du navigateur, parce que l'agent a posé les bons attributs (type="number", min="0.01", step="0.01", required) et laissé la validation native faire son travail. C'est exactement l'approche défendue dans le guide sur les formulaires HTML et la validation native : le comportement au clavier, les messages en français, la gestion des cas limites, tout est déjà dans le navigateur.
Le verdict de cette première manche est sans appel, et il faut le dire honnêtement : les pièges qui faisaient tomber les projets de débutant (et pas mal de démos d'IA de 2023) ont tous été déjoués. Si votre opinion sur le code généré s'est formée il y a deux ans, elle est périmée.
Ce que le banc a quand même révélé
Tout tester m'a pourtant appris trois choses que la lecture du code seule ne m'aurait pas apprises, et c'est là que l'expérience devient intéressante.
D'abord, le flottant caché. Le total de mes trois dépenses de 0,10 € s'affiche « 0,30 € », mais j'ai relevé la somme calculée en interne : 0.30000000000000004. Le fameux problème des nombres à virgule flottante est bien là, dans l'application ; il est simplement masqué par le formateur monétaire, qui arrondit à l'affichage. Aujourd'hui c'est sans conséquence. Le jour où ce total est comparé à un autre ou exporté, l'écart sort de sa cachette. Un débutant qui ne connaît pas ce phénomène ne peut ni le chercher, ni le trouver, ni savoir qu'il devra s'en méfier plus tard.
Ensuite, la perte silencieuse. Quand les données sont corrompues, l'application ne plante pas, c'est vrai. Mais elle jette vos données sans un mot : six mois de dépenses disparaîtraient sans même un message d'excuse. Techniquement, c'est robuste ; humainement, c'est une trahison.
Enfin, la suppression sèche. Un clic sur « Supprimer » et la dépense disparaît, sans confirmation, sans annulation possible. Je l'ai constaté en supprimant une ligne par erreur pendant mes tests, ce qui est la meilleure façon de le constater.
Notez bien la nature de ces trois points : ce ne sont pas des bugs. Ce sont des décisions que personne n'a prises, parce que mon brief ne disait rien du comportement en cas de données corrompues ni de la suppression accidentelle. L'agent a fait exactement ce qu'on lui a demandé, et rien de plus. Le travail de conception, décider ce que l'application doit faire dans les cas que l'utilisateur n'a pas imaginés, n'a pas disparu : il est juste resté sur ma chaise.
Deuxième manche : trois demandes, 90 secondes, zéro régression
J'ai donc joué mon rôle jusqu'au bout et formulé trois demandes en français, sans toucher au code : un sous-total par catégorie, une confirmation avant suppression, et un avertissement à l'utilisateur quand les données enregistrées sont illisibles, au lieu de repartir de zéro en silence.
Nouvelle livraison en 90 secondes, 155 lignes ajoutées (601 au total). Et nouveau passage complet au banc d'essai, car c'est le moment où les agents cassent le plus souvent quelque chose qui marchait. Résultats : les sous-totaux sont justes (15,70 € d'alimentation pour 12,50 + 3,20, mesurés), le bouton « Supprimer » ouvre désormais une confirmation qui cite la ligne visée (« Supprimer la dépense « Courses » (12,50 €) ? Cette action est définitive. »), annuler ne touche à rien, confirmer supprime et recalcule tout. Et au chargement de données corrompues, un bandeau d'alerte s'affiche ; l'agent est même allé plus loin que ma demande : les données illisibles sont copiées sous une clé de secours avant tout écrasement, et le bandeau l'indique. Aucune régression détectée sur les scénarios de la première manche, que j'ai tous rejoués.
Mon retour honnête
Premier constat : le niveau a réellement monté, et le nier serait malhonnête. Sur ce périmètre (une petite application, un domaine ultra classique), le code livré est celui d'un développeur soigneux : validation native bien utilisée, protection contre l'injection par défaut, arrondi monétaire réfléchi, accessibilité de base présente. Neuf pièges tendus, neuf pièges déjoués, à deux reprises.
Deuxième constat : l'aplomb de l'agent ne prouve rien. Son compte-rendu annonçait toutes ces qualités avant que quiconque ait exécuté quoi que ce soit, sur le même ton assuré qu'il aurait employé si le code avait été défaillant. Cette fois, tout était vrai. Rien ne le garantissait, et la seule façon de le savoir était de tester. Un agent qui a raison avec aplomb et un agent qui se trompe avec aplomb ont exactement la même voix.
Troisième constat : le banc d'essai a trouvé ce que la lecture n'aurait pas trouvé. C'est une leçon qui se répète sur ce blog : en codant la todo-list TypeScript, c'est un test manuel, pas le compilateur, qui avait attrapé le bug des identifiants jumeaux. Ici, c'est la mesure qui a exhumé le flottant caché derrière l'affichage et la perte silencieuse de données. Savoir tester méthodiquement, en cherchant les ennuis, devient la compétence numéro un de celui qui travaille avec un agent.
Dernier constat, et limite assumée de l'expérience : j'ai su quels pièges tendre parce que je connais les nombres flottants, l'injection HTML et les caprices de localStorage. Un vrai débutant n'aurait pas su chercher, et aurait conclu au sans-faute en s'arrêtant au nominal. C'est précisément l'argument le plus fort pour continuer à apprendre les bases : elles ne servent plus tant à écrire chaque ligne qu'à savoir quoi exiger, où creuser et quand se méfier.
Ce qu'il faut en retenir
Si vous apprenez le développement, la conclusion de cette journée n'est ni « inutile d'apprendre » ni « l'IA code mal ». Elle tient en une phrase : l'agent a occupé la case d'écriture du code, et toutes les autres cases m'ont attendu. Décrire un besoin complet, y compris les cas que l'utilisateur n'imagine pas ; lire 149 lignes reçues et comprendre ce qu'elles font vraiment ; tester en cherchant les ennuis ; décider de ce qui manque. Chacune de ces compétences se construit de la même façon qu'avant : en codant soi-même de petits projets, comme le jeu Snake en JavaScript, jusqu'à ce que les pièges de ce banc d'essai deviennent des réflexes.
Et si le fonctionnement de ces agents vous intrigue, le mécanisme qui leur permet d'agir sur vos fichiers et vos outils est expliqué en détail dans l'article sur le protocole MCP, avec un serveur à construire soi-même. Dernier rappel d'honnêteté : ce domaine bouge plus vite que tous les autres sujets de ce blog. Ce que j'ai mesuré vaut pour le 31 août 2026, avec l'outil et le modèle de ce jour-là ; refaites l'expérience avec les vôtres, c'est elle qui compte, pas les avis.