1P by GN⁺ 4시간전 | ★ favorite | 댓글 1개
  • zerostack은 Rust로 작성된 최소형 코딩 에이전트로, 여러 LLM 제공자와 사용자 지정 제공자를 함께 지원함
  • 파일 읽기·쓰기·편집, grep, 파일 찾기, 디렉터리 목록, 권한 게이트가 붙은 Bash 실행, MCP, Exa 웹 도구를 제공함
  • 7천 LoC, 8.9MB 바이너리이며 RAM은 빈 세션 약 8MB·작업 중 약 12MB, CPU는 유휴 0.0%로 측정됨
  • 기본 제공자는 OpenRouter이고 cargo install zerostack으로 설치하며, --sandbox에서 Bash 격리를 쓰려면 bubblewrap이 필요함
  • code·plan·review내장 프롬프트, 4가지 권한 모드, 세션 재개, 반복 루프, Git worktrees 통합을 포함함

zerostack 개요

  • zerostack은 Rust로 작성된 최소형 코딩 에이전트이며, piopencode에서 영감을 받음
  • OpenRouter, OpenAI, Anthropic, Gemini, Ollama, 사용자 지정 제공자를 지원하는 다중 제공자 구조를 갖춤
  • 파일 읽기·쓰기·편집, grep, 파일 찾기, 디렉터리 목록 같은 파일 도구와 권한 게이트가 붙은 Bash 실행을 제공함
  • 세션 저장·로드·재개, 컨텍스트 창 유지를 위한 자동 압축, crossterm 기반 터미널 UI, MCP 서버 연결, Exa 기반 WebFetch·WebSearch 도구를 포함함
  • /worktree로 Git worktree 사이를 이동할 수 있고, 장기 작업을 위한 반복 루프도 통합됨

성능과 설치

  • zerostack은 약 7천 LoC 규모이며, 바이너리 크기는 8.9MB
  • RAM 사용량은 빈 세션 약 8MB, 작업 중 약 12MB로, opencode나 다른 JS 기반 코딩 에이전트의 약 300MB와 비교됨
  • CPU 사용량은 유휴 상태 0.0%, 도구 사용 중 약 1.5% 로 측정됐으며, Intel i5 7세대에서 opencode는 유휴 약 2%, 작업 중 약 20% 로 비교됨
  • 설치에는 Cargo와 git이 필요하며, 다음 명령을 사용함
    cargo install zerostack  
    
  • --sandbox 사용 시 모든 Bash 명령을 격리 환경에서 실행하려면 bubblewrap을 설치해야 함
    # Debian/Ubuntu  
    apt install bubblewrap  
    
    # Fedora  
    dnf install bubblewrap  
    
    # Arch  
    pacman -S bubblewrap  
    

빠른 시작

  • 기본 제공자는 OpenRouter이며, API 키는 환경 변수로 설정함
    export OPENROUTER_API_KEY="[api_key]"  
    
  • 대화형 세션은 기본 프롬프트 code로 실행됨
    zerostack  
    
  • 한 번만 실행하는 모드는 -p로 프롬프트를 전달함
    zerostack -p "Explain this project"  
    
  • 마지막 세션은 -c로 이어서 실행함
    zerostack -c  
    
  • 제공자와 모델을 명시할 수 있음
    zerostack --provider openrouter --model deepseek/deepseek-v4-flash  
    

