- ell est une interface en ligne de commande pour LLM écrite en Bash, qui permet de poser des questions à un LLM depuis le terminal et de lui transmettre le contexte du terminal
- Elle prend en charge les entrées via pipe, fichier et entrée standard, ce qui permet de l’utiliser avec les flux d’outils Unix existants ; en mode interactif, il est possible de discuter tout en conservant le contexte
- Les templates prennent en charge les appels de fonctions et les fonctionnalités propres à chaque fournisseur de LLM, et une fonction de suppression des informations sensibles est également incluse
- Son utilisation nécessite bash 4.1 ou supérieur, coreutils ou les utilitaires OS X, jq et curl ; si le record mode est utilisé, perl et la commande
script d’util-linux sont également nécessaires
- Des exemples de configuration sont fournis pour Google
gemini-1.5-flash et OpenAI gpt-4o-mini ; le projet met en avant une implémentation presque entièrement en Bash, légère et facile à installer, étendre et modifier
Ce que propose ell
- ell est une interface en ligne de commande pour LLM écrite en Bash
- Elle permet de poser des questions à un LLM depuis le terminal et est conçue pour être facile à utiliser avec des pipes
- Elle permet de transmettre le contexte du terminal au LLM avant de poser une question
- Elle permet de discuter avec un LLM dans le terminal
- Elle prend en charge les appels de fonctions et des fonctionnalités supplémentaires via des templates
- Elle inclut une fonction de suppression des informations sensibles, avec l’élément associé #14
Prérequis et installation
- L’utilisation de base nécessite les outils suivants
- bash 4.1 ou supérieur
- coreutils ou les utilitaires OS X
- jq pour le parsing JSON
- curl pour les requêtes HTTPS
- Si vous n’utilisez pas le record mode, les outils suivants ne sont pas obligatoires
- perl pour PCRE
- la commande
script d’util-linux pour enregistrer les entrées et sorties du terminal
- L’installation consiste à cloner le dépôt dans
~/.ellrc.d et à ajouter ce chemin au PATH
git clone --depth 1 https://github.com/simonmysun/ell.git ~/.ellrc.d
echo 'export PATH="${HOME}/.ellrc.d:${PATH}"' >> ~/.bashrc
Configuration
- La documentation de configuration se trouve dans Configuration
- L’exemple d’utilisation de Google
gemini-1.5-flash définit les valeurs suivantes dans ~/.ellrc
ELL_API_STYLE=gemini
ELL_LLM_MODEL=gemini-1.5-flash
ELL_TEMPLATE=default-gemini
ELL_API_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
ELL_API_URL=https://generativelanguage.googleapis.com/v1beta/models/
- L’exemple d’utilisation d’OpenAI
gpt-4o-mini utilise la configuration suivante
ELL_API_STYLE=openai
ELL_LLM_MODEL=gpt-4o-mini
ELL_TEMPLATE=default-openai
ELL_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
ELL_API_URL=https://api.openai.com/v1/chat/completions
Exemples d’utilisation
- Une question simple se passe en argument de commande
ell "What is the capital of France?"
- Il est possible de spécifier un modèle et d’utiliser un fichier en entrée
ell -m gpt-4o -f user_prompt.txt
- L’entrée standard est également prise en charge
cat somecode.py | ell -f -
- Il est possible d’ajouter un prompt supplémentaire à la volée, sans l’intégrer dans un template
(cat somecode.py; echo "Explain this code") | ell -f -
- Le record mode enregistre les entrées et sorties du terminal afin de les utiliser ensuite comme contexte pour les questions
ell -r
# do random stuff
ell What does the error code mean?
ell How to fix it?
- Le mode interactif se lance avec
-i ; dans ce mode, le record mode est automatiquement activé pour permettre une discussion basée sur le contexte
ell -i
- Il est possible de démarrer simultanément le record mode et le mode interactif en spécifiant un template
ell -r -i -t ctf-gemini
ell -r -i -t ctf-openai
Templates, style et plugins
- La documentation sur l’écriture de templates se trouve dans Templates
- Les fonctionnalités qui utilisent la prise en charge des plugins des fournisseurs de LLM sont implémentées sous forme de templates dans ell
- La documentation sur le style se trouve dans Styling
- La documentation sur les plugins se trouve dans Plugins
- Ici, Plugin désigne un script qu’ell peut appeler et qui peut servir à étendre les fonctionnalités d’ell
- Les plugins pris en charge par les fournisseurs de LLM n’entrent pas dans cette catégorie ; pour ces fonctionnalités, il faut consulter la documentation sur les templates
Nom et choix d’implémentation
- Le nom
ell est une combinaison de shell et LLM
shellm avait aussi été envisagé, mais il a été écarté car il pouvait être interprété à tort comme she llm
ell est présenté comme un nom court, facile à saisir et à retenir, qui n’entre pas en conflit avec un logiciel actif
- Le choix de Bash s’explique par le fait que Bash est le shell le plus courant sur les systèmes de type Unix et qu’aucun langage plus complexe n’est nécessaire pour cet usage
- Par rapport aux projets similaires, ell met en avant le fait d’être écrit presque entièrement en Bash, ce qui le rend léger et facile à installer, ainsi que facile à étendre et à modifier
- Il est conçu pour bien fonctionner avec les pipes et être combiné avec d’autres outils
Documents associés et licence
- Les risques à prendre en compte sont résumés dans Risks Consideration
- Les contributions peuvent être proposées via des issues ou des pull requests
- La licence est la MIT License ; les détails se trouvent dans le fichier LICENSE
1 commentaires
Avis sur Hacker News
Je me demande si ell peut accepter un pipe depuis l’entrée standard comme outil.
Avec l’outil https://llm.datasette.io/, on l’utilise souvent comme
cat somecode.py | llm -m claude-3.5-sonnet "Explain this code", et on peut aussi séparer l’instruction dans le prompt système, commecat somecode.py | llm -m claude-3.5-sonnet --system "Explain this code".Pouvoir envoyer du contenu à un LLM via un pipe permet des usages intéressants, par exemple récupérer une page web et lui faire répondre à des questions : https://simonwillison.net/2024/Jun/17/cli-language-models/#f...
llm, la critique de Claude 3 Opus et 3.5 Sonnet, beaucoup moins cher, j’ai commencé à utiliser les LLM tous les jours.La fonction de pipe sert vraiment souvent ; je l’utilise pour estimer le temps de lecture d’articles web, par exemple avec
curl | llm -m claude-3.5-sonnet -s 'How long does the main content of this article take to read? First count words, then convert using a slow and fast common reading speed.'.Le nombre de mots est plus souvent faux qu’on ne le penserait, mais l’ordre de grandeur est généralement correct, donc c’est suffisant.
L’un des scripts shell que j’utilise le plus récemment s’appelle
q; il contientllm -s "Answer in as few words as possible. Use a brief style with short replies." -m claude-3.5-sonnet "$*", ce qui me permet de poser des questions idiotes depuis n’importe quel terminal sans me sentir jugé.On peut poser une question courte comme
q How do I run Docker with a different entrypoint to that in the container?, ou des questions plus longues via un here-document pour demander ce que fait du code Perl, et j’aime le fait que le contexte reste dans le terminal.cat somecode.py | ell -f -.Si tu veux ajouter à la volée un prompt supplémentaire sans passer par un template, tu peux faire
(cat somecode.py; echo "Explain this code") | ell -f -.J’aurais dû mettre ça dans le README, et si j’avais vu
llmet les articles associés avant, j’aurais eu beaucoup moins de motivation pour créer ell.llmpour utiliser le modèle claude-3.5-sonnet en local. Même en lisant la documentation des plugins, je n’ai pas réussi à le trouver.Il existe aussi un projet qui tente quelque chose de similaire en shell. Je ne sais pas vraiment lequel est le meilleur.
demo
source code
Au début, je pensais que c’était conçu pour obtenir les entrées utilisateur en lisant quelque chose comme
.bash_history, mais après vérification, ça ne semble pas utiliser la sortie du terminal comme contexte.Cela dit, j’aime le fait qu’ils utilisent awk pour traiter les réponses, et je pense qu’ell pourrait aussi utiliser awk pour réduire ses dépendances à
jqetperl.Je vais l’ajouter à la section des projets liés dans le README.
J’avais créé un outil similaire que je ne maintiens plus : https://github.com/llimllib/gpt-bash-cli/
Comme suggestion, il vaudrait mieux stocker les conversations dans une base de données SQLite, plus facile à manipuler pour l’utilisateur qu’un fichier texte, et utiliser les répertoires XDG au lieu de
~/.ellrcd.Et comme je n’ai pas envie de donner l’accès aux clés API à tous les programmes que je lance, je préfère un stockage système de secrets aux variables d’environnement.
Il est difficile de supposer que tout le monde a SQLite, mais ça semble possible de le proposer en option via un plugin.
Les répertoires XDG et le stockage système de secrets ont l’air bien meilleurs que l’approche actuelle ; je vais apprendre à les utiliser et essayer de les intégrer.
Des scripts et programmes arbitraires doivent pouvoir lire des secrets comme des clés API à l’exécution avec un minimum de friction, sans qu’ils soient stockés en clair sur le disque.
Tu sembles recommander
keyring, mais je me demande si c’est la « manière GNU/Linux », ou si les stocker dans un système de fichiers chiffré, basé sur FUSE ou non, est aussi envisageable.[1] : https://github.com/llimllib/gpt-bash-cli/blob/841682affe2d0e...
Les clés LLM ne sont pas si critiques, et il faut faire confiance aux programmes qu’on exécute sur sa propre machine.
Je n’utilise pas Poetry parce qu’il demande un accès à keyring ; il y a un bug ouvert depuis des années, et en réalité il n’a même pas besoin d’y accéder.
Personnellement, je préfère largement les fichiers texte.
J’ai créé un outil similaire, https://autocomplete.sh
https://github.com/closedloop-technologies/autocomplete-sh
Je voulais donner l’impression que la complétion automatique au clavier, avec Tab, fonctionne tout simplement dans le terminal.
Il a été assez difficile de rendre les réponses du LLM suffisamment sages pour correspondre au format attendu par
bash_completion, mais une fois que ça a marché, j’ai pu encapsuler OpenAI, grok, Claude, Ollama et même des modèles locaux.Pour le rendre plus intelligent, j’ai aussi mis dans la fenêtre de contexte l’historique récent expurgé des mots de passe, les variables d’environnement définies et la sortie
--helpdes commandes pertinentes.J’ai commencé à en faire la promotion récemment du côté de Boston, et les gens semblent apprécier.
J’avais aussi réfléchi à l’autocomplétion, mais mon idée était plus proche de Copilot, et l’expérience utilisateur de ce script me semble meilleure.
La partie qui met l’historique dans le contexte serait vraiment utile si on ajoutait un mode historique comme ell.
Le nettoyage des mots de passe est une bonne idée, je compte l’ajouter sous forme de plugin.
Il s’intègre très bien au shell, et le choix de l’écrire directement en bash est audacieux, mais efficace pour conserver la portabilité.
Je me demande s’il fonctionne aussi avec le shell Fish, et comment se passent les mises à jour ou la suppression.
Ça a l’air bien. Comme je travaille sur plusieurs machines, les outils légers comme ceux écrits en shell m’attirent toujours.
Par curiosité, quelqu’un pourrait-il expliquer pourquoi une commande comme
: "${ELL_LOG_LEVEL:=2}";commence par deux-points ? Je pensais que les deux-points n’étaient utiles que comme commande no-op.[1] : https://github.com/simonmysun/ell/blob/main/ell.sh#L19C1-L19...
:fait essentiellement en sorte que bash ne fasse rien avec le résultat de cette ligne.Donc
: "${ELL_LOG_LEVEL:=2}";initialiseELL_LOG_LEVELà 2 uniquement s’il n’est pas déjà défini, sans rien afficher.Je l’ai appris ici : https://stackoverflow.com/a/28085062/2485717
L’approche consistant à n’utiliser que du bash pur et des outils Unix est intéressante.
J’ai créé Plandex[1], qui poursuit un objectif similaire : pas de dépendances, basé sur le terminal, prise en charge de l’entrée par pipe comme contexte ; mais j’ai choisi une voie complètement différente, en l’écrivant en Go et en le compilant en binaire statique.
Plandex est plus haut niveau et axé sur le code, tandis qu’ell ressemble à un outil LLM très léger et généraliste, et me fait beaucoup penser au
llm[2] de Simon Willison.La fonction d’enregistrement me fait aussi penser à savvy[3].
1 - https://github.com/plandex-ai/plandex
2 - https://github.com/simonw/llm
3 - https://github.com/getsavvyinc/savvy-cli
Je ne connaissais pas l’outil
llmde Simon Willison, mais je me doutais qu’il avait probablement créé ce genre de logiciel.llmprend en charge des fonctionnalités de manipulation plus poussée des LLM, tandis qu’ell en manque, mais essaie en contrepartie de n’utiliser que l’interface la plus courante et la plus basique, tout en gardant aussi légères que possible les améliorations d’expérience utilisateur comme la pagination ou la coloration syntaxique.Je devrais mentionner dans le README qu’il faut orienter les utilisateurs qui ont besoin de davantage de manipulation des LLM vers
simonw/llm.Le lien « Risks » du README est cassé.
Ce que je voudrais, c’est que
ell -rs’active automatiquement et qu’un alias appeléfixpropose un correctif incluant les modifications de fichiers.Par exemple, s’il y a une faute de frappe dans
main.cc, qu’on exécutegcc main.ccpuisfix, ell proposerait une correction sous forme de diff pour le fichier ; après approbation, il appliquerait la modification, puis proposerait de relancergcc, et l’exécuterait si on approuve.ell -rpeut être ajouté à.bashrc, mais je ne suis pas sûr que cela ne risque pas d’entrer en conflit avec la configuration existante de l’utilisateur ou de causer d’autres problèmes.À part la validation du patch, cela semble faisable avec des templates et des plugins, mais appliquer réellement les changements est difficile, à la fois techniquement et du point de vue de la conception de l’interface utilisateur.
Je vais essayer de voir jusqu’où il est possible d’aller.
ell -r, il suffit de l’ajouter à.bashrc.Je vais l’essayer ; personnellement, pour cet usage, j’utilise aichat[0].
C’est intéressant de dire qu’on n’a pas besoin d’un langage plus complexe que bash pour ce genre de chose, alors que le fait d’avoir besoin de
jq/curl/perlsemble plutôt dire le contraire.[0] https://github.com/sigoden/aichat
L’idée de départ était de tout faire en Bash, mais ce n’était pas possible pour les raisons que j’ai notées.
Avec awk, on pourrait peut-être supprimer
jqetperl, mais au prix d’un gros sacrifice en simplicité et en lisibilité du code.Je considère l’implémentation d’un surligneur syntaxique comme la limite basse de ce sur quoi je peux insister, et je n’ai pas envie de construire en Bash quelque chose de plus complexe que ça.
Ce genre de fonctionnalité ne sera donc pas pris en charge, ou seulement via des plugins externes.
Sous Linux, je me suis fait un petit script bash qui télécharge le dernier binaire et le décompresse dans
/home/me/binC’est intéressant, mais la vidéo de démo montre une erreur typique de LLM
Elle explique que l’utilisation de
1<>peut écraser un fichier existant, puis qu’il faut utiliser l’option-apour ajouter en fin de fichier afin de l’éviter, avant de donner l’exemplebash ls 1<> output.txt, mais cet exemple ne correspond pas à l’explication et est incorrectÀ ma connaissance, le comportement le plus proche serait
ls >> output.txtJe ne sais pas trop s’il existe, dans ce contexte, un appel pertinent avec
1<> output.txt; peut-être quelque chose comme le lier à un descripteur de fichier personnalisé, par exemple 3, puis utilisertee --appendEn fait, lors d’un enregistrement précédent, ce n’était pas aussi mauvais, et je n’ai pas changé grand-chose en réenregistrant tout en gardant le script
La vidéo que j’avais enregistrée au départ pour la version précédente est ici : https://github.com/simonmysun/ell/blob/d4fc5468157fa6adc8f9f...
Malheureusement, les LLM ne sont pas stables
Pour référence, voici les liens vers les vidéos qui contiennent l’erreur :
https://github.com/user-attachments/assets/1355ad08-6fbf-4c0...
https://github.com/simonmysun/ell/blob/553d38f60ad104893b2a3...
J’aime beaucoup mods de Charmbracelet
Je l’utilise depuis quelques mois, il fonctionne bien, est très personnalisable et produit une sortie propre
https://github.com/charmbracelet/mods
L’usage interactif d’ell repose sur
scriptpour enregistrer la sortie du terminalOn pourrait prendre en charge la gestion de l’historique des conversations via un plugin à effets de bord, mais il faudrait se demander si cela correspond à l’idée et à la philosophie d’ell
J’ai cherché des projets similaires, mais je n’avais pas trouvé ces outils puissants et éprouvés que des utilisateurs de HN ont partagés