CLAUDE.md 완전 가이드 — AI 코딩 도구의 팀 컨벤션을 한 파일로 통일하는 법
AI 코딩 도구를 팀에 도입했는데, 팀원마다 AI가 뱉어내는 코드 스타일이 전부 다른 경험 있으신가요? 저도 처음엔 "AI가 알아서 해주겠지"라고 낙관했다가 코드 리뷰에서 매번 같은 지적을 반복하게 됐습니다. 누군가는 npm install을 쓰고, 누군가는 async/await 대신 .then()을 쓰고, 심지어 아키텍처 레이어 구분도 제각각이었죠. 그런데 팀 전체가 CLAUDE.md 한 파일을 도입한 뒤, 같은 패턴으로 반복되던 코드 리뷰 지적이 눈에 띄게 줄었습니다. 문제는 AI가 나쁜 게 아니었습니다. 팀의 컨벤션을 아무도 AI에게 알려주지 않았던 겁니다.
Claude Code가 세션을 시작할 때 자동으로 읽어 들이는 CLAUDE.md 파일이 바로 이 문제의 해답입니다. 매 세션마다 "우리 프로젝트는 pnpm 씁니다, NestJS에서 비즈니스 로직은 Service에만 넣어야 합니다"를 반복해서 설명하는 대신, 한 번 잘 만들어 놓은 파일이 팀 전체의 AI 협업을 통일해 줍니다. CLAUDE.md는 단순한 설정 파일이 아니라, 팀이 AI와 맺는 협업 계약서이자 프로젝트 헌법입니다.
이 글에서는 CLAUDE.md의 핵심 원리부터 모노레포 계층 구성, 실무에서 자주 빠지는 함정까지 현장 경험을 담아 정리했습니다. 읽고 나면 오늘 당장 팀 리포지토리에 적용해볼 수 있을 겁니다.
핵심 개념
CLAUDE.md가 필요한 근본 이유
LLM은 기본적으로 대화가 끝나면 모든 기억을 잃습니다. 오늘 "우리 팀은 pnpm 씁니다"라고 알려줘도, 내일 새 세션을 열면 AI는 다시 모릅니다. 이 망각의 문제를 구조적으로 해결하는 것이 CLAUDE.md입니다.
Claude Code는 세션 시작 시 다음 세 위치의 파일을 자동으로 병합하여 로드합니다.
| 위치 | 경로 예시 | 적용 범위 |
|---|---|---|
| 글로벌 | ~/.claude/CLAUDE.md |
모든 프로젝트 공통 |
| 프로젝트 루트 | ./CLAUDE.md |
팀 전체 공유 (git 커밋) |
| 서브디렉터리 | ./packages/api/CLAUDE.md |
특정 모듈·패키지 한정 |
글로벌 파일은 "나는 항상 2-space 들여쓰기를 선호한다"는 개인 선호를 담는 곳이고, 프로젝트 루트 파일이 팀 전체가 합의한 규칙을 담는 핵심입니다.
파일이 다뤄야 할 세 가지 축
처음에 저도 명령 목록만 죽 나열했다가, AI가 엣지 케이스에서 규칙을 무시하는 상황을 반복해서 겪었습니다. 그때서야 단순 명령이 아니라 맥락이 중요하다는 걸 깨달았죠. 잘 만들어진 CLAUDE.md는 WHAT(무엇을), WHY(왜), HOW(어떻게) 세 축을 균형 있게 담아야 합니다.
- WHAT: 기술 스택, 프로젝트 구조, 주요 파일 위치
- WHY: 핵심 설계 결정의 배경 ("우리가 Redux 대신 Zustand를 쓰는 이유")
- HOW: 빌드·테스트 명령어, 브랜치 전략, PR 작성 요령
WHY를 빠뜨리는 경우가 가장 많은데, 배경 없이 규칙만 나열하면 AI가 엣지 케이스에서 규칙을 무시할 가능성이 높아집니다. "레거시 호환 때문에 CommonJS를 유지한다"는 한 줄이, AI가 멋대로 ESM으로 마이그레이션하는 상황을 막아줍니다.
컨텍스트 엔지니어링(Context Engineering): 단순 프롬프트 엔지니어링을 넘어, 팀이 AI에게 제공하는 컨텍스트를 체계적으로 설계·관리하는 개념입니다. 2025년부터 주요 DevEx 담론으로 자리잡았으며,
CLAUDE.md는 이 개념의 핵심 구현체로 평가받습니다.
컨텍스트 윈도우의 물리적 한계
잠깐, 용어 하나만 짚고 넘어가겠습니다. 컨텍스트 윈도우란 LLM이 한 번에 처리할 수 있는 텍스트의 최대 길이입니다. 책 한 권을 한 번에 읽을 수 없듯이, AI도 한 세션에서 처리 가능한 정보량에 물리적 한계가 있습니다. CLAUDE.md는 이 귀한 공간의 일부를 차지하기 때문에 크기 관리가 중요합니다.
솔직히 말씀드리면, CLAUDE.md에 모든 것을 다 넣고 싶은 욕심이 생깁니다. 하지만 Claude Code의 시스템 프롬프트가 이미 상당수의 내부 지시를 선점하고 있고, 현장 경험상 규칙이 과도하게 쌓이면 중요한 지시가 조용히 무시되기 시작합니다. 파일이 500줄을 넘으면 정말 중요한 규칙이 희석될 수 있습니다. 컨텍스트 공간은 비유하자면 한정된 '슬롯'처럼 작동한다고 생각하면 이해하기 쉽습니다.
본격 예시 전에 알아두면 좋은 주의사항
좋은 점만 먼저 보여드리고 싶지만, 팀에 도입하기 전에 이 두 가지 질문을 스스로에게 먼저 던져보시면 좋습니다.
- "이 파일을 누가 업데이트할 것인가?" — 코드베이스가 바뀌었는데
CLAUDE.md가 업데이트되지 않으면, 파일이 없는 것보다 더 나쁠 수 있습니다. AI가 낡은 규칙을 진실로 받아들이기 때문입니다. - "
/init으로 자동 생성한 파일을 그냥 쓸 것인가?" — 여러 사례에서 확인되는 패턴인데, LLM이 자동 생성한 컨텍스트 파일은 오히려 작업 품질을 낮출 수 있습니다. 자동 생성은 초안으로만 활용하고 반드시 팀이 직접 검토하는 과정이 필요합니다.
실전 적용
상황에 따라 어떤 구조가 맞는지 먼저 확인해보시면 좋습니다.
| 상황 | 권장 방식 |
|---|---|
| 팀 규모가 작거나 단일 앱 프로젝트 | 예시 1 (모노레포 계층적 구성) |
CLAUDE.md 한 파일이 너무 비대해진 경우 |
예시 2 (.claude/rules/ 디렉터리 구조) |
| 팀 규칙과 개인 선호를 분리하고 싶은 경우 | 예시 3 (CLAUDE.local.md) |
예시 1: 모노레포 계층적 구성
NestJS 백엔드와 Next.js 프론트엔드가 공존하는 모노레포라면 다음 구조가 효과적입니다. 여기서는 NestJS와 Next.js 기준으로 설명하지만, Django, Spring, Rails 등 어떤 프레임워크든 계층 분리 원칙 자체는 동일하게 적용됩니다.
/
├── CLAUDE.md ← 프로젝트 전역 규칙
├── apps/
│ ├── api/
│ │ └── CLAUDE.md ← NestJS 전용 규칙
│ └── web/
│ └── CLAUDE.md ← Next.js 전용 규칙
└── packages/
└── shared/
└── CLAUDE.md ← 공유 라이브러리 규칙루트 CLAUDE.md는 모든 팀원이 공통으로 알아야 할 최소한의 규칙만 담고, 상세 내용은 하위 파일에 위임합니다.
# 프로젝트 전역 규칙 (루트 CLAUDE.md)
## 기술 스택
- Node.js 20 LTS, TypeScript 5.x strict mode
- 패키지 매니저: pnpm (npm, yarn 사용 금지)
- 모노레포 관리: Turborepo
## 빌드 & 테스트
- Build: `pnpm build`
- Test: `pnpm test`
- Lint: `pnpm lint`
## 코드 스타일
- 2-space 들여쓰기
- async/await 사용 (.then() 체이닝 지양)
- 명시적 반환 타입 선언 필수
## Git 워크플로
- 브랜치: feature/*, fix/*, chore/*
- 커밋: imperative mood 영어 또는 한글
- PR 머지: squash merge 기본
## 상세 규칙 참조
- apps/api/CLAUDE.md 참조 (NestJS 세부 규칙)
- apps/web/CLAUDE.md 참조 (Next.js 세부 규칙)# NestJS 전용 규칙 (apps/api/CLAUDE.md)
## 아키텍처 레이어
- Controller: 요청/응답 변환만 담당, 비즈니스 로직 금지
- Service: 모든 비즈니스 로직이 위치하는 곳
- Repository: DB 접근 추상화
## 입력 검증
- 모든 입력은 class-validator 데코레이터가 적용된 DTO로 검증
- @Body(), @Param()에 직접 primitive 타입 사용 금지
## 예외 처리
- 커스텀 exception filter 사용
(참조: src/common/filters/http-exception.filter.ts)
- 서비스 레이어에서 도메인 예외 throw, 필터에서 HTTP 상태코드로 변환
## 왜 이렇게 하나요?
Controller에 비즈니스 로직이 들어가면 테스트 작성이 어렵고,
다중 진입점(REST, gRPC, CLI) 지원 시 로직 중복이 발생합니다.
어떤 프레임워크든 레이어 분리 원칙 자체는 동일하게 적용됩니다.| 섹션 | 역할 | 위치 |
|---|---|---|
| 기술 스택·명령어 | 즉각 참조 가능한 기계적 규칙 | 루트 |
| 아키텍처 결정 + WHY | 팀 철학·배경 설명 | 루트 또는 하위 |
| 모듈별 상세 규칙 | 범위 한정, 컨텍스트 절약 | 하위 디렉터리 |
예시 2: .claude/rules/ 디렉터리 구조로 관리하기
파일 하나가 너무 비대해진다면 .claude/rules/ 디렉터리로 분산하는 방법도 있습니다. 실제로 팀에서 이 구조를 도입한 뒤 "어디에 규칙을 추가해야 하나?"라는 혼란이 크게 줄었습니다.
.claude/
└── rules/
├── constitution.md ← 프로젝트 전역 원칙 (이것만큼은 지킨다)
├── api.md ← apps/api/** 적용 규칙
├── database.md ← DB 마이그레이션·쿼리 규칙
├── testing.md ← 테스트 컨벤션
└── security.md ← 보안 지침 (인증·인가·입력 검증)# constitution.md — 프로젝트 전역 원칙
## 기술 스택
- Node.js 20 LTS, TypeScript 5.x strict mode
- 패키지 매니저: pnpm (npm, yarn 사용 금지)
## 절대 원칙 (예외 없음)
### 1. 직접 DB 접근은 Repository 레이어를 통해서만
### 2. 환경 변수는 config 모듈을 통해서만 접근 (process.env 직접 접근 금지)
### 3. 외부 API 호출은 전용 서비스 클래스로 추상화
## 왜 이 원칙들인가?
프로젝트 초반 환경 변수 직접 접근으로 인한 배포 사고가 있었습니다.
테스트 환경에서 실수로 프로덕션 DB에 접근한 사례도 있었습니다.
이 원칙들은 그 경험에서 나온 것입니다.# security.md — 보안 지침
## 입력 검증
- SQL 쿼리는 ORM(TypeORM)의 파라미터 바인딩만 사용
- 사용자 입력을 HTML에 직접 삽입 금지 (XSS 방지)
- 파일 업로드: 확장자 + MIME 타입 이중 검증
## 인증·인가
- JWT 토큰 검증은 AuthGuard에서만
- 권한 체크는 반드시 서비스 레이어 진입 전에
## 민감 정보
- 로그에 비밀번호, 토큰, 개인정보 절대 출력 금지
- 에러 메시지에 내부 스택 트레이스 노출 금지 (프로덕션)예시 3: CLAUDE.local.md로 개인 선호 분리하기
팀 규칙과 개인 선호를 분리하고 싶을 때 CLAUDE.local.md를 활용하면 좋습니다. 이 파일은 .gitignore에 추가해 팀 저장소에 올라가지 않도록 합니다.
# CLAUDE.local.md — 내 개인 선호 (git 추적 안 함)
## 응답 스타일
- 코드 설명 시 TypeScript 타입 추론 과정을 항상 같이 보여줄 것
- 에러 메시지는 항상 한국어로
## 작업 방식
- 리팩터링 제안 전에 현재 코드의 의도를 먼저 확인할 것
- 파일 수정 시 변경 범위가 100줄 초과하면 먼저 물어볼 것# .gitignore에 추가
CLAUDE.local.md장단점 분석
팀에 도입하기 전, "우리 팀에 지금 이게 필요한가?"를 판단하는 데 아래 표가 도움이 되면 좋겠습니다.
장점
| 항목 | 내용 |
|---|---|
| 팀 일관성 | 모든 팀원이 동일한 컨벤션을 AI에게 자동 제공 — 코드 리뷰 부담 감소 |
| 버전 관리 | git에 커밋되어 팀 전체가 반복 개선 가능, 히스토리 추적 가능 |
| 계층적 범위 지정 | 루트·서브디렉터리 분리로 모노레포에 최적화된 규칙 적용 |
| 로컬 오버라이드 | CLAUDE.local.md로 개인 선호를 팀 규칙과 분리 |
| 즉시 시작 | /init 명령으로 기존 프로젝트 구조를 분석해 초안 자동 생성 |
| 크로스 도구 호환 | AGENTS.md와 함께 관리하면 Copilot, Cursor 등 타 도구도 커버 가능 |
단점 및 주의사항
| 항목 | 내용 | 대응 방안 |
|---|---|---|
| 컨텍스트 드리프트 | 작성 당시엔 정확했던 내용이 코드베이스 변경 후 오히려 오도 | 분기 리뷰 주기 설정, 유지보수 오너 지정 |
| 크기 한계 | 파일이 과도하게 커지면 중요 규칙 이행률 저하 (체감상 500줄이 분기점) | 핵심만 루트에, 상세는 하위 파일로 분산 |
| LLM 자동 생성 함정 | /init 자동 생성 파일은 태스크 해결률을 오히려 저하시킬 수 있음 |
자동 생성은 초안으로만 활용, 반드시 팀이 검토·수정 |
| 토큰 비용 | 상세한 파일은 추론 토큰 사용량 증가 | API 과금 환경에서 비용 대비 효과 점검 |
| 팀 합의 비용 | 규칙 추가·변경 시 팀 논의 필요 | PR 리뷰 프로세스와 동일하게 관리 |
컨텍스트 드리프트(Context Drift): 시간이 지나면서
CLAUDE.md의 내용과 실제 코드베이스 사이에 괴리가 생기는 현상입니다. 테스팅 프레임워크를 Jest → Vitest로 교체했는데 파일을 업데이트하지 않으면, AI는 계속 Jest 기반 코드를 생성하게 됩니다.
실무에서 가장 흔한 실수
다음 세 가지 실수는 저도 겪었고, 팀에서도 자주 목격한 패턴입니다.
1. 코드 스니펫 직접 삽입
"항상 이렇게 작성하라"며 긴 코드 예시를 파일에 넣으면, 해당 코드가 리팩터링되거나 삭제됐을 때 AI가 낡은 패턴을 따릅니다. 파일 경로와 참조 위치를 알려주는 방식이 훨씬 안전합니다.
# 좋지 않은 예 — 코드를 파일 안에 직접 붙여 넣음
## 예외 처리
항상 아래처럼 처리할 것:
throw new HttpException('Not found', HttpStatus.NOT_FOUND);
# 권장하는 예 — 파일 경로로 참조
## 예외 처리
커스텀 exception filter를 사용합니다.
참조: src/common/filters/http-exception.filter.ts2. 린터·포매터로 해결 가능한 규칙 과다 명시
ESLint·Prettier가 이미 강제하는 규칙을 CLAUDE.md에 중복 작성하면, 정작 중요한 아키텍처 규칙이 뒤로 밀립니다.
# 좋지 않은 예 — 린터가 처리하는 규칙을 중복 명시
- 들여쓰기는 2칸
- 세미콜론은 항상 붙일 것
- 문자열은 작은따옴표 사용
- 후행 쉼표 필수
# 권장하는 예 — 도구가 처리하는 규칙은 언급만
- 코드 스타일은 .eslintrc, .prettierrc 설정을 따릅니다
- CLAUDE.md에는 도구가 체크할 수 없는 아키텍처·도메인 규칙만 명시합니다3. /init 자동 생성 후 장기 방치
/init은 시작점을 빠르게 잡아주는 도구이지, 완성된 결과물이 아닙니다. 자동 생성된 파일을 그대로 두고 장기간 방치하면 오히려 팀 협업을 방해할 수 있습니다. 자동 생성 직후 팀 전체가 내용을 검토하고, 실제 프로젝트 상황과 다른 부분을 수정하는 과정이 반드시 필요합니다.
마치며
CLAUDE.md는 작성하는 순간보다 유지하는 습관이 더 중요한 살아있는 문서입니다. 처음부터 완벽하게 만들려 할 필요는 없습니다. 헌법이 개정을 거듭하며 성숙해지듯, 이 파일도 팀의 경험이 쌓일수록 더 정확해지고 두꺼워져야 합니다. 팀이 AI와 협업하면서 "이 규칙이 없어서 AI가 삽질했다"는 순간마다 파일을 업데이트하는 문화를 만들어가는 것, 그것이 핵심입니다.
지금 바로 시작해볼 수 있는 3단계:
-
초안 자동 생성: 프로젝트 루트 터미널에서 Claude Code를 열고
/init명령을 실행해보시기 바랍니다. 기존 코드베이스를 분석해CLAUDE.md초안을 만들어 줍니다. 이 파일을 열어 팀의 실제 상황과 다른 부분이 없는지 한 줄씩 검토하는 것을 권장합니다. -
핵심 3섹션 먼저 채우기: 빌드·테스트 명령어(WHAT), 가장 자주 어기는 아키텍처 규칙 + 배경(WHY), 브랜치·커밋 컨벤션(HOW) 세 가지부터 채워보시면 좋습니다. 200줄 이내로 시작하는 것을 권장합니다.
-
팀 PR 프로세스에 통합:
CLAUDE.md변경을 일반 코드 PR과 동일하게 리뷰하는 프로세스를 도입해보시면 좋습니다. 분기에 한 번 전체 파일을 검토하는 "컨텍스트 드리프트 점검" 항목을 스프린트 플래닝에 추가해보시는 것도 큰 도움이 됩니다.
다음 글: AGENTS.md vs CLAUDE.md — 멀티 에이전트 환경에서 두 파일을 동기화하다 충돌이 생겼던 실제 사례와 함께, 크로스 도구 컨텍스트 파일을 단일 소스로 통합 관리하는 방법을 공유할 예정입니다.
참고 자료
공식 문서
- Best Practices for Claude Code | Claude Code Docs
- Using CLAUDE.MD files: Customizing Claude Code for your codebase | Claude Blog
- How Anthropic teams use Claude Code (PDF)
실전 가이드
- Writing a good CLAUDE.md | HumanLayer Blog
- How to Write a Good CLAUDE.md File | Builder.io
- Writing the Best CLAUDE.md: A Complete Guide | DataCamp
- CLAUDE.md Best Practices: 10 Sections to Include | UX Planet
- Claude Code in a Monorepo: The Complete Setup Guide | The Prompt Shelf
- CLAUDE.md, AGENTS.md & Copilot Instructions: Configure Every AI Coding Assistant | DeployHQ
- AGENTS.md vs CLAUDE.md: What's the Difference and When to Use Each | The Prompt Shelf
- The Complete Guide to AI Agent Memory Files | Medium
- Mastering Project Context Files for AI Coding Agents | EclipseSource
- Context Engineering for Teams: A Practical Implementation Guide | Packmind
- rulesync: Unified rules management for Claude Code, Gemini CLI, and Cursor | DEV Community