프롬프트 시스템

  • zerostack은 에이전트의 동작과 말투를 바꾸는 내장 시스템 프롬프트 세트를 포함함
  • 목표는 superpowerClaude 공식 skills를 대체할 수 있는 프롬프트 제품군을 만드는 것임
  • /prompt로 등록된 프롬프트를 나열하거나 다른 프롬프트로 전환할 수 있음
  • 내장 프롬프트

    • code는 기본값이며, 전체 파일·Bash 도구 접근과 TDD 워크플로를 사용하는 코딩 모드임
    • plan은 코드를 쓰지 않고 탐색한 뒤 계획을 만드는 계획 전용 모드임
    • review는 정확성, 설계, 테스트, 영향을 검토하는 코드 리뷰 모드임
    • debug는 수정안을 내기 전에 근본 원인을 찾는 디버그 모드임
    • ask는 읽기 전용 모드이며, read·grep·glob만 허용하고 쓰기나 Bash는 허용하지 않음
    • brainstorm은 코드를 작성하지 않고 아이디어를 탐색하고 설계를 제시하는 설계 전용 모드임
    • frontend-design는 독특하고 프로덕션 수준의 UI를 위한 프론트엔드 디자인 모드임
    • review-security는 악용 가능한 취약점을 찾는 보안 리뷰 모드임
    • simplify는 동작을 바꾸지 않고 명확성을 높이는 코드 단순화 모드임
    • write-prompt는 에이전트 프롬프트를 만들고 최적화하는 프롬프트 작성 모드임
    • 사용자 지정 프롬프트는 $XDG_CONFIG_HOME/zerostack/prompts/에 Markdown 파일을 두고 이름으로 참조해 만들 수 있음
    • 프로젝트 루트나 상위 디렉터리의 AGENTS.md 또는 CLAUDE.md를 자동으로 읽어 시스템 프롬프트에 삽입하며, -n 또는 --no-context-files로 비활성화 가능함

권한 시스템

  • zerostack은 가장 안전한 방식부터 가장 허용적인 방식까지 4가지 권한 모드를 제공함
  • 권한 모드

    • restrictive 또는 -R은 설정에서 명시적으로 허용하지 않은 모든 도구 동작마다 승인을 요청함
    • standard는 기본값이며, ls, cd, git log, cargo check 같은 안전한 명령은 자동 승인하고 쓰기와 파괴적 작업은 확인을 요청함
    • accept-all 또는 --accept-all은 작업 디렉터리 안의 모든 작업을 자동 승인하고 외부 경로는 확인을 요청함
    • yolo 또는 --yolo는 프롬프트 없이 모든 작업을 자동 승인함
    • 설정 파일에서 도구별 glob 패턴을 지정해 권한을 세밀하게 구성할 수 있음
    • 예를 들어 write **.rs는 자동 허용하면서 다른 파일 쓰기는 항상 확인하도록 만들 수 있음
    • 세션 허용 목록은 승인된 결정을 세션 동안 유지해 같은 작업을 반복 확인하지 않게 함
    • 동일한 도구 호출이 3회 이상 반복되면 doom-loop 감지가 경고 프롬프트를 띄우거나 설정에 따라 거부해, 에이전트가 파괴적 작업을 반복하지 못하게 막음

슬래시 명령과 세션 관리

  • 주요 슬래시 명령은 모델, 사고 수준, 대화, 세션, 루프, 프롬프트, 권한 모드를 제어함
  • /model은 모델을 전환하고, /thinking은 사고 수준을 설정함
  • /clear는 대화를 지우고, /session은 세션을 나열·저장·로드함
  • /loop는 반복 프롬프트를 예약하고, /prompt는 에이전트 프롬프트를 나열하거나 변경함
  • /mode는 권한 시스템 모드를 설정하며, 전체 명령은 /help로 확인함
  • 세션은 $XDG_DATA_HOME/zerostack/sessions/에 저장됨
  • -c는 가장 최근 세션을 재개하고, -r은 세션을 탐색해 선택하며, --session <id>는 특정 세션을 로드함

