- ell é uma interface de linha de comando para LLMs escrita em Bash, que permite fazer perguntas ao LLM no terminal e enviar junto o contexto do terminal
- Suporta entrada por pipe, arquivo e entrada padrão, podendo ser usada com o fluxo de ferramentas Unix existente, e no modo interativo permite conversar mantendo o contexto
- Por meio de templates, oferece suporte a chamada de funções e recursos específicos de cada provedor de LLM, além de incluir um recurso de remoção de informações sensíveis
- Para usar, são necessários bash 4.1 ou superior, coreutils ou utilitários do OS X, jq e curl; ao usar o record mode, também são necessários perl e o comando
script do util-linux
- São fornecidos exemplos de configuração para Google
gemini-1.5-flash e OpenAI gpt-4o-mini, destacando que, por ser uma implementação quase totalmente em Bash, é leve e fácil de instalar, estender e modificar
Recursos oferecidos pelo ell
- ell é uma interface de linha de comando para LLMs escrita em Bash
- Permite fazer perguntas ao LLM no terminal e foi projetada para funcionar bem com pipes
- É possível enviar o contexto do terminal ao LLM antes de fazer uma pergunta
- É possível conversar com o LLM dentro do terminal
- Oferece suporte a chamada de funções e recursos adicionais por meio de templates
- Inclui um recurso de remoção de informações sensíveis, com referência relacionada em #14
Requisitos e instalação
- Para uso básico, são necessárias as seguintes ferramentas
- bash 4.1 ou superior
- coreutils ou utilitários do OS X
- jq para parsing de JSON
- curl para requisições HTTPS
- Se você não usar o record mode, as ferramentas abaixo não são obrigatórias
- perl para PCRE
- o comando
script do util-linux para registrar entrada e saída do terminal
- A instalação consiste em clonar o repositório em
~/.ellrc.d e adicionar esse caminho ao PATH
git clone --depth 1 https://github.com/simonmysun/ell.git ~/.ellrc.d
echo 'export PATH="${HOME}/.ellrc.d:${PATH}"' >> ~/.bashrc
Forma de configuração
- A documentação de configuração está em Configuration
- O exemplo de uso do Google
gemini-1.5-flash define os valores abaixo em ~/.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/
- O exemplo de uso do OpenAI
gpt-4o-mini usa a configuração abaixo
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
Exemplos de uso
- Perguntas simples são passadas como argumento de comando
ell "What is the capital of France?"
- É possível especificar o modelo e usar um arquivo como entrada
ell -m gpt-4o -f user_prompt.txt
- Também há suporte a entrada padrão
cat somecode.py | ell -f -
- É possível adicionar um prompt extra na hora, sem colocá-lo no template
(cat somecode.py; echo "Explain this code") | ell -f -
- O record mode registra a entrada e a saída do terminal para usá-las depois como contexto de perguntas
ell -r
# do random stuff
ell What does the error code mean?
ell How to fix it?
- O modo interativo é iniciado com
-i; nesse modo, o record mode é ativado automaticamente para permitir chat com base em contexto
ell -i
- Também é possível iniciar record mode e modo interativo ao mesmo tempo, especificando um template
ell -r -i -t ctf-gemini
ell -r -i -t ctf-openai
Templates, estilização e plugins
- A documentação para criação de templates está em Templates
- No ell, o uso do suporte a plugins do provedor de LLM é implementado por templates
- A documentação de estilização está em Styling
- A documentação de plugins está em Plugins
- Aqui, Plugin se refere a scripts que o ell pode chamar, e que podem ser usados para expandir suas funcionalidades
- Plugins suportados pelo provedor de LLM não entram nessa categoria; para esse recurso, consulte a documentação de templates
Nome e escolha de implementação
- O nome
ell é uma combinação de shell e LLM
shellm também foi considerado, mas foi descartado por poder ser entendido como she llm
ell é apresentado como um nome curto, fácil de digitar e lembrar, e que não entra em conflito com softwares ativos
- O motivo para ter sido escrito em Bash é que Bash é o shell mais comum em sistemas Unix-like e, para esse uso, não é necessária uma linguagem mais complexa
- Como diferencial em relação a projetos semelhantes, o texto destaca que ele é escrito quase totalmente em Bash, o que o torna leve e fácil de instalar, além de simples de estender e modificar
- Ele foi projetado para ser amigável a pipes, de modo a ser usado em combinação com outras ferramentas
Documentação relacionada e licença
- Os riscos a considerar estão resumidos em Risks Consideration
- Contribuições podem ser enviadas por issue ou pull request
- A licença é a MIT License; mais detalhes estão no arquivo LICENSE
1 comentários
Opiniões no Hacker News
Fico me perguntando se o ell, como ferramenta, consegue receber um pipe de entrada padrão
Na ferramenta https://llm.datasette.io/, isso é usado com frequência, como em
cat somecode.py | llm -m claude-3.5-sonnet "Explain this code"; também se usa separando a instrução como prompt de sistema, como emcat somecode.py | llm -m claude-3.5-sonnet --system "Explain this code"Poder enviar conteúdo para o LLM por pipe assim permite usos interessantes, como raspar uma página web e fazê-lo responder a perguntas: https://simonwillison.net/2024/Jun/17/cli-language-models/#f...
llm, a resenha do Claude 3 Opus e o 3.5 Sonnet, muito mais barato, comecei a usar LLMs todos os diasO recurso de pipe é usado o tempo todo; uso para estimar o tempo de leitura de textos na web, como em
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.'A contagem de palavras erra com mais frequência do que eu esperava, mas em geral acerta a ordem de grandeza, então é suficiente
Um dos scripts de shell que mais uso recentemente se chama
qe contémllm -s "Answer in as few words as possible. Use a brief style with short replies." -m claude-3.5-sonnet "$*", para que eu possa fazer perguntas bobas em qualquer terminal sem me sentir julgadoDá para fazer perguntas curtas, como
q How do I run Docker with a different entrypoint to that in the container?, ou perguntas longas via here-document sobre o que um código Perl faz, e gosto do fato de o contexto ficar dentro do terminalcat somecode.py | ell -f -Se você quiser acrescentar mais um prompt na hora, sem colocá-lo em um template, pode fazer algo como
(cat somecode.py; echo "Explain this code") | ell -f -Eu deveria ter colocado isso no README e, se tivesse visto antes o
llme os textos relacionados, acho que teria tido muito menos motivação para criar o ellllmpara usar localmente o modelo claude-3.5-sonnet. Li a documentação do plugin e não consegui descobrirTambém existe um projeto tentando fazer algo parecido com shell. Não sei bem qual dos dois é melhor
demo
código-fonte
No começo, pensei que a estrutura obtivesse a entrada do usuário lendo de algum lugar como
.bash_history, mas, verificando, vi que ela não consegue usar a saída do terminal como contextoAinda assim, gosto do uso de awk para processar respostas, e acho que o ell também poderia usar awk para reduzir as dependências de
jqeperlPretendo adicioná-lo à seção de projetos relacionados no README
Criei uma ferramenta parecida que não mantenho mais: https://github.com/llimllib/gpt-bash-cli/
Como sugestão, seria melhor armazenar as conversas em um banco de dados SQLite, que facilita para o usuário manipular os dados, em vez de arquivos de texto, e usar os diretórios XDG em vez de
~/.ellrcdAlém disso, como não quero dar acesso à chave de API para todos os programas que executo, prefiro o armazenamento de segredos do sistema a variáveis de ambiente
É difícil presumir que todo mundo tenha SQLite, mas parece possível torná-lo opcional por meio de plugin
Diretórios XDG e o armazenamento de segredos do sistema parecem muito melhores do que o método atual, então pretendo aprender a usá-los e tentar integrá-los
Scripts e programas arbitrários precisam conseguir ler segredos, como chaves de API, em tempo de execução com o mínimo de atrito, e eles não devem ficar armazenados em texto puro no disco
Acho que foi recomendado
keyring, mas fico na dúvida se essa é a “forma GNU/Linux”, ou se também é possível armazenar em um sistema de arquivos criptografado, seja ele baseado em FUSE ou não[1]: https://github.com/llimllib/gpt-bash-cli/blob/841682affe2d0e...
Chaves de LLM não são tão críticas assim, e você precisa confiar nos programas que executa no próprio sistema
Não uso o Poetry porque ele exige acesso ao keyring; há um bug aberto há anos e, na verdade, ele nem deveria precisar desse acesso
Pessoalmente, prefiro muito mais arquivos de texto
Criei uma ferramenta parecida, https://autocomplete.sh
https://github.com/closedloop-technologies/autocomplete-sh
Queria que a autocompletação baseada em Tab simplesmente funcionasse no terminal
Foi bem difícil fazer as respostas do LLM ficarem certinhas no formato que o
bash_completionespera, mas, quando começou a funcionar, deu para encapsular tudo: OpenAI, grok, Claude, Ollama e até modelos locaisPara deixá-lo mais inteligente, também coloquei na janela de contexto o histórico recente com senhas removidas, variáveis de ambiente definidas e a saída de
--helpdos comandos relevantesComecei a divulgar recentemente na região de Boston, e parece que as pessoas estão gostando
Também pensei em autocompletação, mas minha ideia era mais próxima do Copilot, e a experiência de usuário deste script parece melhor
A parte de colocar o histórico no contexto seria realmente útil se fosse adicionado um modo de histórico como o do ell
A limpeza de senhas é uma boa ideia, pretendo adicioná-la como plugin
Ele se integra muito bem ao shell, e a escolha de escrevê-lo diretamente em bash é ousada, mas eficaz para manter a portabilidade
Fico curioso para saber se também funciona no shell Fish e como são feitas atualizações ou remoção
Parece bom. Trabalho em várias máquinas, então ferramentas leves, como algo escrito em shell, sempre me atraem
Tenho uma dúvida: alguém poderia explicar por que um comando como
: "${ELL_LOG_LEVEL:=2}";começa com dois-pontos? Eu achava que dois-pontos só era útil como comando que não faz nada[1]: https://github.com/simonmysun/ell/blob/main/ell.sh#L19C1-L19...
:basicamente faz com que o bash não faça nada com o resultado daquela linhaEntão
: "${ELL_LOG_LEVEL:=2}";inicializaELL_LOG_LEVELcomo 2, sem saída, apenas se ainda não estiver definidoAprendi isso aqui: https://stackoverflow.com/a/28085062/2485717
A abordagem de usar apenas bash puro e ferramentas Unix é interessante
Criei o Plandex[1], que tem um objetivo parecido: sem dependências, baseado no terminal e com suporte a entrada por pipe como contexto, mas segui um caminho totalmente diferente, escrevendo em Go e compilando para um binário estático
O Plandex é mais de alto nível e focado em programação, enquanto o ell parece uma ferramenta de LLM bem leve e genérica, e lembra bastante o
llm[2] do Simon WillisonO recurso de gravação também lembra o savvy[3]
1 - https://github.com/plandex-ai/plandex
2 - https://github.com/simonw/llm
3 - https://github.com/getsavvyinc/savvy-cli
Eu não conhecia a ferramenta
llmdo Simon Willison, mas imaginava que ele teria criado um software assimO
llmoferece suporte a recursos mais profundos para manipular LLMs; o ell não tem esses recursos, mas, em troca, tenta usar apenas a interface mais comum e básica, mantendo as melhorias de experiência do usuário, como paginação e realce de sintaxe, o mais leves possívelAcho que devo mencionar no README para direcionar usuários que precisam de mais manipulação de LLMs para
simonw/llmO link “Risks” no README está quebrado
O que eu gostaria é que
ell -rfosse ativado automaticamente e que um alias chamadofixsugerisse correções incluindo alterações em arquivosPor exemplo, se houver um erro de digitação em
main.cc, eu executargcc main.cce depois executarfix, seria bom se o ell sugerisse uma correção como um diff para o arquivo e, ao aprovar, aplicasse a alteração; em seguida sugerisse executargccnovamente e, se aprovado, executasseell -rpode ser adicionado ao.bashrc, mas não tenho certeza se isso entraria em conflito com configurações existentes do usuário ou causaria outros problemasTirando a revisão do patch, parece possível com templates e plugins, mas aplicar alterações de fato é difícil tanto tecnicamente quanto do ponto de vista do design da interface do usuário
Pretendo investigar até onde isso é viável
ell -rautomaticamente, basta adicioná-lo ao.bashrcPretendo experimentar, e pessoalmente uso aichat[0] para esse fim
É interessante dizer que não é preciso uma linguagem mais complexa que bash para algo assim, mas o fato de precisar de
jq/curl/perlnão indica justamente o contrário?[0] https://github.com/sigoden/aichat
A ideia original era fazer tudo em Bash, mas, pelos motivos que escrevi, isso não foi possível
Usando awk, talvez fosse possível remover
jqeperl, mas isso sacrificaria bastante a simplicidade e a legibilidade do códigoConsidero que a implementação do realce de sintaxe é o limite inferior do que eu consigo insistir em fazer, e não quero criar nada mais complexo que isso em Bash
Esses recursos serão ou não suportados, ou suportados apenas como plugins externos
No Linux, deixei um pequeno script bash que baixa o binário mais recente e o descompacta em
/home/me/binÉ interessante, mas no vídeo de demonstração aparece um erro típico de LLM
Ele explica que usar
1<>pode sobrescrever um arquivo existente e, para evitar isso, diz para usar a opção-apara fazer append, depois dá o exemplobash ls 1<> output.txt, mas o exemplo não bate com a explicação e está erradoAté onde sei, o comportamento mais próximo é
ls >> output.txtNão tenho certeza se, nesse contexto, existe alguma chamada em que
1<> output.txtfaça sentido; talvez fosse algo como vinculá-lo a um descritor de arquivo customizado, como 3, e depois usartee --appendNa verdade, quando gravei antes, não estava tão ruim, e ao regravar mantendo o script, também não mudei muita coisa
O vídeo que gravei primeiro para a versão anterior está aqui: https://github.com/simonmysun/ell/blob/d4fc5468157fa6adc8f9f...
Infelizmente, LLMs não são estáveis
Para referência, estes são os links dos vídeos com o erro:
https://github.com/user-attachments/assets/1355ad08-6fbf-4c0...
https://github.com/simonmysun/ell/blob/553d38f60ad104893b2a3...
Gosto muito do mods da Charmbracelet
Uso há alguns meses, funciona bem, é bastante customizável e a saída é limpa
https://github.com/charmbracelet/mods
O uso interativo do ell depende de
scriptpara registrar a saída do terminalSeria possível oferecer suporte ao gerenciamento de conversas anteriores com plugins que tenham efeitos colaterais, mas é preciso pensar se isso combina com a ideia e a filosofia do ell
Pesquisei projetos semelhantes, mas não encontrei essas ferramentas práticas e poderosas que os usuários do HN indicaram