- ell เป็นอินเทอร์เฟซบรรทัดคำสั่งสำหรับ LLM ที่เขียนด้วย Bash ช่วยให้ถาม LLM จากเทอร์มินัลและส่งบริบทของเทอร์มินัลไปพร้อมกันได้
- รองรับอินพุตจาก pipe, ไฟล์ และ standard input จึงใช้ร่วมกับ โฟลว์เครื่องมือ Unix ที่มีอยู่ได้ และในโหมดโต้ตอบสามารถแชตโดยคงบริบทไว้ได้
- รองรับ function calling และฟีเจอร์เฉพาะของผู้ให้บริการ LLM ผ่านเทมเพลต และมีฟีเจอร์ลบข้อมูลอ่อนไหวรวมอยู่ด้วย
- การใช้งานต้องมี bash 4.1 ขึ้นไป, coreutils หรือยูทิลิตีของ OS X, jq, curl และหากใช้ record mode ต้องมี perl กับคำสั่ง
script ของ util-linux เพิ่มเติม
- มีตัวอย่างการตั้งค่าสำหรับ Google
gemini-1.5-flash และ OpenAI gpt-4o-mini โดยชูจุดเด่นว่าเป็นการพัฒนาเกือบทั้งหมดด้วย Bash ล้วน จึงเบา ติดตั้ง·ขยาย·แก้ไขได้ง่าย
ฟีเจอร์ที่ ell มีให้
- ell เป็นอินเทอร์เฟซบรรทัดคำสั่งสำหรับ LLM ที่เขียนด้วย Bash
- สามารถถาม LLM จากเทอร์มินัลได้ และออกแบบมาให้ใช้งานร่วมกับ pipe ได้ง่าย
- สามารถส่ง บริบท ของเทอร์มินัลไปยัง LLM แล้วถามคำถามได้
- สามารถแชตกับ LLM ภายในเทอร์มินัลได้
- รองรับ function calling และฟีเจอร์เพิ่มเติมผ่านเทมเพลต
- มีฟีเจอร์ลบข้อมูลอ่อนไหวรวมอยู่ด้วย และเชื่อมโยงไปยังรายการที่เกี่ยวข้อง #14
ข้อกำหนดและการติดตั้ง
- การใช้งานพื้นฐานต้องใช้เครื่องมือต่อไปนี้
- bash 4.1 ขึ้นไป
- coreutils หรือยูทิลิตีของ OS X
- jq สำหรับแยกวิเคราะห์ JSON
- curl สำหรับคำขอ HTTPS
- หากไม่ใช้ record mode เครื่องมือต่อไปนี้ไม่จำเป็นต้องมี
- perl สำหรับ PCRE
- คำสั่ง
script ของ util-linux สำหรับบันทึกอินพุตและเอาต์พุตของเทอร์มินัล
- การติดตั้งทำโดย clone repository ไปที่
~/.ellrc.d และเพิ่มพาธดังกล่าวเข้าใน 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
- รองรับ standard input ด้วย
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 มาจากการผสมกันของ shell และ LLM
- เคยพิจารณาชื่อ
shellm ด้วย แต่ตัดออกเพราะอาจถูกเข้าใจผิดเป็น she llm
ell ถูกนำเสนอว่าเป็นชื่อที่สั้น พิมพ์ง่าย จำง่าย และไม่ชนกับซอฟต์แวร์ที่ใช้งานอยู่
- เหตุผลที่เขียนด้วย Bash คือ Bash เป็น shell ที่พบได้บ่อยที่สุดบนระบบตระกูล Unix และงานลักษณะนี้ไม่จำเป็นต้องใช้ภาษาที่ซับซ้อนกว่านั้น
- ความแตกต่างจากโปรเจกต์ที่คล้ายกันคือเขียนด้วย Bash เกือบล้วน จึง เบาและติดตั้งง่าย รวมถึงขยายและแก้ไขได้ง่าย
- ออกแบบมาให้เป็นมิตรกับ pipe เพื่อใช้ร่วมกับเครื่องมืออื่น ๆ
เอกสารที่เกี่ยวข้องและไลเซนส์
- ความเสี่ยงที่ควรพิจารณาถูกรวบรวมไว้ใน Risks Consideration
- รับการมีส่วนร่วมผ่าน issue หรือ pull request
- ไลเซนส์คือ MIT License และมีรายละเอียดเพิ่มเติมในไฟล์ LICENSE
1 ความคิดเห็น
ความคิดเห็นใน Hacker News
สงสัยว่า ell สามารถรับ standard input pipe เป็นเครื่องมือได้ไหม
ในเครื่องมือ https://llm.datasette.io/ มักใช้บ่อย ๆ แบบ
cat somecode.py | llm -m claude-3.5-sonnet "Explain this code"และยังใช้แยกคำสั่งเป็น system prompt ได้ด้วย เช่นcat somecode.py | llm -m claude-3.5-sonnet --system "Explain this code"ถ้าสามารถ pipe เนื้อหาเข้า LLM แบบนี้ได้ ก็จะนำไปใช้สนุก ๆ ได้ เช่น ดึงหน้าเว็บมาแล้วให้ตอบคำถาม: https://simonwillison.net/2024/Jun/17/cli-language-models/#f...
llmกับ รีวิว Claude 3 Opus และ 3.5 Sonnet ที่ราคาถูกกว่ามาก ก็เริ่มใช้ LLM ทุกวันฟีเจอร์ pipe ใช้บ่อยมากจริง ๆ และใช้ประเมินเวลาอ่านบทความบนเว็บ เช่น
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.'การนับคำมักผิดบ่อยกว่าที่คิด แต่โดยรวมลำดับขนาดถูกต้อง จึงเพียงพอ
หนึ่งใน shell script ที่ใช้บ่อยที่สุดช่วงหลังตั้งชื่อว่า
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 -ถ้าอยากแนบ prompt เพิ่มแบบทันทีโดยไม่ใส่ในเทมเพลต ก็ทำได้แบบ
(cat somecode.py; echo "Explain this code") | ell -f -น่าจะใส่เรื่องนี้ไว้ใน README และถ้าเห็น
llmกับบทความที่เกี่ยวข้องก่อน แรงจูงใจในการทำ ell คงลดลงมากllmแบบ local อ่านเอกสารปลั๊กอินแล้วก็ยังหาไม่เจอมีโปรเจกต์ที่พยายามทำสิ่งคล้าย ๆ กันด้วย shell เหมือนกัน ไม่แน่ใจว่าอันไหนดีกว่า
demo
source code
ตอนแรกคิดว่าโครงสร้างคืออ่านจากที่อย่าง
.bash_historyเพื่อดึง input ของผู้ใช้ แต่พอลองดูแล้วไม่ได้ใช้ output ของเทอร์มินัลเป็นบริบทถึงอย่างนั้นก็ชอบที่ใช้ awk จัดการ response และคิดว่า ell เองก็น่าจะใช้ awk เพื่อลด dependency อย่าง
jqกับperlได้จะเพิ่มไว้ในบทโปรเจกต์ที่เกี่ยวข้องของ README
เคยทำเครื่องมือคล้ายกันที่ตอนนี้ไม่ได้ดูแลต่อแล้ว: https://github.com/llimllib/gpt-bash-cli/
ถ้าจะเสนอแนะ ควรเก็บบทสนทนาไว้ใน ฐานข้อมูล SQLite ที่ผู้ใช้จัดการข้อมูลได้ง่ายกว่าไฟล์ข้อความ และใช้ ไดเรกทอรี XDG แทน
~/.ellrcdอีกอย่างคือไม่อยากให้ทุกโปรแกรมที่รันเข้าถึง API key ได้ จึงชอบใช้ที่เก็บ secret ของระบบมากกว่าตัวแปรสภาพแวดล้อม
คงสมมติไม่ได้ว่าทุกคนมี SQLite แต่ดูเหมือนจะทำให้เลือกใช้เป็นปลั๊กอินได้
ไดเรกทอรี XDG กับที่เก็บ secret ของระบบดูดีกว่าวิธีปัจจุบันมาก เลยคิดว่าจะเรียนรู้วิธีใช้แล้วลองผสานเข้าไป
script และโปรแกรมทั่วไปต้องอ่าน secret อย่าง API key ตอน runtime ได้โดยยุ่งยากน้อยที่สุด และไม่ควรเก็บเป็น plain text บนดิสก์
เหมือนจะแนะนำ
keyringแต่สงสัยว่านี่คือ “วิถี GNU/Linux” หรือไม่ หรือการเก็บไว้ใน filesystem ที่เข้ารหัส ไม่ว่าจะใช้ FUSE หรือไม่ ก็น่าจะเป็นไปได้ไหม[1]: https://github.com/llimllib/gpt-bash-cli/blob/841682affe2d0e...
คีย์ LLM ไม่ได้ร้ายแรงขนาดนั้น และโปรแกรมที่รันบนระบบของตัวเองก็ควรต้องเชื่อถือได้
ไม่ใช้ Poetry เพราะมันขอเข้าถึง keyring มีบั๊กเปิดค้างมาหลายปี และจริง ๆ ก็ไม่จำเป็นต้องเข้าถึง
ส่วนตัวแล้วชอบ ไฟล์ข้อความ มากกว่าเยอะ
ผมทำเครื่องมือคล้าย ๆ กันไว้ที่ https://autocomplete.sh
https://github.com/closedloop-technologies/autocomplete-sh
อยากให้มันให้ความรู้สึกว่า autocomplete แบบใช้ปุ่ม Tab ในเทอร์มินัลทำงานได้เลย
การทำให้คำตอบของ LLM ออกมาเป็นรูปแบบที่
bash_completionคาดหวังนั้นค่อนข้างยาก แต่พอทำได้แล้วก็สามารถครอบ OpenAI, grok, Claude รวมถึงโมเดลโลคัลอย่าง Ollama ได้ทั้งหมดเพื่อให้มันฉลาดขึ้น ยังใส่ประวัติล่าสุดที่ลบรหัสผ่านออกแล้ว, environment variables ที่ตั้งไว้ และผลลัพธ์
--helpของคำสั่งที่เกี่ยวข้องเข้าไปในหน้าต่างบริบทด้วยช่วงหลังเริ่มโปรโมตแถว Boston และดูเหมือนคนจะชอบกัน
ผมก็เคยคิดเรื่อง autocomplete เหมือนกัน แต่ไอเดียของผมใกล้เคียง Copilot มากกว่า และ user experience ของสคริปต์นี้ดูดีกว่า
ส่วนที่ใส่ประวัติเข้าไปในบริบท ถ้าเพิ่ม โหมดประวัติ แบบ ell จะช่วยได้มากจริง ๆ
การลบรหัสผ่านเป็นไอเดียที่ดี เลยตั้งใจจะเพิ่มเป็นปลั๊กอิน
มันผสานกับเชลล์ได้ดีมาก และการเลือกเขียนด้วย bash โดยตรงเป็นทางเลือกที่กล้า แต่ก็ได้ผลในการรักษา portability
อยากรู้ว่าใช้กับ Fish shell ได้ไหม และการอัปเดตหรือถอนการติดตั้งทำอย่างไร
ดูดีนะ ผมทำงานบนหลายเครื่อง เลยถูกใจ เครื่องมือเบา ๆ แบบที่เขียนเป็นเชลล์เสมอ
สงสัยว่าอธิบายได้ไหมว่าทำไมคำสั่งอย่าง
: "${ELL_LOG_LEVEL:=2}";ถึงเริ่มด้วยโคลอน ผมนึกว่าโคลอนมีประโยชน์แค่เป็นคำสั่ง no-op เท่านั้น[1]: https://github.com/simonmysun/ell/blob/main/ell.sh#L19C1-L19...
:ทำให้ bash ไม่ทำอะไรกับผลลัพธ์ของบรรทัดนั้นดังนั้น
: "${ELL_LOG_LEVEL:=2}";จะ initializeELL_LOG_LEVELเป็น 2 เฉพาะเมื่อยังไม่ได้ตั้งค่า โดยไม่มีเอาต์พุตเรียนรู้จากที่นี่: https://stackoverflow.com/a/28085062/2485717
แนวทางที่ใช้เฉพาะ bash ล้วนกับเครื่องมือ Unix น่าสนใจ
ผมสร้าง Plandex[1] ที่มีเป้าหมายคล้ายกัน คือไม่มี dependency, ทำงานบนเทอร์มินัล, รองรับ input จาก pipe เป็นบริบทเหมือนกัน แต่เลือกเส้นทางที่ต่างออกไปโดยสิ้นเชิง คือเขียนด้วย Go แล้วคอมไพล์เป็น static binary
Plandex อยู่ใน ระดับสูงกว่า และเน้นงานเขียนโค้ด ส่วน ell ดูเหมือนเป็นเครื่องมือ LLM แบบอเนกประสงค์ที่เบามาก และทำให้นึกถึง
llm[2] ของ Simon Willison อยู่มากฟีเจอร์บันทึกการทำงานก็ทำให้นึกถึง savvy[3] ด้วย
1 - https://github.com/plandex-ai/plandex
2 - https://github.com/simonw/llm
3 - https://github.com/getsavvyinc/savvy-cli
ผมไม่รู้จักเครื่องมือ
llmของ Simon Willison แต่ก็คิดอยู่แล้วว่าเขาน่าจะเคยทำซอฟต์แวร์แบบนั้นllmรองรับฟีเจอร์สำหรับจัดการ LLM ลึกกว่า ส่วน ell ขาดฟีเจอร์แบบนั้น แต่พยายามใช้เฉพาะอินเทอร์เฟซที่พบบ่อยและพื้นฐานที่สุด พร้อมคงการปรับปรุง user experience อย่าง paging หรือ syntax highlighting ให้เบาที่สุดน่าจะต้องระบุใน README เพื่อชี้ผู้ใช้ที่ต้องการจัดการ LLM มากกว่านี้ไปที่
simonw/llmลิงก์ “Risks” ใน README เสีย
สิ่งที่อยากได้คือให้
ell -rเปิดโดยอัตโนมัติ และให้ alias ชื่อfixเสนอวิธีแก้รวมถึงการเปลี่ยนแปลงไฟล์ด้วยเช่น ถ้ามี typo ใน
main.ccแล้วรันgcc main.ccจากนั้นรันfixก็อยากให้ ell เสนอการแก้เป็น diff ของไฟล์ และถ้า approve ก็ apply การเปลี่ยนแปลง แล้วเสนอว่าจะรันgccอีกครั้งไหม และถ้า approve ก็รันให้ell -rเพิ่มลงใน.bashrcได้ แต่ไม่แน่ใจว่าจะชนกับการตั้งค่าเดิมของผู้ใช้หรือเกิดปัญหาอื่นไหมถ้าไม่นับการตรวจสอบแพตช์ ดูเหมือนทำได้ด้วยเทมเพลตและปลั๊กอิน แต่การ apply การเปลี่ยนแปลงจริง ๆ ยากทั้งในเชิงเทคนิคและการออกแบบ user interface
ตั้งใจจะลองดูว่าทำได้แค่ไหน
ell -rรันอัตโนมัติ ก็แค่เพิ่มลงใน.bashrcเดี๋ยวจะลองใช้ดู ส่วนตัวตอนนี้ใช้ aichat[0] สำหรับงานแบบนี้อยู่
น่าสนใจที่บอกว่าสิ่งนี้ไม่จำเป็นต้องใช้ภาษาที่ซับซ้อนกว่า bash แต่ข้อเท็จจริงที่ว่าต้องใช้
jq/curl/perlนี่ไม่ได้บอกตรงกันข้ามหรือ[0] https://github.com/sigoden/aichat
ไอเดียเดิมคือจัดการทุกอย่างด้วย Bash แต่ด้วยเหตุผลที่เขียนไว้จึงทำไม่ได้
ถ้าใช้ awk ก็อาจตัด
jqกับperlออกได้ แต่ต้องแลกกับความเรียบง่ายและความอ่านง่ายของโค้ดค่อนข้างมากผมมองว่าการทำ syntax highlighter เป็นขีดล่างสุดที่ผมจะยืนกรานได้ และไม่อยากทำอะไรที่ซับซ้อนกว่านั้นด้วย Bash
ฟีเจอร์แบบนั้นจะไม่รองรับ หรือรองรับเฉพาะผ่านปลั๊กอินภายนอกเท่านั้น
บน Linux ผมทำสคริปต์ bash เล็ก ๆ ไว้ดาวน์โหลด binary ล่าสุดแล้วแตกไฟล์ลง
/home/me/binน่าสนใจดี แต่ในวิดีโอเดโมเห็น ข้อผิดพลาดแบบที่พบบ่อยของ LLM
มันอธิบายว่าถ้าใช้
1<>อาจทำให้ไฟล์เดิมถูกเขียนทับได้ และถ้าต้องการหลีกเลี่ยงให้ append ด้วยตัวเลือก-aแล้วก็ยกตัวอย่างbash ls 1<> output.txtซึ่งตัวอย่างไม่ตรงกับคำอธิบายและผิดด้วยเท่าที่ผมรู้ พฤติกรรมที่ใกล้เคียงที่สุดคือ
ls >> output.txtในบริบทนี้ผมไม่แน่ใจว่า
1<> output.txtมีการเรียกใช้งานที่มีความหมายหรือไม่ อาจเป็นแนวผูกกับ file descriptor แบบกำหนดเองอย่าง 3 แล้วใช้tee --appendก็ได้จริง ๆ ตอนที่อัดไว้ก่อนหน้านี้มันไม่ได้แย่ขนาดนี้ และตอนอัดใหม่โดยคงสคริปต์เดิมไว้ก็ไม่ได้เปลี่ยนอะไรมาก
วิดีโอที่อัดครั้งแรกสำหรับเวอร์ชันก่อนหน้าอยู่ที่นี่: https://github.com/simonmysun/ell/blob/d4fc5468157fa6adc8f9f...
น่าเสียดายที่ LLM ไม่เสถียร
สำหรับอ้างอิง ลิงก์วิดีโอที่มีข้อผิดพลาดมีดังนี้:
https://github.com/user-attachments/assets/1355ad08-6fbf-4c0...
https://github.com/simonmysun/ell/blob/553d38f60ad104893b2a3...
ชอบ mods ของ Charmbracelet มาก
ใช้มาหลายเดือนแล้ว ทำงานได้ดี ปรับแต่งได้เยอะ และ output ก็ดูสะอาด
https://github.com/charmbracelet/mods
การใช้งาน ell แบบโต้ตอบอาศัย
scriptเพื่อบันทึก output ของเทอร์มินัลอาจรองรับการจัดการบทสนทนาย้อนหลังได้ด้วยปลั๊กอินที่มี side effect แต่ต้องพิจารณาว่านั่นสอดคล้องกับแนวคิดและปรัชญาของ ell หรือไม่
ผมลองค้นหาโปรเจกต์ที่คล้ายกันแล้ว แต่ไม่พบเครื่องมือใช้งานจริงที่ทรงพลังแบบที่ผู้ใช้ HN เอามาแชร์เหล่านี้