TRENDSHIFT DAILY #17 · 2026.05.26 · HMBOWN

CodeWhale — DeepSeek-First 에이전트 터미널, "프리픽스 캐시 안정성"을 코어로 만든 코딩 에이전트

Rust로 만든 TUI 코딩 에이전트. DeepSeek V4 1M 컨텍스트·thinking-mode 스트리밍·prefix-cache 안정성 추적을 핵심 셀링 포인트로 내건다. --model auto가 저지연 auto-route(flash router)로 매 턴 모델과 thinking 레벨을 자동 선택한다. Plan/Agent/YOLO 3모드, OS 레벨 샌드박스(Seatbelt/Landlock+seccomp/Job Objects), durable task queue, MCP/ACP/HTTP-SSE 런타임 API까지.

Rust
엔진 + TUI 풀스택 (crates/cli, crates/tui)
1M 토큰
DeepSeek V4 컨텍스트 윈도
24+ 프로바이더
DeepSeek/NVIDIA/Atlas/OpenRouter/Ollama/vLLM… (docs/PROVIDERS.md 기준 25종)
MIT
라이선스 (오픈소스, DeepSeek 비계열)

1프로젝트 한줄 요약

"DeepSeek 모델을 1급 시민으로 모신, prefix-cache 친화적 터미널 에이전트"

핵심 메시지

"OpenAI/Anthropic용으로 설계된 에이전트가 아니라,
DeepSeek의 가성비와 reasoning을 살리려고 처음부터 다시 설계한 코딩 에이전트."

CodeWhalecodewhale 명령으로 실행되는 터미널 코딩 에이전트다. 외형은 Claude Code/Codex/OpenCode와 비슷한 TUI지만, 코어가 다르다 — DeepSeek V4의 reasoning 블록 스트리밍, 1M 토큰 컨텍스트, 그리고 무엇보다 "prefix-cache 안정성"을 비용 절감의 1차 지표로 본다.

이름의 "Whale(고래)"은 DeepSeek 로고에서 따왔지만 DeepSeek 회사의 공식 제품은 아니다. 모델은 DeepSeek API를 기본 백엔드로 쓰되, 같은 OpenAI 호환 인터페이스로 NVIDIA NIM·OpenRouter·SGLang·vLLM·Ollama 같은 셀프호스팅 백엔드까지 두루 받는다. open-weight 친화적인 에이전트 하니스 — 이게 트렌딩 17위에 오른 이유다.

2왜 주목받는가

트렌딩 #17 · 클로즈드 모델 락인에 지친 사용자의 대안

2026년 5월 기준, 터미널 코딩 에이전트 시장은 폭증했다. Claude Code, Codex CLI, OpenCode, Cursor의 CLI 모드, Gemini CLI… 그런데 대부분 한 회사의 클로즈드 모델에 묶여 있다. 사용자들은 두 가지 고통을 호소한다.

고통 1
비용 폭발 + 캐시 비효율

Claude Sonnet/Opus, GPT-5, Gemini Pro 모두 비싸다. 게다가 에이전트가 매 턴 시스템 프롬프트·도구 정의·이전 히스토리를 다시 보내면 prefix cache가 매번 깨져 cache-miss 단가로 청구된다. 30분짜리 코딩 세션이 수 달러로 늘어나는 일이 흔하다.

고통 2
셀프호스팅·중국권 사용자 차단

중국 본토에서는 OpenAI/Anthropic API가 막혀 있고, 셀프호스팅 추론 서버(vLLM/SGLang)를 띄워도 기존 에이전트가 OpenAI 형식을 강하게 가정해 호환이 깨진다. 오픈웨이트(open-weight) 모델인 DeepSeek/Kimi/Qwen으로 갈아타기가 생각보다 어렵다.

해결책
DeepSeek를 1급 시민으로, 나머지는 OpenAI-호환으로 통일

CodeWhale은 DeepSeek V4 Pro/Flash를 디폴트 모델로 박아두고, cache hit당 \$0.003625/1M 토큰이라는 극저가를 활용하도록 prefix-cache 안정성 추적을 코어 기능으로 만들었다. 동시에 같은 OpenAI 호환 어댑터로 24개 이상의 다른 프로바이더까지 받아준다.

구체적인 차별점 5가지

차별점 1

auto-route(flash router) — 매 턴마다 "이 턴에 얼마짜리 모델이 필요한가" 자동 결정

codewhale --model auto를 켜면, 본 요청이 나가기 직전 deepseek-v4-flash + thinking off로 짧은 라우팅 호출을 먼저 던진다(내부 구현: auto_route_flash_recommendation). 라우터가 "이 턴은 단순 요약이니까 Flash + thinking off로 충분", "이 턴은 디버깅이니까 Pro + thinking max"처럼 결정하면 본 호출이 그 모델로 나간다. 실제로는 휴리스틱 우선이고 모호할 때만 Flash LLM 호출(4초 타임아웃)이 일어난다. 라우팅 자체가 Flash라 거의 공짜고, 본 호출은 적정 등급으로 청구돼 토큰 비용이 줄어든다.

차별점 2

prefix-cache 안정성을 statusline에 띄움

대부분의 에이전트는 "cache hit"이 얼마나 자주 깨지는지 사용자에게 안 보여준다. CodeWhale은 /statusline 푸터에 최근 N턴 동안 prefix가 얼마나 안정적이었는가를 칩으로 띄운다. 비용을 폭발시키는 편집 패턴(예: 시스템 프롬프트 중간을 건드리는 도구 호출)이 일어나면 사용자가 즉시 눈치챈다.

차별점 3

workspace rollback — 진짜 git을 건드리지 않는 별도 스냅샷

YOLO 모드에서 에이전트가 잘못 편집하면 어떻게 되돌리지? CodeWhale은 side-git 스냅샷이라는 별도 저장소를 만들어, 매 턴 전/후로 워크스페이스를 스냅샷한다. /restorerevert_turn으로 되돌려도 사용자 본인의 .git은 전혀 건드리지 않는다. 이게 깨지지 않는 rollback이다.

