1 pontos por GN⁺ 2024-08-04 | 1 comentários | Compartilhar no WhatsApp
  • 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

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

    • Fui cético em relação a LLMs por muito tempo, mas depois que conheci a ferramenta de linha de comando llm, a resenha do Claude 3 Opus e o 3.5 Sonnet, muito mais barato, comecei a usar LLMs todos os dias
      O 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 q e contém llm -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 julgado
      Dá 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 terminal
    • É possível. Por exemplo, basta usar cat 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 llm e os textos relacionados, acho que teria tido muito menos motivação para criar o ell
    • Não sei como configurar no llm para usar localmente o modelo claude-3.5-sonnet. Li a documentação do plugin e não consegui descobrir
  • Também existe um projeto tentando fazer algo parecido com shell. Não sei bem qual dos dois é melhor
    demo
    código-fonte

    • Parece muito mais sofisticado
      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 contexto
      Ainda 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 jq e perl
      Pretendo adicioná-lo à seção de projetos relacionados no README
    • É bonito e cheio de recursos, mas fico me perguntando por que tem tão poucas estrelas no GitHub
  • 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 ~/.ellrcd
    Alé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

    • O suporte a imagens é legal
      É 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
    • Fico me perguntando qual é a prática recomendada para armazenar segredos em uma máquina de desenvolvimento Linux
      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...
    • Na verdade, eu preferiria que não usasse keyring. É chato e não existe em alguns sistemas
      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
    • Não tenho SQLite e nem sei usá-lo
      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_completion espera, mas, quando começou a funcionar, deu para encapsular tudo: OpenAI, grok, Claude, Ollama e até modelos locais
    Para 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 --help dos comandos relevantes
    Comecei a divulgar recentemente na região de Boston, e parece que as pessoas estão gostando

    • O vídeo de demonstração é muito bom: https://youtu.be/IAgkjerCvz8
    • Parece muito útil
      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
    • Vi o autocomplete-sh funcionando no encontro AI Tinkerers em Cambridge, MA, e fiquei impressionado
      Ele se integra muito bem ao shell, e a escolha de escrevê-lo diretamente em bash é ousada, mas eficaz para manter a portabilidade
    • Parece interessante
      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 linha
      Então : "${ELL_LOG_LEVEL:=2}"; inicializa ELL_LOG_LEVEL como 2, sem saída, apenas se ainda não estiver definido
    • Coloquei os dois-pontos para garantir que o resultado não seja executado
      Aprendi 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 Willison
    O 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

    • O Plandex também é bom, e eu nunca tinha pensado nesse tipo de fluxo de trabalho
      Eu não conhecia a ferramenta llm do Simon Willison, mas imaginava que ele teria criado um software assim
      O llm oferece 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ível
      Acho que devo mencionar no README para direcionar usuários que precisam de mais manipulação de LLMs para simonw/llm
  • O link “Risks” no README está quebrado
    O que eu gostaria é que ell -r fosse ativado automaticamente e que um alias chamado fix sugerisse correções incluindo alterações em arquivos
    Por exemplo, se houver um erro de digitação em main.cc, eu executar gcc main.cc e depois executar fix, 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 executar gcc novamente e, se aprovado, executasse

    • Corrigi o link “Risks”
      ell -r pode ser adicionado ao .bashrc, mas não tenho certeza se isso entraria em conflito com configurações existentes do usuário ou causaria outros problemas
      Tirando 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
    • Para executar ell -r automaticamente, basta adicioná-lo ao .bashrc
  • Pretendo 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/perl não indica justamente o contrário?
    [0] https://github.com/sigoden/aichat

    • Sim. Por isso listei esses itens como limitações
      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 jq e perl, mas isso sacrificaria bastante a simplicidade e a legibilidade do código
      Considero 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
    • Mais um voto para o aichat. É muito bom
      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 -a para fazer append, depois dá o exemplo bash ls 1<> output.txt, mas o exemplo não bate com a explicação e está errado
    Até onde sei, o comportamento mais próximo é ls >> output.txt
    Não tenho certeza se, nesse contexto, existe alguma chamada em que 1<> output.txt faça sentido; talvez fosse algo como vinculá-lo a um descritor de arquivo customizado, como 3, e depois usar tee --append

  • 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 mods funciona bem para conversas, mas, por outro lado, o próprio ell é sem estado em termos de entrada do usuário e conteúdo gerado
      O uso interativo do ell depende de script para registrar a saída do terminal
      Seria 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