1 ポイント 投稿者 GN⁺ 2024-08-04 | 1件のコメント | WhatsAppで共有
  • 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 にまとめられている
  • コントリビューションは issue または pull request で受け付けている
  • ライセンスは MIT License で、詳細は LICENSE ファイルにある

1件のコメント

 
GN⁺ 2024-08-04
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 に内容をパイプで渡せると、Web ページを取得して質問に答えさせるといった面白い活用ができる: 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.' のように Web 記事の読了時間を見積もるのに使っている
      単語数は思ったより頻繁に間違えるが、だいたい桁は合っているので十分
      最近いちばんよく使うシェルスクリプトの一つは 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 を作る動機はずっと小さかったと思う
    • llmclaude-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 ディレクトリとシステムのシークレットストアは今の方式よりずっと良さそうなので、使い方を学んで統合してみるつもり
    • Linux 開発マシンでのシークレット保存の推奨方法が気になる
      任意のスクリプトやプログラムが 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 と Unix ツールだけを使うアプローチが興味深いです
    似た目標を持つ 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 ユーザーたちが挙げてくれたこうした強力な実用ツールは見つからなかった