- ell es una interfaz de línea de comandos para LLM escrita en Bash, que permite hacer preguntas a un LLM desde la terminal y pasarle también el contexto de la terminal
- Admite entrada por pipes, archivos y entrada estándar, por lo que puede usarse junto con el flujo existente de herramientas Unix; en modo interactivo permite chatear manteniendo el contexto
- Mediante plantillas admite llamadas a funciones y capacidades específicas de cada proveedor de LLM, e incluye una función para eliminar información sensible
- Para usarlo se requiere bash 4.1 o superior, coreutils o utilidades de OS X, jq y curl; si se usa el record mode, también se necesitan perl y el comando
script de util-linux
- Se ofrecen ejemplos de configuración para Google
gemini-1.5-flash y OpenAI gpt-4o-mini, y se destaca que, al estar implementado casi por completo en Bash puro, es ligero y fácil de instalar, extender y modificar
Funcionalidades que ofrece ell
- ell es una interfaz de línea de comandos para LLM escrita en Bash
- Permite hacer preguntas a un LLM desde la terminal y está diseñada para usarse fácilmente con pipes
- Permite pasar el contexto de la terminal al LLM y luego hacer preguntas
- Permite chatear con el LLM dentro de la terminal
- Mediante plantillas admite llamadas a funciones y funciones adicionales
- Incluye una función para eliminar información sensible, con el elemento relacionado #14
Requisitos e instalación
- Para el uso básico se necesitan las siguientes herramientas
- bash 4.1 o superior
- coreutils o utilidades de OS X
- jq para parsear JSON
- curl para solicitudes HTTPS
- Si no se usa record mode, las siguientes herramientas no son obligatorias
- perl para PCRE
- El comando
script de util-linux para registrar la entrada y salida de la terminal
- La instalación consiste en clonar el repositorio en
~/.ellrc.d y agregar esa ruta al PATH
git clone --depth 1 https://github.com/simonmysun/ell.git ~/.ellrc.d
echo 'export PATH="${HOME}/.ellrc.d:${PATH}"' >> ~/.bashrc
Forma de configuración
- La documentación de configuración está en Configuration
- El ejemplo de uso de Google
gemini-1.5-flash configura los siguientes valores en ~/.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/
- El ejemplo de uso de OpenAI
gpt-4o-mini utiliza la siguiente configuración
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
Ejemplos de uso
- Una pregunta simple se pasa como argumento del comando
ell "What is the capital of France?"
- Se puede especificar un modelo y usar un archivo como entrada
ell -m gpt-4o -f user_prompt.txt
- También admite entrada estándar
cat somecode.py | ell -f -
- Se puede agregar un prompt adicional al vuelo sin ponerlo en una plantilla
(cat somecode.py; echo "Explain this code") | ell -f -
- record mode registra la entrada y salida de la terminal para usarla como contexto en preguntas posteriores
ell -r
# do random stuff
ell What does the error code mean?
ell How to fix it?
- El modo interactivo se ejecuta con
-i; en el modo interactivo, record mode se activa automáticamente para el chat basado en contexto
ell -i
- Se puede iniciar record mode y el modo interactivo juntos especificando una plantilla
ell -r -i -t ctf-gemini
ell -r -i -t ctf-openai
Plantillas, estilos y plugins
- La documentación para crear plantillas está en Templates
- Las funciones de ell que usan el soporte de plugins de los proveedores de LLM se implementan mediante plantillas
- La documentación de estilos está en Styling
- La documentación de plugins está en Plugins
- Aquí, Plugin se refiere a un script que ell puede invocar y que puede usarse para extender sus funciones
- Los plugins admitidos por los proveedores de LLM no se incluyen en esta categoría; para esa función se debe consultar la documentación de plantillas
Nombre y decisiones de implementación
- El nombre
ell es una combinación de shell y LLM
- También se consideró
shellm, pero se descartó porque podía malinterpretarse como she llm
ell se presenta como un nombre corto, fácil de escribir y recordar, y que no entra en conflicto con software activo
- Se escribió en Bash porque Bash es el shell más común en sistemas tipo Unix y para este caso de uso no hace falta un lenguaje más complejo
- Como diferencia frente a proyectos similares, se plantea que está escrito casi por completo en Bash puro, por lo que es ligero y fácil de instalar, además de fácil de extender y modificar
- Está diseñado para combinarse con otras herramientas gracias a su enfoque amigable con pipes
Documentación relacionada y licencia
- Los riesgos a considerar están resumidos en Risks Consideration
- Las contribuciones pueden hacerse mediante issues o pull requests
- La licencia es MIT License y los detalles están en el archivo LICENSE
1 comentarios
Opiniones en Hacker News
Me pregunto si ell puede recibir un pipe de entrada estándar como herramienta.
En la herramienta https://llm.datasette.io/ se usa mucho algo como
cat somecode.py | llm -m claude-3.5-sonnet "Explain this code", y también se separa la instrucción como prompt de sistema, por ejemplocat somecode.py | llm -m claude-3.5-sonnet --system "Explain this code".Si se puede pasar contenido al LLM por pipe de esta forma, se abren usos interesantes, como scrapear una página web y hacer que responda preguntas: https://simonwillison.net/2024/Jun/17/cli-language-models/#f...
llm, las reseñas de Claude 3 Opus y el mucho más barato 3.5 Sonnet, empecé a usar LLM a diario.La función de pipe se usa muchísimo; la uso para estimar el tiempo de lectura de artículos web con algo como
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.'.El conteo de palabras se equivoca más seguido de lo que uno esperaría, pero por lo general acierta el orden de magnitud, así que alcanza.
Uno de los scripts de shell que más uso últimamente se llama
qy contienellm -s "Answer in as few words as possible. Use a brief style with short replies." -m claude-3.5-sonnet "$*", así puedo hacer preguntas tontas desde cualquier terminal sin sentirme observado.Se le puede preguntar algo corto como
q How do I run Docker with a different entrypoint to that in the container?, o hacer preguntas largas con un here-document sobre qué hace un código Perl, y me gusta que el contexto quede dentro de la terminal.cat somecode.py | ell -f -.Si quieres agregar otro prompt al vuelo sin ponerlo en una plantilla, puedes hacer algo como
(cat somecode.py; echo "Explain this code") | ell -f -.Debí haber incluido esto en el README; si hubiera visto antes
llmy los artículos relacionados, probablemente habría tenido mucha menos motivación para crear ell.llmpara usar localmente el modelo claude-3.5-sonnet. Leí la documentación de plugins y aun así no pude averiguarlo.También hay un proyecto que intenta hacer algo parecido con shell. No estoy seguro de cuál sea mejor.
demo
código fuente
Al principio pensé que obtenía la entrada del usuario leyendo desde algún lugar como
.bash_history, pero al revisarlo vi que no puede usar la salida de la terminal como contexto.Aun así, me gusta que use awk para procesar las respuestas, y creo que ell también podría usar awk para reducir las dependencias de
jqyperl.Lo voy a agregar al capítulo de proyectos relacionados del README.
Hice una herramienta similar que ya no mantengo: https://github.com/llimllib/gpt-bash-cli/
Como sugerencia, sería mejor guardar las conversaciones en una base de datos SQLite, que al usuario le facilita más manejar los datos que un archivo de texto, y usar directorios XDG en vez de
~/.ellrcd.Además, como no quiero dar acceso a la clave de API a todos los programas que ejecuto, prefiero un almacén de secretos del sistema antes que variables de entorno.
Es difícil asumir que todo el mundo tiene SQLite, pero parece algo que podría hacerse opcional mediante un plugin.
Los directorios XDG y el almacén de secretos del sistema se ven mucho mejores que el enfoque actual, así que pienso aprender a usarlos e integrarlos.
Scripts y programas arbitrarios deberían poder leer secretos como claves de API en tiempo de ejecución con la menor fricción posible, y no deberían guardarse en texto plano en el disco.
Parece que recomendabas
keyring, pero me pregunto si esa es la “forma GNU/Linux”, o si también sería viable guardarlos en un sistema de archivos cifrado, sea o no basado en FUSE.[1]: https://github.com/llimllib/gpt-bash-cli/blob/841682affe2d0e...
Las claves de LLM no son tan críticas, y uno debería confiar en los programas que ejecuta en su propio sistema.
No uso Poetry porque exige acceso a keyring; hay un bug abierto desde hace años y, en realidad, ni siquiera debería necesitar acceso.
Personalmente, prefiero mucho más los archivos de texto.
Hice una herramienta similar: https://autocomplete.sh
https://github.com/closedloop-technologies/autocomplete-sh
Quería que la autocompletación basada en Tab simplemente se sintiera como que funciona en la terminal.
Fue bastante difícil hacer que las respuestas del LLM quedaran prolijas en el formato que espera
bash_completion, pero una vez que funcionó pude envolver tanto OpenAI, grok y Claude como modelos locales tipo Ollama.Para hacerlo más inteligente, también metí en la ventana de contexto el historial reciente con contraseñas eliminadas, variables de entorno configuradas y la salida
--helpde comandos relevantes.Hace poco empecé a promocionarlo por Boston y parece que a la gente le gusta.
También había pensado en autocompletación, pero mi idea era más parecida a Copilot y la experiencia de usuario de este script se ve mejor.
La parte de incluir el historial en el contexto sería realmente útil si se agrega un modo historial como el de ell.
Limpiar contraseñas es una buena idea, pienso agregarlo como plugin.
Está muy bien integrado con el shell, y la decisión de escribirlo directamente en bash es audaz, pero efectiva para mantener la portabilidad.
Me pregunto si también funciona en el shell Fish, y cómo se actualiza o se elimina.
Se ve bien. Como trabajo en varias máquinas, siempre me atraen las herramientas livianas como las escritas en shell.
Tengo curiosidad: ¿podrías explicar por qué un comando como
: "${ELL_LOG_LEVEL:=2}";empieza con dos puntos? Pensaba que los dos puntos solo servían como comando sin operación.[1]: https://github.com/simonmysun/ell/blob/main/ell.sh#L19C1-L19...
:básicamente hace que bash no haga nada con el resultado de esa línea.Entonces
: "${ELL_LOG_LEVEL:=2}";inicializaELL_LOG_LEVELen 2 solo si todavía no está configurada, sin imprimir nada.Lo aprendí acá: https://stackoverflow.com/a/28085062/2485717
Me parece interesante el enfoque de usar solo bash puro y herramientas Unix.
Creé Plandex[1], que tiene objetivos similares: sin dependencias, basado en terminal y soporte de entrada por pipe como contexto, pero tomé un camino totalmente distinto: está escrito en Go y compila a un binario estático.
Plandex es de más alto nivel y está enfocado en programación, mientras que ell parece una herramienta LLM muy ligera y de propósito general, y me recuerda mucho a
llm[2] de Simon Willison.La función de grabación también me recuerda a savvy[3].
1 - https://github.com/plandex-ai/plandex
2 - https://github.com/simonw/llm
3 - https://github.com/getsavvyinc/savvy-cli
No conocía la herramienta
llmde Simon Willison, aunque sí me imaginaba que habría creado software de ese estilo.llmadmite funciones para manipular LLMs con más profundidad, mientras que ell carece de esas funciones y, a cambio, intenta usar solo la interfaz más común y básica, manteniendo lo más livianas posible las mejoras de experiencia de usuario como paginación o resaltado de sintaxis.Debería mencionarlo en el README para dirigir a los usuarios que necesiten más manipulación de LLMs hacia
simonw/llm.El enlace “Risks” del README está roto.
Lo que quisiera es que
ell -rse active automáticamente, y que un alias llamadofixproponga una corrección que incluya cambios en archivos.Por ejemplo, si hay un typo en
main.cc, ejecutogcc main.ccy luegofix, sería bueno que ell proponga una corrección como diff sobre el archivo, y que al aprobarla aplique el cambio y después sugiera volver a ejecutargcc; si lo apruebo, que lo ejecute.ell -rse puede agregar a.bashrc, pero no estoy seguro de si chocará con la configuración existente del usuario o causará otros problemas.Salvo por la confirmación del parche, parece posible con plantillas y plugins, pero aplicar cambios reales es difícil tanto técnicamente como desde el diseño de la interfaz de usuario.
Voy a investigar qué alcance es posible.
ell -rautomáticamente, basta con agregarlo a.bashrc.Voy a probarlo; personalmente uso aichat[0] para este caso.
Es interesante decir que para algo así no hace falta un lenguaje más complejo que bash, pero el hecho de que necesite
jq/curl/perlme parece que más bien dice lo contrario.[0] https://github.com/sigoden/aichat
La idea original era manejar todo con Bash, pero por las razones que escribí no fue posible.
Usando awk tal vez podría eliminar
jqyperl, pero sacrificaría mucho la simplicidad y legibilidad del código.Considero que implementar un resaltador de sintaxis es el límite inferior en el que puedo insistir, y no quiero hacer en Bash nada más complejo que eso.
Esas funciones no se admitirán o solo se admitirán mediante plugins externos.
En Linux tengo hecho un pequeño script bash que descarga el binario más reciente y lo descomprime en
/home/me/bin.Es interesante, pero en el video demo se ve un típico error de LLM
Explica que usar
1<>puede sobrescribir un archivo existente y que, para evitarlo, hay que hacer append con la opción-a; luego da el ejemplobash ls 1<> output.txt, pero el ejemplo no coincide con la explicación y está malHasta donde sé, lo más cercano sería
ls >> output.txtEn este contexto, no estoy muy seguro de que
1<> output.txttenga una invocación con sentido; quizá podría ser algo como vincularlo a un descriptor de archivo personalizado, como el 3, y luego usartee --appendDe hecho, cuando lo grabé antes no era tan malo, y tampoco cambié mucho el script al volver a grabarlo manteniéndolo igual
El video que grabé primero para la versión anterior está aquí: https://github.com/simonmysun/ell/blob/d4fc5468157fa6adc8f9f...
Lamentablemente, los LLM no son estables
Como referencia, estos son los enlaces al video con el error:
https://github.com/user-attachments/assets/1355ad08-6fbf-4c0...
https://github.com/simonmysun/ell/blob/553d38f60ad104893b2a3...
Me gusta mucho mods de Charmbracelet
Lo he estado usando durante meses, funciona bien, se puede personalizar mucho y la salida es limpia
https://github.com/charmbracelet/mods
El uso interactivo de ell depende de
scriptpara registrar la salida de la terminalSe podría admitir la gestión de conversaciones anteriores mediante plugins con efectos secundarios, pero habría que pensar si eso encaja con la idea y la filosofía de ell
Busqué proyectos similares, pero no encontré herramientas prácticas tan potentes como estas que compartieron los usuarios de HN