ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Claude Code가 플랜을 짜는 방법 - Plan Mode 내부 동작 원리
    IT 2026. 4. 8. 21:00
    Claude Code가 플랜을 짜는 방법 - Plan Mode 내부 동작 원리

    Claude Code에는 Plan Mode라는 기능이 있다. 코드를 바로 수정하는 대신, 먼저 구현 전략을 설계하고 사용자 승인을 받은 뒤 실행하는 모드다. "Think first, ship faster"라는 철학인데, 내부적으로 어떻게 돌아가는지 궁금해서 파헤쳐봤다.

    Plan Mode란?

    Plan Mode는 Claude Code의 읽기 전용 모드다. 이 모드에서 Claude는 파일을 읽고, 코드베이스를 탐색하고, 웹을 검색할 수 있지만, 파일을 수정하거나 생성할 수는 없다. 대신 마크다운 파일로 구현 계획을 작성한다.

    진입 방법은 여러 가지다:

    • Shift+Tab 두 번 눌러 권한 모드 순환 (default → acceptEdits → plan)
    • 시작 시 claude --permission-mode plan 플래그
    • 프롬프트 앞에 /plan 접두사
    • 설정에서 defaultMode: "plan"으로 기본값 지정

    플랜은 어떤 형태로 저장되나?

    Plan Mode에서 Claude가 작성하는 플랜은 마크다운(.md) 파일이다. 저장 위치는 기본적으로 ~/.claude/plans/ 디렉토리이며, .claude/settings.jsonplansDirectory 설정으로 변경할 수 있다.

    여기서 흥미로운 점은 플랜 파일의 생명주기다:

    • 세션당 하나의 익명 플랜 파일이 생성된다
    • 같은 세션에서 여러 번 플랜을 짜면 조용히 덮어쓴다
    • /clear 명령에도 플랜은 살아남는다
    • 세션이 끝나도 파일은 남아 있어 다음 세션에서 재개 가능

    사용자는 Ctrl+G를 눌러 에디터에서 직접 플랜 파일을 열어 수정할 수도 있다. Claude와 사람이 같은 마크다운 파일을 편집하는 협업 구조인 셈이다.

    컨텍스트 윈도우와 Compaction

    이 부분이 가장 궁금했다. 플랜 정보가 매 턴마다 주입되는 건지, 아니면 컨텍스트 윈도우에 계속 남아있는 건지?

    답은 둘 다에 가깝다. Plan Mode에 진입하면 시스템 프롬프트에 플랜 관련 지시사항이 추가된다. 플랜 파일 경로와 "읽기 전용으로만 동작하라"는 제약이 포함된다. 이 시스템 프롬프트는 매 턴마다 주입된다.

    Compaction(컨텍스트 압축)이 일어나면 어떻게 될까?

    • Claude Code는 컨텍스트가 약 83.5%에 도달하면 자동으로 compaction을 수행한다
    • 이때 대화 내용, 도구 출력, 중간 결과물은 요약되거나 제거된다
    • 하지만 플랜 파일은 일반 대화보다 높은 우선순위로 보존된다
    • 시스템 프롬프트에 포함된 플랜 관련 지시사항은 compaction과 무관하게 매 턴 재주입된다

    즉, 플랜의 "규칙"(읽기 전용 등)은 시스템 프롬프트로 매번 주입되고, 플랜의 "내용"(구체적 구현 단계)은 파일 시스템에 저장되어 compaction에서도 참조 가능하다. 다만, compaction 후 Claude가 플랜 내용을 "잊어버린" 것처럼 행동할 수 있는데, 이때는 플랜 파일을 다시 읽도록 유도하면 된다.

    서브에이전트는 플랜의 체크리스트를 실행하나?

    아니다. 이 부분은 많은 사람들이 오해하는 지점이다.

    Claude Code의 서브에이전트(Agent 도구)는 메인 에이전트가 명시적으로 위임한 작업만 수행한다. 플랜의 체크리스트를 자동으로 순회하며 하나씩 체크하는 "오케스트레이터"는 존재하지 않는다.

    실제 동작 흐름은 이렇다:

    1. Plan Phase: Claude가 마크다운 플랜 파일을 작성한다
    2. User Review: 사용자가 플랜을 검토하고 승인한다
    3. Implementation Phase: Claude(메인 에이전트)가 플랜을 참조하며 순차적으로 구현한다
    4. Sub-agent Delegation: 필요 시 탐색(Explore)이나 범용(general-purpose) 서브에이전트에게 특정 작업을 위임한다

    서브에이전트의 특성:

    • 각자 독립된 컨텍스트 윈도우를 가진다 (메인 세션과 격리)
    • 다른 서브에이전트를 스폰할 수 없다 (무한 중첩 방지)
    • 작업 완료 시 요약만 반환하므로 메인 컨텍스트를 오염시키지 않는다
    • isolation: worktree 옵션으로 별도 Git 브랜치에서 병렬 작업 가능

    결국 Claude Code 하네스(harness)는 플랜 기반으로 서브프로세스를 자동 오케스트레이션하지 않는다. 하네스의 역할은 권한 모드 강제, 컨텍스트 주입, 체크포인트 스냅샷, 세션 지속성 관리에 한정된다. 실행 순서의 결정은 전적으로 메인 에이전트(Claude)의 추론에 달려있다.

    읽기 전용 제약: 프롬프트 vs Tool Call 수준 제어

    Plan Mode의 읽기 전용 제약이 어떤 수준에서 강제되는지는 중요한 문제다. Armin Ronacher의 분석에서는 이것이 프롬프트 기반 가이드라고 지적했다. 시스템 프롬프트에 "파일을 수정하지 마라"는 지시를 강화 주입하는 방식이라는 것이다.

    그런데 Tool Call 수준에서 강제할 수 있는 인프라가 이미 존재한다는 점이 흥미롭다.

    이미 작동하는 도구 수준 제어: Plan 서브에이전트

    Claude Code의 Agent 도구로 서브에이전트를 생성할 때, subagent_type: "Plan"을 지정하면 해당 서브에이전트에는 Edit, Write, NotebookEdit 도구가 아예 제공되지 않는다. 시스템 정의에 이렇게 명시되어 있다:

    Plan: "Tools: All tools except Agent, ExitPlanMode, Edit, Write, NotebookEdit"

    즉, 서브에이전트에게는 쓰기 도구 자체가 도구 목록에서 제거된다. 프롬프트로 "쓰지 마"라고 말하는 게 아니라, 쓸 수 있는 도구 자체가 없는 것이다. LLM이 아무리 강하게 쓰고 싶어도 호출할 도구가 없으니 물리적으로 불가능하다.

    그런데 메인 세션의 Plan Mode는?

    메인 세션에서 Shift+Tab으로 진입하는 Plan Mode는 상황이 다르다. 메인 세션의 도구 세트는 세션 시작 시 고정되며, Plan Mode 전환 시 도구를 동적으로 제거하지 않는다. 대신 시스템 프롬프트에 읽기 전용 지시를 주입하는 방식이다.

    왜 이런 차이가 있을까?

    • 서브에이전트는 생성 시점에 도구 세트가 결정된다. "Plan용 서브에이전트"라는 새 프로세스를 만드는 것이므로, 처음부터 쓰기 도구 없이 시작하면 된다.
    • 메인 세션은 이미 실행 중인 대화다. 중간에 도구를 제거하려면 하네스가 턴(turn) 단위로 도구 목록을 재구성해야 한다. 기술적으로 불가능한 것은 아니지만, 현재 구현에서는 이를 지원하지 않는다.

    강제할 수 있는 다른 경로: Hooks

    Claude Code의 PreToolUse 훅을 사용하면 도구 호출을 가로채서 차단할 수 있다. 예를 들어:

    // .claude/hooks.json (개념적 예시)
    {
      "PreToolUse": [{
        "matcher": "Edit|Write|NotebookEdit",
        "command": "if [ \"$CLAUDE_PERMISSION_MODE\" = 'plan' ]; then echo 'BLOCK: Plan mode active'; exit 1; fi"
      }]
    }

    이렇게 하면 Plan Mode에서 Edit/Write/NotebookEdit 호출 시 훅이 차단하므로, 사용자가 직접 도구 수준 강제를 구현할 수 있다. 다만 이는 공식 기능이 아니라 사용자의 DIY 해법이다.

    정리: 세 가지 강제 수준

    강제 수준 메커니즘 우회 가능? 현재 상태
    프롬프트 기반 시스템 프롬프트에 "수정 금지" 주입 이론적으로 가능 (LLM이 무시할 수 있음) 메인 세션 Plan Mode에서 사용
    도구 제거 도구 목록에서 Edit/Write 자체를 제외 불가능 (호출할 도구가 없음) Plan 서브에이전트에서 사용
    훅 차단 PreToolUse 훅으로 도구 호출 인터셉트 불가능 (하네스가 실행 차단) 사용자가 직접 구성 가능

    결론적으로 "Tool Call 수준에서 강제할 수 있냐"에 대한 답은 "이미 부분적으로 하고 있고, 전면 적용도 기술적으로 가능하다"이다. Plan 서브에이전트는 도구 제거 방식으로 완벽히 강제하고 있으며, 메인 세션에서도 PreToolUse 훅을 쓰면 같은 효과를 낼 수 있다. 메인 세션 Plan Mode가 프롬프트 기반인 이유는 기술적 불가가 아니라, 유연성과 구현 복잡도 사이의 트레이드오프로 보인다.

    정리: Plan Mode 아키텍처 한눈에 보기

    구성요소 저장 위치 형식 Compaction 생존
    플랜 파일 ~/.claude/plans/ Markdown 높은 우선순위로 보존
    Plan Mode 규칙 시스템 프롬프트 텍스트 매 턴 재주입
    대화 히스토리 컨텍스트 윈도우 메시지 요약/제거 대상

    Claude Code의 Plan Mode는 "AI에게 먼저 생각하게 하자"는 단순한 아이디어를 파일 시스템 기반 지속성 + 프롬프트 기반 제약 + 독립 서브에이전트라는 실용적 아키텍처로 구현한 것이다. 완벽하진 않지만(멀티 플랜 관리, 메인 세션의 도구 수준 강제 등이 아직 미구현), 복잡한 구현 작업에서 "삽질 전에 설계도부터"라는 습관을 강제하는 효과가 있다.


    이 글은 생성형 AI의 도움을 받아 작성되었습니다.

Designed by Tistory.