반복 루프

  • zerostack은 장기 작업을 위한 반복 코딩 루프를 포함함
  • 에이전트는 작업을 반복해서 읽고, 계획에서 항목을 고르고, 작업을 수행하고, 테스트를 실행하고, 계획을 갱신하며, 작업 완료 또는 반복 제한 도달까지 루프를 계속함
  • 루프 시스템은 실험적 기능
  • 루프 사용법

    • /loop Implement the user authentication system은 지정한 프롬프트로 루프를 시작함
    • /loop stop은 활성 루프를 중지함
    • /loop status는 현재 루프 상태를 표시함
    • 각 반복에는 원래 작업, 변화하는 LOOP_PLAN.md, 이전 반복 요약, 검증 출력이 포함됨
    • 루프가 활성화된 동안에는 슬래시 명령이 아닌 입력이 차단됨
  • CLI 기반 헤드리스 루프

    • 다음 명령으로 헤드리스 루프를 실행할 수 있음
      zerostack --loop --loop-prompt "Refactor the API" --loop-max 10 --loop-run "cargo test"  
      
    • --loop는 헤드리스 루프 모드를 켬
    • --loop-prompt <text>는 각 반복에 사용할 프롬프트를 지정함
    • --loop-plan <path>는 사용자 지정 계획 파일 경로를 지정하며, 기본값은 LOOP_PLAN.md
    • --loop-max <N>은 최대 반복 횟수를 지정하며, 기본값은 제한 없음임
    • --loop-run <cmd>는 각 반복 뒤 실행할 검증 명령을 지정함

Git worktrees 통합

  • zerostack은 브랜치별 작업 흐름을 git worktrees로 제공함
  • 채팅 UI 안에서 worktree를 만들고, 그 안에서 작업하고, 병합하고, 빠져나올 수 있음
  • Git worktrees 통합은 실험적 기능
  • worktree 명령

    • /worktree <name><name> 브랜치에 git worktree를 만들고 그곳으로 이동하며, 이미 존재하면 생성을 건너뜀
    • /wt-merge [branch]는 worktree 브랜치를 [branch]로 병합하고, push하고, 정리한 뒤 메인 저장소로 돌아감
    • /wt-exit은 병합하지 않고 메인 저장소로 돌아감
  • 예시 워크플로

    • /worktree feature-x는 새 브랜치와 worktree 디렉터리를 만들고 그곳으로 이동함
    • 이후 zerostack을 평소처럼 사용하면 변경 사항이 feature 브랜치에 남음
    • /wt-merge는 에이전트가 브랜치를 병합하고 push하고 정리한 뒤 메인 저장소로 돌아가게 함
    • /wt-exit은 병합 없이 즉시 메인 저장소로 돌아감

지원 제공자와 라이선스

  • 기본 제공자는 OpenRouter
  • OpenAI 호환 제공자로 vLLM, LiteLLM 등을 지원함
  • Anthropic, Gemini, Ollama를 지원함
  • 사용자 지정 제공자는 $XDG_CONFIG_HOME/zerostack/config.json에서 임의의 base URL과 API 키 환경 변수로 구성할 수 있음
  • 라이선스는 GPL-3.0-only

댓글과 토론

