- zerostack là một tác nhân lập trình tối giản được viết bằng Rust, hỗ trợ nhiều nhà cung cấp LLM cùng với các nhà cung cấp tùy chỉnh
- Cung cấp đọc·ghi·chỉnh sửa tệp, grep, tìm tệp, liệt kê thư mục, thực thi Bash có cổng cấp quyền, MCP và các công cụ web Exa
- Khoảng 7 nghìn LoC, nhị phân 8.9MB; RAM đo được khoảng 8MB ở phiên trống và khoảng 12MB khi làm việc, CPU 0.0% khi nhàn rỗi
- Nhà cung cấp mặc định là OpenRouter; cài đặt bằng
cargo install zerostack, và cần bubblewrap để dùng cách ly Bash trong --sandbox
- Bao gồm prompt tích hợp sẵn như
code·plan·review, 4 chế độ quyền hạn, tiếp tục phiên, vòng lặp lặp lại và tích hợp Git worktrees
Tổng quan về zerostack
- zerostack là một tác nhân lập trình tối giản được viết bằng Rust, lấy cảm hứng từ pi và opencode
- Có kiến trúc đa nhà cung cấp, hỗ trợ OpenRouter, OpenAI, Anthropic, Gemini, Ollama và các nhà cung cấp tùy chỉnh
- Cung cấp các công cụ tệp như đọc·ghi·chỉnh sửa tệp, grep, tìm tệp, liệt kê thư mục và thực thi Bash có cổng cấp quyền
- Bao gồm lưu·tải·tiếp tục phiên, nén tự động để duy trì cửa sổ ngữ cảnh, giao diện terminal dựa trên crossterm, kết nối máy chủ MCP và các công cụ WebFetch·WebSearch dựa trên Exa
- Có thể di chuyển giữa các Git worktree bằng
/worktree, đồng thời tích hợp cả vòng lặp lặp lại cho các tác vụ dài hạn
Hiệu năng và cài đặt
Bắt đầu nhanh
- Nhà cung cấp mặc định là OpenRouter, khóa API được thiết lập bằng biến môi trường
export OPENROUTER_API_KEY="[api_key]"
- Phiên tương tác chạy với prompt mặc định
code
zerostack
- Chế độ chạy một lần truyền prompt bằng
-p
zerostack -p "Explain this project"
- Có thể tiếp tục phiên cuối bằng
-c
zerostack -c
- Có thể chỉ định nhà cung cấp và mô hình
zerostack --provider openrouter --model deepseek/deepseek-v4-flash
Hệ thống prompt
- zerostack bao gồm một bộ system prompt tích hợp sẵn để thay đổi hành vi và giọng điệu của tác nhân
- Mục tiêu là tạo ra một họ prompt có thể thay thế superpower hoặc Claude official skills
- Có thể dùng
/prompt để liệt kê các prompt đã đăng ký hoặc chuyển sang prompt khác
-
Prompt tích hợp sẵn
code là mặc định, là chế độ lập trình dùng quyền truy cập đầy đủ vào tệp·công cụ Bash và quy trình làm việc TDD
plan là chế độ chỉ lập kế hoạch, khám phá trước rồi tạo kế hoạch mà không viết mã
review là chế độ review mã để kiểm tra độ chính xác, thiết kế, kiểm thử và tác động
debug là chế độ gỡ lỗi tìm nguyên nhân gốc rễ trước khi đề xuất sửa đổi
ask là chế độ chỉ đọc, chỉ cho phép read·grep·glob và không cho phép ghi hoặc Bash
brainstorm là chế độ chỉ thiết kế, khám phá ý tưởng và đề xuất thiết kế mà không viết mã
frontend-design là chế độ thiết kế frontend cho UI độc đáo và đạt mức production
review-security là chế độ review bảo mật để tìm các lỗ hổng có thể bị khai thác
simplify là chế độ đơn giản hóa mã để tăng độ rõ ràng mà không thay đổi hành vi
write-prompt là chế độ viết prompt để tạo và tối ưu hóa prompt cho tác nhân
- Có thể tạo prompt tùy chỉnh bằng cách đặt tệp Markdown trong
$XDG_CONFIG_HOME/zerostack/prompts/ và tham chiếu theo tên
- Tự động đọc
AGENTS.md hoặc CLAUDE.md ở thư mục gốc dự án hay thư mục cha và chèn vào system prompt; có thể tắt bằng -n hoặc --no-context-files
Hệ thống quyền hạn
- zerostack cung cấp 4 chế độ quyền hạn từ an toàn nhất đến cho phép nhiều nhất
-
Chế độ quyền hạn
restrictive hoặc -R sẽ yêu cầu phê duyệt cho mọi thao tác công cụ không được cho phép rõ ràng trong cấu hình
standard là mặc định; tự động phê duyệt các lệnh an toàn như ls, cd, git log, cargo check và yêu cầu xác nhận cho thao tác ghi cùng các tác vụ mang tính phá hủy
accept-all hoặc --accept-all sẽ tự động phê duyệt mọi thao tác bên trong thư mục làm việc và yêu cầu xác nhận với đường dẫn bên ngoài
yolo hoặc --yolo sẽ tự động phê duyệt mọi thao tác không cần prompt
- Có thể cấu hình quyền hạn chi tiết bằng mẫu glob theo từng công cụ trong tệp cấu hình
- Ví dụ, có thể tự động cho phép
write **.rs nhưng luôn yêu cầu xác nhận khi ghi các tệp khác
- Danh sách cho phép theo phiên giữ lại các quyết định đã phê duyệt trong suốt phiên để không phải xác nhận lặp lại cùng một thao tác
- Nếu cùng một lời gọi công cụ lặp lại từ 3 lần trở lên, cơ chế phát hiện doom-loop sẽ hiện prompt cảnh báo hoặc từ chối theo cấu hình, ngăn tác nhân lặp lại các tác vụ phá hủy
Lệnh slash và quản lý phiên
- Các lệnh slash chính điều khiển mô hình, mức độ suy nghĩ, hội thoại, phiên, vòng lặp, prompt và chế độ quyền hạn
/model dùng để chuyển mô hình, /thinking dùng để đặt mức độ suy nghĩ
/clear xóa hội thoại, /session liệt kê·lưu·tải phiên
/loop lên lịch prompt lặp lại, /prompt liệt kê hoặc thay đổi prompt của tác nhân
/mode đặt chế độ của hệ thống quyền hạn, và có thể xem toàn bộ lệnh bằng /help
- Các phiên được lưu trong
$XDG_DATA_HOME/zerostack/sessions/
-c tiếp tục phiên gần nhất, -r duyệt để chọn phiên, còn --session <id> tải một phiên cụ thể
Vòng lặp lặp lại
- zerostack bao gồm vòng lặp lập trình lặp lại cho các tác vụ dài hạn
- Tác nhân sẽ liên tục đọc tác vụ, chọn mục từ kế hoạch, thực hiện công việc, chạy kiểm thử, cập nhật kế hoạch và tiếp tục vòng lặp cho đến khi hoàn thành hoặc chạm giới hạn lặp
- Hệ thống vòng lặp là tính năng thử nghiệm
-
Cách dùng vòng lặp
/loop Implement the user authentication system bắt đầu vòng lặp với prompt đã chỉ định
/loop stop dừng vòng lặp đang hoạt động
/loop status hiển thị trạng thái vòng lặp hiện tại
- Mỗi lần lặp bao gồm tác vụ gốc,
LOOP_PLAN.md thay đổi theo thời gian, tóm tắt lần lặp trước và đầu ra xác minh
- Khi vòng lặp đang hoạt động, mọi đầu vào không phải lệnh slash đều bị chặn
-
Vòng lặp headless dựa trên CLI
Tích hợp Git worktrees
- zerostack cung cấp luồng làm việc theo từng nhánh bằng git worktrees
- Có thể tạo worktree, làm việc trong đó, hợp nhất và thoát ra ngay trong UI chat
- Tích hợp Git worktrees là tính năng thử nghiệm
-
Lệnh worktree
/worktree <name> tạo git worktree cho nhánh <name> và chuyển sang đó; nếu đã tồn tại thì bỏ qua bước tạo
/wt-merge [branch] hợp nhất nhánh worktree vào [branch], push, dọn dẹp rồi quay về kho chính
/wt-exit quay về kho chính mà không hợp nhất
-
Quy trình ví dụ
/worktree feature-x tạo nhánh mới cùng thư mục worktree rồi chuyển sang đó
- Sau đó có thể dùng zerostack như bình thường và các thay đổi sẽ nằm lại trên nhánh feature
/wt-merge khiến tác nhân hợp nhất nhánh, push, dọn dẹp rồi quay về kho chính
/wt-exit lập tức quay về kho chính mà không hợp nhất
Các nhà cung cấp được hỗ trợ và giấy phép
- Nhà cung cấp mặc định là OpenRouter
- Hỗ trợ các nhà cung cấp tương thích OpenAI như vLLM, LiteLLM
- Hỗ trợ Anthropic, Gemini, Ollama
- Các nhà cung cấp tùy chỉnh có thể được cấu hình trong
$XDG_CONFIG_HOME/zerostack/config.json bằng base URL tùy ý và biến môi trường khóa API
- Giấy phép là GPL-3.0-only
1 bình luận
Ý kiến trên Hacker News
Tôi không rành lắm về các công cụ kiểu này, nên khá tò mò không biết nó có ưu điểm gì so với các model/công cụ như Claude Code
Tôi cũng đang tự làm một thứ tương tự lúc rảnh, mục đích là để hiểu agent sâu hơn và học Rust nữa
Tuy vậy, tôi vẫn muốn giữ khả năng cấu hình của
pi. Khả năng tự biến đổi và tạo công cụ mới của nó rất hữu ích, và tôi nghĩ những công cụ như thế này không nên có quyền chạy mã tùy ý thông quabashTất nhiên, nếu có quyền truy cập
editvàcargo runthì vẫn có thể thực thi mã tùy ý, nhưng nếu có việc gì mà một agent không cóbashcần làm thì tôi thiên về việc tạo công cụ ngay lúc đóVì vậy tôi quyết định cho phép tùy biến theo cách khác. Thư viện prompt ở
~/.config/hypernova/prompts/là một phương án thay thế đơn giản cho Skills, và các prompt tích hợp sẵn sẽ thay thế superpowers và frontend-design của ClaudeNhững tính năng có thể làm agent nặng hơn có thể bị tắt bằng feature flag khi biên dịch, và vì mã ngắn, dễ đọc nên nếu cần bạn có thể chạy zerostack trên chính mã nguồn zerostack để tạo một custom fork
Sau khá nhiều cân nhắc, mô hình quyền hạn được chia thành 4 mức như trong README, từ “Restrictive” không có lệnh nào cho tới “YOLO” nơi agent muốn làm gì thì làm, và bạn cũng có thể đặt regex cho việc gọi
bashtheo kiểu cho phép/hỏi/từ chối. Trong trường hợp này chỉ cần chạyzerostack -Rlà có thể buộc mọi công cụ đều phải xin quyềnTính năng agent có thể lập trình cũng đang được làm, nhưng chưa tới mức để công bố
Gần đây tôi có làm một bản kiểu nửa đùa nửa thật dưới 200 dòng: https://github.com/pnegahdar/nano
Nó có REPL, session, chạy không tương tác, phê duyệt các kiểu. Tôi nghĩ khi model ngày càng thông minh hơn thì ngoài trải nghiệm lập trình viên ra, tầm quan trọng của harness sẽ giảm đi
Có khi lúc nào đó tôi sẽ cho nó chạy trên SWE-bench
Tuần trước tôi cũng tự làm một cái để vui và học hỏi, và nó còn tích hợp được với
mcpServersđã cấu hình như hầu hết các coding agent khácTôi có ghi lại từng bước, cái gì cần và vì sao cần: https://nb1t.sh/building-a-real-agent-step-by-step/
“RAM footprint: ~8MB on an empty session, ~12MB when working”
Tôi thích đoạn này. Claude Code ngốn tới vài GB nên trên laptop cấu hình thấp khá là khó chịu
Thời gian khởi động dưới 0,5 giây và mức dùng RAM cũng rất thấp. Nó chạy tốt trên cả laptop 12 năm tuổi mà không bị chậm
Về bản chất, thứ gần như chỉ là một cỗ máy nối chuỗi thì không có lý do gì phải chậm trên bất kỳ thiết bị nào, kể cả phần cứng cũ
1: https://zed.dev/acp
Tôi sẽ thử khi về nhà. Công cụ nhẹ và nhanh tạo khác biệt rất lớn trong trải nghiệm code
Tôi tò mò cách tiếp cận bằng prompt trong thực tế so với kiểu kết hợp skill và sub-agent thông thường thì thế nào. Tôi hay dùng kiểu nếu build fail thì chạy skill
/fix-ci, rồi để sub-agent lôi lỗi, stack trace và log liên quan ra để xử lýNếu test tích hợp gặp vấn đề truy vấn DB thì agent có thể tự, hoặc tôi gợi ý nhẹ, gọi một skill truy cập DB chỉ đọc để điều tra. Khi cần đào sâu trong thời gian dài, tôi sẽ nói kiểu “hãy dùng Sonnet sub-agent và bảo nó debug hành vi này bằng skill truy vấn DB”
Skill cho thêm năng lực ngay tại chỗ, còn sub-agent giúp cô lập để tránh phình context. Có lẽ agent tự gọi chính nó qua
bashvới prompt khác cũng làm na ná được, nhưng có vẻ sẽ kém mượt hơn một chút, tôi phải tự kiểm tra mới biếtVí dụ một trong các prompt tích hợp là
/prompt debug, nó mở một agent tập trung vào debug, rồi từ đó bạn có thể trò chuyện như agent thường và quay lại agent code tiêu chuẩn bằng/prompt codeSub-agent hiện chưa được hỗ trợ vì toàn bộ agent đang chạy trong một buffer ngữ cảnh duy nhất để giữ cho nó nhẹ. Tuy vậy, các tác vụ cần khám phá nhiều thường làm phình context window, nên rất có thể sau này sẽ thêm sub-agent
Tôi cũng đã bảo Claude Code làm cho mình một thứ như vậy, và còn thêm cả line hashing của Dirac cho phần chỉnh sửa
Tôi dùng Rust, cũng từng nghĩ tới việc làm hook bằng plugin để nó có thể tự sửa chính mình, nhưng cuối cùng chốt lại theo hướng để nó tạo một file riêng ghi chi tiết các cải tiến, cập nhật mã nguồn rồi biên dịch lại
Vì vị trí mã nguồn là cố định nên agent có thể tự viết lại chính nó rồi build lại. Tôi đang dùng nó với DeepSeek 4 Flash chạy trên 2x RTX 6000 Pro và được khoảng 138 tok/s
Nói thật thì tôi gần như sao chép Pi, Dirac và OpenCode. Có kỹ thuật mới nào ở đây đáng để học lỏm không?
Tôi vừa thử một lúc và đúng là khá nhanh
Không biết bạn đang tìm cộng tác viên hay chỉ làm như một công cụ cá nhân thôi
Tuy nhiên tôi có gặp vài vấn đề khi thử model khác. Azure gpt-5.5 dù dùng endpoint tương thích OpenAI thì
max_tokensvẫn bị đổi thànhmax_completion_tokensnên không chạy đượcCũng có vẻ không có cách truyền custom header, nên tôi không thể chỉ định
reasoning_effortcho model DeepSeekNhững gì bạn nói nghe như bug khá rõ trong codebase, nên nếu được thì hãy mở GitHub issue riêng cho từng lỗi
Claude Code và Opencode chạy ổn trong môi trường của tôi
Cũng hơi buồn cười khi coding agent đang chạy trong datacenter với hơn 1000W điện và hơn 2TB bộ nhớ, vậy mà mọi người lại tập trung vào vài watt cuối cùng và vài trăm MB RAM trên laptop
Dù sao thì so với chi phí năng lượng để biên dịch code chắc cũng chẳng đáng là bao, nhưng làm cho nó nhanh và nhẹ hơn thì vẫn không có gì xấu
Mỗi lần dùng coding agent là pin tụt khá nhanh, điều này khá bất ngờ khi phần lớn công việc đâu có diễn ra trên laptop của tôi
Tối ưu coding agent phía client không phải để cứu khí hậu mà là để kéo dài thời gian làm việc. Thực ra xét tổng thể còn có thể tệ hơn cho khí hậu
Phần mềm chạy trên máy người khác không phải vấn đề của tôi. Tôi không kiểm soát được trên server của người khác đang chạy gì, và kể cả có kiểm soát được thì tôi cũng đâu trả tiền cho số RAM đó nên chẳng quan tâm
Còn RAM trên thiết bị của tôi thì tôi phải trả tiền. Nếu một TUI chỉ để hiển thị chưa tới 1KB văn bản mà lại chiếm vài GB bộ nhớ, làm app khác trên Windows bị OOM hoặc trên Linux phải swap xuống HDD khiến cả máy đơ ra, thì đương nhiên tôi phải quan tâm
Trong bối cảnh giá RAM thực tế tăng gấp 5 lần, còn các linh kiện khác cũng tăng 2~3 lần, thì tránh lãng phí bộ nhớ lại càng quan trọng
Đúng là model rất lớn và ngốn tài nguyên, nhưng harness có thể ảnh hưởng rất nhiều đến việc model bị dùng nhiều đến đâu
Ví dụ nếu harness có bộ công cụ mạnh thì model có thể làm việc hiệu quả hơn hẳn
Codebase nhỏ nên tôi ném nó vào DeepSeek v4 Flash trong Pi để rà xem có chỗ nguy hiểm nào không, và không thấy gì đáng lo lắm. Làm tốt đấy
Với dự án Rust, nếu không dặn model đừng sửa trực tiếp
Cargo.tomlmà hãy dùngcargo add, thì ngay cả Claude 4.7 Opus cũng gần như luôn thêm dependency cũTôi kiểm tra thủ công các dependency của dự án này thì thấy đều là bản mới nhất, khá tốt. Tất nhiên điều đó không có nghĩa là không có vấn đề nào ẩn trong dependency bắc cầu
Việc dùng LLM để review code rất nhanh sẽ thành chuyện gu cá nhân. Ví dụ khi nhìn bằng mắt thường, tôi thấy vài method qua lại giữa string và enum và nghĩ “chỗ này dùng
strumvới một#[derive]là xong nhỉ”. Thêm một crate không dependency có thể khiếnprovider.rsgọn hơn nhiềuCho vui, tôi để DeepSeek V4 Pro ở chế độ Max thinking “kiểm toán” codebase và nó nói không có dấu hiệu rõ ràng nào của telemetry ẩn. Tuy vậy, nó có chỉ ra rằng dự án đặt panic handler là
abort, và tôi có ý kiến khá mạnh về chuyện nàyCó lẽ là để tránh link
libunwindnhằm giảm vài KB kích thước binary, nhưng đổi lại binary sẽ dừng ngay khi crash và không cho người dùng stack trace. Tôi nghĩ tăng khoảng 50KiB kích thước binary để có thông tin debug hữu ích khi panic sẽ đáng hơnNgoài ra, nếu panic xảy ra trong tác vụ bất đồng bộ thì bạn không thể khôi phục để hiển thị lỗi bình thường mà toàn bộ process sẽ dừng ngay
Vì DeepSeek cứ liên tục thất bại ở một số logic di chuyển con trỏ cụ thể. Toàn bộ quá trình tối ưu bộ nhớ là do tôi tự kiểm soát, và như tôi đã nói ở bình luận khác, tôi kết hợp tối ưu từ compiler với việc dùng các crate Rust để tận dụng cấu trúc dữ liệu hiệu quả hơn
Thú vị là đúng hôm nay nó xuất hiện. Tôi cũng đang định bắt đầu viết một cái bằng Rust
Nhìn opencode trên project lớn rò rỉ bộ nhớ chậm chậm rồi leo lên 6GB và ngày càng chậm đi thì đúng là đáng kinh ngạc
Tôi sẽ thử xem. Trông hay đấy