Minbook
EN
Claude Code 유출이 보여준 것: AI 에이전트의 해부학

Claude Code 유출이 보여준 것: AI 에이전트의 해부학

MJ · · 5 분 소요

2026년 3월 31일 npm 소스맵 사고로 드러난 Claude Code 내부. 4단계 실행, 7가지 모드, 11단계 Agent Loop의 전체 구조를 분석

2026년 3월 31일, 보안 연구자 Chaofan Shou가 npm 패키지에서 이상한 점을 발견했습니다. Anthropic이 @anthropic-ai/claude-code v2.1.88을 배포하면서 .npmignore 설정 오류로 59.8MB 소스맵을 포함시킨 것입니다. 소스맵에는 전체 TypeScript 원본이 복원 가능한 상태로 들어 있었습니다. 512,000줄, 1,884개 파일. X(구 트위터)에 올라간 게시물은 수시간 만에 2,880만 뷰를 기록했습니다.

뒤이은 사건도 주목할 만합니다. Sigrid Jin이 한국시간 새벽 4시에 Claw Code(Python/Rust 클린룸 재구현)를 공개하자 2시간 만에 GitHub 스타 5만 개를 돌파했고, ccunpacked.dev가 비주얼 아키텍처 분석 사이트로 개설되었습니다. Anthropic은 8,100개 이상의 포크에 DMCA 테이크다운을 요청하고, npm 배포에서 네이티브 인스톨러 방식으로 전환했습니다.

같은 시간대에 npm 공급망 공격(supply-chain attack)도 병행되었습니다. 악성 axios 패키지(RAT 포함)가 유포되어, 유출 사태와 맞물리며 npm 생태계 전체의 보안 경각심을 높였습니다. 소스맵 포함 사고 자체는 Bun 런타임의 번들링 버그가 원인으로 추정됩니다.

이 글은 “Claude Code 해부학” 시리즈의 첫 번째 편으로, 유출 소스에서 확인된 전체 아키텍처를 분석합니다.


기술 스택

레이어기술역할
언어TypeScript (strict)전체 코드베이스, Zod 기반 런타임 검증
UI 프레임워크React + Ink터미널 UI를 React 컴포넌트로 구성 (TUI)
상태 관리Zustand불변 상태 트리, DeepImmutable 타입
런타임Bun빌드 및 실행
레이아웃Yoga (flexbox)터미널 내 flexbox 레이아웃 엔진
API 통신SSE (Server-Sent Events)토큰 스트리밍
셸 파싱Tree-sitter23단계 AST 보안 분석

핵심은 React 기반 TUI(Terminal UI)입니다. 웹 브라우저 대신 터미널을 렌더 타겟으로 사용하되, 컴포넌트 구조와 상태 관리는 웹 React 앱과 동일한 패턴을 따릅니다. 전체 애플리케이션은 단일 약 800KB 번들(main.tsx)로 컴파일됩니다.


소스 디렉터리 구조

유출 소스의 디렉터리별 파일 수입니다.

디렉터리파일 수역할
utils/564유틸리티, 헬퍼 함수
components/389React TUI 컴포넌트
commands/189슬래시 커맨드 정의
tools/18452개 빌트인 도구 구현
services/130API, 인증, 텔레메트리
hooks/104React/상태 훅
ink/96Ink TUI 확장
bridge/31claude.ai 연동 브리지
기타197+테스트, 설정, 타입
합계~1,884

utils/가 전체의 30%를 차지한다는 점이 눈에 띕니다. 프로덕션 시스템의 복잡성이 “핵심 로직”이 아니라 “주변 인프라”에 집중된다는 현실을 보여줍니다.


4단계 실행 모델

Claude Code의 실행 흐름은 4개의 명확한 페이즈로 나뉩니다.

flowchart LR
    subgraph P1["Phase 1: Startup"]
        A1["병렬 I/O\n프리페치"]
        A2["인증\n5가지 방식"]
        A3["모델 결정\n도구 조립"]
        A1 --> A2 --> A3
    end
    subgraph P2["Phase 2: Query Loop"]
        B1["전처리\nsnip/compact"]
        B2["API 스트리밍\nSSE"]
        B3["에러 복구\nWithhold"]
        B4["도구 실행"]
        B1 --> B2 --> B3 --> B4
    end
    subgraph P3["Phase 3: Tool Execution"]
        C1["52개 도구\n10단계 파이프라인"]
    end
    subgraph P4["Phase 4: Display"]
        D1["React 조정기\nYoga flexbox\n이중 버퍼"]
    end
    P1 --> P2 --> P3 --> P4
    P3 -->|"tool_use 존재"| P2