차별점 4

OS 레벨 샌드박스 — macOS Seatbelt / Linux 다층 샌드박스 / Windows Job Objects

shell 도구가 "워크스페이스 폴더 바깥"의 파일을 건드리지 못하도록 OS 커널 수준에서 막는다. macOS는 sandbox-exec(Seatbelt) 프로파일, Linux는 Landlock LSM + seccomp BPF(강제) + process hardening(prctl) + 선택적 bwrap 총 4개 레이어, Windows는 Job Objects + path 제한으로 구현된다. 이건 사용자가 켜는 옵션이 아니라 기본 동작이다.

차별점 5

durable task queue + sub-agents pool — 동시 10~20개 자식 에이전트 실행

agent_open으로 자식 에이전트를 띄우면 부모는 블록되지 않는다. 자식들은 별도 컨텍스트로 병렬 실행되고(기본 cap 10, 최대 20), 완료되면 <codewhale:subagent.done> 이벤트로 요약/메트릭을 부모에게 던진다. 큰 결과는 var_handle 참조로 "주차"되어 부모 컨텍스트는 가볍게 유지된다. 게다가 작업 큐가 durable이라 프로세스를 죽였다가 살려도 백그라운드 작업이 살아 있다.

3기술 스택 전체 지도

Rust 풀스택 + 다중 프로바이더 어댑터 + 시스템 통합 다수

CodeWhale은 거의 모든 핵심 코드가 Rust로 작성되어 있다. 두 개의 바이너리(codewhale, codewhale-tui)가 한 모노레포 안에 살고, npm 패키지는 단지 GitHub Releases에서 OS별 prebuilt 바이너리를 내려받는 얇은 인스톨러다.

핵심 런타임 (Rust)

레이어기술역할
Dispatcher CLIcrates/cli (codewhale)서브커맨드 라우팅, auth, doctor, sessions, update
TUI 런타임crates/tui + ratatui터미널 UI 렌더링, composer, 패널, 모달
비동기 엔진tokio + 자체 turn loop턴 상태 머신, 도구 호출, 스트리밍 파싱
스트리밍 클라이언트OpenAI-호환 SSEreasoning_content/content 블록 분리 처리
도구 레지스트리typed registryshell, file ops, git, web_search, fetch_url, sub-agents, MCP, RLM, apply-patch
LSP 통합Language Server Protocol편집 후 진단을 모델 컨텍스트에 자동 주입
샌드박스Seatbelt(macOS) / Landlock+seccomp BPF+process hardening+bwrap(Linux) / Job Objects(Windows)OS 레벨 파일 시스템 제한
스냅샷side-git워크스페이스를 별도 git에 매 턴 스냅샷
durable queue로컬 파일 기반 큐재시작 후에도 백그라운드 작업 복원
런타임 APIHTTP/SSE 서버codewhale serve --http로 헤드리스 운영
ACP 어댑터Agent Client ProtocolZed 같은 에디터가 stdio로 붙음
MCP 서버/클라Model Context Protocol외부 도구 통합 (양방향)
용어
ratatui (라타튀이)
Rust로 터미널 UI를 만들 때 가장 널리 쓰는 라이브러리. 옛 이름은 tui-rs였다. 셀 기반 렌더링·이벤트 루프·위젯 시스템을 제공해 vim/htop 같은 풍부한 TUI를 만들 수 있다. CodeWhale은 ratatui 위에 자체 위젯·키바인딩·테마 시스템을 얹었다.
용어
SSE (Server-Sent Events, 서버 전송 이벤트)
HTTP 단방향 스트리밍 방식. text/event-stream 헤더로 응답을 열고, 서버가 작은 청크를 계속 흘려보낸다. ChatGPT/Claude가 글자를 한 자씩 띄우는 게 이걸로 구현된다. CodeWhale은 OpenAI 호환 SSE를 파싱하면서 reasoning_content(thinking)와 content(답변)를 분리해 다르게 렌더링한다.
용어
LSP (Language Server Protocol)
에디터와 컴파일러/언어 서버 간의 표준 통신 규약. VS Code의 인텔리센스가 이걸로 동작한다. CodeWhale은 rust-analyzer, pyright, typescript-language-server, gopls, clangd를 띄워두고, 에이전트가 파일을 편집하면 즉시 LSP 진단(에러/경고)을 받아 다음 reasoning step의 컨텍스트로 모델에 넣어준다. "고치고도 깨진 줄 모르는" 에이전트의 흔한 실수를 막는다.
용어
MCP (Model Context Protocol, 모델 컨텍스트 프로토콜)
Anthropic이 만든 LLM 도구 통합 표준. JSON-RPC 기반으로 외부 프로세스(stdio·streamable HTTP·SSE)와 도구·리소스·프롬프트를 주고받는다. CodeWhale은 양방향이다 — MCP 클라이언트로 외부 도구 서버를 부르기도 하고, 자기 자신을 codewhale mcp-server로 띄워 다른 에이전트에게 도구로 제공도 한다.
용어
ACP (Agent Client Protocol)
Zed 에디터가 만든 에이전트-에디터 통신 규약. stdio 기반으로 에디터가 로컬 에이전트를 자식 프로세스로 띄워 새 세션·프롬프트 응답을 주고받는다. codewhale serve --acp로 켜면 Zed의 "custom agent"로 등록할 수 있다. 도구 백 편집까지는 아직 미지원이라 ACP 슬라이스가 점진적으로 확장 중이다.

모델 프로바이더 어댑터 (25종 등록, 주요 프로바이더)

같은 OpenAI 호환 어댑터로 다음을 받는다. base URL과 모델 ID만 바뀌고 코드 경로는 거의 동일하다. docs/PROVIDERS.md 기준 25종 등록; 아래는 주요 프로바이더.

