1P by GN⁺ | ★ favorite | 댓글 1개
  • ell은 Bash로 작성된 LLM용 명령줄 인터페이스로, 터미널에서 LLM에 질문하고 터미널 문맥을 함께 전달할 수 있게 함
  • 파이프 입력, 파일 입력, 표준 입력을 지원해 기존 Unix 도구 흐름과 함께 사용할 수 있으며, 대화형 모드에서는 문맥을 유지한 채 채팅할 수 있음
  • 템플릿을 통해 함수 호출과 LLM 제공자별 기능을 지원하고, 민감 정보 삭제 기능도 포함함
  • 사용에는 bash 4.1 이상, coreutils 또는 OS X 유틸리티, jq, curl이 필요하며, record mode를 쓰는 경우 perl과 util-linux의 script 명령이 추가로 필요함
  • Google gemini-1.5-flash와 OpenAI gpt-4o-mini 설정 예시가 제공되며, 거의 순수 Bash 구현이라 가볍고 설치·확장·수정이 쉽다는 점을 내세움

ell이 제공하는 기능

  • ell은 Bash로 작성된 LLM용 명령줄 인터페이스임
  • 터미널에서 LLM에 질문할 수 있고, 파이프와 함께 쓰기 쉽게 설계됨
  • 터미널의 문맥을 LLM에 전달한 뒤 질문할 수 있음
  • 터미널 안에서 LLM과 채팅할 수 있음
  • 템플릿을 통해 함수 호출과 추가 기능을 지원함
  • 민감 정보 삭제 기능이 포함되어 있으며 관련 항목으로 #14가 연결되어 있음

요구 사항과 설치

  • 기본 사용에는 다음 도구가 필요함
    • bash 4.1 이상
    • coreutils 또는 OS X 유틸리티
    • JSON 파싱용 jq
    • HTTPS 요청용 curl
  • record mode를 사용하지 않으면 다음 도구는 필수가 아님
    • PCRE용 perl
    • 터미널 입력과 출력을 기록하기 위한 util-linux의 script 명령
  • 설치는 저장소를 ~/.ellrc.d에 clone하고, 해당 경로를 PATH에 추가하는 방식임
git clone --depth 1 https://github.com/simonmysun/ell.git ~/.ellrc.d
echo 'export PATH="${HOME}/.ellrc.d:${PATH}"' >> ~/.bashrc

설정 방식

  • 설정 문서는 Configuration에 있음
  • Google gemini-1.5-flash 사용 예시는 ~/.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/
  • OpenAI gpt-4o-mini 사용 예시는 다음 설정을 사용함
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

사용 예시

  • 단순 질문은 명령 인자로 전달함
ell "What is the capital of France?"
  • 모델을 지정하고 파일을 입력으로 사용할 수 있음
ell -m gpt-4o -f user_prompt.txt
  • 표준 입력도 지원함
cat somecode.py | ell -f -
  • 템플릿에 넣지 않고 즉석에서 추가 프롬프트를 붙일 수 있음
(cat somecode.py; echo "Explain this code") | ell -f -
  • record mode는 터미널 입력과 출력을 기록해 이후 질문의 문맥으로 사용함
ell -r

# do random stuff
ell What does the error code mean?
ell How to fix it?
  • 대화형 모드는 -i로 실행하며, 대화형 모드에서는 문맥 기반 채팅을 위해 record mode가 자동 활성화됨
ell -i
  • 템플릿을 지정하면서 record mode와 대화형 모드를 함께 시작할 수 있음
ell -r -i -t ctf-gemini
ell -r -i -t ctf-openai

템플릿, 스타일링, 플러그인

  • 템플릿 작성 문서는 Templates에 있음
  • ell에서 LLM 제공자의 플러그인 지원을 사용하는 기능은 템플릿으로 구현됨
  • 스타일링 문서는 Styling에 있음
  • 플러그인 문서는 Plugins에 있음
  • 여기서 말하는 Plugin은 ell이 호출할 수 있는 스크립트를 뜻하며, ell의 기능 확장에 사용할 수 있음
    • LLM 제공자가 지원하는 플러그인은 이 범주에 포함되지 않으며, 해당 기능은 템플릿 문서를 참조해야 함

