Kiro et l'avenir du développement logiciel piloté par l'IA à partir de Specs
Marc Brooker
VP/Distinguished Engineer
Dans les années 1950 et 1960, on a assisté à une explosion de l'innovation dans les langages de programmation. Les programmeurs sont passés de la programmation en langage d'assemblage et en code machine à l'écriture de programmes dans des langages portables de plus haut niveau. Des pionniers comme John Backus, Jean Sammet et Grace Hopper ont eu la clairvoyance de voir ce qui est aujourd'hui une évidence : le logiciel est au cœur de la technologie, et améliorer la vitesse et le coût du développement logiciel accélérerait l'essor de l'informatique, et l'essor de l'économie mondiale.
Ces langages des années 50 et 60 ont été une révolution pour la productivité des programmeurs, et pour découpler le comportement des programmes du matériel sous-jacent. Au cours des six décennies qui ont suivi, la programmation a considérablement changé, mais une chose fondamentale n'a pas changé : la plupart des langages de programmation grand public décrivent comment faire une tâche, plutôt que de décrire la tâche à accomplir. Il y a eu de nombreuses tentatives pour élever le niveau d'abstraction auquel travaillent les programmeurs. La plupart de celles qui ont tenté de remettre en question la nature fondamentalement séquentielle de la programmation ont échoué. Celles qui ont réussi ont connu des succès de niche (y compris certains très grands succès de niche, comme SQL).
SQL en est un excellent exemple : une requête SQL décrit le résultat souhaité par le programmeur (ces données, sous cette forme, provenant de ces sources), et le système de gestion de base de données trouve comment y arriver. Les choix d'implémentation de bas niveau, comme les structures de données et les algorithmes, sont abstraits, ou choisis de façon déclarative (« veuillez rendre la récupération des données efficace pour cette colonne »). Malgré l'omniprésence quasi totale de SQL, il n'est généralement utilisé que pour interagir avec les systèmes de gestion de bases de données, et non pour le développement général d'applications.
Le paradigme fondamental de la programmation, vieux de 60 ans, demeure en grande partie inchangé.
L'IA générative et agentive sont sur le point d'apporter une nouvelle vague de changement. Pour la première fois, il existe des outils que les développeurs peuvent utiliser pour traduire des descriptions de bon sens du comportement souhaité d'un programme en systèmes réels et fonctionnels. De nombreux développeurs utilisent déjà ces outils. Requête par requête, étape par étape, ils décrivent le système qu'ils veulent créer aux générateurs de code par IA. Cette approche de développement par programmation intuitive s'est déjà révélée être un outil puissant. Mais sa puissance est limitée parce qu'il lui manque un élément important : une vision globale complète de ce que le programme devrait faire, et pourquoi il devrait le faire.
Voici la spécification.
Une spécification est simplement une description de ce qu'un programme devrait faire, et des besoins qu'il devrait combler. Les développeurs sont habitués à travailler avec des spécifications tous les jours. Les noms et les formes diffèrent, des billets, aux documents d'exigences, aux conversations informelles avec des collègues. Les langages diffèrent aussi : des simples descriptions textuelles, aux esquisses et maquettes d'interface utilisateur, jusqu'aux définitions mathématiques formelles.
Une spécification, c'est la vue d'ensemble. C'est ce vers quoi ces requêtes tendent, étape par étape. C'est, à la base, le but même du programme que développe un développeur ou une équipe.
Nous avons créé Kiro pour concrétiser cette approche de développement axée sur les Specs et la vue d'ensemble. Avec Kiro, vous pouvez développer ou améliorer des programmes requête par requête, ou ligne par ligne. Vous pouvez aussi prendre du recul jusqu'au niveau du Spec, et travailler avec l'IDE pour générer, maintenir et agir sur les changements apportés à un Spec qui décrit ce que vous voulez que votre programme fasse. À ce niveau supérieur, au-dessus de tous les détails d'implémentation, il est plus facile de comprendre le but d'un programme, d'apporter des changements fondamentaux à sa structure, et de réfléchir à l'objectif global du code et de le communiquer.
Aborder le développement avec des Specs présente trois avantages importants. D'abord, cela offre aux développeurs et aux parties prenantes un moyen de comprendre et de s'entendre sur les objectifs du programme. C'est une documentation claire sur ce que nous voulons que le programme fasse, à quoi devrait ressembler l'interface, et comment il devrait être implémenté. Travailler au niveau du Spec permet aux programmeurs d'avancer plus rapidement, et de passer plus de temps à réfléchir aux choses qui comptent vraiment. Ensuite, cela fournit un guide à partir duquel les agents d'IA peuvent travailler, se référer, et valider leur travail. Une étoile polaire qui guide le travail de l'agent, lui permettant de prendre en charge des tâches plus importantes sans se perdre. Troisièmement, le Spec apprivoise le chaos de la programmation intuitive pilotée par requêtes sur de grandes bases de code, en s'éloignant d'un exercice ad hoc d'ingénierie de requêtes, pour offrir aux programmeurs une façon d'exprimer clairement leur intention aux agents. Un Spec est une sorte de super-requête (contrôlée en version, lisible par des humains).
Pour comprendre comment cela se déroule dans Kiro, commençons par un exemple simple de ce qu'est un Spec, et de comment nous pouvons en utiliser un dans notre processus de développement. Je vais créer une petite version du jeu classique des Tours de Hanoï, basée sur un navigateur.
Nous allons commencer avec un nouveau répertoire, et une requête :
Kiro va ensuite se mettre au travail et rédiger la première version du Spec. Malgré son nom sophistiqué, il s'agit simplement d'un fichier markdown décrivant les user stories de ce petit jeu que nous créons. Nous pouvons faire une pause maintenant pour modifier ces user stories, ou passer à la phase de conception. Kiro me demandera quand j'aurai terminé avec le Spec. Quand c'est fait, je lance la phase suivante en disant :
Bien que cela ressemble et donne l'impression d'un développement basé sur des requêtes à partir des requêtes, la capacité de lire et de personnaliser les user stories, la conception, et le plan des tâches à accomplir par l'agent permet une collaboration plus approfondie entre le développeur et l'agent. Cela permet aux développeurs d'être beaucoup plus précis sur des détails particuliers, et à l'agent de communiquer son plan à l'avance. En consignant ces détails ainsi que le plan – en tant qu'artéfacts contrôlés en version – l'approche de Kiro transforme le développement propulsé par l'IA, de la programmation intuitive à une véritable collaboration durable entre le programmeur et l'agent de développement d'IA.
Après quelques minutes, on arrive ici :