프로바이더활용처
DeepSeek (기본)deepseek-v4-pro, deepseek-v4-flash — 1M 컨텍스트, prefix-cache 친화
NVIDIA NIMNVIDIA 클라우드의 모델 카탈로그
AtlasCloud중국권 인프라 (커뮤니티 PR로 통합)
Wanjie Ark중국권 reasoner 모델 호스팅
OpenRouter200+ 모델 메타 라우터 (DeepSeek부터 시작)
Novita / Fireworks오픈웨이트 모델 API 호스팅
Moonshot / Kimikimi-k2.6 등 — 중국권 1M 컨텍스트 대안
OpenAI-호환 (generic)OPENAI_BASE_URL로 어떤 호환 엔드포인트든
SGLang (self-host)로컬/사내 LLM 서버
vLLM (self-host)로컬/사내 LLM 서버, 산업 표준
Ollama (self-host)로컬 노트북에서도 작은 모델 (예: codewhale-coder:1.3b)

설치/패키징 파이프라인

4아키텍처 심화 분석

디스패처 → TUI → 엔진 → 도구 레지스트리, 그리고 prefix-cache가 모든 결정의 중심

4-1. 상위 시스템 구조도

┌─────────────────────────────────────────────────────────────────────┐ │ 사용자 터미널 │ │ $ codewhale (얇은 디스패처 CLI — clap 기반 서브커맨드 라우팅) │ └─────────────────────────────────────────────────────────────────────┘ │ exec ▼ ┌─────────────────────────────────────────────────────────────────────┐ │ codewhale-tui (Rust + ratatui 기반 TUI) │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │ │ Composer │ │ Transcript │ │ Approval/Modal│ │ │ │ (입력 박스) │ │ (대화 + 도구) │ │ (권한 게이트) │ │ │ └──────────────┘ └──────────────┘ └──────────────┘ │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │ │ /statusline │ │ Theme/Locale │ │ Notifications│ │ │ │ (cache 안정성)│ │ (Catppuccin..)│ │ (OSC 9/99/777)│ │ │ └──────────────┘ └──────────────┘ └──────────────┘ │ └─────────────────────────────────────────────────────────────────────┘ │ in-proc events ▼ ┌─────────────────────────────────────────────────────────────────────┐ │ Async Turn Engine (tokio) │ │ ┌──────────┐ ┌──────────┐ ┌──────────────┐ ┌──────────────┐ │ │ │ Session │←→│ Turn │ │ Tool Registry │ │ Compaction │ │ │ │ State │ │ Loop │←→│ (shell/file/ │ │ + Memory │ │ │ │ │ │ │ │ git/web/...) │ │ │ │ │ └──────────┘ └──────────┘ └──────────────┘ └──────────────┘ │ │ │ │ │ │ │ │ ▼ ▼ ▼ ▼ │ │ ┌──────────────────────────────────────────────────────────────┐ │ │ │ side-git │ durable │ LSP │ OS-Sandbox │ Sub-agents Pool │ │ │ │ snapshot │ task │ pool │ (Seatbelt/ │ (max 10~20 동시) │ │ │ │ │ queue │ │ Landlock) │ │ │ │ └──────────────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────────┘ │ OpenAI-compatible SSE ▼ ┌─────────────────────────────────────────────────────────────────────┐ │ Provider Layer (25 adapters, single trait) │ │ DeepSeek (default) NVIDIA-NIM OpenRouter AtlasCloud Wanjie │ │ Novita Fireworks Moonshot SGLang vLLM Ollama │ └─────────────────────────────────────────────────────────────────────┘

4-2. auto-route(flash router) — "본 요청 전에 0.001달러짜리 결정 호출"

모델 auto-routing은 두 차원을 동시에 정한다 — (a) 모델 (Pro vs Flash)(b) thinking 레벨 (off/high/max). 실제로는 휴리스틱 우선으로 동작하고, 요청이 모호할 때만 Flash + thinking off 호출을 던져 결정한다(4초 타임아웃). 소스 내 구현명: auto_route_flash_recommendation / resolve_auto_route_with_inventory.

유저 입력 │ ▼ ┌─────────────────────┐ │ auto-route │ ← "이 턴은 어느 등급?" 결정 │ (휴리스틱 우선; │ 모호할 때만 Flash LLM 호출 │ Flash + off, 4s) │ 캐시 hit이면 거의 무료. │ 출력: {model, think} │ └─────────────────────┘ │ ▼ (예: Pro + high) ┌─────────────────────┐ │ Real Turn │ ← 결정된 등급으로 본 호출 │ deepseek-v4-pro │ 본격 reasoning + 도구 호출 │ thinking: high │ └─────────────────────┘ │ ▼ 응답 스트림 (reasoning blocks + content + tool_calls)
비유

auto-route = 응급실 트리아지 간호사. 환자(턴)가 도착하면 의사(Pro)에게 바로 보내지 않고, 간호사(Flash + off)가 30초 만에 "찰과상이면 인턴, 가슴 통증이면 심장내과"를 결정한다. 결정 비용은 거의 0이지만, 잘못 분류해도 환자가 죽지는 않는다 (다음 턴에 사용자가 /model로 강제 지정 가능).

휴리스틱이 답을 못 내거나 Flash 호출 형식이 이상하면 로컬 폴백이 동작한다. 그리고 결정적으로 — 업스트림 API는 "model": "auto"를 절대 받지 않는다. 항상 구체적인 모델 ID로 청구되므로 비용 추적이 정확하다.

4-3. Sub-agent — var_handle로 부모 컨텍스트를 가볍게

부모 에이전트가 agent_open(role, prompt)을 호출하면 즉시 자식 ID를 반환한다. 부모는 다른 작업을 계속한다. 자식이 끝나면 다음 형태의 이벤트가 부모 turn loop에 들어온다:

<codewhale:subagent.done id="sub-abc123"> summary: "리팩토링 완료. 12개 파일 수정, 모든 테스트 통과." evidence: [ {file: "src/router.rs", lines: "+45/-12"}, {file: "tests/integration.rs", lines: "+8/-0"}, ... ] metrics: {tokens_in: 12450, tokens_out: 3210, duration_ms: 84500} var_handles: ["full_diff:vh_xyz789", "tool_log:vh_def456"] </codewhale:subagent.done>

핵심은 var_handle이다. 자식이 만든 큰 결과물(전체 diff·로그·전체 reasoning trace)이 부모 컨텍스트로 통째로 흘러들어가면 토큰 비용이 폭발한다. 그래서 큰 데이터는 핸들 ID로 "주차"되고, 부모는 handle_read(vh_xyz789, range=...)나 JSONPath 프로젝션으로 필요한 슬라이스만 꺼낸다.

4-4. workspace rollback — 사용자 .git을 안 건드림

YOLO 모드에서 에이전트가 잘못 편집하면 어떻게 복구할까? 대부분의 에이전트는 사용자의 .git에 자동 커밋을 만들어 그걸 reset한다. CodeWhale은 그 길을 안 간다.

사용자 워크스페이스 side-git (별도 저장소) ┌──────────────────────┐ ┌──────────────────────┐ │ /home/me/myproject │ │ ~/.deepseek/snapshots│ │ ├── .git/ │ │ /myproject/.git │ │ ├── src/ │ 매 턴 전·후 │ ├── refs/heads/ │ │ ├── tests/ │ hard-link 스냅샷 │ │ pre-turn-001 │ │ └── ... │ ────────────► │ │ post-turn-001 │ │ │ │ │ pre-turn-002 ... │ │ ✗ 절대 commit 안 함 │ │ └── objects/ │ └──────────────────────┘ └──────────────────────┘ │ /restore turn-001 ────┘ revert_turn 002 ──────┘

이 구조의 장점은 사용자가 자기 git 워크플로를 그대로 유지한다는 것이다. 에이전트가 만든 "auto-commit"이 PR diff에 섞이지 않고, git log가 깨끗하게 유지된다.

4-5. Skills 시스템 — workspace-first 디스커버리

CodeWhale의 Skills는 디렉토리 + SKILL.md 한 쌍이다. 다음 순서로 찾는다:

  1. 워크스페이스 우선: .agents/skillsskills.opencode/skills.claude/skills.cursor/skills
  2. 전역: ~/.agents/skills~/.claude/skills~/.deepseek/skills
  3. 번들 시스템 스킬은 자동 설치: skill-creator, delegate, v4-best-practices, plugin-creator, skill-installer, mcp-builder, documents, presentations, spreadsheets, pdf, feishu

흥미로운 점은 Claude Code의 .claude/skills와 OpenCode의 .opencode/skills를 그대로 인식한다는 것. 사용자가 한 프로젝트에서 여러 에이전트를 섞어 쓸 때 스킬을 중복으로 안 만들어도 된다.

5디렉토리 구조 해부

레포는 모노레포지만 책임이 깔끔하게 분리되어 있다

CodeWhale/ ├── crates/ │ ├── cli/ ← 디스패처 바이너리 (codewhale) │ │ └── src/ │ │ ├── main.rs → clap 기반 서브커맨드 라우팅 │ │ ├── lib.rs → auth·doctor 포함 서브커맨드 구현 │ │ ├── update.rs → 자가 업데이트 (codewhale update) │ │ └── metrics.rs → 사용 메트릭 수집 │ │ │ ├── tui/ ← TUI 런타임 바이너리 (codewhale-tui) ※ 엔진 런타임 포함 │ │ └── src/ │ │ ├── main.rs │ │ ├── app.rs → ratatui 메인 루프 │ │ ├── composer.rs → 입력 영역 │ │ ├── transcript.rs→ 대화 + 도구 호출 출력 │ │ ├── status.rs → /statusline (prefix-cache chip) │ │ ├── theme/ → Catppuccin/Tokyo Night/Dracula... │ │ └── notify/ → OSC 9/99/777 + 데스크톱 폴백 │ │ │ ├── agent/ ← 에이전트 로직 │ ├── app-server/ ← HTTP/SSE 서버 (codewhale serve) │ ├── config/ ← 설정 파싱 │ ├── core/ ← 핵심 타입/트레이트 │ ├── execpolicy/ ← 도구 실행 정책 │ ├── hooks/ ← 훅 시스템 │ ├── mcp/ ← MCP 클라/서버 │ ├── protocol/ ← 프로토콜 정의 │ ├── release/ ← 릴리즈/업데이트 │ ├── secrets/ ← API 키 관리 │ ├── state/ ← 세션 상태 │ ├── tools/ ← shell, file, git, web_search 등 │ ├── tui-core/ ← TUI 공통 컴포넌트 │ └── whaleflow/ ← 워크플로 오케스트레이션 │ (※ crates/engine/, crates/ffi/ 는 실제 존재하지 않음; 엔진 코드는 crates/tui/ 내부) │ ├── docs/ ← 풍부한 한·중·영 문서 │ ├── ARCHITECTURE.md → 엔진 내부 │ ├── CONFIGURATION.md → 전체 옵션 레퍼런스 │ ├── MODES.md → Plan/Agent/YOLO │ ├── MCP.md → MCP 통합 가이드 │ ├── RUNTIME_API.md → HTTP/SSE API │ ├── INSTALL.md → 플랫폼별 설치 │ ├── DOCKER.md → GHCR 이미지 + 볼륨 │ ├── TENCENT_CLOUD_REMOTE_FIRST.md ← Tencent/CNB/Lighthouse/Feishu │ ├── TENCENT_LIGHTHOUSE_HK.md ← HK 서버 setup │ ├── MEMORY.md → 사용자 메모리 feature │ ├── SUBAGENTS.md → 자식 에이전트 taxonomy │ ├── KEYBINDINGS.md → 전체 단축키 │ ├── SWEBENCH.md → SWE-bench 평가 어댑터 │ ├── LOCALIZATION.md → i18n 매트릭스 │ ├── OPERATIONS_RUNBOOK.md→ 운영/복구 │ └── RECURSIVE_SELF_IMPROVEMENT.md ← "에이전트로 에이전트 개선" 프롬프트 │ ├── README.md ← 영문 (메인) ├── README.zh-CN.md ← 간체 중국어 ├── README.ja-JP.md ← 일본어 ├── config.example.toml ← 모든 옵션이 들어간 예제 ├── Cargo.toml ← 워크스페이스 루트 ├── npm/ ← npm 패키지 (얇은 인스톨러) └── .github/workflows/ci.yml ← CI: lint, test, cross-build
비유

