- ell là giao diện dòng lệnh cho LLM được viết bằng Bash, cho phép đặt câu hỏi cho LLM ngay trong terminal và gửi kèm ngữ cảnh của terminal
- Hỗ trợ đầu vào từ pipe, tệp và đầu vào chuẩn, nên có thể dùng cùng luồng công cụ Unix hiện có; ở chế độ tương tác, có thể chat trong khi vẫn giữ nguyên ngữ cảnh
- Hỗ trợ function calling và các tính năng riêng theo từng nhà cung cấp LLM thông qua template, đồng thời cũng bao gồm tính năng xóa thông tin nhạy cảm
- Để sử dụng cần bash 4.1 trở lên, coreutils hoặc tiện ích OS X, jq, curl; nếu dùng record mode thì cần thêm perl và lệnh
script của util-linux
- Có ví dụ cấu hình cho Google
gemini-1.5-flash và OpenAI gpt-4o-mini, đồng thời nhấn mạnh đây là triển khai gần như Bash thuần nên nhẹ, dễ cài đặt, mở rộng và chỉnh sửa
Các tính năng ell cung cấp
- ell là giao diện dòng lệnh cho LLM được viết bằng Bash
- Có thể đặt câu hỏi cho LLM trong terminal, và được thiết kế để dễ dùng cùng pipe
- Có thể gửi ngữ cảnh của terminal cho LLM rồi đặt câu hỏi
- Có thể chat với LLM ngay trong terminal
- Hỗ trợ function calling và các tính năng bổ sung thông qua template
- Bao gồm tính năng xóa thông tin nhạy cảm, với mục liên quan tại #14
Yêu cầu và cài đặt
- Để sử dụng cơ bản cần các công cụ sau
- bash 4.1 trở lên
- coreutils hoặc tiện ích OS X
- jq để phân tích JSON
- curl để gửi yêu cầu HTTPS
- Nếu không dùng record mode thì các công cụ sau không bắt buộc
- perl cho PCRE
- Lệnh
script của util-linux để ghi lại đầu vào và đầu ra của terminal
- Cài đặt bằng cách clone kho vào
~/.ellrc.d rồi thêm đường dẫn đó vào PATH
git clone --depth 1 https://github.com/simonmysun/ell.git ~/.ellrc.d
echo 'export PATH="${HOME}/.ellrc.d:${PATH}"' >> ~/.bashrc
Cách cấu hình
- Tài liệu cấu hình có tại Configuration
- Ví dụ dùng Google
gemini-1.5-flash là đặt các giá trị sau trong ~/.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/
- Ví dụ dùng OpenAI
gpt-4o-mini là dùng cấu hình sau
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
Ví dụ sử dụng
- Câu hỏi đơn giản được truyền dưới dạng đối số lệnh
ell "What is the capital of France?"
- Có thể chỉ định model và dùng tệp làm đầu vào
ell -m gpt-4o -f user_prompt.txt
- Cũng hỗ trợ đầu vào chuẩn
cat somecode.py | ell -f -
- Có thể thêm prompt bổ sung ngay tại chỗ mà không đưa vào template
(cat somecode.py; echo "Explain this code") | ell -f -
- record mode ghi lại đầu vào và đầu ra của terminal để dùng làm ngữ cảnh cho các câu hỏi sau
ell -r
# do random stuff
ell What does the error code mean?
ell How to fix it?
- Chế độ tương tác chạy bằng
-i; trong chế độ này, record mode được tự động bật để hỗ trợ chat dựa trên ngữ cảnh
ell -i
- Có thể khởi động đồng thời record mode và chế độ tương tác trong khi chỉ định template
ell -r -i -t ctf-gemini
ell -r -i -t ctf-openai
Template, styling, plugin
- Tài liệu viết template có tại Templates
- Tính năng dùng hỗ trợ plugin của nhà cung cấp LLM trong ell được triển khai bằng template
- Tài liệu styling có tại Styling
- Tài liệu plugin có tại Plugins
- Plugin ở đây có nghĩa là script mà ell có thể gọi, dùng để mở rộng chức năng của ell
- Plugin do nhà cung cấp LLM hỗ trợ không thuộc nhóm này; với tính năng đó cần tham khảo tài liệu về template
Tên gọi và lựa chọn triển khai
- Tên
ell là sự kết hợp của shell và LLM
shellm cũng từng được cân nhắc nhưng bị loại vì có thể bị hiểu nhầm thành she llm
ell được giới thiệu là ngắn, dễ gõ, dễ nhớ và không xung đột với phần mềm đang hoạt động
- Lý do viết bằng Bash là vì Bash là shell phổ biến nhất trên các hệ Unix, và trường hợp sử dụng này không cần ngôn ngữ phức tạp hơn
- Điểm khác với các dự án tương tự là nó được viết gần như bằng Bash thuần nên nhẹ và dễ cài đặt, đồng thời dễ mở rộng và chỉnh sửa
- Thân thiện với pipe nên được thiết kế để kết hợp với các công cụ khác
Tài liệu liên quan và giấy phép
- Các rủi ro cần cân nhắc được tổng hợp tại Risks Consideration
- Có thể đóng góp qua issue hoặc pull request
- Giấy phép là MIT License; chi tiết có trong tệp LICENSE
1 bình luận
Ý kiến trên Hacker News
Không rõ ell với tư cách là một công cụ có thể nhận pipe từ đầu vào chuẩn không
Với công cụ https://llm.datasette.io/, tôi thường dùng kiểu
cat somecode.py | llm -m claude-3.5-sonnet "Explain this code", và cũng dùng kiểu tách chỉ thị ra làm system prompt nhưcat somecode.py | llm -m claude-3.5-sonnet --system "Explain this code"Nếu có thể pipe nội dung vào LLM như vậy thì có thể có những cách dùng thú vị, chẳng hạn cào nội dung trang web rồi bắt nó trả lời câu hỏi: https://simonwillison.net/2024/Jun/17/cli-language-models/#f...
llm, bài review Claude 3 Opus, và 3.5 Sonnet rẻ hơn rất nhiều, tôi bắt đầu dùng LLM hằng ngàyTính năng pipe được dùng thực sự rất thường xuyên; tôi dùng nó để ước tính thời gian đọc bài viết trên web, kiểu
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.'Số từ thì sai nhiều hơn tôi tưởng, nhưng nhìn chung vẫn đúng cỡ bậc độ lớn nên thế là đủ
Một trong các shell script tôi dùng nhiều nhất gần đây có tên là
q, chứallm -s "Answer in as few words as possible. Use a brief style with short replies." -m claude-3.5-sonnet "$*", nhờ vậy tôi có thể hỏi những câu ngớ ngẩn ở bất kỳ terminal nào mà không phải ngạiCó thể hỏi ngắn như
q How do I run Docker with a different entrypoint to that in the container?, hoặc hỏi dài bằng here-document để xem một đoạn mã Perl làm gì; tôi thích việc ngữ cảnh vẫn còn trong terminalcat somecode.py | ell -f -là đượcNếu muốn gắn thêm một prompt ngay tại chỗ mà không đưa vào template, có thể làm như
(cat somecode.py; echo "Explain this code") | ell -f -Lẽ ra tôi nên đưa phần này vào README; và nếu tôi xem
llmcùng bài viết liên quan trước thì có lẽ động lực tạo ell đã giảm đi rất nhiềullm. Đọc tài liệu plugin rồi mà vẫn không tìm raCũng có một dự án cố làm thứ tương tự bằng shell. Tôi không chắc bên nào tốt hơn
demo
source code
Ban đầu tôi tưởng nó lấy input người dùng bằng cách đọc từ nơi như
.bash_history, nhưng kiểm tra rồi thì hóa ra nó không thể dùng output của terminal làm ngữ cảnhDù vậy tôi thích việc nó dùng awk để xử lý phản hồi, và có lẽ ell cũng có thể dùng awk để giảm phụ thuộc vào
jqvàperlTôi dự định thêm nó vào chương các dự án liên quan trong README
Tôi từng làm một công cụ tương tự nhưng không còn bảo trì nữa: https://github.com/llimllib/gpt-bash-cli/
Nếu được góp ý, tôi nghĩ nên lưu hội thoại vào cơ sở dữ liệu SQLite, nơi người dùng dễ thao tác dữ liệu hơn so với file văn bản, và nên dùng thư mục XDG thay vì
~/.ellrcdNgoài ra, vì tôi không muốn mọi chương trình được chạy đều có quyền truy cập API key, tôi thích dùng kho bí mật của hệ thống hơn là biến môi trường
Khó có thể giả định ai cũng có SQLite, nhưng có vẻ có thể làm thành tùy chọn qua plugin
Thư mục XDG và kho bí mật của hệ thống trông tốt hơn cách hiện tại rất nhiều, nên tôi định học cách dùng rồi tích hợp thử
Các script và chương trình tùy ý cần có thể đọc bí mật như API key lúc runtime với ít phiền phức nhất, và chúng không được lưu plaintext trên đĩa
Có vẻ bạn đã gợi ý
keyring, nhưng tôi không rõ đó có phải là “cách GNU/Linux” không, hay lưu trong một filesystem được mã hóa — dù có dựa trên FUSE hay không — cũng được[1]: https://github.com/llimllib/gpt-bash-cli/blob/841682affe2d0e...
Khóa LLM không nghiêm trọng đến mức đó, và các chương trình chạy trên hệ thống của mình thì mình phải tin tưởng
Tôi không dùng Poetry vì nó đòi quyền truy cập keyring; lỗi này đã mở nhiều năm rồi và thật ra nó cũng chẳng cần truy cập
Cá nhân tôi thấy file văn bản tốt hơn nhiều
Tôi đã tạo một công cụ tương tự là https://autocomplete.sh
https://github.com/closedloop-technologies/autocomplete-sh
Tôi muốn có cảm giác tự động hoàn thành dựa trên phím Tab trong terminal cứ thế hoạt động
Việc làm cho phản hồi của LLM ngoan ngoãn khớp với định dạng mà
bash_completionmong đợi khá khó, nhưng khi đã chạy được thì có thể bọc được cả OpenAI, grok, Claude, Ollama và các model cục bộ tương tựĐể làm cho nó thông minh hơn, tôi cũng đưa vào cửa sổ ngữ cảnh lịch sử gần đây đã loại bỏ mật khẩu, các biến môi trường đã thiết lập, và đầu ra
--helpcủa các lệnh liên quanGần đây bắt đầu quảng bá ở khu vực Boston và có vẻ mọi người thích nó
Tôi cũng đã nghĩ đến tự động hoàn thành, nhưng ý tưởng của tôi gần với Copilot hơn, còn trải nghiệm người dùng của script này có vẻ tốt hơn
Phần đưa lịch sử vào ngữ cảnh sẽ thực sự hữu ích nếu thêm một chế độ lịch sử như ell
Làm sạch mật khẩu là ý tưởng hay nên tôi dự định thêm dưới dạng plugin
Nó tích hợp rất tốt với shell, và lựa chọn viết trực tiếp bằng bash tuy táo bạo nhưng hiệu quả để giữ tính di động
Tôi tò mò liệu nó có chạy được trên Fish shell không, và cập nhật hay gỡ bỏ thì làm thế nào
Trông ổn. Vì tôi làm việc trên nhiều máy, các công cụ nhẹ như thứ được viết bằng shell luôn hấp dẫn
Tôi tò mò liệu bạn có thể giải thích vì sao một lệnh như
: "${ELL_LOG_LEVEL:=2}";lại bắt đầu bằng dấu hai chấm không. Tôi cứ nghĩ dấu hai chấm chỉ hữu ích như một lệnh no-op[1]: https://github.com/simonmysun/ell/blob/main/ell.sh#L19C1-L19...
:khiến bash không làm gì với kết quả của dòng đóVì vậy
: "${ELL_LOG_LEVEL:=2}";khởi tạoELL_LOG_LEVELthành 2 chỉ khi nó chưa được thiết lập, và không in ra gìTôi học được ở đây: https://stackoverflow.com/a/28085062/2485717
Cách tiếp cận chỉ dùng bash thuần và công cụ Unix thật thú vị
Tôi đã tạo Plandex[1] với mục tiêu tương tự: không có dependency, chạy trên terminal, hỗ trợ input qua pipe làm ngữ cảnh; nhưng chọn một hướng hoàn toàn khác là viết bằng Go và biên dịch thành binary tĩnh
Plandex ở cấp cao hơn và tập trung vào coding, còn ell trông như một công cụ LLM rất nhẹ và đa dụng, làm tôi nhớ nhiều đến
llm[2] của Simon WillisonTính năng ghi lại cũng khiến tôi nhớ đến savvy[3]
1 - https://github.com/plandex-ai/plandex
2 - https://github.com/simonw/llm
3 - https://github.com/getsavvyinc/savvy-cli
Tôi không biết công cụ
llmcủa Simon Willison, nhưng cũng đoán là ông ấy có thể đã làm phần mềm như vậyllmhỗ trợ các chức năng thao tác LLM sâu hơn, còn ell thiếu các chức năng đó nhưng cố gắng chỉ dùng giao diện phổ biến và cơ bản nhất, đồng thời giữ các cải thiện trải nghiệm người dùng như phân trang hay tô sáng cú pháp thật nhẹCó lẽ tôi nên đề cập trong README để hướng người dùng cần thao tác LLM nhiều hơn sang
simonw/llmLiên kết “Risks” trong README bị hỏng
Điều tôi muốn là
ell -rtự động bật, và một alias tênfixcó thể đề xuất bản sửa bao gồm cả thay đổi fileVí dụ nếu
main.cccó lỗi typo, sau khi chạygcc main.ccrồi chạyfix, ell sẽ đề xuất sửa dưới dạng diff cho file; nếu chấp thuận thì áp dụng thay đổi, rồi đề nghị chạy lạigcc, và nếu chấp thuận thì chạy giúpCó thể thêm
ell -rvào.bashrc, nhưng tôi không chắc liệu nó có xung đột với cấu hình hiện có của người dùng hoặc gây vấn đề khác khôngNgoại trừ phần xác nhận patch, có vẻ có thể làm bằng template và plugin, nhưng việc áp dụng thay đổi thực sự thì khó cả về mặt kỹ thuật lẫn thiết kế giao diện người dùng
Tôi sẽ tìm hiểu xem phạm vi khả thi đến đâu
ell -rthì chỉ cần thêm vào.bashrcTôi sẽ thử dùng, còn cá nhân thì hiện đang dùng aichat[0] cho mục đích này
Việc nói rằng những thứ như vậy không cần ngôn ngữ phức tạp hơn bash khá thú vị, nhưng thực tế cần
jq/curl/perlchẳng phải lại nói điều ngược lại sao[0] https://github.com/sigoden/aichat
Ý tưởng ban đầu là xử lý mọi thứ bằng Bash, nhưng vì những lý do đã nêu nên không thể
Nếu dùng awk thì có thể loại bỏ
jqvàperl, nhưng sẽ phải hy sinh nhiều về độ đơn giản và khả năng đọc của codeTôi xem việc triển khai bộ tô sáng cú pháp là giới hạn thấp nhất mà mình có thể cố chấp, và không muốn làm thứ phức tạp hơn thế bằng Bash
Những chức năng như vậy sẽ không được hỗ trợ, hoặc chỉ hỗ trợ dưới dạng plugin bên ngoài
Trên Linux, tôi đã tạo một script bash nhỏ để tải binary mới nhất xuống rồi giải nén vào
/home/me/binThú vị, nhưng trong video demo có thể thấy một lỗi LLM điển hình
Nó giải thích rằng dùng
1<>có thể ghi đè tệp hiện có, rồi nói để tránh điều đó thì hãy append bằng tùy chọn-a, sau đó đưa ví dụbash ls 1<> output.txt, nhưng ví dụ này không khớp với phần giải thích và là saiTheo tôi biết, hành vi gần nhất là
ls >> output.txtTrong ngữ cảnh này tôi không chắc có lời gọi nào mà
1<> output.txtcó ý nghĩa hay không; có thể là kiểu bind vào một file descriptor tùy chỉnh như 3 rồi dùngtee --appendThực ra khi quay trước đó thì nó không tệ như vậy, và khi quay lại tôi cũng không thay đổi nhiều, vẫn giữ nguyên script
Video quay ban đầu cho phiên bản trước ở đây: https://github.com/simonmysun/ell/blob/d4fc5468157fa6adc8f9f...
Tiếc là LLM không ổn định
Để tham khảo, đây là các liên kết video có lỗi:
https://github.com/user-attachments/assets/1355ad08-6fbf-4c0...
https://github.com/simonmysun/ell/blob/553d38f60ad104893b2a3...
Tôi rất thích mods của Charmbracelet
Tôi đã dùng vài tháng nay, nó hoạt động tốt, có thể tùy biến rất nhiều và đầu ra cũng gọn gàng
https://github.com/charmbracelet/mods
Việc dùng ell theo kiểu tương tác dựa vào
scriptđể ghi lại đầu ra terminalCó thể hỗ trợ quản lý các cuộc trò chuyện trước đó bằng plugin có side effect, nhưng cần cân nhắc liệu điều đó có phù hợp với ý tưởng và triết lý của ell hay không
Tôi đã tìm các dự án tương tự nhưng không tìm thấy những công cụ thực chiến mạnh mẽ như các công cụ mà người dùng HN đã chia sẻ