이 저장소가 대체 무엇인가.
Claude Code는 Anthropic 모델에, Codex는 OpenAI 모델에 사실상 묶여 있다. zero의 출발점은 정반대다. 에이전트의 "실행 엔진(도구 호출·파일 편집·셸 실행·권한 통제)"과 "두뇌(LLM provider)"를 완전히 분리해서, 두뇌만 /model 한 줄로 갈아끼울 수 있게 만들었다.
그리고 "내 컴퓨터에서 돈다"는 말을 진지하게 받아들여, 에이전트가 실수하거나 악의적 프롬프트에 넘어가도 워크스페이스 밖 파일을 못 건드리고, 네트워크를 못 열고, 위험한 셸 명령은 사용자 승인을 거치도록 OS 커널 기능으로 강제한다. 세션·비밀키·기록은 텔레메트리로 업로드되지 않고 로컬에만 남는다.
go test를 실행하며 알아서 목표에 도달하려 한다. zero는 이 루프를 터미널(TUI)과 스크립트(zero exec) 양쪽에서 굴린다.Claude Code·Codex가 즐비한데 왜 하필 zero인가.
터미널 코딩 에이전트는 이미 레드오션이다(Claude Code, OpenAI Codex, aider, opencode…). 그럼에도 zero가 TrendShift 상위에 오른 이유는 세 가지 "소유권(ownership)" 포인트를 하나의 도구에 모두 담았기 때문이다: 모델 소유(어떤 LLM이든), 데이터 소유(전부 로컬), 실행 통제 소유(OS 샌드박스).
| 기준 | Claude Code | aider | Gitlawb/zero |
|---|---|---|---|
| 모델 선택 | Anthropic 위주 | 다중 provider | ✓ 25종+ (OpenAI/Anthropic/Gemini/로컬) |
| 구현 언어 | Node/TS | Python | ✓ Go — 단일 정적 바이너리 |
| OS 샌드박스 | 제한적 | 없음(권한 프롬프트) | ✓ Linux Landlock/seccomp + macOS 로그감시 |
| 헤드리스/CI | 가능 | 가능 | ✓ exec + stream-JSON + 종료코드 |
| 서브에이전트 | 일부 | 없음 | ✓ specialist + swarm(병렬 팀) |
| 확장 | MCP/스킬 | 제한적 | ✓ MCP·skills·plugins·hooks 전부 |
| 데이터 위치 | 일부 클라우드 | 로컬 | ✓ 100% 로컬 세션·비밀키 |
OpenAI/Anthropic/Google 세 개의 네이티브 provider 클라이언트를 직접 구현하고, 그 외는 "OpenAI 호환 / Anthropic 호환" 어댑터로 흡수한다. 그래서 값싼 로컬 모델(Ollama)로 초안을 뽑고, 어려운 부분만 /model로 강력한 모델로 올리는 식의 비용 최적화가 자연스럽다.
go.mod을 열어보면 무거운 AI SDK가 하나도 없다. 의존성은 대부분 charm 계열 TUI 라이브러리(bubbletea/lipgloss)와 문법 하이라이터(chroma), 셸 파서(mvdan/sh) 정도. HTTP로 provider API를 직접 호출하기 때문에 결과물이 의존성 없는 실행파일 하나로 나온다. npm 래퍼는 이 바이너리를 릴리스에서 내려받아 설치할 뿐이다.
README의 안전 철학이 명확하다 — 워크스페이스 읽기는 기본 허용, 쓰기는 워크스페이스 안으로 제한, 셸/네트워크/파괴적 명령/워크스페이스 밖 쓰기는 권한 게이트. --add-dir로 필요한 디렉토리만 골라 쓰기 권한을 준다. 이걸 커널 기능(Landlock)으로 강제하니 프롬프트 인젝션에도 방어선이 하나 더 있다.
첫 릴리스가 2026-07-02다. CHANGELOG상 아직 SemVer 안정화 전이며, 소스 빌드는 버전을 dev로 보고한다. 프로덕션에 무겁게 물리기보다는 "아키텍처를 공부하고 실험"하기에 좋은 시점이다. 스타·이슈 수도 초기 단계.
go.mod과 internal/ 트리에서 실제로 읽어낸 구성.
| 구분 | 선택 | 메모 |
|---|---|---|
| 언어 | Go 1.25+ (toolchain 1.26) | 정적 단일 바이너리, 크로스컴파일 쉬움 |
| 배포 | GitHub Releases + npm 래퍼 | @gitlawb/zero postinstall이 바이너리 다운로드 |
| 지원 OS | Linux · macOS · Windows | x64 · arm64 |
| 라이선스 | MIT | 완전 오픈 |
| 라이브러리 | 역할 |
|---|---|
| bubbletea/v2 | Elm 스타일 상태머신 기반 터미널 앱 프레임워크(메인 이벤트 루프) |
| bubbles/v2 | 입력창·리스트·뷰포트 등 재사용 UI 컴포넌트 |
| lipgloss/v2 | 터미널 스타일링(색·박스·레이아웃) — 12종 테마의 뿌리 |
| chroma/v2 | 코드 문법 하이라이팅(diff·코드블록 렌더) |
| mvdan.cc/sh/v3 | 순수 Go 셸 파서 — 셸 명령을 안전하게 분석/프리픽스 판정 |
| ledongthuc/pdf | PDF 텍스트 추출(문서 읽기 도구) |
zero의 구조는 "자동차"에 가깝다. 엔진(engine)은 provider(LLM)로 갈아끼울 수 있고, 운전대·계기판(TUI)은 charm 라이브러리로 만들었고, 안전벨트·에어백(sandbox/permission)은 OS 커널이 잡아준다. 그리고 정비 매뉴얼(skills/specialist/hooks)을 꽂아 기능을 확장한다.
internal/providers/ 아래에 anthropic/, openai/, gemini/ 세 개의 네이티브 클라이언트가 있고, factory.go가 설정에 따라 알맞은 클라이언트를 만든다. 코드를 열어보면 ProviderKindOpenAI, ProviderKindOpenAICompatible, ProviderKindAnthropic, ProviderKindAnthropicCompat, ProviderKindGoogle 같은 종류(kind)로 갈라진다. 즉 "OpenAI 호환"이라는 사실상의 표준 프로토콜 하나만 맞으면 어떤 신규 모델이든 흡수된다. OAuth 로그인(zero auth), 모델 능력 카탈로그(modelregistry), provider 건강검진(providerhealth), 자동 탐지(providermodeldiscovery)까지 별도 패키지로 분리돼 있다.
| 패키지 | 무엇 |
|---|---|
| internal/mcp | MCP 서버 연결 — 외부 도구를 표준 프로토콜로 흡수. zero serve --mcp로 zero 자신을 MCP 서버로도 노출 |
| internal/skills | 마크다운으로 쓰는 "지시 스킬"(재사용 프롬프트/절차) |
| internal/plugins | 플러그인 관리 |
| internal/hooks | 수명주기 훅 — 도구 실행 전/후에 커스텀 로직 삽입 |
| internal/specialist | 전문화된 서브에이전트(리뷰·회계 등) 생성·실행 |
| internal/swarm | 여러 에이전트를 팀으로 묶어 병렬 협업(coordinator·mailbox·scheduler) |
두 개의 심장: (1) 도구를 부르며 목표에 다가가는 루프, (2) 그 도구를 커널이 가두는 샌드박스.
루프는 "LLM에게 물어보고 → 도구를 실행하고 → 결과를 다시 넣는" 것을 반복한다. 코드를 보면 단순한 while가 아니라 실전에서 부딪히는 함정들을 하나하나 방어한다:
compaction.go + 보존 규칙).compaction_preserve)까지 규칙으로 관리한다. "긴 작업을 시켜도 에이전트가 앞부분을 까먹지 않게" 하는 핵심 장치.
대부분의 코딩 에이전트가 "이 명령 실행할까요?"라는 프롬프트로만 안전을 지킨다면, zero는 여기에 OS 커널 수준의 강제를 얹는다. Linux에서는 Landlock(파일시스템 접근을 커널이 제한)과 seccomp(허용된 시스템콜만 통과)를 쓴다. 코드를 보면 도구 실행 직전에 PR_SET_NO_NEW_PRIVS를 걸어 권한 상승을 원천 차단한 뒤, 워크스페이스 밖 쓰기·네트워크 열기를 커널에 등록한 규칙으로 막는다.
// sandbox/landlock_linux.go — 실제 구조(요약) func ApplyLandlockFilesystemProfile(profile, cwd) error { // 1) 이 프로세스는 이제 권한을 더 못 얻는다 unix.Prctl(unix.PR_SET_NO_NEW_PRIVS, 1, ...) // 2) 파일시스템 규칙: 워크스페이스만 쓰기 허용 // 3) 네트워크 차단(NetworkDeny)이면 소켓 개설 봉쇄 // → 이후 caller가 최종 명령을 exec 한다 }
권한 프롬프트가 "문 앞에서 신분증 확인하는 경비원"이라면, 커널 샌드박스는 "애초에 다른 방으로 통하는 문 자체를 벽으로 막아버린 것"이다. 경비원은 속일 수 있어도(프롬프트 인젝션), 벽은 못 뚫는다. zero는 둘 다 쓴다 — 승인 프롬프트 + 커널 벽.
하나의 큰 문제를 전문 서브에이전트에게 위임한다. internal/specialist/에는 코드 리뷰·회계 같은 역할별 실행기가 있고, internal/swarm/은 여러 멤버 에이전트를 coordinator가 지휘하고 mailbox로 메시지를 주고받으며 scheduler가 작업을 배분하는 병렬 팀 협업 구조다. 메인 에이전트가 지휘자, 서브들이 일꾼인 셈.
zero exec는 TUI 없이 스크립트로 돌리는 모드다. --input-format stream-json / --output-format stream-json으로 JSON 라인 스트림을 표준입출력으로 주고받아 CI 파이프라인에 물릴 수 있고, 의미 있는 종료 코드를 돌려준다. --worktree로 격리된 git worktree에서 실험하고, --use-spec로 "먼저 계획을 세우고 실행"하는 spec-first 방식도 지원한다.
internal/ 아래 60여 개 패키지 — 어디에 무엇이 있나.
cmd/zero/main.go(11줄, 얇음) → internal/agent/loop.go(에이전트 심장) → internal/tools/registry.go(도구가 어떻게 등록되나) → internal/sandbox/engine.go(샌드박스 엔진) → internal/providers/factory.go(provider가 어떻게 만들어지나) 순으로 보면 전체 그림이 잡힌다. _test.go 파일이 매우 많은데(패키지마다 다수), 이건 동작 명세서 역할을 하니 함께 읽으면 이해가 빠르다.
이 저장소에서 실제로 뽑아 배울 수 있는 것들.
bubbletea의 Elm 아키텍처(Model-Update-View)로 대화형 터미널 앱을 만드는 정석을 볼 수 있다. 슬래시 커맨드 자동완성, 실시간 도구 렌더링, 스크롤백, 테마 라이브 프리뷰 같은 UX가 어떻게 상태머신으로 구현되는지 배운다.
서로 다른 API(OpenAI Chat/Responses, Anthropic Messages, Gemini)를 하나의 내부 인터페이스로 통합하는 법. "OpenAI 호환/Anthropic 호환"이라는 사실상의 표준을 축으로 신규 provider를 어댑터로 흡수하는 factory 패턴이 교과서적이다.
가장 희소가치 높은 학습 포인트. Linux Landlock LSM, seccomp-bpf, PR_SET_NO_NEW_PRIVS, macOS의 sandbox-exec+로그 감시, Windows 헬퍼 프로세스까지 — "신뢰할 수 없는 코드를 어떻게 커널로 가두나"를 실제 코드로 공부할 수 있다. 보안·인프라 지망생에게 특히 값지다.
맥락 압축, 무한루프 방지, 스트림 정체 재시도, 이미지 거부 감지, 권한 스코프 — LLM 에이전트를 "데모"가 아닌 "제품"으로 만들 때 부딪히는 현실 문제와 그 해법이 internal/agent의 테스트 파일 이름에 고스란히 드러난다.
MCP 클라이언트/서버 양방향 구현, 마크다운 스킬, 수명주기 훅, 플러그인을 한 CLI에 모두 태우는 아키텍처. 자신만의 에이전트 확장을 설계할 때 참고 지도가 된다.
1) go run ./cmd/zero로 소스 빌드해 로컬 Ollama 모델을 붙여본다. 2) internal/tools/에서 도구 하나(예: grep.go)를 골라 어떻게 등록·실행·결과 반환되는지 추적한다. 3) zero exec --output-format stream-json으로 출력 JSON 스키마를 관찰한다.
돌리려면·빌드하려면 무엇이 필요한가.
| 항목 | 요구 |
|---|---|
| 실행(설치판) | Linux/macOS/Windows(x64·arm64) — 바이너리 하나면 끝 |
| 소스 빌드 | Go 1.25+ (toolchain 1.26). go build -o zero ./cmd/zero |
| Linux 네이티브 샌드박스 | zero-linux-sandbox 헬퍼를 같은 PATH에 함께 배치 |
| npm 설치 | Node ≥ 18 — npm i -g @gitlawb/zero(postinstall이 바이너리 다운로드) |
| Bun 설치 | lifecycle 스크립트 미실행 → 헬퍼 수동 실행 또는 trustedDependencies 지정 |
| 클라우드 모델 | OPENAI_API_KEY/ANTHROPIC_API_KEY/GEMINI_API_KEY 등 환경변수 |
| 로컬 모델 | Ollama 또는 LM Studio 구동 후 zero providers detect |
Bun은 기본적으로 postinstall을 실행하지 않아 바이너리가 안 받아진다("No native binary found" 에러). node node_modules/@gitlawb/zero/scripts/postinstall.mjs를 수동 실행하거나 package.json에 "trustedDependencies": ["@gitlawb/zero"]를 넣어야 한다.
난이도별로 손을 움직여 보자.
Ollama에 작은 모델(예: qwen2.5-coder)을 받고, 소스 빌드한 zero를 붙여 zero exec "이 저장소의 구조를 요약해줘"를 실행한다. 클라우드 키 없이도 완전 로컬로 에이전트가 도는 걸 체험. zero doctor로 연결 상태를 점검한다.
zero sandbox policy와 zero sandbox grants list를 실행해 현재 어떤 경로에 쓰기가 허용되는지 확인한다. 그다음 --add-dir ../other로 디렉토리를 추가하면 grants가 어떻게 바뀌는지 비교한다.
zero exec --output-format stream-json "hello" 출력을 파일로 저장하고, docs/STREAM_JSON_PROTOCOL.md와 대조하며 각 이벤트(메시지·도구호출·결과) 스키마를 표로 정리한다. 이후 자신만의 파서를 짜서 토큰 사용량을 집계해 본다.
zero skills로 마크다운 스킬을 하나 정의한다(예: "커밋 메시지를 Conventional Commits로 쓰기"). 에이전트가 그 스킬을 불러 동작이 바뀌는지 확인하고, hook을 하나 걸어 도구 실행 전 로그를 남겨본다.
internal/providers/openai/provider.go를 정독해 요청/응답 변환·스트리밍·finish reason 처리를 파악한 뒤, "OpenAI 호환" 신규 엔드포인트(예: 로컬 vLLM)를 설정만으로 붙여본다. 여유가 되면 internal/agent/loop.go의 스트림 정체 재시도 로직을 직접 트레이스한다.
zero를 제대로 이해하려면 곁들이면 좋은 순서.
| 주차 | 주제 | 학습 내용 |
|---|---|---|
| 1주차 | Go + TUI | Go 기본 문법, goroutine/channel, bubbletea의 Model-Update-View 패턴으로 미니 TUI 만들기 |
| 2주차 | LLM 도구 호출 | function/tool calling 개념, OpenAI·Anthropic 메시지 포맷 차이, 스트리밍 응답 파싱 |
| 3주차 | 에이전트 루프 | ReAct 패턴(생각→행동→관찰), 컨텍스트 관리·압축, 무한루프/에러 복구 설계 |
| 4주차 | OS 샌드박싱 | Linux Landlock·seccomp-bpf, no_new_privs, macOS sandbox-exec — 최소권한 원칙 |
| 5주차 | MCP & 확장 | Model Context Protocol 스펙, MCP 서버/클라이언트 구현, 스킬·훅·플러그인 설계 |
| 6주차 | 멀티에이전트 | coordinator/worker 패턴, 메시지 패싱(mailbox), 병렬 스케줄링, git worktree 격리 |
문서에 자주 나오는 용어 빠른 참조.
zero exec "…". 표준입출력으로 JSON을 주고받아 자동화에 쓴다.zero serve --mcp)한다.--worktree로 실험 변경을 격리해, 본 작업 트리를 더럽히지 않고 시도한다./spec · zero exec --use-spec. 큰 변경의 방향을 먼저 잡는다.직접 파고들 때.