책임 분리가 잘된 모노레포 = 한 단지에 책임이 다른 동들이 있는 아파트. CLI 동은 현관(서브커맨드 라우팅), TUI 동은 거실(눈에 보이는 UI), Engine 동은 보일러실(상태 머신·도구·샌드박스). 한 동을 통째로 들어내도 다른 동은 멀쩡히 산다. codewhale serve --http로 TUI를 빼고 엔진만 띄울 수 있는 게 이 분리 덕이다.

6학습 포인트 (기술별)

CodeWhale 코드베이스에서 실제로 배울 수 있는 것들

학습 1 — Rust

대형 비동기 시스템을 tokio + ratatui로 어떻게 만드나

CodeWhale은 "실시간 스트리밍 + 도구 호출 + 사용자 입력"이 동시에 일어나는 복잡한 비동기 시스템이다. 채널(tokio::sync::mpsc) 디자인, select! 매크로, cancellation token, 그리고 ratatui의 이벤트 루프와 엔진 이벤트 루프를 어떻게 분리하는지 — 이 패턴은 어떤 TUI 앱에도 직접 적용된다. 실습 아이디어: 자기만의 작은 TUI 채팅 봇을 ratatui + tokio로 만들어 보기.

학습 2 — OS Sandbox

플랫폼별 샌드박스를 한 trait으로 추상화하기

sandbox/seatbelt.rs, landlock.rs, seccomp.rs, process_hardening.rs, bwrap.rs, jobobj.rs가 각각 macOS/Linux/Windows의 OS 레벨 권한 제한을 같은 인터페이스로 노출한다. macOS는 sandbox-exec에 SBPL 프로파일을 전달, Linux는 Landlock + seccomp BPF + process hardening(prctl) + 선택적 bwrap 4개 레이어, Windows는 Job Objects + path restrictions. 실습 아이디어: Linux Landlock을 직접 호출하는 1파일 Rust 프로그램으로 "이 디렉토리만 쓰기 가능"을 구현해 보기.

학습 3 — Streaming 파싱

OpenAI 호환 SSE에서 reasoning과 content 분리하기

DeepSeek/OpenAI의 chat completions SSE는 delta.contentdelta.reasoning_content를 같은 스트림에 흘려보낸다. 청크가 단어 중간에서 끊길 수 있고, JSON이 깨질 수 있고, tool_call이 여러 청크에 걸쳐 분할 도착한다. CodeWhale은 이걸 위해 증분 파서를 만들어 부분 JSON을 합치고, 한 번 완성될 때마다 UI에 푸시한다. 실습 아이디어: Python으로 OpenAI SSE를 직접 파싱해 두 종류의 blob을 분리 렌더링하기.

학습 4 — side-git Snapshot

git을 쓰면서도 사용자 .git을 안 건드리는 법

core git 도구로 별도 디렉토리에 git init한 다음, 워크스페이스 파일을 hard-link로 거기 복사하고 commit한다. hard-link라 디스크 비용이 거의 0. 복원할 때는 hard-link를 다시 워크스페이스로 풀어쓴다. 실습 아이디어: 셸 스크립트로 "매 분 워크스페이스 스냅샷을 별도 폴더에 잡아두기"를 구현 — 5줄짜리 cron job + git 한두 줄이면 끝.

학습 5 — MCP/ACP 양방향

한 프로세스가 protocol의 클라이언트이자 서버가 되는 패턴

CodeWhale은 MCP 클라(외부 도구 서버를 부름)이자 MCP 서버(자기 자신을 다른 에이전트에 도구로 제공)다. ACP도 마찬가지. 이런 양방향 protocol을 다룰 때 메시지 ID 충돌, 세션 라이프사이클, 그리고 한 프로세스 안에서 클라/서버 핸들러를 어떻게 분리하느냐가 핵심 설계 결정. 실습 아이디어: Python으로 echo MCP 서버 + 그 서버를 부르는 MCP 클라를 한 스크립트에 같이 구현.

학습 6 — durable task queue

프로세스를 죽여도 백그라운드 작업이 살아남는 큐

로컬 파일 기반 큐(SQLite/JSONL/sled 등)로 각 작업의 상태를 영속화한다. 워커가 작업을 집어 들 때 "leased" 상태로 표시, 완료/실패 시 트랜잭션으로 update. 프로세스 재시작 시 "in_progress"였던 작업을 다시 큐로 돌려놓는다. 실습 아이디어: Python sqlite3로 50줄짜리 durable queue를 만들어 워커 두 개가 race condition 없이 일하게 하기.

학습 7 — Prefix-Cache 친화 설계

"시스템 프롬프트 중간을 안 건드리는" 코드를 어떻게 작성하나

대부분의 에이전트는 매 턴 시스템 프롬프트 + 도구 정의 + 메모리 + 히스토리를 다시 보낸다. 그런데 메모리가 살짝만 바뀌어도 그 뒤 모든 토큰의 캐시가 깨진다. CodeWhale은 "가변 영역을 모두 메시지 뒤쪽으로 몰고, 앞쪽은 동결"한다. 시스템 프롬프트 → 도구 정의 → (동결) → 히스토리 → (가변) 사용자 메시지. 이 순서를 지키면 cache hit율이 극적으로 올라간다. 실습 아이디어: OpenRouter 같은 메타 라우터의 cached input 메트릭을 보면서 자기 프롬프트를 재배열해 보기.

