GitHub ↗
CHAPTER 03 OF 10
🗺️

The Loading Architecture: How Claude Reads Your Files

로딩 아키텍처 — Claude는 파일들을 어떻게 읽는가

Claude가 세션 시작 시 어떤 순서로 어떤 파일들을 로드하는지 정확히 이해하면, 규칙의 범위와 우선순위를 의도대로 설계할 수 있다.

The Loading Architecture: How Claude Reads Your Files cheatsheet
🍌 NANO BANANA CHEATSHEET · CH 03

Overview

개관

Claude Code가 실행되면 내부적으로 일련의 파일 로딩 시퀀스가 시작된다. 이 시퀀스의 순서와 우선순위를 이해하는 것은 단순한 호기심을 넘어 실용적인 설계 결정에 영향을 미친다. 중요한 규칙을 어디에 두어야 하는가? 팀 규칙과 개인 규칙을 어떻게 분리하는가? 특정 서브디렉토리에만 적용되는 규칙은 어디에 두는가?

이 챕터는 Claude Code의 파일 로딩 메커니즘을 정밀하게 분해한다. 문서에 명시된 것과 실제 동작 사이의 미묘한 차이, 특히 '지연 로딩'의 함의를 깊이 이해하면 더 신뢰할 수 있는 설정 아키텍처를 만들 수 있다.

🎯 Learning Goals
  • 글로벌, 프로젝트, 로컬, 서브디렉토리 CLAUDE.md의 차이와 우선순위를 설명한다
  • 서브디렉토리 CLAUDE.md가 지연 로딩되는 이유와 그 함의를 이해한다
  • settings.json 파일 5단계 우선순위를 정확히 안다
  • 팀 공유 규칙과 개인 규칙을 어떻게 분리해야 하는지 설계할 수 있다
  • CLAUDE_CODE_ADDITIONAL_DIRECTORIES 환경 변수의 동작을 이해한다

Sections

본문

CLAUDE.md 4계층 로딩 순서

Claude Code는 세션 시작 시 다음 순서로 CLAUDE.md 파일들을 로드한다:

계층 위치 범위 Git 커밋
글로벌 ~/.claude/CLAUDE.md 모든 프로젝트 N/A (개인 기기)
프로젝트 .claude/CLAUDE.md 또는 루트 CLAUDE.md 이 저장소 예 (팀 공유)
로컬 .claude/CLAUDE.md.local 이 저장소 아니오 (gitignore)
서브디렉토리 any/sub/dir/CLAUDE.md 해당 경로 접근 시 선택적

우선순위는 구체적인 것이 일반적인 것을 오버라이드한다. 같은 규칙이 글로벌과 프로젝트 CLAUDE.md에 충돌되게 있으면, 프로젝트 규칙이 이긴다.

또한 조상 경로도 탐색된다. ~/projects/myapp/src/api/ 디렉토리에서 작업 중이라면, Claude는 src/api/CLAUDE.md, src/CLAUDE.md, CLAUDE.md를 순서대로 찾는다. 이 ancestor walk가 모노레포에서 유용하다 — 패키지별 규칙과 저장소 전체 규칙을 자연스럽게 계층화할 수 있다.

서브디렉토리의 지연 로딩 — 핵심 함정

이 동작을 모르면 규칙이 작동하지 않는다고 착각할 수 있다.

서브디렉토리 CLAUDE.md는 세션 시작 시 로드되지 않는다. Claude의 도구(Read, Edit, Write, Bash)가 해당 경로의 파일에 실제로 접근할 때 비로소 로드된다.

즉:

  • src/api/CLAUDE.md에 있는 규칙은 세션 시작 시 없다
  • Claude가 src/api/ 아래의 파일을 읽거나 편집할 때 로드된다
  • 그 이전에 일어난 대화나 결정에는 영향을 주지 않는다

이 함의는 중요하다: 세션 초반에 영향을 주어야 하는 규칙은 루트 레벨 CLAUDE.md에 두어야 한다. 예를 들어 '이 프로젝트에서 API 에러는 AppError 클래스를 써야 한다'는 규칙을 src/api/CLAUDE.md에만 두면, Claude가 API 파일을 처음 편집하기 전까지 그 규칙을 모른다.

