CLAUDE.md가 너무 길어졌다면 — .claude/rules로 규칙을 조건부 로드하는 법 (완전 가이드)
목차
개발이 진행되고 규칙화를 거듭하다 보면, CLAUDE.md 가 점점 길어져 관리가 힘들어지는 — 그런 경험 없으신가요?
프런트엔드/백엔드 각각의 규칙, 테스트 규칙, 커밋 메시지 규칙…. 이것들은 전부 기동 시 항상 읽히기 때문에 토큰을 소비하고, 컨텍스트를 압박해 성능 저하의 원인이 됩니다.
이걸 해결하는 것이 .claude/rules 에 작업별 규칙을 나눠 배치하는 방법입니다. 이 글에서는 그 개념 → 설정 방법 → 실전 데모를 한 편에 정리했습니다.
이 글에서 알 수 있는 것
- 왜
CLAUDE.md에 전부 쓰면 비효율인가(비대화 문제) CLAUDE.md(상시)와 규칙(조건부)의 차이와 구분 사용path필드와 글로브 패턴을 이용한 동적 로드 설정- 실제로 어느 파일을 만지면 어느 규칙이 발동하는가(데모)
제1장: 왜 "규칙"이 필요한가(개념)
CLAUDE.md 비대화의 3가지 문제
CLAUDE.md 에 모든 규칙을 쓰면 다음 문제가 일어납니다.
- 토큰 소비 증가: 전체 규칙이 매번 읽힌다
- 쓸데없는 컨텍스트 점유: 그 작업과 무관한 규칙까지 읽힌다
- 유지보수성 저하: 파일이 길어져 한눈에 들어오지 않게 된다
특히 큰 것이 두 번째입니다. 프런트엔드를 쓰고 있는데 무관한 백엔드 규칙까지 읽히는 건, 컨텍스트 관점에서 낭비가 꽤 많거든요.
편의점으로 비유하면
이 상황은 편의점 매뉴얼에 비유하면 이해하기 쉽습니다.
인사와 계산대 조작은 전원이 항상 참조해야 할 매뉴얼이지만, 즉석조리 식품의 조리 절차나 술·담배의 연령 확인은 그 작업을 맡을 때만 참조하면 되는 것들입니다. 전부를 항상 머리에 넣어 두는 건, 사람과 마찬가지로 퍼포먼스가 떨어집니다.
CLAUDE.md와 규칙의 차이
.claude/rules 에 두는 규칙(이하 "규칙")은 Claude Code 공식이 지원하는 구조로, 필요할 때만 필요한 규칙을 읽어 들입니다.
| 관점 | CLAUDE.md | 규칙(.claude/rules) |
|---|---|---|
| 로드 | 항상 읽힌다 | 조건부로 읽힌다 |
| 토큰 | 항상 소비 | 필요할 때만 최소한 |
| 알맞은 내용 | 항상 의식해야 할 공통 규칙(코딩 규약·금지 사항) | 상황별 규칙(API 설계·테스트 규약 등) |
구분 사용의 기본은, CLAUDE.md 에는 항상 참조해야 할 기본 규칙, 규칙에는 상황별 규칙. 나아가 "TypeScript를 쓸 때만의 코딩 규약"처럼 규약 중에서도 조건을 좁힐 수 있는 것은 규칙 쪽에 두면 더 효율적입니다.
제2장: 설정 방법
디렉터리 구조
규칙을 쓰려면 .claude 안에 rules 폴더를 새로 파는, 정해진 구조로 갑니다.
.claude/
└── rules/
├── codestyle.md # path 지정 없음 → 항상 적용
├── api.md # src/api/ 아래만
├── testing.md # *.test.ts(x) 만
└── frontend/ # 정리용 서브폴더(거동에는 영향 없음)
└── react.md # src/components/ 아래만
rules 바로 아래에 Markdown을 둬도 되고, frontend/ backend/ 처럼 서브폴더로 정리할 수도 있습니다. 서브폴더 자체는 Claude Code의 거동에 영향을 주지 않지만, 사람이 관리하기 쉬워집니다.
파일의 기본 형식: 프론트매터 + 본문
각 규칙 파일은 첫머리에 --- 로 감싼 프론트매터를 쓰고, 그 아래 본문으로 지시를 씁니다.
---
path: src/components/**/*
---
# 프런트엔드 개발 규칙
- 컴포넌트는 함수 컴포넌트로 쓴다
- props는 타입 정의를 필수로 한다
위 예시에서는 src/components/ 아래 파일을 편집·작성할 때 이 파일이 읽히고, Claude Code는 본문(프런트엔드 개발 규칙)을 인식합니다.
열쇠가 되는 path 필드
path 를 쓰느냐 마느냐로 거동이 달라집니다.
path 를 지정하지 않으면 CLAUDE.md 에 쓰는 것과 다르지 않습니다. 굳이 규칙으로 나눌 필요는 없고, 규칙을 쓸 때는 기본적으로 path 를 지정한다고 기억해 둡시다. 다만 "항상 읽히게 하고 싶지만 한눈에 보기 좋게 파일을 나누고 싶다"는 사람 쪽 정리 목적으로 일부러 path 없이 두는 건 괜찮은 선택입니다.
글로브 패턴(path 작성법)
path 의 작성법은 글로브 패턴이라 불리며, .gitignore 와 같은 표기법입니다. 자주 쓰는 것을 챙겨 둡시다.
| 패턴 | 의미 |
|---|---|
**/*.ts | 전체 디렉터리의 .ts 파일에 적용 |
*.md | 프로젝트 루트 바로 아래의 .md 만(재귀하지 않음) |
src/**/* | src/ 아래 전체에 재귀적으로 적용 |
src/components/**/* | src/components/ 아래 전체에 적용 |
**/*.{ts,tsx} | .ts 또는 .tsx 어느 쪽이든(복수 패턴) |
.test.ts 라고 하면 테스트 관련만, 같은 식으로 확장자 지정이 가장 많이 쓰입니다. {ts,tsx} 처럼 쉼표와 중괄호로 복수 패턴을 지정하는 것도 자주 쓰이는 패턴이에요. 작성법이 헷갈리면 .gitignore 에서 온 표기법이니 Claude Code 본인에게 물어보는 것도 방법입니다.
로드의 거동
규칙이 읽히면 Claude Code 콘솔 위에 동적으로 로드됐다는 표시가 뜹니다. 포인트는, 같은 세션 안에서 한번 읽히면 그 뒤로는 계속 유효하다는 것. 같은 폴더나 확장자를 만질 때마다 다시 읽는 중복은 없으니 안심하세요.
제3장: 실전 데모
다음 같은 샘플 구성으로 동적 로드를 확인해 봅니다.
project/
├── .claude/rules/
│ ├── codestyle.md # path 없음(상시)
│ ├── api.md # src/api/ 아래
│ ├── testing.md # *.test.ts(x)
│ └── frontend/
│ └── react.md # src/components/ 아래
├── src/
│ ├── api/users.ts
│ └── components/Button.tsx
└── test/
└── Button.test.tsx
실제로 돌리면 다음처럼 동작합니다.
codestyle.md(path 없음):/memory커맨드로 확인하면 항상 읽히는 규칙으로 표시된다. "변수는 카멜 케이스", "상수는 UPPER_SNAKE_CASE", "함수는 동사로 시작한다" 같은 내용이 처음부터 인식된다.src/api/users.ts를 읽는다: Read 툴 실행 후.claude/rules/api.md가 동적으로 로드되어, "RESTful 원칙을 따른다", "오류 응답은 통일 포맷" 등이 인식된다.src/components/Button.tsx·test/Button.test.tsx: 각각react.md·testing.md가 동적으로 읽힌다.
/memory 에 안 나와도 인식되고 있다
나중에 동적으로 읽힌 규칙은 /memory 커맨드 표시에는 나오지 않는 사양인 듯합니다. 표시에 안 나와도 세션 안에서는 규칙으로 제대로 계속 인식되고 있으니 안심하세요(상시 규칙은 표시됩니다).
정리: 규칙 활용 체크리스트
-
CLAUDE.md가 비대해지면.claude/rules/에 작업별로 규칙을 나눈다 - 항상 의식해야 할 규칙은
CLAUDE.md, 상황별 규칙은 규칙으로 - 규칙을 쓸 때는 기본적으로
path를 지정한다(미지정=상시=CLAUDE.md와 같음) -
path는.gitignore와 같은 글로브 패턴(**/*.ts,src/**/*,{ts,tsx}등) - 서브폴더(
frontend/등)는 정리 목적. 거동에는 영향 없음 - 한번 읽힌 규칙은 세션 중 계속 유효
- 동적 로드된 규칙은
/memory에 안 나오지만, 인식은 되고 있다
작성법 설정 자체는 외울 것이 적어 의외로 단순합니다. CLAUDE.md 가 커지기 시작하면 적용 장면에 따라 규칙 파일로 분할해서, 토큰을 절약하며 Claude Code를 돌려 갑시다.
이 글이 도움이 됐다면 추천해 주세요