1 points par GN⁺ 2024-08-04 | 1 commentaires | Partager sur WhatsApp
  • 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

 
GN⁺ 2024-08-04
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, comme cat 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...

    • J’ai longtemps été sceptique vis-à-vis des LLM, mais après avoir découvert l’outil en ligne de commande 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 contient llm -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.
    • C’est possible. Par exemple, on peut faire 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 llm et les articles associés avant, j’aurais eu beaucoup moins de motivation pour créer ell.
    • Je ne vois pas comment configurer llm pour 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

    • Ça a l’air beaucoup plus sophistiqué.
      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 à jq et perl.
      Je vais l’ajouter à la section des projets liés dans le README.
    • C’est beau et riche en fonctionnalités, mais je me demande pourquoi il y a si peu d’étoiles GitHub.
  • 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.

    • Le support des images est chouette.
      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.
    • Je me demande quelle est la méthode recommandée pour le stockage de secrets sur une machine de développement Linux.
      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...
    • Au contraire, je préférerais qu’ils n’utilisent pas keyring. C’est pénible, et certains systèmes ne l’ont pas.
      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.
    • Je n’ai pas SQLite et je ne sais pas m’en servir.
      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 --help des commandes pertinentes.
    J’ai commencé à en faire la promotion récemment du côté de Boston, et les gens semblent apprécier.

    • La vidéo de démo est excellente : https://youtu.be/IAgkjerCvz8
    • Ça a l’air très utile.
      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.
    • J’ai vu autocomplete-sh fonctionner lors d’une rencontre AI Tinkerers à Cambridge, MA, et j’ai été impressionné.
      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é.
    • Ça a l’air intéressant.
      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}"; initialise ELL_LOG_LEVEL à 2 uniquement s’il n’est pas déjà défini, sans rien afficher.
    • Les deux-points sont là pour garantir que le résultat ne soit pas exécuté.
      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

    • Plandex est bien aussi, et je n’avais pas pensé à ce type de workflow.
      Je ne connaissais pas l’outil llm de Simon Willison, mais je me doutais qu’il avait probablement créé ce genre de logiciel.
      llm prend 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 -r s’active automatiquement et qu’un alias appelé fix propose un correctif incluant les modifications de fichiers.
    Par exemple, s’il y a une faute de frappe dans main.cc, qu’on exécute gcc main.cc puis fix, ell proposerait une correction sous forme de diff pour le fichier ; après approbation, il appliquerait la modification, puis proposerait de relancer gcc, et l’exécuterait si on approuve.

    • J’ai corrigé le lien « Risks ».
      ell -r peut ê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.
    • Pour lancer automatiquement 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/perl semble plutôt dire le contraire.
    [0] https://github.com/sigoden/aichat

    • C’est vrai. C’est pour ça que je les ai indiqués comme limitations.
      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 jq et perl, 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.
    • +1 pour aichat. C’est très bien.
      Sous Linux, je me suis fait un petit script bash qui télécharge le dernier binaire et le décompresse dans /home/me/bin
  • C’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 -a pour ajouter en fin de fichier afin de l’éviter, avant de donner l’exemple bash 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.txt
    Je 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 utiliser tee --append

  • 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

    • mods convient bien aux conversations, mais à l’inverse, ell lui-même est sans état du point de vue des entrées utilisateur et du contenu généré
      L’usage interactif d’ell repose sur script pour enregistrer la sortie du terminal
      On 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