학습 8 — TUI 알림 OSC

터미널 자체에 알림을 띄우는 OSC 시퀀스

printf '\033]9;뭔가 끝났어요!\033\\'를 출력하면 iTerm2/WezTerm/Ghostty 같은 터미널이 데스크톱 알림을 띄운다. 이게 OSC 9. Kitty는 OSC 99, Ghostty는 OSC 777로 더 풍부한 알림을 보낸다. CodeWhale은 이걸 도구가 끝날 때마다 자동으로 쏜다. 실습 아이디어: 쉘 스크립트 끝에 echo -e "\033]9;빌드 끝\033\\"를 붙여 iTerm2에서 알림 받아 보기.

7하드웨어/시스템 요구사항

개인 노트북부터 NAS/클라우드 VPS까지

로컬 실행 (DeepSeek API 사용)

셀프호스팅 (vLLM/SGLang)

DeepSeek V4 같은 큰 모델을 셀프호스팅하면 하드웨어 요구가 폭증한다. CodeWhale 자체는 클라이언트라 가볍지만, 추론 서버에 GPU가 필요.

원격 워크플로 (Tencent Cloud + Feishu)

특이하게 docs에 "Tencent-native remote-first path"가 있다. Tencent Lighthouse HK VPS에 CodeWhale을 띄우고, Feishu/Lark의 long-connection bridge로 모바일에서 명령을 보내, EdgeOne으로 공개 HTTPS edge를 만든다 — 중국권 사용자가 휴대폰에서 24/7 코딩 에이전트를 부리는 시나리오에 최적화되어 있다.

용어
Tencent Lighthouse / EdgeOne
Tencent Cloud의 저가 VPS 서비스가 Lighthouse(轻量应用服务器), CDN/엣지 서비스가 EdgeOne. 중국권에서 GitHub/npm 접속이 느린 문제를 우회하면서 GFW 친화적으로 운영할 때 자주 쓰이는 조합. CodeWhale은 이 둘에 특화한 가이드가 있을 정도로 중국 사용자층을 진지하게 본다.

비용 (DeepSeek 공식 가격, 2026-06-01 시행)

모델컨텍스트Input (cache hit)Input (cache miss)Output
deepseek-v4-pro1M\$0.003625 / 1M\$0.435 / 1M\$0.87 / 1M
deepseek-v4-flash1M\$0.0028 / 1M\$0.14 / 1M\$0.28 / 1M

cache hit과 cache miss의 단가 차이는 100배. 그래서 prefix-cache 친화 설계가 모든 비용 절감의 시작점이다.

8직접 해볼 수 있는 실습 과제

난이도별 5개 — 노트북 한 대에서 다 해볼 수 있음

난이도 ★ (1시간)

1. CodeWhale 설치 + DeepSeek API로 "내 레포 README 한국어 번역"

npm install -g codewhaleplatform.deepseek.com에서 API 키 발급. codewhale 실행해 첫 화면에서 키 입력. 자기 GitHub 레포를 git clone 한 디렉토리로 가서 codewhale --model deepseek-v4-flash "README.md를 한국어로 번역해서 README.ko.md로 저장". 학습 포인트: 도구 호출(read_file, write_file) 흐름을 transcript에서 직접 본다.

난이도 ★★ (2~3시간)

2. /statusline의 prefix-cache 칩을 보면서 자기 워크플로 분석

5개 이상의 도구 호출이 일어나는 작업을 시켜 본다 (예: "이 레포의 테스트 커버리지를 측정하고 30% 미만인 모듈에 단위 테스트 5개씩 추가"). 매 턴 statusline의 캐시 안정성 칩을 관찰. 찾을 것: 어느 도구가 호출됐을 때 캐시가 깨졌는지. 보통 load_skill이나 메모리 업데이트가 trigger다. 패턴을 메모하면 자기 프롬프트/스킬 설계에 직접 도움이 된다.

난이도 ★★★ (4~6시간)

3. 자기만의 Skill 패키지 만들기 + GitHub로 배포

codewhale /skill new my-skill로 스캐폴드. SKILL.md에 frontmatter(name, description)와 본문 instruction 작성. 자기 일상 워크플로(예: "한국어 commit 메시지를 conventional commits 영어로 변환")를 캡슐화. ~/.agents/skills/my-skill에 두고 /skills에서 자동 발견되는지 확인. 그 다음 GitHub 레포에 푸시하고 다른 사람이 /skill install github:<you>/<repo>로 설치 가능한지 테스트.

난이도 ★★★★ (1~2일)

4. codewhale serve --http로 헤드리스 에이전트 + 자기 웹 UI

CodeWhale 엔진을 HTTP/SSE 서버로 띄운다(RUNTIME_API.md 참조). Next.js 또는 SvelteKit으로 작은 채팅 UI를 만들어, POST /v1/turns로 메시지를 보내고 SSE 스트림으로 응답을 받는다. 핵심 챌린지: reasoning_content와 content를 각각 다른 색으로 렌더링하기. 그리고 tool_call이 일어날 때 사용자에게 권한 모달을 띄우기 (TUI의 Approval modal을 웹에 재현).

난이도 ★★★★★ (3~7일)

5. Ollama + codewhale-coder:1.3b로 완전 로컬 코딩 에이전트

Ollama 설치 후 ollama pull codewhale-coder:1.3b. CodeWhale을 --provider ollama --model codewhale-coder:1.3b로 실행. 관찰할 것: 1.3B 모델은 대부분의 복잡한 reasoning을 못 해서 도구 호출이 자주 실패한다. 어떤 작업이 잘 되고 어떤 작업이 망가지는지 매핑. 그 다음 자기 GPU가 받쳐주면 같은 워크플로를 DeepSeek Distill 7B 또는 Qwen 2.5 Coder 7B로 갈아 보고 품질이 어떻게 바뀌는지 기록. 학습 포인트: 모델 크기와 도구 호출 성공률 간 관계. 이게 "모델 auto-routing"이 왜 필요한지를 몸으로 깨닫게 한다.