Hacker News 의견들
  • 이런 도구를 잘 몰라서 그런데, Claude Code 같은 모델/도구에 비해 어떤 장점이 있는지 궁금함

  • 여가 시간에 비슷한 걸 직접 만들고 있었고, 에이전트를 더 깊이 이해하고 Rust도 배우려는 목적이었음
    다만 pi설정 가능성은 유지하고 싶음. 스스로 변형하고 새 도구를 생성하는 능력이 매우 유용하고, 이런 도구들이 bash를 통한 임의 코드 실행 권한을 가져서는 안 된다고 보기 때문임
    물론 editcargo run에 접근 가능하면 여전히 임의 코드 실행이 가능하긴 하지만, bash 없는 에이전트가 해야 할 일이 생기면 그때그때 도구를 생성하는 편임

    • 이 문제를 생각해 봤지만, Pi는 TypeScript 기반이라 스크립트 같은 환경을 가질 수 있는 반면 Rust는 컴파일 언어라 제약이 있음
      그래서 다른 방식으로 사용자화를 허용하기로 했음. ~/.config/hypernova/prompts/의 프롬프트 라이브러리는 Skills의 단순한 대안이고, 내장 프롬프트가 superpowers와 Claude의 frontend-design을 대체해야 함
      에이전트를 무겁게 만들 수 있는 기능은 컴파일 시 기능 플래그로 끌 수 있고, 코드가 짧고 읽기 쉬워서 필요하면 zerostack 자체 소스에 zerostack을 돌려 커스텀 포크를 만들 수 있음
      권한 모델은 README에 보이듯 많은 고민 끝에, 명령이 없는 “Restrictive”부터 에이전트가 원하는 대로 하는 “YOLO”까지 4단계로 만들었고, bash 호출에 대해 허용/질문/거부 정규식도 둘 수 있음. 이 경우에는 zerostack -R만 실행하면 모든 도구가 권한을 묻게 강제 가능함
      프로그래밍 가능한 에이전트 기능도 작업 중이지만 아직 발표할 단계는 아님
    • 나도 같은 걸 Zig로 만들고 있음
  • 최근에 장난 반 진심 반으로 200줄 미만짜리도 만들었음: https://github.com/pnegahdar/nano
    REPL, 세션, 비대화형 실행, 승인 같은 기능이 들어 있음. 모델이 똑똑해질수록 개발자 경험을 제외하면 하네스의 중요성은 줄어든다고 봄
    언젠가 SWE-bench에 돌려볼지도 모르겠음

    • 200줄, 실제로는 190줄만으로 만들었다니 정말 멋짐
      나도 지난주에 재미와 학습용으로 하나 직접 만들었고, 대부분의 코딩 에이전트처럼 설정된 mcpServers와의 통합까지 동작함
      단계별로 무엇이 왜 필요한지 정리해 두었음: https://nb1t.sh/building-a-real-agent-step-by-step/
  • “RAM footprint: ~8MB on an empty session, ~12MB when working”
    이 부분이 좋음. Claude Code는 몇 GB씩 써서 저사양 노트북에서는 꽤 짜증남

    • Go로 에이전트 프레임워크를 만들고 있는데 매우 가벼움
      시작 시간이 0.5초 미만이고 RAM 사용량도 아주 낮음. 12년 된 노트북에서도 느려지지 않고 잘 돌아감
      본질적으로 문자열 이어붙이기 엔진에 가까운 것이 구형 하드웨어를 포함해 어떤 장비에서도 느릴 이유는 없음
    • Zed로 옮겨 보려는 중인데 Agent Client Protocol이 꽤 괜찮아 보임. Claude Code가 이 방식을 거치면 메모리 압박이 얼마나 줄어들지 궁금함
      1: https://zed.dev/acp
    • 맞음. 이 사실 하나만으로도 많은 사람이 한번 써 보게 될 것 같음
    • 메모리 사용량이 훌륭해서, 이제 shellbox.dev의 x1 같은 아주 작은 인스턴스에서도 코딩 에이전트를 돌릴 수 있음
    • LSP 플러그인 같은 게 같이 돌고 있는 건 아닌지 확인해 봐야 함
  • 집에 가면 써 봐야겠음. 가볍고 빠른 도구는 코딩 경험에 큰 차이를 만듦
    프롬프트 방식이 실제로 일반적인 스킬과 하위 에이전트 조합과 비교해 어떤지 궁금함. 나는 빌드 실패가 있으면 /fix-ci 스킬을 실행하고, 하위 에이전트가 오류 메시지·스택 추적·관련 로그를 뽑아 문제를 풀게 하는 식으로 자주 섞어 씀
    통합 테스트에서 DB 쿼리 문제가 나면 에이전트가 직접, 또는 내가 살짝 유도해서 읽기 전용 DB 접근 스킬을 불러 조사하기도 함. 오래 깊게 파야 할 때는 “Sonnet 하위 에이전트를 쓰고 DB 쿼리 스킬로 이 동작을 디버그하라고 지시해” 같은 식으로 말함
    스킬은 즉석에서 추가 능력을 주고, 하위 에이전트는 문맥 비대를 막기 위해 격리해 줌. 에이전트가 bash로 자기 자신을 다른 프롬프트와 함께 실행하면 비슷하게는 될 수 있겠지만 조금 덜 매끄러울 것 같아 직접 확인해 봐야겠음

    • 대부분은 스킬처럼 쓰지만, “명령”보다는 환경으로 생각하면 됨
      예를 들어 통합 프롬프트 중 하나인 /prompt debug는 디버그 중심 에이전트를 열고, 그 상태에서 일반 에이전트처럼 대화하다가 /prompt code로 표준 코딩 에이전트로 돌아갈 수 있음
      하위 에이전트는 현재 전체 에이전트가 하나의 문맥 버퍼에서 돌아가므로, 가볍게 유지하려고 아직 지원하지 않음. 다만 탐색이 많은 작업은 문맥 창을 자주 부풀리기 때문에 하위 에이전트가 추가될 가능성은 큼
  • 나도 Claude Code로 이런 걸 하나 만들게 했고, 편집에는 Dirac의 라인 해싱도 넣었음
    Rust를 썼고, 플러그인으로 훅을 구현해 자기 수정이 가능하게 하자는 생각도 했지만, 결국 개선 사항에 대한 상세 정보를 별도 파일에 만들게 하고 소스 코드를 갱신한 뒤 다시 컴파일하는 방식으로 정리함
    소스 코드 위치가 고정되어 있어서 에이전트가 자기 자신을 다시 쓰고 빌드할 수 있음. 2x RTX 6000 Pro에서 DeepSeek 4 Flash를 돌리며 쓰고 있고 대략 138 tok/s 정도 나옴
    솔직히 Pi, Dirac, OpenCode를 베낀 셈임. 여기서 훔쳐 갈 만한 새로운 기법이 있나?

    • 가벼운 것 외에 흥미로운 기능으로는 프롬프트 라이브러리, Git worktree 통합, Ralph Wiggum 루프 통합을 넣었음
    • GitHub에 공개되어 있는지 궁금함
  • 잠깐 써 봤는데 실제로 꽤 빨랐음
    기여자를 찾는 중인지, 아니면 개인 도구로 만들고 있는지도 궁금함
    다만 다른 모델을 쓰려다 몇 가지 문제를 만났음. Azure의 gpt-5.5는 OpenAI 호환 엔드포인트를 써도 max_tokensmax_completion_tokens로 바뀌어서 동작하지 않음
    커스텀 헤더를 넘길 방법도 없어 보여서 DeepSeek 모델에 reasoning_effort를 지정할 수 없었음

    • PR은 받을 생각임
      말한 내용은 코드베이스의 명확한 버그라서, 가능하면 각 버그별로 GitHub 이슈를 열어 주면 좋겠음
  • Claude Code와 Opencode는 내 환경에서는 잘 동작함
    코딩 에이전트는 데이터센터에서 1000W 이상 전력과 2TB 이상 메모리를 써서 돌아가는데, 정작 사람들은 노트북의 마지막 몇 와트와 몇백 MB 메모리에 집중한다는 점이 조금 웃김
    어차피 코드 컴파일 에너지 비용에 비하면 묻히긴 하겠지만, 그래도 더 빠르고 가볍게 만드는 게 나쁘지는 않음

    • 데이터센터는 전용 전력선으로 돌아가지만, 내 노트북은 배터리로 돌아감
      지금 코딩 에이전트를 쓰면 배터리가 꽤 빨리 닳는데, 대부분의 작업이 내 노트북에서 일어나지 않는다는 점을 생각하면 놀라움
      클라이언트 쪽 코딩 에이전트를 효율화하는 건 기후를 구하려는 게 아니라 근무 시간을 늘리려는 것임. 실제로는 기후에 더 나쁠 수도 있음
    • 당연히 사람들은 자기 컴퓨터에서 돌아가는 소프트웨어에 집중함
      남의 컴퓨터에서 돌아가는 소프트웨어는 내 문제가 아님. 남의 서버에서 무엇이 도는지 통제할 수 없고, 설령 가능해도 그 RAM 비용을 내가 내는 게 아니니 신경 쓰지 않음
      반면 내 장비의 RAM은 내가 비용을 냄. 1KB 미만의 텍스트를 표시하는 TUI가 몇 GB 메모리를 차지해서 Windows에서 다른 앱을 OOM으로 죽이거나, Linux에서 HDD로 스와핑하며 전체 머신을 멈추게 만들면 신경 쓸 수밖에 없음
      RAM 가격이 실제로 5배, 다른 부품 가격도 2~3배 오른 상황에서는 메모리 낭비를 피하는 일이 특히 중요함
    • 이건 지나치게 단순화한 말임
      모델이 거대하고 자원을 많이 쓰는 건 맞지만, 하네스는 모델이 얼마나 많이 쓰이는지에 큰 영향을 줄 수 있음
      예를 들어 하네스에 강력한 도구 세트가 있으면 모델이 훨씬 효율적으로 작업할 수 있음
  • 코드베이스가 작아서 Pi 안의 DeepSeek v4 Flash에 넘겨 위험한 부분이 있는지 훑게 했고, 딱히 걱정되는 건 찾지 못했음. 잘 만들었음

    • OP가 코드 상당 부분을 DeepSeek V4 Flash로 생성했다고 해서 오래된 의존성이 있는지 확인해 봤음
      Rust 프로젝트에서는 모델에게 Cargo.toml을 직접 수정하지 말고 cargo add를 쓰라고 지시하지 않으면, Claude 4.7 Opus조차 거의 항상 오래된 의존성을 추가하는 경험이 있었음
      이 프로젝트의 의존성을 수동으로 확인해 보니 모두 최신 버전이라 좋았음. 물론 전이 의존성 안에 문제가 숨어 있지 않다는 뜻은 아님
      LLM으로 코드 리뷰를 시키는 문제는 금방 취향 싸움이 될 수 있음. 예를 들어 코드를 눈으로 보다가 문자열과 enum을 오가는 몇몇 메서드는 “이건 strum으로 #[derive] 하나면 되지 않았을까”라는 생각이 들었음. 의존성 없는 크레이트 하나를 추가하는 대신 provider.rs가 훨씬 간결해질 수 있음
      재미로 DeepSeek V4 Pro의 Max thinking으로 코드베이스를 “감사”하게 해 봤는데, 숨은 원격 측정의 명백한 흔적은 없다고 했음. 다만 프로젝트가 패닉 핸들러를 abort로 설정한 점을 짚었고, 이 부분에는 강한 의견이 있음
      아마 바이너리 크기 몇 KB를 줄이려고 libunwind 링크를 피한 것 같지만, 그러면 충돌 시 즉시 중단되고 사용자에게 스택 추적을 주지 않는 바이너리가 됨. 패닉 때 유용한 디버그 정보를 얻을 수 있다면 바이너리가 약 50KiB 커지는 편이 낫다고 봄
      또한 비동기 작업에서 패닉이 나면 복구해서 일반 오류 메시지를 보여 줄 수 없고, 전체 프로세스가 바로 중단됨
    • 코드의 꽤 큰 부분은 DeepSeek v4 Flash가 작성했고, TUI 로직 일부는 직접 작성했음
      DeepSeek가 특정 커서 이동 로직에서 계속 실패했기 때문임. 메모리 최적화 과정은 전부 직접 관리했고, 다른 댓글에 쓴 것처럼 컴파일러 최적화와 더 효율적인 자료구조를 활용하기 위한 Rust 크레이트 사용을 조합했음
    • “Pi 안의 DeepSeek v4 Flash에 넘겨 위험한 부분을 훑게 했다”는 방식은 프롬프트 주입 때문에 꽤 허술한 조사 아닌가?
  • 마침 오늘 나왔다는 게 재미있음. 나도 막 Rust로 하나 쓰기 시작하려던 참이었음
    큰 프로젝트에서 opencode가 천천히 메모리를 누수하다가 6GB까지 올라가고 점점 느려지는 걸 보면 놀라울 정도임
    한번 확인해 보겠음. 멋져 보임

    • 맞음. 이 프로젝트는 오래된 노트북에서 Firefox와 opencode 인스턴스를 2개 넘게 같이 띄웠다가 OOM killer가 발동한 데서 시작했음