Kevlin Henney et moi étions en practice de discuter de quelques idées sur Copilote GitHub, l’outil de génération automatique de code basé sur le modèle de langage GPT-3, formé sur le corps de code qui se trouve dans GitHub. Cet article pose quelques questions et (peut-être) quelques réponses, sans chercher à présenter de conclusions.
Tout d’abord, nous nous sommes interrogés sur la qualité du code. Il existe de nombreuses façons de résoudre un problème de programmation donné ; mais la plupart d’entre nous ont des idées sur ce qui rend le code « bon » ou « mauvais ». Est-il lisible, est-il bien organisé ? Des choses comme ça. Dans un cadre professionnel, où les logiciels doivent être maintenus et modifiés sur de longues périodes, la lisibilité et l’organisation comptent pour beaucoup.
Nous savons remark tester si le code est right ou non (au moins jusqu’à une certaine limite). Avec suffisamment de assessments unitaires et de assessments d’acceptation, nous pouvons imaginer un système de génération automatique de code right. Propriétébasé sur les assessments pourrait nous donner quelques idées supplémentaires sur la development de suites de assessments suffisamment robustes pour vérifier que le code fonctionne correctement. Mais nous n’avons pas de méthodes pour tester le code qui est « bon ». Imaginez que vous demandiez à Copilot d’écrire une fonction qui trie une liste. Il existe de nombreuses façons de trier. Certains sont très bons, par exemple, tri rapide. Certains d’entre eux sont horribles. Mais un check unitaire n’a aucun moyen de savoir si une fonction est implémentée à l’aide de quicksort, tri par permutation(qui se termine en temps factoriel), tri du sommeilou l’un des autres algorithmes de tri étranges sur lesquels Kevlin a écrit.
Est-ce que nous nous soucions? Eh bien, nous nous soucions du comportement O(N log N) par rapport à O(N!). Mais en supposant que nous ayons un moyen de résoudre ce problème, si nous pouvons spécifier le comportement d’un programme suffisamment précisément pour que nous soyons très confiants que Copilot écrira un code right et assez performant, nous soucions-nous de son esthétique ? Est-ce que nous nous soucions de savoir si c’est lisible? Il y a 40 ans, nous aurions pu nous soucier du code en langage assembleur généré par un compilateur. Mais aujourd’hui, nous ne le faisons pas, à l’exception de quelques cas de plus en plus rares qui impliquent généralement des pilotes de périphériques ou des systèmes embarqués. Si j’écris quelque selected en C et que je le compile avec gcc, de manière réaliste, je ne regarderai jamais la sortie du compilateur. Je n’ai pas besoin de le comprendre.
Pour arriver à ce level, nous aurons peut-être besoin d’un méta-langage pour décrire ce que nous voulons que le programme fasse, qui soit presque aussi détaillé qu’un langage moderne de haut niveau. Cela pourrait être ce que l’avenir nous réserve : une compréhension de « l’ingénierie rapide » qui nous permet de dire précisément à un système d’IA ce que nous voulons qu’un programme fasse, plutôt que remark le faire. Les assessments deviendraient beaucoup plus importants, tout comme la compréhension précise du problème métier à résoudre. Le « code d’élingage » dans n’importe quelle langue deviendrait moins courant.
Mais que se passe-t-il si nous n’arrivons pas au level où nous faisons confiance au code généré automatiquement autant que nous faisons maintenant confiance à la sortie d’un compilateur ? La lisibilité sera primordiale tant que les humains auront besoin de lire le code. Si nous devons lire la sortie de l’un des descendants de Copilot pour juger si cela fonctionnera ou non, ou si nous devons déboguer cette sortie automobile elle fonctionne la plupart du temps, mais échoue dans certains cas, nous en aurons besoin pour générer du code lisible . Non pas que les humains réussissent actuellement à écrire du code lisible ; mais nous savons tous à quel level il est pénible de déboguer du code qui n’est pas lisible, et nous avons tous une idée de ce que signifie « lisibilité ».
Deuxièmement : Copilot a été formé sur le corps du code dans GitHub. À ce stade, tout (ou presque) est écrit par des humains. Certains d’entre eux sont de bons codes lisibles de haute qualité; beaucoup ne le sont pas. Et si Copilot rencontrait un tel succès que le code généré par Copilot en venait à constituer un pourcentage significatif du code sur GitHub ? Le modèle devra certainement être réentrainé de temps en temps. Alors maintenant, nous avons une boucle de rétroaction : Copilot s’est entraîné sur du code qui a été (au moins partiellement) généré par Copilot. La qualité du code s’améliore-t-elle ? Ou ça se dégrade ? Et encore une fois, nous soucions-nous, et pourquoi ?
Cette query peut être débattue dans les deux sens. Les personnes travaillant sur le marquage automatisé pour l’IA semblent adopter la place selon laquelle le marquage itératif donne de meilleurs résultats : c’est-à-dire qu’après une passe de marquage, utilisez un humain dans la boucle pour vérifier certaines des balises, corrigez-les là où elles sont incorrectes, et puis utilisez cette entrée supplémentaire dans une autre passe de formation. Répétez au besoin. Ce n’est pas si différent de la programmation actuelle (non automatisée) : écrivez, compilez, exécutez, déboguez, aussi souvent que nécessaire pour obtenir quelque selected qui fonctionne. La boucle de rétroaction vous permet d’écrire un bon code.
Une approche humaine dans la boucle pour former un générateur de code IA est un moyen doable d’obtenir un « bon code » (quel que soit le « bon » signifie) – bien que ce ne soit qu’une resolution partielle. Les problèmes tels que le type d’indentation, les noms de variables significatifs, and many others. ne sont qu’un début. Évaluer si un corps de code est structuré en modules cohérents, possède des API bien conçues et peut être facilement compris par les mainteneurs est un problème plus difficile. Les humains peuvent évaluer le code avec ces qualités à l’esprit, mais cela prend du temps. Un humain dans la boucle pourrait aider à former des systèmes d’IA pour concevoir de bonnes API, mais à un second donné, la partie « humaine » de la boucle commencera à dominer le reste.
Si vous regardez ce problème du level de vue de l’évolution, vous voyez quelque selected de différent. Si vous cultivez des plantes ou des animaux (une forme d’évolution hautement sélectionnée) pour une qualité désirée, vous verrez presque certainement toutes les autres qualités se dégrader : vous obtiendrez gros chiens avec des hanches qui ne fonctionnent pasou chiens avec des visages plats qui ne peuvent pas respirer correctement.
Quelle route prendra le code généré automatiquement ? Nous ne savons pas. Notre hypothèse est que, sans moyens de mesurer rigoureusement la « qualité du code », la qualité du code se dégradera probablement. Depuis Peter Drucker, les consultants en administration aiment à dire : « Si vous ne pouvez pas le mesurer, vous ne pouvez pas l’améliorer. Et nous soupçonnons que cela s’applique également à la génération de code : les features du code qui peuvent être mesurés s’amélioreront, les features qui ne le pourront pas. Ou, comme l’historien de la comptabilité H.Thomas Johnson a dit: «Peut-être que ce que vous mesurez est ce que vous obtenez. Plus probablement, ce que vous mesurez est tout ce que vous obtiendrez. Ce que vous ne mesurez pas (ou ne pouvez pas) mesurer est perdu.
Nous pouvons écrire des outils pour mesurer certains features superficiels de la qualité du code, comme obéir aux conventions stylistiques. Nous avons déjà des outils qui peuvent « réparer » des problèmes de qualité assez superficiels comme l’indentation. Mais encore une fois, cette approche superficielle ne touche pas les events les plus difficiles du problème. Si nous disposions d’un algorithme succesful d’évaluer la lisibilité et de limiter l’ensemble d’entraînement de Copilot à un code qui se situe dans le 90e centile, nous verrions certainement une sortie qui semble meilleure que la plupart des codes humains. Même avec un tel algorithme, cependant, il n’est toujours pas clair si cet algorithme pourrait déterminer si les variables et les fonctions avaient des noms appropriés, et encore moins si un grand projet était bien structuré.
Et une troisième fois : on s’en soucie ? Si nous avons une manière rigoureuse d’exprimer ce que nous voulons qu’un programme fasse, nous n’aurons peut-être jamais besoin de regarder le C ou le C++ sous-jacent. À un second donné, l’un des descendants de Copilot n’aura peut-être pas du tout besoin de générer du code dans un « langage de haut niveau »: peut-être générera-t-il directement du code machine pour votre machine cible. Et peut-être que cette machine cible sera Assemblage Internetla JVM ou quelque selected d’autre qui est très moveable.
Est-ce que nous nous soucions de savoir si des outils comme Copilot écrivent un bon code ? Nous le ferons, jusqu’à ce que nous ne le fassions pas. La lisibilité sera importante tant que les humains auront un rôle à jouer dans la boucle de débogage. La query importante n’est probablement pas « nous en soucions-nous » ; c’est « quand cesserons-nous de nous en soucier? » Lorsque nous pourrons faire confiance à la sortie d’un modèle de code, nous verrons un changement de section rapide. Nous nous soucierons moins du code et plus de la description correcte de la tâche (et des assessments appropriés pour cette tâche).