Phase 1: Startup (기동)

6단계 초기화가 진행됩니다. 핵심은 병렬 I/O 프리페치입니다.

  1. 병렬 I/O 프리페치 — Git 상태, Keychain 읽기 등 독립 작업을 동시에 실행 (약 135ms 중 65ms 절약)
  2. 조건부 모듈 로딩 — Feature-gated 코드(COORDINATOR_MODE, KAIROS)는 활성 시에만 로드
  3. 초기 설정 — CLI 플래그, bare 모드 파싱
  4. 인증 — OAuth, API Key, AWS Bedrock, Google Vertex, Azure Foundry 5가지 순차 시도
  5. 모델 결정 — 티어 기반 자동 선택 (Max/Team Premium은 Opus, 그 외 Sonnet)
  6. 초기 상태 — REPL 또는 Headless 모드 진입

Phase 2: Query Loop (질의 루프)

사용자 입력이 들어오면 query.tsQueryEngine.ts가 핵심 역할을 합니다.

전처리 단계에서 4가지 압축이 순서대로 작동합니다: Snip Compact(오래된 메시지 제거), Microcompact(tool_use 블록 축소), Context Collapse(컨텍스트 약축), Auto-Compact(토큰 임계값 context_window minus 13,000 초과 시 요약).

API 스트리밍은 SSE로 토큰을 실시간 수신합니다. 에러 복구(Withhold and Recover)는 복구 가능한 에러를 사용자에게 바로 표시하지 않고 자동 치유를 시도합니다. 413이면 collapse drain 후 reactive compact, Max Output Tokens이면 8K에서 64K로 에스컬레이션.

도구 실행 시 안전한 도구는 최대 10개 병렬, 위험한 도구는 순차 단독 실행합니다.

Phase 3: Tool Execution (도구 실행)

52개 빌트인 도구가 공통 10단계 파이프라인을 거칩니다: 이름 조회, 중단 확인, 입력 검증, PreToolUse 훅, 권한 확인, 실행, 결과 매핑, 크기 검사, PostToolUse 훅, 텔레메트리.

Phase 4: Display (화면 출력)

일반 CLI의 console.log가 아니라, React Reconciler, Yoga flexbox, 이중 버퍼, ANSI 시퀀스 파이프라인을 거칩니다. Int32Array 기반 ASCII 버퍼로 50배 캐시 성능 향상을 달성했고, CharPool/StylePool 인턴 풀로 메모리를 최적화합니다.


7가지 실행 모드

단일 바이너리지만 실행 컨텍스트에 따라 7가지 모드로 동작합니다.

모드설명UI핵심 특징
REPL대화형 터미널Full TUI기본 모드, 전체 도구 사용
Headless비대화형 SDK없음CI/CD, 스크립팅용
Coordinator멀티 에이전트 리더최소워커별 격리된 git worktree
Bridgeclaude.ai 연동양방향최대 32 병렬 세션
Kairos상시 실행 보조백그라운드Dream 모드, GitHub 웹훅, 크론
Daemontmux 백그라운드없음터미널 종료에도 생존
Viewer읽기 전용 원격 관찰읽기 전용도구 실행 불가
graph TB
    Q["query(deps)"]
    Q --> R["REPL\nFull UI + 전체 도구"]
    Q --> H["Headless\nNo UI + 전체 도구"]
    Q --> C["Coordinator\n위임 + 워커"]
    Q --> B["Bridge\nWeb 동기화"]
    Q --> K["Kairos\n백그라운드 + Dream"]
    Q --> D["Daemon\ntmux + UDS"]
    Q --> V["Viewer\n읽기 전용"]

모든 모드가 동일한 query() 루프를 공유합니다. 차이는 Dependency Injection으로 처리합니다. query() 함수가 deps 파라미터를 받아 도구 풀, 권한 컨텍스트, 렌더링 타겟을 교체합니다.


11단계 에이전트 루프

Claude Code의 핵심 실행 단위입니다. 매 턴마다 이 11개 단계를 순회합니다.