Cool! Mais ce code ne fait pas tout à fait ce que je voulais qu'il fasse dans ma tête quand j'ai écrit la requête. Quand je clique sur Auto Solve, ça démarre une nouvelle partie au lieu de résoudre la mienne à partir de là où j'en suis. Dans une approche traditionnelle de programmation intuitive, je pourrais alors demander les changements nécessaires par requête. Kiro m'offre une autre option : ajouter cette exigence au fichier requirements.md généré, puis demander les changements. De cette façon, le changement demandé est contrôlé en version et consigné. Il ne se perd pas au fil des autres changements apportés. Cela offre aussi plus d'espace pour écrire un texte structuré, spécifique et précis. C'est le pouvoir clé de l'approche de Kiro. En consignant les choses, nous les rendons durables et officielles. Alors que je continue à travailler avec l'agent, je sais qu'il se souvient encore de tout ce qui m'importe (et qu'il a la flexibilité de changer ce qui ne m'importe pas).
Concrètement, faire ce changement nécessite deux nouvelles lignes dans requirements.md :
Kiro apportera ces changements pour nous, y compris la création d'une nouvelle tâche, et l'ajustement du code pour qu'il corresponde à ces nouvelles exigences. Fait crucial, à mesure que j'ajoute et retire d'autres exigences de requirements.md, ces nouveaux changements ne se perdent pas. De la programmation intuitive, au développement logiciel reproductible et traçable, propulsé par des agents d'IA.
Chez Amazon, nous rédigeons des spécifications depuis longtemps, sous de nombreuses formes. Nous utilisons un processus appelé working backwards, créant des documents comme des communiqués de presse et des billets de blogue tôt dans la vie d'un projet pour nous assurer que nous adoptons une vision centrée sur le client de ce que nous créons. Nous avons depuis longtemps la discipline de rédiger et de réviser des documents de conception, à la fois formels et informels, précisant la conception et le comportement des systèmes que nous créons. Une des fonctions les plus importantes de notre communauté d'ingénieurs principaux est de rédiger et de réviser ces documents. Nous utilisons aussi des spécifications plus formelles, où nous consignons les propriétés de nos systèmes avec une précision mathématique (en utilisant des langages comme TLA+ et P), ce qui nous permet de prouver des propriétés importantes de nos systèmes, et d'automatiser les tests1.
Nous consacrons ce temps à la spécification parce que nous pensons que cela nous aide à avancer plus rapidement, en augmentant les chances que nous écrivions le bon code pour résoudre le bon problème client. Cela réduit les retours en arrière en conservant une trace des décisions que nous avons prises et pourquoi. Cela communique aux développeurs et aux parties prenantes ce qui est vraiment important dans une conception.
Les Specs de Kiro s'appuient sur nos expériences dans ce domaine. Cela ne veut pas dire qu'ils sont complexes (ce sont de simples documents markdown), ni qu'ils sont conçus uniquement pour les grandes entreprises (vous pouvez rendre un Spec aussi formel ou informel que vous le souhaitez). Mais nous croyons profondément dans la valeur fondamentale de consigner ce que nous faisons. Nous pensons que cela fait de nous des développeurs meilleurs, plus efficaces et plus performants.
Quand les précurseurs des langages de programmation grand public d'aujourd'hui ont été créés, dans les années 1950 et 1960, ils repoussaient les limites de la technologie de l'époque. Ils ont élevé le niveau d'abstraction du niveau de l'assemblage et du code machine à un niveau beaucoup plus élevé, fait d'instructions et de fonctions qui peuvent se convertir en centaines d'instructions machine. Mais la technologie de l'époque ne permettait pas d'élever davantage le niveau d'abstraction. De nombreuses tentatives ont été faites pour élever l'abstraction du étape par étape au que voulez-vous accomplir?, allant de l'ésotérique (comme Datalog) au grand public mais de niche (comme SQL).
Je crois que l'approche par Spec de Kiro est une étape importante et puissante vers un avenir de la programmation où les résultats comptent plus que les détails d'implémentation, et où l'implémentation de programmes qui résolvent des problèmes complexes est plus facile et plus accessible. Où nous pouvons nous concentrer davantage sur ce que nous voulons faire, et moins sur comment nous voulons le faire. Plus immédiatement, c'est un pas important vers l'apprivoisement du chaos de la programmation intuitive sans perdre la puissance et la productivité qu'apporte la programmation assistée par un agent d'IA.