9관련 기술 심화 학습 로드맵

CodeWhale 한 레포로 시작해 8주 동안 에이전트 시스템 풀스택을 짚는 코스

Week 1 — 기초 다지기

OpenAI Chat Completions + DeepSeek API + SSE 스트리밍 직접 다루기

Python requests 또는 Node fetch로 DeepSeek API를 raw HTTP로 호출. system/user/assistant 메시지 형식, tool_calls의 JSON 구조, stream: true로 SSE 받기. 왜: CodeWhale의 모든 추상화는 결국 이걸 감싸는 것이다. raw API를 안 만져보면 추상화가 어떤 문제를 푸는지 모른다.

Week 2 — TUI

Rust + ratatui 또는 Python + textual로 작은 채팅 TUI 만들기

composer(입력) + transcript(대화) + statusline(하단 상태) 3개 영역. tokio/asyncio 채널로 입력 핸들러와 API 호출을 분리. 도전: SSE 스트리밍 중에 사용자가 새 메시지를 타이핑할 수 있게 (반응형 입력).

Week 3 — 도구 호출

file_read / file_write / shell_exec를 직접 만들고 LLM에게 노출

OpenAI tool_calls 스키마로 자기 도구 JSON Schema를 정의. LLM이 도구 호출을 요청하면 실제로 실행하고 결과를 다음 턴 컨텍스트에 넣어 응답을 다시 받는다. 도전: shell_exec에서 위험한 명령(rm -rf, curl | sh)을 차단하는 정책 — 정규식 vs OS 샌드박스 vs LLM judge 비교.

Week 4 — 샌드박스

OS 레벨로 자식 프로세스의 파일 시스템 제한

Linux Landlock(또는 macOS sandbox-exec)로 "이 디렉토리만 쓰기 가능"을 직접 구현. 레퍼런스: CodeWhale의 engine/sandbox/landlock.rs. 도전: 자식 셸 안에서 cd ..; touch /etc/passwd를 시도했을 때 정확히 어디서 막히는지 strace로 추적.

Week 5 — 멀티 모델 라우팅

auto-route(flash router) 같은 라우터를 자기 도구로 구현

OpenRouter API로 같은 코드에서 DeepSeek, Kimi, Qwen, Llama를 다 받게 하고, 라우터 함수(작은 LLM 또는 휴리스틱)가 "이 요청은 어느 모델?"을 결정하게 한다. CodeWhale의 auto_route_flash_recommendation처럼 휴리스틱 우선으로 동작하고, 모호할 때만 Flash LLM 호출을 던진다. 도전: 라우팅 결정에 들어가는 비용 vs 절약되는 비용을 측정 — 손익분기점이 어디인가?

Week 6 — Sub-agents

부모/자식 에이전트 + var_handle parking 구현

asyncio.gather 또는 tokio::spawn으로 자식 N개를 동시에 띄우고, 큰 결과는 메모리 안 dict에 ID로 저장하고 부모는 ID만 보유. 도전: 자식이 실패했을 때 retry 정책, timeout, 부모가 자식을 cancel할 수 있게 cancellation token 전파.

Week 7 — Durable Queue

SQLite/sled로 재시작 견디는 백그라운드 작업 큐

워커 프로세스 N개가 race 없이 작업을 leasing. 도전: 작업 leasing이 끊긴 채 워커가 죽으면 TTL 후 다른 워커가 재시도. 정확히 한 번(exactly-once) vs 적어도 한 번(at-least-once) 시맨틱의 차이를 구현으로 체험.

Week 8 — MCP/ACP

MCP 서버를 만들어 자기 도구를 다른 에이전트(Claude Code, Codex)에 제공

Python mcp SDK 또는 TypeScript @modelcontextprotocol/sdk로 stdio 기반 MCP 서버 작성. 자기가 만든 도구(예: 사내 Confluence 검색)를 노출. 도전: 같은 서버를 SSE 모드와 stdio 모드로 둘 다 지원하기. Claude Code의 .mcp.json에 등록해서 실제로 부르기.

10핵심 키워드 사전

CodeWhale 문서에 자주 나오는 용어 — 다른 에이전트 도구에도 그대로 통한다