flowchart TB
    S1["1. User Input\nTextInput.tsx"]
    S2["2. Message Creation\nmessages.ts"]
    S3["3. History Append\nhistory.ts"]
    S4["4. System Prompt Assembly\ncontext.ts"]
    S5["5. API Streaming\nquery.ts SSE"]
    S6["6. Token Parsing\nQueryEngine.ts"]
    S7["7. Tool Detection\ntools.ts"]
    S8["8. Tool Execution Loop\nStreamingToolExecutor.ts"]
    S9["9. Response Rendering"]
    S10["10. Post-Sampling Hooks\nautoCompact.ts"]
    S11["11. Await"]

    S1 --> S2 --> S3 --> S4 --> S5 --> S6 --> S7
    S7 -->|"tool_use 감지"| S8
    S8 -->|"결과 -> 이력 -> API 재호출"| S5
    S7 -->|"tool_use 없음"| S9 --> S10 --> S11
    S11 -->|"새 입력"| S1

1-3단계: 입력 처리. 사용자 메시지를 TextInput.tsx에서 수신하고, createUserMessage()로 구조화된 메시지 객체를 생성한 뒤, history.ts의 인메모리 배열에 추가합니다. API 호출 전 트랜스크립트를 디스크에 저장 — 크래시 안전성 보장.

4단계: 시스템 프롬프트 합성. context.ts가 두 소스를 결합합니다:

  • 시스템 컨텍스트 (메모이제이션): Git 브랜치, git status(최대 2,000자), 최근 커밋, 사용자명
  • 사용자 컨텍스트 (메모이제이션): CLAUDE.md 파일, 현재 날짜

세션 1회만 계산하고 매 턴 재사용합니다. API 프롬프트 캐싱(1시간 캐시)의 적중률을 극대화하는 전략입니다.

5-6단계: API 호출과 스트리밍. SSE로 토큰을 실시간 수신하면서 mutableMessages[], totalUsage, permissionDenials[]를 가변 상태로 유지합니다. maxBudgetUsd 초과 시 세션이 중단됩니다.

7-8단계: 에이전틱 루프. 모델 응답에 tool_use 블록이 있으면 findToolByName()으로 도구를 식별하고, canUseTool()로 접근을 검증한 뒤, StreamingToolExecutor.ts에 넘깁니다. 도구 결과가 이력에 추가되고 API를 재호출 — AI 판단, 도구 실행, 결과 피드백의 반복이 도구 호출 없는 텍스트 응답이 나올 때까지 계속됩니다.

9-11단계: 완료. 응답 렌더링, 후처리 훅(Auto-Compact, 메모리 추출), 다음 입력 대기.


상태 관리: 불변성과 자동 부수효과

전역 상태는 AppState라는 단일 객체에 DeepImmutable 타입이 적용됩니다. Zustand의 set 함수를 통해서만 변경되며, 변경 시 자동 부수효과(권한 변경 시 리스너 알림, 모델 변경 시 설정 저장, 설정 변경 시 캐시 무효화)가 트리거됩니다.


설계를 관통하는 3가지 원칙

1. 안전 우선 (Safety First)

23단계 bash AST 검사, 5단계 권한 파이프라인, fail-closed 기본 방어. “실행 전에 안전을 증명하라” 원칙이 일관됩니다.

2. 성능 집착 (Performance Obsession)

병렬 I/O 프리페치(65ms 절약), 도구 이름순 정렬(프롬프트 캐싱 보전), 이중 버퍼링(터미널 깜빡임 제거). 개별적으로 작지만 수백만 세션에 곱하면 인프라 비용 차이입니다.

3. 확장성 (Extensibility)

7가지 모드, 44개 Feature Flag, MCP 5가지 트랜스포트. 새 모드나 도구를 추가할 때 기존 코드를 수정하지 않고 확장 가능한 구조입니다.



Sources & Limitations

이 시리즈는 아래 공개 분석 자료를 종합하여 작성했으며, 유출된 소스 코드를 직접 포함하지 않습니다.

SourceURL특징
ccunpacked.devccunpacked.dev시각적 아키텍처 가이드, 도구/커맨드 카탈로그
Wikidocs 분석서wikidocs.net/338204한국어 상세 기술 분석 (실행 흐름, 상태 관리, 렌더링)
PyTorch KRdiscuss.pytorch.krGeekNews 기반 커뮤니티 분석 + HN 의견 종합
Claw Codegithub.com/ultraworkers/claw-code클린룸 재구현 (Rust/Python), PARITY.md 패리티 갭 분석

분석 시점: 2026-04-02. Anthropic은 유출 직후 DMCA로 8,100+ 포크를 차단하고 npm 배포를 중단했으므로, 일부 소스의 접근성이 변경되었을 수 있습니다. 또한 Feature Flag 뒤의 미공개 기능은 출시 전 변경되거나 폐기될 수 있습니다.

공유

관련 글