lx : un outil de vibe coding sous le contrôle total du développeur
(github.com/chebread)Introduction
Bonjour. Je suis un étudiant intéressé par l’informatique. J’ai récemment développé un programme appelé lx et j’ai voulu publier pour la première fois sur GeekNews, que je lisais jusqu’ici sans jamais y poster.
Ces derniers temps, le vibe coding, où l’on donne des instructions en langage naturel à une IA qui écrit ensuite tout le code toute seule, est en vogue.
Cette forme de vibe coding m’inquiète.
Ce n’est pas simplement la peur de perdre son emploi, mais plutôt un sentiment de perte en programmation, car on nous retire à la fois « le plaisir d’écrire du code (Wrangling code) (source : Kent Beck - Augmented Coding: Beyond the Vibes) » et « le contrôle du développeur ».
Certains disent que ce changement n’est qu’une évolution naturelle de la programmation, dans la continuité des cartes perforées, du langage machine, de l’assembleur, puis du C. Mais je pense que cette analogie est erronée.
Les abstractions du passé consistaient à mettre « un meilleur marteau » entre les mains du développeur.
Les outils ont continué à progresser, mais celui qui maniait le marteau restait toujours l’humain, et le résultat demeurait entièrement sous le contrôle du développeur.
Mais l’IA de codage actuelle est différente.
Désormais, c’est le robot qui manie le marteau à notre place, et le développeur se retrouve réduit à regarder, ou au mieux à essayer de raisonner un peu le robot.
Si nous ne pouvons plus manier nous-mêmes le marteau, alors je pense qu’on ne peut plus vraiment appeler cela de la programmation.
Parce que ce n’est plus entièrement sous notre contrôle.
C’est pour cela que j’ai créé lx.
lx est un outil qui reprend le marteau au robot pour le remettre entre les mains du développeur.
lx permet de traiter l’IA comme un outil strictement contrôlable.
Corps du sujet
lx repose sur la philosophie suivante : « l’interface est humaine, la logique est IA ».
Le développeur définit les entrées/sorties d’une fonction ainsi que ce qu’elle doit faire, établissant ainsi un « contrat », et l’IA ne se charge que de l’implémentation interne de cette fonction.
Cette approche garantit la continuité du développement.
Dès que les entrées/sorties d’une fonction sont rédigées, cette logique est déjà considérée comme terminée.
Le programmeur peut immédiatement écrire la logique de plus haut niveau sans se perdre dans les détails d’implémentation, et ainsi maintenir un flux de développement ininterrompu.
En outre, lx n’est pas un simple remplacement de texte. Il s’appuie sur le package github.com/tree-sitter/go-tree-sitter pour parser le code source sur la base d’un AST (arbre syntaxique abstrait). Il ne pollue donc ni les autres parties du code dans le fichier, ni les commentaires, ni l’indentation, et ne remplace en toute sécurité que la logique du scope spécifié.
Utilisation de base
La forme de base d’utilisation de lx est la suivante.
package main
import (
"fmt"
lx "github.com/chebread/lxgo"
)
func main() {
var year string = "2025-01-02"
// Le développeur contrôle l’appel de fonction et le flux.
result1 := LX_GetYear(year)
var age = 30
result2 := LX_GetAge(age)
fmt.Println(result1, result2)
}
func LX_GetYear(year string) (result string) {
// Prompt à transmettre à l’IA
lx.Generate("Convertir le format yyyy-dd-mm en date au format coréen")
return
}
func LX_GetAge(year int) (result string) {
// Si installer séparément la bibliothèque lx correspondant au langage est trop fastidieux, la forme de marqueur en commentaire lx() ci-dessous est également prise en charge.
// lx("Convertir l’âge coréen en âge international")
return
}
Dans le code ci-dessus, la fonction LX_GetYear est le contrat défini par le développeur.
Lorsqu’on exécute l’outil lx, il reconnaît les marqueurs lx.Generate(...) ou // lx(...), envoie le prompt au LLM, puis remplace le corps de la fonction concernée par du code réellement exécutable.
Une optimisation des tokens est appliquée à ce moment-là. Au lieu d’envoyer le fichier entier, seuls la signature de la fonction et le prompt sont transmis au LLM, ce qui réduit les coûts et renforce la sécurité.
2. Contrôle du développeur
Même si la logique à l’intérieur des fonctions lx est écrite par l’IA, celui qui utilise cette fonction doit rester le développeur.
Cependant, comme toute logique personnalisée mélangée à l’intérieur d’une fonction lx sera ignorée, il est possible de garder le contrôle via une fonction wrapper, comme ci-dessous.
package test
import (
"fmt"
lx "github.com/chebread/lxgo"
)
func main() {
var year string = "2025-01-02"
result1 := ParseYear(year) // Appel de la fonction wrapper
fmt.Println(result1)
}
// Logique métier contrôlée par le développeur
func ParseYear(year string) string {
// Utiliser la logique générée par l’IA comme un composant
res := LX_GetYear(year)
// Le traitement supplémentaire du résultat revient au développeur
foo := fmt.Sprintf("Nous sommes le %v aujourd’hui !", res)
return foo
}
func LX_GetYear(year string) (result string) {
lx.Generate("Convertir le format yyyy-dd-mm en date au format coréen")
return
}
3. Gestion sûre des dépendances et transparence
lx vise le principe de responsabilité unique (SRP).
Il se contente de générer du code, sans compiler ni exécuter le programme.
De plus, si le code généré par l’IA nécessite des bibliothèques externes, lx n’installe pas de packages de manière arbitraire.
-
Code : indication d’un commentaire
// lx-dep: ...en tête du code généré -
Output : rapport de la liste des installations nécessaires via la sortie standard du CLI
À la place, il le signale au développeur de ces deux façons.
Le développeur peut alors vérifier et décider lui-même d’installer ou non les dépendances.
4. Configuration
Pour utiliser lx, une configuration du LLM est nécessaire. Il suffit de créer un fichier lx-config.yaml dans le répertoire personnel (~/) ou à la racine du projet (./). Si un fichier est présent aux deux emplacements, la configuration locale est prioritaire, ce qui permet de gérer des réglages lx différents selon chaque projet.
# lx-config.yaml
provider: "gemini"
api_key: "foo"
model: "bar"
5. Installation et exécution
Les utilisateurs Mac peuvent l’installer via Homebrew, et pour les autres OS, il est possible de télécharger le binaire depuis les GitHub Releases de lx.
brew tap chebread/lx
brew install lx
Après installation, exécuter la commande lx dans le répertoire du projet génère effectivement le code.
lx dispose d’une fonction de génération intelligente : pour les fonctions dont le code a déjà été généré, il ne rappelle pas le LLM, ce qui permet de relancer la commande lx autant de fois que nécessaire en toute tranquillité.
Remarque : lx utilise des outils spécifiques à chaque langage pour le formatage du code généré (Go : goimports, Python : ruff, JS : prettier). Ces outils doivent être installés à l’avance.
6. Licence
lx est distribué sous licence AGPL-3.0.
L’objectif est de contribuer à l’écosystème open source tout en empêchant l’appropriation fermée de cet outil.
Conclusion
Le logiciel est le fruit tissé par les efforts incessants des humains. Même à l’ère de l’IA, les programmeurs doivent rester les maîtres du code.
lx permet de confier à l’IA les « implémentations ennuyeuses » comme les expressions régulières pénibles ou le parsing de données, tout en laissant aux humains la pleine maîtrise de la structure et du flux du programme.
Je recommande cet outil à tous les développeurs qui ne veulent pas perdre le plaisir d’écrire du code (Wrangling code) ni leur contrôle !
12 commentaires
Conformément à la politique de modération, ce commentaire inapproprié a été supprimé et l’utilisation de ce compte a été restreinte.
En réalité, le code actuel reste lui aussi conçu à l’échelle humaine
À l’avenir, je pense qu’on développera sous une forme qui ne sera plus un langage inefficace pensé pour les humains
Profitons bien des frameworks actuels pensés pour les humains tant qu’ils sont là
C’est très intéressant, car l’approche va complètement à contre-courant de l’ambiance actuelle selon laquelle il faudrait carrément ne plus regarder le code pour bien faire.
Selon les choix qu’on fait, on pourrait aussi l’utiliser simplement avec l’idée de définir clairement le périmètre sur lequel l’IA intervient.
Ce ne serait pas mal non plus d’essayer d’en faire quelque chose à partir des compétences des agents de codage, non ?
Je vais l’examiner activement. Si cela vous intéresse, n’hésitez pas à soumettre beaucoup de PR !
Cela semble être un projet intéressant !
Rédaction des spécifications Ix -> remplacement des fonctions lx par de vraies fonctions avec l’outil Ix -> puis compilation en Go.
Si un langage rare utilisant lx apparaît dans le projet,
il devrait être possible de séparer la couche écrite par le LLM,
ce qui pourrait aussi rendre la maintenance plus pratique par la suite.
Cela ressemble à une tentative intéressante utilisant un LLM !
Merci. lx prend aussi en charge des langages autres que Go, donc n’hésitez pas à l’utiliser largement et à nous faire part de vos retours !
L’objectif est intéressant, mais le style typique de l’IA est très perceptible tout au long du texte,
ce qui le rend difficile à juger fiable.
C’est une remarque pertinente. Comme je suis encore au lycée et que je n’ai pas beaucoup de temps, en m’appuyant sur l’IA pour écrire, le texte a fini par perdre beaucoup en fiabilité. Même si cela peut être un peu gênant, je vous prie de bien vouloir m’en excuser.
Waouh, c’est vraiment impressionnant qu’un lycéen ait imaginé ça.
Avec davantage d’expérience, il pourrait sans doute créer quelque chose d’encore plus remarquable.
J’imagine que le mécanisme consiste à ce que le code appelant
lx.Generatesoit remplacé, lorsqu’on lance une commande en ligne de commande, par du code écrit par le LLM, n’est-ce pas ?Le fait que la partie appelante puisse servir d’une certaine manière de contrainte de type me semble être une bonne idée. Je me demande aussi si vous envisagez un mode où la commande
lxs’exécute automatiquement depuis l’éditeur, etc., pour remplacer le code d’implémentation. (Par ailleurs, ce serait bien s’il existait un moyen de régénérer le code lorsque le résultat généré ne convient pas.)J’ai trouvé le projet très intéressant.
Le fonctionnement est bien que le code appelant
lx.Generatesoit remplacé, lorsqu’une commande est lancée en ligne de commande, par du code écrit par le LLM, n’est-ce pas ? -> Oui, c’est bien cela !L’idée que la partie appelante puisse constituer une sorte de contrainte de type me paraît bonne. Je me demande aussi si vous envisagez une approche où la commande
lxs’exécuterait automatiquement depuis l’éditeur, par exemple, pour remplacer le code d’implémentation. -> Je trouve que c’est une très bonne idée. Nous allons sérieusement nous en inspirer.Par ailleurs, ce serait bien s’il existait un moyen de régénérer le code quand le résultat généré ne plaît pas. -> Comme la philosophie du projet est une IA sous le contrôle du développeur, nous l’avons conçu de sorte que, si une régénération est nécessaire, il faille recréer le marqueur
lx.Le niveau des commentaires laissés ici après s’être acharné à entrer parce qu’un jeune lycéen l’a créé en dit long sur le niveau d’intelligence.
Regardez-vous dans un miroir et allez vous faire soigner.
killdong | il y a 9 mois | parent | on: J’utilise des bombes ZIP pour protéger mon serveur (idiallo.com)
À mon avis, si on ne prend pas ses responsabilités pour les excréments qu’on déverse sur Internet, on devrait être interdit d’utiliser Internet. Assumez un peu ce que vous avez déversé.