Claude Code는 세션마다 기억이 리셋된다. 어제 알려준 코딩 컨벤션을 오늘은 모른다. 테스트 명령어를 매번 알려줘야 한다. 프로젝트 구조를 설명하고, 금지 사항을 반복하고, 선호하는 패턴을 다시 말한다.
CLAUDE.md가 이 문제를 해결한다. 프로젝트 루트에 놓으면 Claude Code가 매 세션 시작 시 자동으로 읽는다. AI 에이전트를 위한 온보딩 문서다.
이전 글에서 Compound Engineering의 핵심이 "학습을 문서로 축적한다"는 것이고, Harness Engineering에서 "AGENTS.md는 백과사전이 아니라 목차"라고 했다. CLAUDE.md가 그 구체적인 구현이다.
이 글은 공식 문서(code.claude.com)와 실제 사용 사례를 기반으로, CLAUDE.md를 제대로 쓰는 법을 정리한다.
CLAUDE.md는 뭔가
마크다운 파일이다. Claude Code가 세션을 시작할 때 컨텍스트 윈도우에 로드한다. 여기에 적힌 내용을 Claude가 매번 참조한다.
중요한 점: CLAUDE.md는 **설정이 아니라 맥락(context)**이다. 강제 실행되는 설정 파일이 아니라, Claude가 참고하는 안내서다. 공식 문서에서 "Claude treats them as context, not enforced configuration"이라고 명시한다.
따라서 100% 따르는 건 아니다. 약 80% 정도의 준수율이라고 보면 된다. 반드시 지켜야 하는 규칙은 CLAUDE.md가 아니라 **훅(hooks)**으로 강제해야 한다. 훅은 결정적이고, CLAUDE.md는 확률적이다.
파일 위치와 계층 구조
CLAUDE.md는 여러 위치에 놓을 수 있다. 각각 역할이 다르다.
글로벌 (개인 설정)
~/.claude/CLAUDE.md
모든 프로젝트에 적용되는 개인 설정이다. 버전 관리하지 않는다. "나는 한국어로 커밋 메시지를 쓴다", "응답은 간결하게" 같은 것들
프로젝트 (팀 공유)
./CLAUDE.md 또는 ./.claude/CLAUDE.md
프로젝트 루트에 놓는다. git에 커밋해서 팀과 공유한다. 빌드 명령어, 코딩 컨벤션, 아키텍처 결정, 금지 사항 같은 프로젝트 수준의 규칙
로컬 (개인 + 프로젝트)
./CLAUDE.local.md
프로젝트별이지만 개인적인 설정이다. .gitignore에 추가해서 버전 관리하지 않는다. "이 프로젝트에서 나는 feature/x 브랜치 작업 중이다" 같은 것들
서브디렉토리
./src/components/CLAUDE.md
하위 디렉토리에도 CLAUDE.md를 놓을 수 있다. Claude가 해당 디렉토리의 파일을 읽을 때 온디맨드로 로드된다. 프로젝트 루트의 CLAUDE.md처럼 시작 시 로드되는 게 아니라, 필요할 때만 로드된다.
로드 순서
- ~/.claude/CLAUDE.md (글로벌)
- 작업 디렉토리 위쪽의 CLAUDE.md와 CLAUDE.local.md (전체 로드)
- 서브디렉토리의 CLAUDE.md (온디맨드 로드)
프로젝트 루트의 CLAUDE.md와 CLAUDE.local.md는 세션 시작 시 전체가 로드된다. 서브디렉토리의 것들은 Claude가 그 디렉토리 파일을 읽을 때만 로드된다.
뭘 넣어야 하나
1. 빌드와 테스트 명령어
Claude가 코드를 수정하면 검증해야 한다. 어떤 명령어로 빌드하고, 어떤 명령어로 테스트하는지 알아야 한다.
## 명령어
- `pnpm dev`: 개발 서버 실행 (포트 5173)
- `pnpm build`: 프로덕션 빌드
- `pnpm test`: Vitest 실행
- `pnpm test:e2e`: Playwright E2E 테스트
- `pnpm lint`: ESLint 체크
- `pnpm typecheck`: TypeScript 타입 체크
단일 테스트 실행 방법도 포함한다. 전체 테스트 스위트를 돌리면 느리다. Claude에게 수정한 파일 관련 테스트만 돌리도록 안내한다.
- 단일 테스트: `pnpm test -- src/features/auth/model/useAuth.test.ts`
- 코드 수정 후 반드시 typecheck를 돌린다
2. 코드 스타일 (최소한으로)
여기서 가장 흔한 실수가 나온다. 코드 스타일 가이드라인을 CLAUDE.md에 전부 넣는 것이다.
HumanLayer의 가이드에서 명확히 말한다: "린터가 할 일을 LLM에게 시키지 말라." LLM은 린터에 비해 비싸고 느리다. 코드 스타일은 ESLint와 Prettier가 잡아야 한다.
CLAUDE.md에는 린터로 잡을 수 없는 것만 넣는다.
## 코드 스타일
- TypeScript strict 모드, `any` 타입 사용 금지
- `React.FC` 사용하지 않는다. 함수형 컴포넌트는 일반 함수로 선언
- 절대 경로 import 사용 (`@/` 별칭)
- interface 우선, type은 Union/Intersection에만 사용
ESLint가 이미 잡는 규칙은 적지 않는다. PostToolUse 훅으로 파일 수정 후 자동으로 포매터를 돌리면 된다.
{
"hooks": {
"PostToolUse": [{
"matcher": "Edit|Write",
"hooks": [{
"type": "command",
"command": "npx prettier --write $CLAUDE_FILE_PATH"
}]
}]
}
}
3. 아키텍처
프로젝트 구조와 각 디렉토리의 역할. Claude가 코드를 어디에 넣어야 하는지 판단하는 근거가 된다.
## 아키텍처 (FSD)
- `src/app/`: 애플리케이션 진입점, 전역 설정만
- `src/pages/`: 라우팅 페이지, widgets+features+entities 조합만
- `src/widgets/`: 독립적 UI 블록
- `src/features/`: 사용자 상호작용 기능
- `src/entities/`: 도메인 데이터 모델
- `src/shared/`: 공통 유틸리티
### 의존성 규칙
상위 레이어는 하위 레이어만 참조할 수 있다.
- features는 entities와 shared만 import 가능
- entities는 shared만 import 가능
- shared는 다른 레이어 참조 금지
이 규칙을 위반하는 import를 만들지 않는다.
4. 절대 하지 말 것
Claude가 가끔 하는 위험한 행동을 명시적으로 금지한다.
## 금지 사항
- .env 파일 커밋 금지
- `any` 타입 사용 금지
- node_modules 안의 파일 수정 금지
- 기존 테스트를 삭제하거나 skip하지 않는다
- 사용자에게 확인 없이 데이터베이스 마이그레이션 실행하지 않는다
5. 컴팩트 지시사항
Claude의 컨텍스트 윈도우가 가득 차면 자동으로 압축(compact)된다. 이때 어떤 정보를 보존할지 지시할 수 있다.
## 컴팩트 지시사항
컴팩트 시 다음을 반드시 보존한다:
- 수정한 파일의 전체 목록
- 현재 테스트 상태
- 진행 중인 작업의 맥락
뭘 넣지 말아야 하나
너무 긴 파일
HumanLayer의 연구에 따르면, 프론티어 모델이 합리적으로 따를 수 있는 지시 사항은 약 150~200개다. Claude Code의 시스템 프롬프트 자체가 이미 약 50개의 지시를 포함한다. CLAUDE.md에 넣을 수 있는 여유는 100~150개 정도다.
공식 문서에서도 200줄, 25KB를 넘으면 컨텍스트 소비가 커지고 준수율이 떨어진다고 한다.
지시가 많아지면 전체적으로 준수율이 균등하게 떨어진다. 뒤에 있는 지시만 무시하는 게 아니라, 전부를 고르게 무시하기 시작한다.
코드 스타일 가이드 전체
위에서 말했다. 린터가 할 일이다.
Claude가 이미 잘 하는 것
Claude가 지시 없이도 이미 잘 하는 것을 적으면 불필요한 토큰을 소비한다. 기존 코드를 분석해서 패턴을 파악하는 건 LLM의 기본 능력이다. CLAUDE.md가 없어도 package.json을 보고 스택을 추론하고, 기존 코드의 패턴을 따른다.
CLAUDE.md에는 코드에서 추론할 수 없는 것만 넣는다.
분리 전략: rules 디렉토리
CLAUDE.md가 길어지면 쪼갠다. 두 가지 방법이 있다.
@import
CLAUDE.md에서 다른 파일을 참조한다.
## 아키텍처
자세한 내용은 @docs/architecture.md 참조
## 인증 플로우
@docs/authentication.md 참조
.claude/rules/ 디렉토리
.claude/rules/ 디렉토리에 마크다운 파일을 넣으면 CLAUDE.md와 동일한 우선순위로 자동 로드된다.
.claude/
├── CLAUDE.md # 핵심 지시사항만
└── rules/
├── code-style.md # 코드 스타일 규칙
├── testing.md # 테스트 컨벤션
└── security.md # 보안 요구사항
팀원별로 다른 규칙을 관리할 때 유용하다. 프론트엔드 팀이 code-style.md를, 보안 팀이 security.md를 관리하는 식
Auto Memory: Claude가 스스로 기억하는 것
CLAUDE.md 외에 Auto Memory 시스템이 있다. Claude가 작업하면서 스스로 학습한 내용을 저장하는 것이다. 빌드 명령어, 디버깅 인사이트, 아키텍처 메모, 코드 스타일 선호도 같은 것들.
매 세션마다 저장하는 건 아니다. "미래 대화에서 유용할 것"이라고 판단될 때만 저장한다.
MEMORY.md의 첫 200줄 또는 25KB(먼저 도달하는 쪽)가 세션 시작 시 로드된다.
/memory로 Claude가 저장한 내용을 확인하고, 편집하거나 삭제할 수 있다. 전부 일반 마크다운이다.
CLAUDE.md와 Auto Memory의 관계는 이렇다.
- CLAUDE.md: 내가 직접 쓴 지시사항. 프로젝트의 규칙과 컨벤션.
- Auto Memory: Claude가 스스로 쌓은 학습. 내 교정과 선호도에서 배운 것.
둘 다 세션 시작 시 로드된다. Compound Engineering에서 말한 "축적"이 자동으로 일어나는 것이다.
Auto Memory를 끄려면 /memory에서 토글하거나, 프로젝트 설정에서 autoMemoryEnabled: false를 설정한다. Claude Code v2.1.59 이상이 필요하다.
Skills: 항상 로드하지 않아도 되는 지식
CLAUDE.md는 매 세션마다 로드된다. 하지만 모든 지식이 매 세션에 필요한 건 아니다.
**스킬(Skills)**은 필요할 때만 로드되는 지식이다. .claude/skills/에 마크다운 파일로 정의하고, 관련 작업이 나타나면 Claude가 자동으로 로드한다.
.claude/
├── CLAUDE.md
└── skills/
├── deployment/
│ └── SKILL.md # 배포 절차
├── api-design/
│ └── SKILL.md # API 설계 컨벤션
└── testing/
└── SKILL.md # 테스트 작성 가이드
CLAUDE.md에 넣기엔 너무 상세하지만, 특정 작업에서는 필요한 지식이 스킬에 적합하다.
이전 useEffect 글에서 다뤘던 react-tips-skill 플러그인이 이 패턴의 예시다. useEffect 판단 트리를 스킬로 패키징해서, React 컴포넌트를 작성할 때만 자동으로 로드되게 했다.
Hooks: CLAUDE.md로 안 되는 것
CLAUDE.md는 확률적이다. 80% 준수. 나머지 20%가 문제가 되는 경우가 있다.
"절대 .env를 커밋하지 마"라고 CLAUDE.md에 적어도, 가끔 커밋한다. 이런 건 **훅(hooks)**으로 강제한다.
{
"hooks": {
"PreToolUse": [{
"matcher": "Bash(git commit*)",
"hooks": [{
"type": "command",
"command": "git diff --cached --name-only | grep -q '.env' && echo 'BLOCKED: .env 파일 커밋 금지' && exit 1 || exit 0"
}]
}]
}
}
Harness Engineering 글에서 "가이드는 방향을 잡아주고, 센서는 결과를 검증한다"고 했다. CLAUDE.md가 가이드라면, 훅이 센서다.
파일 수정 후 자동 포매팅, 커밋 전 린트 체크, 위험한 명령어 차단 같은 것들은 전부 훅으로 처리한다.
FSD 프로젝트 예시
지금까지의 내용을 종합한 실제 CLAUDE.md 예시다.
# 프로젝트: 로보틱스 GCS
React + TypeScript + Vite 기반 로보틱스 관제 시스템.
## 명령어
- `pnpm dev`: 개발 서버 (포트 5173)
- `pnpm build`: 프로덕션 빌드
- `pnpm typecheck`: TypeScript 타입 체크
- `pnpm lint`: ESLint
- `pnpm test -- <파일경로>`: 단일 테스트 실행
- 코드 수정 후 반드시 `pnpm typecheck` 실행
## 아키텍처 (FSD)
- app/ → 전역 설정만. 비즈니스 로직 금지
- pages/ → widgets+features+entities 조합만. 직접 구현 금지
- widgets/ → 독립적 UI 블록
- features/ → 사용자 액션. entities+shared만 참조
- entities/ → 도메인 모델. shared만 참조
- shared/ → 공통 유틸. 다른 레이어 참조 금지
상위 레이어는 하위 레이어만 import 가능.
### 플랫폼 구분
- common/: 데스크탑+모바일 공통
- desktop/: 데스크탑 전용
- mobile/: 모바일 PWA 전용
## 코드 스타일
- `any` 타입 사용 금지. `unknown` 사용
- `React.FC` 사용 금지
- 절대 경로 import (`@/`)
- API 호출은 TanStack Query 사용
## 금지
- .env 파일 커밋 금지
- 기존 테스트 삭제/skip 금지
- FSD 레이어 의존성 규칙 위반 금지
- node_modules 수정 금지
## 컴팩트 지시사항
컴팩트 시 수정 파일 목록과 현재 작업 맥락을 보존한다.
44줄이다. 짧다. 이 정도면 충분하다.
상세한 API 설계 규칙, 배포 절차, 테스트 작성 가이드는 .claude/skills/에 넣거나 @docs/로 참조한다.
/init으로 시작하기
빈 파일에서 시작하는 게 막막하면 /init 명령어가 있다.
Claude Code에서 /init을 실행하면, 현재 프로젝트의 빌드 시스템, 테스트 프레임워크, 코드 패턴을 분석해서 초안을 생성한다. 이걸 기반으로 다듬으면 된다.
자동 생성된 초안을 그대로 쓰는 건 권장하지 않는다. 코드에서 추론할 수 있는 것들이 많이 포함되어 있어서, 정리가 필요하다.
핵심 정리
- 짧게 유지한다. 200줄, 25KB 이하. 길수록 준수율이 떨어진다.
- 코드에서 추론할 수 없는 것만 넣는다. 빌드 명령어, 아키텍처 규칙, 금지 사항.
- 린터가 할 일은 린터에게. 코드 스타일은 ESLint + Prettier + 훅으로 강제한다.
- 반드시 지켜야 하는 건 훅으로. CLAUDE.md는 80% 준수. 훅은 100%.
- 길어지면 쪼갠다. .claude/rules/와 @import로 분리한다.
- 상세 지식은 스킬로. 매 세션에 필요 없는 건 .claude/skills/에 넣는다.
- Auto Memory를 활용한다. Claude의 학습이 자동으로 축적된다.
CLAUDE.md는 "새로 합류한 팀원에게 주는 온보딩 문서"라고 생각하면 된다. 다만 그 팀원이 매일 아침 기억이 리셋되고, 문서를 완벽하게 따르지는 않지만, 작업 속도가 5배 빠른 팀원이다.
문서를 잘 쓰면 그 팀원이 더 잘 일한다. 문서를 너무 많이 쓰면 오히려 핵심을 놓친다.
- 공식 문서 (메모리): https://code.claude.com/docs/en/memory
- 공식 문서 (Best Practices): https://code.claude.com/docs/en/best-practices
- 공식 문서 (.claude 디렉토리): https://code.claude.com/docs/en/claude-directory
- HumanLayer 가이드: https://www.humanlayer.dev/blog/writing-a-good-claude-md
- Builder.io 가이드: https://www.builder.io/blog/claude-md-guide
'IT' 카테고리의 다른 글
| Claude Design이 나왔고, Figma 주가가 7% 빠졌다 (1) | 2026.04.19 |
|---|---|
| Claude Code 토큰, 어디서 새는지 알아야 아낀다 (0) | 2026.04.19 |
| Playwright MCP - AI 에이전트에게 브라우저를 줬다 (0) | 2026.04.14 |
| Claude Mythos Preview System Card - Anthropic이 자사 최강 모델을 공개하지 않기로 한 이유 (3) | 2026.04.14 |
| Harness Engineering - 모델을 바꾸지 않고 코딩 에이전트 성능을 52%에서 66%로 올렸다 (0) | 2026.04.14 |