용어
prefix cache (프리픽스 캐시)
LLM 추론 서버가 동일한 시스템 프롬프트·도구 정의·초반 메시지를 만나면, 그 부분의 attention KV를 미리 계산해 두고 다음 요청에 재활용하는 기법. DeepSeek은 cache hit 단가를 100~150배 싸게 책정한다. "앞 토큰만 동일하면 무조건 hit"이 아니라 정확히 prefix가 같아야 동작한다. 그래서 메시지 중간에 변하는 값을 끼우면 그 뒤로 다 깨진다.
용어
thinking mode / reasoning_content
DeepSeek R1/V4 같은 reasoning 모델이 "최종 답"을 내기 전 펼치는 사고 과정 토큰. OpenAI API에서는 delta.reasoning_content로 별도 필드 전송. CodeWhale은 이걸 다른 색/스타일로 렌더링해 사용자가 모델이 어디서 헤매는지 본다. thinking: off/high/max로 강도를 조절.
용어
durable queue
프로세스 재시작·크래시를 견디는 작업 큐. 메모리 큐(Python queue.Queue, Rust tokio::sync::mpsc)는 프로세스가 죽으면 사라진다. durable은 디스크(SQLite/RocksDB/sled/파일)에 작업 상태를 영속화하고, 워커가 작업을 받을 때 "leased + TTL"을 표시해 워커 사망도 견딘다.
용어
var_handle (변수 핸들)
큰 데이터(자식 에이전트의 전체 trace, 큰 파일 내용)를 부모 컨텍스트에 통째로 넣지 않고 ID 참조로만 쥐는 방식. 부모가 필요할 때 handle_read(id, slice)로 일부만 꺼낸다. 토큰 비용 폭발 방지의 핵심 패턴. Claude Code의 filesystem.read + line range도 같은 사상.
용어
YOLO mode
"You Only Live Once" — 모든 도구 호출에 자동 승인을 주는 모드. 워크플로가 빠르지만 위험. CodeWhale은 YOLO 모드여도 OS 샌드박스로 워크스페이스 바깥은 못 건드리게 막고, side-git 스냅샷으로 되돌릴 수 있게 안전망을 친다. "신뢰할 수 있는 워크스페이스에서만"이라는 단서가 항상 붙는다.
용어
checklist_write
에이전트가 여러 단계 작업을 시작할 때 자기 자신에게 체크리스트를 쓰는 내부 도구. Plan 모드의 결과물이자, Agent/YOLO 모드 중에도 진행 상황을 transcript에 가시화한다. Claude Code의 TodoWrite와 같은 사상.
용어
RLM (Reasoning Loop Memory)
CodeWhale 고유 용어. 큰 분석 작업을 위해 자식 reasoning 세션을 "주차"해두고 부모가 필요할 때 rlm_open, rlm_eval로 부르는 메커니즘. 파이썬의 REPL을 모델 컨텍스트 안에서 흉내 낸다고 생각하면 된다. peek, search, chunk, sub_query_batch 같은 보조 도구로 부분 조회.
용어
Seatbelt / Landlock / seccomp BPF / Job Objects
macOS/Linux/Windows의 OS 레벨 권한 제한 메커니즘. Seatbelt는 SBPL(Scheme 유사)이라는 DSL로 프로파일을 작성. Linux는 Landlock(LSM, 5.13+) + seccomp BPF(시스템콜 필터링, 강제) + process hardening(prctl) + 선택적 bwrap 4개 레이어. Job Objects는 Windows의 프로세스 그룹 + path 정책. "이 디렉토리만 쓸 수 있다"를 커널이 보장한다.
용어
OSC (Operating System Command)
ANSI escape 시퀀스의 한 종류. \033]N;데이터\033\\ 형식으로 터미널에 메타 신호를 보낸다. 9는 알림, 99는 Kitty 알림, 777은 Ghostty 알림, 8은 하이퍼링크. CodeWhale은 도구가 끝날 때마다 알림 OSC를 쏴서 데스크톱 알림 없이도 터미널 자체가 깜빡이게 한다.
용어
auto-route / flash router
CodeWhale의 모델 자동 라우팅 시스템. 소스 구현명은 auto_route_flash_recommendation / resolve_auto_route_with_inventory (crates/tui/src/model_routing.rs). 본 요청 전에 휴리스틱을 먼저 적용하고, 모호할 때만 Flash + thinking off 호출을 던져 "이 턴엔 어느 모델, 어느 thinking 레벨이 적절한가"를 결정(4초 타임아웃). 라우팅 자체가 캐시 hit으로 거의 무료. 사용자가 codewhale --model auto를 켜면 자동 활성화된다. ※ "Fin"이라는 이름은 소스코드 어디에도 없다 — 공식 명칭이 아닌 점에 주의.
용어
Recursive Self-Improvement (RSI)
"에이전트로 에이전트를 개선"하는 메타 워크플로. CodeWhale은 docs/RECURSIVE_SELF_IMPROVEMENT.md에 자체 코드베이스를 개선하기 위한 프롬프트 모음을 공개한다. "하나의 작고 리뷰 가능한 패치"를 만들도록 강제하는 프롬프트 디자인이 핵심.

11참고 링크

공식 문서 + 관련 생태계

CodeWhale 자체

관련 모델/플랫폼

주변 생태계 (CodeWhale과 같은 사상의 도구들)

시도해볼 만한 것

CodeWhale을 직접 굴려보면서
"prefix-cache 친화"라는 개념을 몸으로 느껴보자.

  1. 오늘 30분: npm install -g codewhale + DeepSeek API 키 발급 + codewhale --model deepseek-v4-flash "현재 디렉토리에 어떤 파일이 있는지 요약해줘"로 한 번 굴려보기. transcript에서 reasoning_content가 어떻게 다른 색으로 뜨는지 관찰.
  2. 이번 주: 같은 작업을 --model auto--model deepseek-v4-pro로 각각 해보고, 응답 시간·비용·품질이 어떻게 달라지는지 표로 정리. 이 비교가 향후 "어떤 모델을 언제 쓸지" 직감을 만든다.
  3. 이번 달: 자기 일상 워크플로 하나(커밋 메시지 정리, README 업데이트, 테스트 시나리오 생성 등)를 Skill로 패키징해 ~/.agents/skills/에 두기. /skills로 자동 감지되는지 확인. 잘 작동하면 GitHub에 올려 공개.
  4. 이번 분기: codewhale serve --http로 헤드리스 모드를 띄우고, 자기가 쓰는 다른 도구(Raycast, Slack 봇, 웹 UI)에서 HTTP로 호출하는 통합을 1개 만들어 보기. "터미널 밖에서도 같은 에이전트"라는 감각을 얻는다.
  5. 장기적으로: 자기 노트북에 Ollama로 작은 코더 모델(7B 정도)을 띄워, CodeWhale을 완전 로컬로 굴려 본 후 클라우드 DeepSeek과의 품질 격차를 정량화. 어디까지가 로컬로 충분한지 자기 데이터로 결정한다.
출처: github.com/Hmbown/CodeWhale · TrendShift Daily (2026-05-26 #17) · 라이선스 MIT · 본 자료는 README와 공식 문서를 한국어로 풀어쓴 학습 노트. DeepSeek 공식 제품이 아닌 커뮤니티 프로젝트.