InstructionsLoaded 훅은 이 지연 로딩 이벤트에 반응할 수 있다 — 새로운 CLAUDE.md가 로드될 때마다 특정 동작을 트리거할 수 있다.

settings.json 5단계 우선순위 체계

CLAUDE.md와 달리, settings.json은 훨씬 복잡한 우선순위 체계를 가진다:

우선순위 위치 설명
1 (최고) Managed/IT policy 기업 IT 정책, 사용자가 오버라이드 불가
2 CLI arguments claude --permission-mode plan
3 ~/.claude/settings.json 사용자 글로벌 설정
4 .claude/settings.json 프로젝트 설정 (git 커밋)
5 (최저) .claude/settings.local.json 프로젝트 로컬 설정 (gitignore)

실시간 리로드: Claude Code는 settings 파일들을 감시(watch)하고 세션 도중 변경이 감지되면 즉시 리로드한다. 재시작 없이 설정이 반영된다. ConfigChange 훅이 이 리로드 이벤트에 반응할 수 있다.

팀 설정의 모범 사례: 팀 전체에 적용되어야 하는 hooks와 permissions는 .claude/settings.json에 (git 커밋), 개인의 모델 선호나 개인 hooks는 ~/.claude/settings.json에, 이 프로젝트에 대한 개인 오버라이드는 .claude/settings.local.json에 (gitignore) 넣는다.

추가 디렉토리와 멀티 저장소 설계

단일 저장소를 넘어서는 경우 — 여러 저장소를 동시에 작업하거나, 공유 라이브러리를 참조하는 경우 — --add-dir 플래그를 사용해 추가 디렉토리를 Claude의 범위에 포함할 수 있다.

claude --add-dir ~/shared-utils/

중요한 gotcha: --add-dir로 추가된 디렉토리의 CLAUDE.md는 기본적으로 로드되지 않는다. 환경 변수 CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1을 설정해야 추가된 디렉토리의 CLAUDE.md도 로드된다.

모노레포 설계 패턴:

/monorepo/
├── CLAUDE.md              ← 전체 저장소 공통 규칙
├── .claude/settings.json  ← 팀 설정
├── packages/
│   ├── api/
│   │   └── CLAUDE.md      ← API 패키지 특화 규칙
│   └── frontend/
│       └── CLAUDE.md      ← 프론트엔드 특화 규칙
└── .claude/
    └── CLAUDE.md.local    ← 개인 설정 (gitignored)

이 구조에서 공통 규칙은 루트에, 패키지별 규칙은 패키지 안에. 루트 규칙이 항상 로드되고, 패키지 규칙은 해당 패키지 파일에 접근할 때 추가로 로드된다.

💡 Analogy · 비유
법률의 위계 — 헌법, 법률, 시행령

법률 시스템을 생각해보자. 헌법이 있고, 그 아래에 법률이 있고, 그 아래에 시행령이 있다. 충돌이 있으면 상위 법령이 우선한다. 하지만 시행령은 법률이 다루지 않는 구체적인 사항을 규정할 수 있다.

Claude Code의 설정 계층도 정확히 이와 같다. 글로벌 CLAUDE.md는 헌법이다 — 모든 프로젝트에 적용되는 기본 원칙. 프로젝트 CLAUDE.md는 법률 — 이 저장소에 특화된 규칙. 서브디렉토리 CLAUDE.md는 시행령 — 특정 모듈이나 컴포넌트에만 적용되는 세부 규정.

그리고 헌법보다도 높은 곳에 기업 IT 정책(managed settings)이 있다 — 어떤 사용자도 오버라이드할 수 없는 절대적 제약. 이 계층을 이해하면, 어떤 규칙을 어느 레벨에 두어야 하는지 직관적으로 알 수 있다.

실제 모노레포에서 CLAUDE.md 계층을 어떻게 설계하는지, 그리고 각 파일이 어느 시점에 로드되는지를 보여주는 예제다.

bash
# 모노레포 구조 설계
# /workspace/myapp/

# 1. 루트 CLAUDE.md — 세션 시작 시 즉시 로드
cat > CLAUDE.md << 'EOF'
# MyApp 공통 규칙 (모든 패키지 적용)

## 절대 금지
- any 타입 사용 금지
- console.log 프로덕션 코드 금지
- 직접 push to main 금지 (PR 필수)