이름과 구현 선택

  • ell이라는 이름은 shellLLM의 조합임
  • shellm도 고려됐지만 she llm으로 오해될 수 있어 제외됨
  • ell은 짧고 입력하기 쉬우며 기억하기 쉽고, 활성 소프트웨어와 충돌하지 않는 이름으로 소개됨
  • Bash로 작성한 이유는 Bash가 Unix 계열 시스템에서 가장 흔한 셸이고, 이 용도에 더 복잡한 언어가 필요 없기 때문임
  • 유사 프로젝트와의 차이로 거의 순수 Bash로 작성돼 가볍고 설치가 쉬우며, 확장과 수정이 쉽다는 점을 제시함
  • 파이프 친화적이라 다른 도구와 조합해 쓰도록 설계됨

관련 문서와 라이선스

  • 고려할 위험은 Risks Consideration에 정리되어 있음
  • 기여는 이슈 또는 pull request로 받을 수 있음
  • 라이선스는 MIT License이며, 자세한 내용은 LICENSE 파일에 있음

댓글과 토론

Hacker News 의견들
  • ell은 도구로 표준 입력 파이프를 받을 수 있는지 궁금함
    https://llm.datasette.io/ 도구에서는 cat somecode.py | llm -m claude-3.5-sonnet "Explain this code"처럼 자주 쓰고, 지시문을 시스템 프롬프트로 분리해 cat somecode.py | llm -m claude-3.5-sonnet --system "Explain this code"처럼도 씀
    이렇게 LLM에 내용을 파이프로 넣을 수 있으면 웹페이지를 긁어 질문에 답하게 하는 식으로 재미있는 활용이 가능함: https://simonwillison.net/2024/Jun/17/cli-language-models/#f...

    • 오래 LLM 회의론자였지만, llm 명령줄 도구와 Claude 3 Opus 리뷰, 그리고 훨씬 저렴한 3.5 Sonnet을 알게 된 뒤 LLM을 매일 쓰기 시작함
      파이프 기능은 정말 자주 쓰이고, 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.'처럼 웹 글의 읽는 시간을 추정하는 데 씀
      단어 수는 생각보다 자주 틀리지만 대체로 자릿수는 맞아서 충분함
      최근 가장 많이 쓰는 셸 스크립트 중 하나는 q라는 이름으로, llm -s "Answer in as few words as possible. Use a brief style with short replies." -m claude-3.5-sonnet "$*"를 담아 두고 어떤 터미널에서든 바보 같은 질문을 눈치 보지 않고 던질 수 있음
      q How do I run Docker with a different entrypoint to that in the container?처럼 짧게 묻거나, here-document로 Perl 코드가 무엇을 하는지 묻는 긴 질문도 가능하고, 터미널 안에 맥락이 남는 점이 좋음
    • 가능함. 예를 들어 cat somecode.py | ell -f -처럼 쓰면 됨
      템플릿에 넣지 않고 즉석에서 프롬프트를 하나 더 붙이고 싶다면 (cat somecode.py; echo "Explain this code") | ell -f -처럼 가능함
      README에 이 내용을 넣었어야 했고, llm과 관련 글을 먼저 봤다면 ell을 만들 동기가 훨씬 줄었을 것 같음
    • llm에서 claude-3.5-sonnet 모델을 로컬로 쓰려면 어떻게 설정하는지 모르겠음. 플러그인 문서를 읽어도 알아내지 못했음
  • 셸로 비슷한 걸 하려는 프로젝트도 있음. 어느 쪽이 나은지는 잘 모르겠음
    demo
    source code

    • 훨씬 화려해 보임
      처음에는 .bash_history 같은 곳에서 읽어 사용자 입력을 얻는 구조라고 생각했지만, 확인해 보니 터미널 출력을 맥락으로 활용하지는 못함
      그래도 응답 처리에 awk를 쓰는 점이 마음에 들고, ell도 jqperl 의존성을 줄이는 데 awk를 쓸 수 있을 것 같음
      README의 관련 프로젝트 장에 추가할 예정임
    • 아름답고 기능도 많은데 GitHub 별이 왜 이렇게 적은지 궁금함
  • 더 이상 유지보수하지 않는 비슷한 도구를 만들었음: https://github.com/llimllib/gpt-bash-cli/
    제안하자면 대화는 텍스트 파일보다 사용자가 데이터를 다루기 쉬운 SQLite 데이터베이스에 저장하고, ~/.ellrcd 대신 XDG 디렉터리를 쓰는 편이 좋음
    또 실행하는 모든 프로그램에 API 키 접근을 주고 싶지 않으니 환경 변수보다 시스템 비밀 저장소를 선호함

    • 이미지 지원이 멋짐
      모두에게 SQLite가 있다고 가정하긴 어렵지만, 플러그인으로 선택 가능하게 만들 수는 있어 보임
      XDG 디렉터리와 시스템 비밀 저장소는 지금 방식보다 훨씬 나아 보여서 사용법을 배워 통합해볼 생각임
    • 리눅스 개발 머신에서 비밀값 저장의 권장 방식이 뭔지 궁금함
      임의의 스크립트와 프로그램이 API 키 같은 비밀값을 런타임에 최소한의 번거로움으로 읽을 수 있어야 하고, 디스크에는 평문으로 저장되면 안 됨
      keyring을 추천한 것 같은데 이것이 “GNU/Linux 방식”인지, 아니면 FUSE 기반이든 아니든 암호화 파일시스템에 저장하는 쪽도 가능한지 궁금함
      [1]: https://github.com/llimllib/gpt-bash-cli/blob/841682affe2d0e...
    • 오히려 keyring은 쓰지 않았으면 함. 귀찮고 어떤 시스템에는 없음
      LLM 키는 그렇게 치명적이지 않고, 자기 시스템에서 실행하는 프로그램은 신뢰해야 함
      Poetry가 keyring 접근을 요구해서 쓰지 않는데, 몇 년째 열린 버그가 있고 사실 접근할 필요도 없음
    • SQLite가 없고 쓰는 법도 모름
      개인적으로는 텍스트 파일이 훨씬 좋음
  • 비슷한 도구로 https://autocomplete.sh를 만들었음
    https://github.com/closedloop-technologies/autocomplete-sh
    터미널에서 탭 기반 자동완성이 그냥 동작하는 느낌을 원했음
    LLM 응답을 bash_completion이 기대하는 형식에 맞게 얌전하게 만드는 게 꽤 어려웠지만, 일단 되자 OpenAI, grok, Claude, Ollama 같은 로컬 모델까지 모두 감쌀 수 있었음
    더 똑똑하게 만들려고 비밀번호를 제거한 최근 기록, 설정된 환경 변수, 관련 명령의 --help 출력도 맥락 창에 넣음
    최근 Boston 쪽에서 홍보하기 시작했는데 사람들이 좋아하는 것 같음

    • 데모 영상이 아주 좋음: https://youtu.be/IAgkjerCvz8
    • 매우 유용해 보임
      자동완성도 생각해 봤지만, 내 아이디어는 Copilot에 가까웠고 이 스크립트의 사용자 경험이 더 나아 보임
      기록을 맥락에 넣는 부분은 ell 같은 기록 모드를 추가하면 정말 도움이 됨
      비밀번호 정리는 좋은 아이디어라 플러그인으로 추가할 예정임
    • Cambridge, MA의 AI Tinkerers 모임에서 autocomplete-sh가 동작하는 걸 봤고 인상적이었음
      셸과 아주 잘 통합되어 있고, bash로 직접 작성한 선택은 대담하지만 이식성을 유지하는 데 효과적임
    • 흥미로워 보임
      Fish 셸에서도 동작하는지, 그리고 업데이트나 제거는 어떻게 하는지 궁금함
  • 좋아 보임. 여러 머신에서 작업하므로 셸로 작성된 것처럼 가벼운 도구는 항상 끌림
    궁금한데 : "${ELL_LOG_LEVEL:=2}"; 같은 명령이 왜 콜론으로 시작하는지 설명해 줄 수 있는지 궁금함. 콜론은 무동작 명령으로만 유용하다고 생각했음
    [1]: https://github.com/simonmysun/ell/blob/main/ell.sh#L19C1-L19...

    • :는 기본적으로 해당 줄의 결과로 bash가 아무것도 하지 않게 함
      그래서 : "${ELL_LOG_LEVEL:=2}";는 출력 없이, 아직 설정되지 않은 경우에만 ELL_LOG_LEVEL을 2로 초기화함
    • 콜론은 결과가 실행되지 않도록 보장하려고 넣었음
      여기서 배웠음: https://stackoverflow.com/a/28085062/2485717
  • 순수 bash와 유닉스 도구만 쓰는 접근이 흥미로움
    비슷한 목표를 가진 Plandex[1]를 만들었는데, 의존성 없음, 터미널 기반, 맥락으로 파이프 입력 지원은 같지만 Go로 작성해 정적 바이너리로 컴파일하는 전혀 다른 길을 택함
    Plandex는 더 상위 수준이고 코딩에 초점을 맞춘 반면, ell은 매우 가볍고 범용적인 LLM 도구처럼 보이며 Simon Willison의 llm[2]이 많이 떠오름
    녹화 기능은 savvy[3]도 떠오르게 함
    1 - https://github.com/plandex-ai/plandex
    2 - https://github.com/simonw/llm
    3 - https://github.com/getsavvyinc/savvy-cli

    • Plandex도 좋고 그런 작업 흐름은 생각해 본 적이 없었음
      Simon Willison의 llm 도구는 몰랐지만 그런 소프트웨어를 만들었을 것 같긴 했음
      llm은 LLM을 더 깊게 조작하는 기능을 지원하고, ell은 그런 기능이 부족한 대신 가장 흔하고 기본적인 인터페이스만 쓰면서 페이지 처리나 구문 강조 같은 사용자 경험 개선을 최대한 가볍게 유지하려 함
      더 많은 LLM 조작이 필요한 사용자는 simonw/llm으로 안내하도록 README에 언급해야겠음
  • README의 “Risks” 링크가 깨져 있음
    원하는 건 ell -r이 자동으로 켜지고, fix라는 별칭이 파일 변경까지 포함해 수정안을 제안하는 것임
    예를 들어 main.cc에 오타가 있고 gcc main.cc를 실행한 뒤 fix를 실행하면, ell이 파일에 대한 diff로 수정을 제안하고, 승인하면 변경을 적용한 다음 gcc를 다시 실행할지 제안하며 승인 시 실행해 주면 좋겠음

    • “Risks” 링크는 고쳤음
      ell -r.bashrc에 추가할 수 있지만, 사용자 기존 설정과 충돌하거나 다른 문제가 생길지는 확신이 없음
      패치 확인을 제외하면 템플릿과 플러그인으로 가능해 보이지만, 실제 변경 적용은 기술적으로도 사용자 인터페이스 설계 측면에서도 어려움
      가능한 범위를 알아볼 생각임
    • ell -r을 자동 실행하려면 그냥 .bashrc에 추가하면 됨
  • 한번 써볼 예정이고, 개인적으로는 이 용도로 aichat[0]을 쓰고 있음
    이런 것에 bash보다 복잡한 언어가 필요 없다고 말하는 게 흥미로운데, jq/curl/perl이 필요하다는 사실은 오히려 반대를 말하는 것 아닌가 싶음
    [0] https://github.com/sigoden/aichat

    • 맞음. 그래서 그것들을 제한 사항으로 적었음
      원래 아이디어는 모든 걸 Bash로 처리하는 것이었지만, 적어 둔 이유들 때문에 가능하지 않았음
      awk를 쓰면 jqperl은 제거할 수도 있겠지만, 코드의 단순성과 가독성을 많이 희생하게 됨
      구문 강조기 구현이 내가 고집할 수 있는 하한선이라고 보고, Bash로 그보다 복잡한 건 만들고 싶지 않음
      그런 기능은 지원하지 않거나 외부 플러그인으로만 지원할 예정임
    • aichat에 한 표 더함. 아주 좋음
      Linux에서는 최신 바이너리를 내려받아 /home/me/bin에 압축 해제하는 작은 bash 스크립트를 만들어 둠
  • 흥미롭지만 데모 영상에서 전형적인 LLM 오류가 보임
    1<>를 쓰면 기존 파일이 덮어써질 수 있다고 설명하고, 이를 피하려면 -a 옵션으로 append하라고 한 뒤 bash ls 1<> output.txt 예시를 드는데, 예시는 설명과 맞지 않고 틀렸음
    내가 아는 한 가장 가까운 동작은 ls >> output.txt
    이 맥락에서 1<> output.txt가 의미 있는 호출이 있는지 잘 모르겠고, 3 같은 사용자 지정 파일 디스크립터에 바인딩한 뒤 tee --append를 쓰는 식일 수는 있겠음

  • Charmbracelet의 mods를 아주 좋아함
    몇 달째 쓰고 있는데 잘 동작하고, 커스터마이즈가 많이 가능하며 출력도 깔끔함
    https://github.com/charmbracelet/mods

    • mods는 대화에는 잘 맞지만, 반대로 ell 자체는 사용자 입력과 생성 내용 측면에서 상태가 없음
      ell의 대화형 사용은 script로 터미널 출력을 기록하는 데 의존함
      부작용이 있는 플러그인으로 과거 대화 관리를 지원할 수는 있지만, 그것이 ell의 아이디어와 철학에 맞는지는 고민이 필요함
      비슷한 프로젝트를 검색했는데 HN 사용자들이 올려 준 이런 강력한 실전 도구들은 찾지 못했음