Feriez-vous confiance à un compilateur créé par une IA ?
Anthropic vient de sortir la version 4.6 de son modèle "Claude Opus". Il parait qu'il est génial : "Il planifie plus soigneusement, peut fonctionner de manière plus fiable dans des bases de code plus importantes et possède de meilleures compétences en matière de revue de code et de débogage pour détecter ses propres erreurs."
Et pour le montrer, outre les classiques comparaisons avec les autres modèles, Anthropic a publié les résultats d'une expérience : la création d'un compilateur C entièrement fonctionnel, écrit en Rust par une équipe d'agents IA avec très peu de supervision humaine.
Entre l'IA et Rust, on a les mots clefs pour la meilleure des hypes, d'autant plus que la conclusion de l'expérience est présentée comme très positive. Le contraire aurait été étonnant. Si les résultats avaient fait une mauvaise pub, on n'en aurait pas entendu parler.
Mais que trouve-t-on vraiment lorsqu'on soulève le capot de ce compilateur ?
Des métriques catastrophiques
Le code source a été rendu public. En 24 heures, il a déjà des centaines d'étoiles sur github, des forks, des issues, des pull requests. Ce qui est présenté comme une expérience d'écriture de code sans intervention humaine est déjà considéré, par un bon nombre d'humains, comme un nouveau projet open source de compilateur C.
Loin de moi l'idée de brider l'enthousiasme des gens, mais ont-ils vraiment regardé le code de ce truc ?
Quand on découvre un projet, si on a un minimum d'intérêt pour l'ingénierie logicielle, on se pose des questions très basiques pour déterminer l'état de la base de code. Comment est organisé le code ? Comment est-il testé ? Est-il facile à lire, à modifier ?
Un de mes anciens chefs, dans cette situation, aimait bien reprendre les mots de Coluche. "On va découvrir la gueule de la bavure".
Et, avec ce compilateur, on peut dire qu'on a été servi. Le code est en Rust. Ce n'est pas le langage ou je suis le plus à l'aise mais j'arrive quand même à identifier quelques trucs.
Commençons par quelques métriques, avec les outils classiques d'exécution de tests et de couverture de code.
| Nombre de fichiers de code source | 351 |
|---|---|
| Nombre de ligne de codes | ~120k |
| Nombre de tests | 503 |
| Nombre de tests réussis | 493 |
| Nombre de tests ignorés | 7 |
| Nombre de tests en échec | 3 |
| Couverture des lignes de code par les tests | 14% |
Franchement, est-il utile d'aller plus loin ? Pour un compilateur, le truc le plus facile à tester automatiquement car il n'y a quasiment aucune entrée sortie ni phénomène asynchrone, ces chiffres me suffisent à dire que cette base de code n'est, en l'état, pas viable.
Des tests sporadiques
L'article d'Anthropic met en avant un succès de 99% sur les ensembles de tests utilisés classiquement pour tester les compilateurs, tels que le GCC torture test. On va devoir les croire sur parole car ils n'ont fourni aucun fichier pour vérifier ces affirmations.
La démarche de fiabilisation du compilateur n'a pas été pilotée par des tests dédiés. En fait, il ont demandé à chaque agent de se focaliser sur un programme existant écrit en C (SQlite, Redis, libjpeg, MQuickJS, et Lua) et d'itérer sur les corrections de bug jusqu'à ce que la compilation n'ait plus d'erreurs. L'article ne parle que de compilation. L'histoire ne dit pas si les programmes ainsi compilés fonctionnent.
Mais pour le noyau Linux, cette méthode n'a pas été possible car la tâche était trop grosse : impossible de compiler la totalité sans avoir de bug et donc impossible d'itérer en parallèle. L'astuce a été de compiler le noyau avec GCC et de paralléliser l'insertion, dans ce noyau fonctionnel, de fichiers choisis aléatoirement et compilés par le nouveau compilateur. Chaque agent travaille donc indépendamment sur un fichier source unique et si le noyau boote correctement, c'est que le fichier choisi aléatoirement est correctement compilé.
Ces observations nous montrent une forte limite qu'Anthropic se garde bien de mettre en avant : les agents ont beaucoup de mal avec la pyramide de tests.
Pour les tests unitaires de très faible granularité, pas de problème. Quand on regarde les tests existants, qui ne couvrent que 14% du code, on constate qu'ils sont toujours à l'échelle d'une fonction, donc tout en bas de la pyramide.
D'un autre côté, les tests avec les suites pour compilateur et les programmes C existants attaquent le haut de la pyramide. Ils testent le compilateur en boite noire dans sa totalité.
L'angle mort, c'est tout ce qu'il y a entre les deux. Les agents ne testent pas en tant que telle l'imbrication des divers concepts présents dans leur code. C'est l'espace où le boulot de conception est le plus important : le découpage des concepts, leur couplage, leur intégration. La faible attention portée à ce niveau produit des logiciels compliqués à maintenir.
Vérifier des fonctions élémentaires, c'est facile car le résultat attendu pour des entrées données est évident. Vérifier un fonctionnement global en boite noire, c'est moins facile mais c'est une vision orientée utilisateur : ça ne demande aucune compétence en conception de logiciel. Il manque ici tout le niveau de test qui permet d'évoluer sereinement dans une base de code.
Une idée dangereuse
On pourrait continuer en observant la complexité du code, les niveaux d'imbrication, la faiblesse des cas testés par rapport au nombre de ligne couvertes. Oui, les tests ne couvrent déjà pas beaucoup de lignes mais en plus, quand ils les couvrent, ils n'en font pas grand chose. Un exemple intéressant est ce module "dce.rs". DCE pour Dead Code Elimination. Il n'est pas bien long (moins de 300 lignes hors tests) mais on y trouve jusqu'à 9 niveaux de for/if imbriqués, une fonction principale qui ne tient même pas sur mon écran 4K, et 4 malheureux tests unitaires.
Le plus inquiétant c'est quand Anthropic dit que "la qualité de code n'est pas au niveau de ce qu'un expert Rust produirait mais elle est acceptable" (reasonnable dans le texte). Avec ce que l'on vient de voir, comment pourrait-elle être acceptable ? Ça n'inspire pas confiance sur le niveau des développeurs chez Anthropic, et, peut être, plus généralement, chez les spécialistes de l'IA, qui n'auraient pas assez de recul en ingénierie logicielle.
Tant que les agents IA servent à créer des interfaces web, on peut avoir des bugs mais les conséquences sont souvent limitées. Ici, ce qui me gêne, c'est l'idée qui est lancée comme quoi les agents IA pourraient écrire des compilateurs. Et les compilateurs, c'est un enjeu beaucoup plus grand. On s'attend à un logiciel capable d'avoir une longue durée de vie, un logiciel qui pourra être maintenu pendant des années car il est la pierre angulaire de tous les projets qui lui font confiance.
En banalisant cette idée erronée que les agents IA sont aujourd'hui capables d'écrire des compilateurs sans supervision, j'ai l'impression que le discours sur l'utilisation de l'IA dans la conception de logiciel prend un virage dangereux.