## 변경 후 반드시
1. pnpm typecheck
2. pnpm test
EOF

# 2. API 패키지 CLAUDE.md — api/ 파일 접근 시 지연 로드
cat > packages/api/CLAUDE.md << 'EOF'
# API 패키지 규칙 (루트 규칙에 추가됨)

## API 특화 규칙
- 모든 에러: AppError 클래스 사용 (src/errors.ts 참조)
- 인증이 필요한 엔드포인트: requireAuth 미들웨어 필수
- DB 쿼리: Prisma ORM만 사용, raw query 금지
EOF

# 3. 팀 공유 settings.json — git 커밋
cat > .claude/settings.json << 'EOF'
{
  "permissions": {
    "allow": ["Bash(pnpm *)", "Bash(git status)", "Bash(git diff *)"],
    "deny": ["Bash(git push --force *)", "Bash(rm -rf *)"]
  }
}
EOF

# 4. 개인 로컬 설정 — gitignore에 추가
echo '.claude/settings.local.json' >> .gitignore
cat > .claude/settings.local.json << 'EOF'
{
  "model": "claude-opus-4-7",
  "env": {
    "ANTHROPIC_MODEL": "claude-opus-4-7"
  }
}
EOF

echo 'CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1' >> .env.local

이 구조의 핵심은 각 파일이 로드되는 타이밍이다. 루트 CLAUDE.md는 항상 로드되므로 전체에 적용되어야 하는 금지 사항들이 들어간다. API 패키지 CLAUDE.md는 API 파일에 처음 접근할 때 로드되므로 API 특화 규칙이 들어간다. settings.json은 팀 공유 설정(git 커밋)이고, settings.local.json은 개인 취향(gitignore)이다.

🏭 현업에서의 평가
로딩 아키텍처를 이해하는 엔지니어는 '왜 이 규칙이 작동하지 않지?'라는 질문에 스스로 답할 수 있다. 이것은 디버깅 능력이기도 하다.

✅ 시니어가 보는 것

  • 팀 공유 settings.json과 개인 settings.local.json의 적절한 분리
  • 서브디렉토리 CLAUDE.md의 지연 로딩을 고려한 규칙 배치
  • 모노레포에서의 계층적 규칙 설계 경험

⚠️ 레드 플래그

  • 중요한 규칙을 서브디렉토리 CLAUDE.md에만 두고 작동 안 한다고 혼란스러워하는 경우
  • settings.json을 git에 커밋하지 않아 팀원마다 다른 권한이 설정된 경우
  • 글로벌과 프로젝트 CLAUDE.md에 중복 규칙이 많은 경우

🎤 예상 인터뷰 질문

  1. 서브디렉토리 CLAUDE.md의 지연 로딩이 실제 문제를 일으킨 경험이 있나요?
  2. 팀 공유 설정과 개인 설정을 어떻게 구조화하시나요?
  3. 모노레포에서 패키지별로 다른 규칙이 필요할 때 어떻게 설계하시나요?
숙달 vs 익숙함: 단순히 아는 수준: 여러 CLAUDE.md 파일이 있다는 것을 안다. 마스터 수준: 각 파일이 로드되는 정확한 타이밍을 알고, 그것을 기반으로 팀의 규칙 계층을 의도적으로 설계하며, 규칙이 예상대로 작동하지 않을 때 로딩 순서를 기반으로 디버깅할 수 있다.

Key Takeaways

핵심 정리

4계층 로딩 순서를 외워라

글로벌 → 프로젝트 → 로컬 → 서브디렉토리(지연). 더 구체적인 것이 더 일반적인 것을 오버라이드한다.

서브디렉토리는 지연 로딩이다

세션 초반에 영향을 줘야 하는 규칙은 반드시 루트 레벨에 두어야 한다.

settings.json 5단계 체계

Managed > CLI > 사용자 global > 프로젝트 > 로컬. 팀 공유는 프로젝트에, 개인 취향은 로컬에.

실시간 리로드를 활용하라

settings.json 변경은 재시작 없이 즉시 반영된다. ConfigChange 훅으로 리로드 이벤트에 반응할 수 있다.

모노레포는 계층을 활용하라

공통 규칙은 루트에, 패키지별 규칙은 패키지 안에. Ancestor walk가 두 계층을 자동으로 합성해준다.