「설정과 커스터마이즈」 코스의 마지막 글입니다. 앞에서 CLAUDE.md를 짧게 유지하라고 거듭 말했고, @참조는 정리는 되지만 절약은 안 된다고 했습니다. 실제로 컨텍스트를 아끼는 도구가 이 글의 .claude/rules/입니다. 규칙을 주제별 파일로 나누고, paths 프론트매터를 걸면 그 패턴에 맞는 파일을 Claude가 읽을 때만 규칙이 실립니다. 우리 팀이 CLAUDE.md 관례로 채택한 ".claude/rules + paths glob으로 조건부 로딩"이 바로 이것입니다.
핵심 요약
.claude/rules/아래.md파일은 재귀적으로 전부 발견되며,paths가 없으면 시작 시 프로젝트 CLAUDE.md와 같은 우선순위로 로드됩니다.paths를 걸면 Claude가 일치하는 파일을 읽을 때만 로드됩니다. 모든 도구 호출마다가 아니라 "파일을 읽을 때"입니다.- glob은
**/*.ts,src/**/*,src/**/*.{ts,tsx}처럼 쓰고, 한 규칙에 여러 패턴을 나열할 수 있습니다. - 사용자 수준
~/.claude/rules/도 있으며 프로젝트 규칙보다 먼저 로드됩니다. - 로드 확인은
/context의 Memory files 목록, 편집은/memory, 정밀 추적은InstructionsLoaded훅입니다.
CLAUDE.md는 왜 비대해지는가
한 파일에 모든 팀의 규칙이 모이기 때문입니다. 프론트엔드 스타일 30줄, API 규칙 30줄, 테스트 규칙 20줄, 문서 규칙 20줄, DB 규칙 20줄. 각각은 짧지만 합치면 200줄을 넘고, 회의록을 정리하는 세션에도 React 규칙이 실립니다. 매 세션 토큰을 내고 준수율은 떨어집니다. 공식 문서도 지침이 커지면 경로 범위 규칙으로 옮기라고 안내합니다.
우리 사이트 레포의 경우 결제·DB·UI·문의 처리 규칙 11개가 한 파일에 있습니다. 아직 200줄 아래라 유지하고 있지만, 어드민 리스타일이 시작되면 UI 규칙은 app/**/*.tsx에서만 실리도록 뺄 계획입니다.
.claude/rules/의 기본 구성
project/
├── CLAUDE.md # 공통 규칙 20줄
└── .claude/
└── rules/
├── code-style.md # paths 없음: 항상 로드
├── testing.md
├── security.md
└── frontend/
└── components.md # 하위 폴더도 재귀적으로 발견
파일 하나에 주제 하나를 두고 이름을 설명적으로 짓습니다. paths가 없는 규칙은 무조건 로드되어 모든 파일에 적용되며, 우선순위는 .claude/CLAUDE.md와 같습니다. 즉 파일을 나누기만 해도 팀이 유지 관리하기는 쉬워지지만 컨텍스트는 그대로입니다. 절약은 다음 절부터입니다.
paths로 조건부 로드하기
---
paths:
- "app/api/**/*.ts"
---
# API 규칙
- 모든 엔드포인트는 입력 검증을 포함한다.
- 결제 금액은 서버가 정한다. 클라이언트 값을 신뢰하지 않는다.
- 오류 응답은 `{ error: string }` 형식으로 통일한다.
동적 로드가 일어나는 모습
세션을 열면 이 규칙은 컨텍스트에 없습니다. /context의 Memory files 목록을 봐도 없습니다. Claude에게 "문의 접수 API를 고쳐 줘"라고 하면 Claude가 app/api/course-inquiry/route.ts를 읽고, 그 순간 패턴이 맞아 규칙이 실립니다. 이후 /context의 Memory files 목록에 나타납니다. 트리거는 "일치하는 파일을 읽을 때"이며 Grep이나 Bash 같은 다른 도구 호출로는 발동하지 않습니다. v2.1.198 이상에서는 심볼릭 링크 경로로 파일에 도달해도 일치합니다.
Glob 패턴은 어떻게 쓰나
| 패턴 | 일치 |
|---|---|
**/*.ts |
모든 폴더의 TypeScript 파일 |
src/**/* |
src/ 아래 전부 |
*.md |
프로젝트 루트의 마크다운만 |
app/components/*.tsx |
그 폴더 바로 아래의 컴포넌트 |
src/**/*.{ts,tsx} |
중괄호 확장으로 확장자 여러 개 |
*는 한 폴더 안, **는 폴더를 건너 재귀입니다. [는 [abc] 같은 괄호 표현식의 시작으로 해석되므로 파일명에 [가 있으면 \[로 이스케이프합니다. 잘못된 패턴은 아무것도 맞지 않을 뿐 규칙의 다른 패턴은 계속 동작합니다(v2.1.207 이상).
여러 패턴을 한 규칙에 걸기
---
paths:
- "app/**/*.tsx"
- "components/**/*.tsx"
- "lib/ui/**/*.ts"
---
하나라도 맞으면 로드됩니다. 프론트엔드 코드가 세 폴더에 흩어져 있어도 규칙은 하나면 됩니다.
실전 구성 예 3가지
예 1: 프론트엔드와 백엔드 규칙 분리
.claude/rules/
├── frontend.md # paths: ["app/**/*.tsx", "components/**/*.tsx"]
└── backend.md # paths: ["app/api/**/*.ts", "lib/db.ts"]
frontend.md에는 "390px·360px에서 가로 스크롤 실측", "브랜드명은 env로만", backend.md에는 "service_role 키 모듈은 클라이언트에서 import 금지", "스키마는 add column if not exists로 누적". 회의록을 정리하는 세션에는 둘 다 실리지 않습니다.
예 2: 테스트 파일 전용 규칙
---
paths:
- "**/*.test.ts"
- "tests/**/*"
---
# 테스트 규칙
- 실제 결제·발송 API를 호출하지 않는다. 모킹한다.
- 테스트 데이터의 고객명은 홍OO 형태로만 쓴다.
- 통과 시 출력 없음, 실패 시만 로그를 남긴다.
예 3: 문서 작성 규칙
---
paths:
- "content/**/*.md"
- "docs/**/*.md"
---
# 발행 문구 규칙
- 존댓말 "~합니다"로 쓴다.
- 수익 보장 표현을 쓰지 않는다. 수치는 실측 사례와 조건을 병기한다.
- 문장을 잇는 작대기를 쓰지 않는다. 목록은 마크다운 불릿과 번호만 쓴다.
우리 팀의 발행 문구 게이트를 규칙 파일로 옮긴 형태입니다. 코드 작업 세션에는 문구 규칙이 실리지 않고, content/ 아래 문서를 열면 그때 실립니다.
규칙이 로드됐는지 확인하려면
/context: Memory files 목록에 현재 로드된 CLAUDE.md, CLAUDE.local.md, rules 파일이 나열됩니다. 조건부 규칙은 일치하는 파일을 읽은 뒤에 나타납니다. rules가 차지하는 토큰도 여기서 보고, 조건부로 뺀 뒤 CLAUDE.md 항목이 줄었는지 비교합니다./memory: 로드되는 메모리 파일을 골라 편집기로 여는 진입점입니다.InstructionsLoaded훅: 어떤 지침 파일이 언제, 왜 로드됐는지 기록합니다. 경로 조건부 규칙과 하위 폴더 CLAUDE.md의 지연 로드를 디버깅하는 공식 방법입니다.
{
"hooks": {
"InstructionsLoaded": [
{ "hooks": [ { "type": "command", "command": "jq -c . >> ${CLAUDE_PROJECT_DIR}/.claude/instructions.log" } ] }
]
}
}
@참조·Skills와는 언제 가르나
| 로드 시점 | 적합한 것 | |
|---|---|---|
| CLAUDE.md | 항상 | 매 세션 필요한 사실과 명령 |
| @참조 | 항상 | 기존 문서를 중복 없이 연결 |
.claude/rules/ + paths |
일치 파일을 읽을 때 | 파일 종류별 규칙 |
| Skill | 호출 시 또는 description이 맞을 때 | 다단계 절차, 긴 참조 자료 |
"항상 알아야 하는가"에 예면 CLAUDE.md나 @참조, "특정 파일을 다룰 때만"이면 rules, "특정 작업을 할 때만"이면 Skill입니다. Skill도 paths 프론트매터를 지원하므로 파일 종류에 묶인 절차는 Skill에 paths를 거는 선택지도 있습니다. 규칙은 "어떻게 써라", Skill은 "이 순서로 해라"로 나누면 헷갈리지 않습니다.
정리
.claude/rules/는 규칙을 주제별로 나누는 폴더이고,paths가 있어야 컨텍스트가 절약됩니다.- 트리거는 일치하는 파일을 읽을 때이며, 여러 패턴과 중괄호 확장을 쓸 수 있습니다.
- 프론트·백엔드, 테스트, 문서 세 갈래로 나누는 것이 가장 흔한 출발점입니다.
- 확인은
/context의 Memory files 목록과InstructionsLoaded훅, 편집은/memory입니다.
자주 묻는 질문
paths를 지정하지 않으면 어떻게 되나요?
무조건 로드되어 모든 파일에 적용됩니다. 시작 시 .claude/CLAUDE.md와 같은 우선순위로 실립니다. 파일을 나누는 정리 효과는 있지만 컨텍스트 절약은 없으므로, 절약이 목적이면 paths를 꼭 붙입니다.
규칙이 실제로 로드됐는지 어떻게 확인하나요?
/context의 Memory files 목록에서 봅니다. 조건부 규칙은 일치하는 파일을 읽은 뒤에야 나타납니다. 정확한 시점과 이유까지 필요하면 InstructionsLoaded 훅으로 로그를 남깁니다.
같은 규칙이 세션 안에서 여러 번 로드되나요?
한 번 실린 규칙은 그 세션의 컨텍스트에 남아 이후 턴에도 적용됩니다. 다만 /compact 뒤에는 루트 CLAUDE.md만 자동으로 다시 실리고 하위 폴더의 중첩 CLAUDE.md는 그 폴더 파일을 다시 읽을 때 재로드되므로, 압축 직후 규칙이 빠진 것처럼 보이면 관련 파일을 다시 읽게 하면 됩니다.
여러 경로를 한 규칙에 걸 수 있나요?
됩니다. paths 아래에 패턴을 여러 줄 나열하고, 한 패턴 안에서 {ts,tsx} 중괄호 확장도 쓸 수 있습니다. 하나라도 맞으면 로드됩니다.