
CLAUDE.md 를 줄이는 얘기를 두 편 썼다. 내 파일은 원래도 50줄 남짓이라 더 지울 것도 마땅치 않았는데, 안 지켜지는 규칙은 그대로 남아 있었다. 지우는 것보다 먼저 확인할 게 있었다. 그 규칙이 로드되기는 하는가.
배경
"더 지워야 하나" 를 고민하다 방향을 바꿨다. 지운다는 건 그 규칙이 로드돼 있다는 전제 위에서만 성립하는데, 그 전제를 확인해본 적이 없었다. /context 를 열어 Memory files 목록을 봤더니, 있을 거라 믿었던 규칙 파일 하나가 없었다. Claude 는 그 규칙을 무시한 게 아니라 읽은 적이 없었다.
여기서 문제가 갈린다. 안 지켜지는 규칙에는 로드됐는데 묻힌 것과 아예 로드되지 않은 것이 있다. 앞의 것은 줄여서 해결한다. 뒤의 것은 아무리 줄여도 해결되지 않는다. 둘을 구분하지 않으면 멀쩡한 규칙을 계속 지우게 된다.
그래서 로딩 규칙을 공식 문서에서 다시 읽었다. 앞선 두 편(1편, 2편)이 "무엇을 지울 것인가" 였다면 이 글은 "무엇이 언제 들어오는가" 다.
내가 쓴 규칙은 어느 시점에, 어떤 순서로 로드되는가?
CLAUDE.md는 시스템 프롬프트가 아니다
먼저 깨야 할 전제가 하나 있다. CLAUDE.md 는 시스템 프롬프트에 박히지 않는다.
CLAUDE.md content is delivered as a user message after the system prompt, not as part of the system prompt itself.
출처: Claude Code 공식 문서 — memory
설정 파일이 아니라 컨텍스트라는 뜻이다. "규칙을 썼는데 안 지킨다" 는 버그가 아니라 정상 동작 범위 안에 있다. 문서도 강제 준수를 보장하지 않는다고 명시한다.
반드시 실행돼야 하는 것은 CLAUDE.md 에 쓰면 안 된다. 커밋 전에 무조건 린트를 돌려야 한다면 hook 으로 내린다. CLAUDE.md 는 판단에 영향을 주고, hook 은 판단을 건너뛴다.
규칙이 들어오는 네 곳
CLAUDE.md 는 네 개의 스코프에서 로드된다. 넓은 것부터 좁은 것 순이다.
| 스코프 | 위치 | 공유 범위 |
|---|---|---|
| managed policy | macOS /Library/Application Support/ClaudeCode/CLAUDE.mdLinux /etc/claude-code/CLAUDE.md |
조직 전체 |
| user | ~/.claude/CLAUDE.md |
나 (모든 프로젝트) |
| project | ./CLAUDE.md 또는 ./.claude/CLAUDE.md |
팀 (git 으로 공유) |
| local | ./CLAUDE.local.md |
나 (이 프로젝트) |
project 스코프가 두 경로를 받는다는 건 몰랐다. ./.claude/CLAUDE.md 에 넣으면 루트가 덜 지저분해진다. managed policy 는 개인 설정으로 제외할 수 없다.
순서가 의미를 갖는 이유
여러 파일이 발견되면 덮어쓰기가 아니라 이어붙이기로 처리된다. 하위 CLAUDE.md 가 상위 것을 무효화하지 않는다. 둘 다 들어간다.
순서는 세 층으로 정해진다. 스코프는 넓은 것에서 좁은 것으로, 디렉터리 트리는 파일시스템 루트에서 작업 디렉터리 방향으로 쌓인다. 그리고 같은 디렉터리 안에서는 CLAUDE.md 다음에 CLAUDE.local.md 가 붙는다. 실행 위치에 가까운 것일수록 마지막에 읽힌다.
monorepo/apps/web/ 에서 세션을 열었을 때 무엇이 어떤 순서로 쌓이는지를 그림으로 정리했다.

순서를 안다고 충돌이 해결되지는 않는다. 상위와 하위가 모순되는 규칙을 갖고 있으면 Claude 는 둘 중 하나를 임의로 고른다. 나중에 읽힌 쪽이 이긴다는 보장이 없다.
계층을 늘려 상위 규칙을 덮어쓰려는 설계가 위험한 이유다. 상위에 "커밋 메시지는 영어로", 하위에 "한국어로" 를 두면 매번 다른 결과가 나온다. 덮어쓰고 싶으면 상위에서 지워야 한다.
하위 디렉터리는 지연 로드된다
작업 디렉터리보다 위에 있는 파일은 시작할 때 전부 읽힌다. 아래에 있는 파일은 다르다. 시작 시점에는 들어오지 않고, Claude 가 그 디렉터리의 파일을 읽는 순간 들어온다.
├── CLAUDE.md 시작할 때 로드
└── apps/
└── web/ ← 여기서 세션을 열었다
├── CLAUDE.md 시작할 때 로드
└── src/api/
└── CLAUDE.md src/api 안의 파일을 읽어야 로드
내 파일이 /context 에 안 보였던 이유가 여기 있었다. 세션을 막 열었을 때는 목록에 없는 게 맞다.
파생 문제가 하나 더 있다. /compact 로 컨텍스트를 압축하면 프로젝트 루트 CLAUDE.md 는 디스크에서 다시 읽혀 재주입된다. 하위 디렉터리 CLAUDE.md 는 자동으로 재주입되지 않는다. 다음번에 그 디렉터리 파일을 읽을 때까지 없는 상태로 남는다.
긴 세션에서 규칙이 중간부터 무너지는 느낌을 받았다면 여기를 의심해볼 만하다. 다만 나는 문서로 확인했을 뿐, 실제 세션에서 그 순간을 재현해 측정하지는 않았다.
@import는 컨텍스트를 줄이지 않는다
가장 크게 잘못 알고 있던 부분이다. CLAUDE.md 가 길어지면 @ 로 파일을 쪼갠다. 나는 그렇게 하면 본체가 가벼워진다고 믿었다. 1편에서 한 줄로 짚고 지나갔던 얘긴데, 로딩 시점이 이 글의 주제인 만큼 여기서 제대로 판다.
개인 설정은 @~/.claude/my-project-instructions.md 에 있다.
경로를 언급만 하고 싶으면 백틱으로 감싼다: `@README.md`
import 된 파일은 시작 시점에 전부 펼쳐져서 컨텍스트에 들어간다. 문서가 이걸 못 박는다.
Splitting into
@pathimports helps organization but doesn't reduce context, since imported files load at launch.
출처: Claude Code 공식 문서 — memory
200줄짜리 CLAUDE.md 를 50줄 본체와 150줄 import 넷으로 나눠도 컨텍스트에 들어가는 양은 그대로다. 파일 탐색기에서만 깔끔해진다.
규칙이 몇 개 더 있다. import 는 재귀되지만 최대 4홉까지다. 백틱과 코드 블록 안의 @경로 는 import 되지 않으므로, 경로를 텍스트로 언급할 때는 백틱으로 감싼다. 상대 경로는 작업 디렉터리가 아니라 그 import 를 쓴 파일 기준으로 풀린다.
그럼 import 는 쓸모가 없나. 용도가 다르다. AGENTS.md 를 이미 쓰는 레포라면 @AGENTS.md 한 줄로 끌어와 중복을 없앨 수 있다. 정리와 재사용의 도구지, 절감의 도구가 아니다.
진짜로 줄이려면 rules에 paths를 단다
컨텍스트를 실제로 줄이는 수단은 따로 있다. .claude/rules/ 아래에 규칙 파일을 두고 paths 프런트매터를 다는 것이다.
paths:
- "src/api/**/*.ts"
---
# API 규칙
- 모든 엔드포인트에 입력 검증을 넣는다
- 에러 응답은 공통 포맷을 쓴다
이렇게 두면 Claude 가 src/api/ 아래 TypeScript 파일을 읽을 때만 이 규칙이 들어온다. 다른 작업을 할 때는 아예 존재하지 않는다.
함정이 하나 있다. paths 가 없는 rule 파일은 시작할 때 전부 로드된다. .claude/CLAUDE.md 와 같은 우선순위로 들어간다. rules 디렉터리로 옮기는 것만으로는 아무것도 줄어들지 않는다. 줄이는 건 paths 지 디렉터리가 아니다.
세 저장소의 차이를 로드 시점 기준으로 정리하면 이렇다.
| 넣을 곳 | 로드 시점 | 쓸 것 |
|---|---|---|
CLAUDE.md |
매 세션 시작 | 항상 필요한 규칙, 빌드 커맨드 |
.claude/rules/ + paths |
매칭되는 파일을 읽을 때 | 파일 종류·디렉터리별 규칙 |
.claude/skills/ |
호출되거나 관련 판단이 설 때 | 가끔 쓰는 절차, 워크플로 |
확인하는 법
추측하지 말고 목록을 본다. /context 를 실행하면 Memory files 항목에 실제로 로드된 파일이 나온다. 여기 없으면 Claude 는 그 파일을 보고 있지 않다.
/memory 와 헷갈리기 쉽다. /memory 는 파일을 나열하고 편집기로 여는 커맨드라, 아직 존재하지 않는 파일까지 후보로 보여준다. 편집은 /memory, 검증은 /context 로 갈라 쓴다.
목록에 남의 팀 규칙이 딸려 들어와 있다면 claudeMdExcludes 설정으로 경로를 지정해 걷어낼 수 있다. 단 managed policy 파일은 이걸로도 제외되지 않는다.
작은 것 하나 더. 블록 단위 HTML 주석은 컨텍스트에 주입되기 전에 제거된다. <!-- 이 규칙은 2026-07 이후 재검토 --> 처럼 사람 관리자용 메모를 남겨도 토큰을 쓰지 않는다.
트레이드오프
paths 로 잘게 쪼개면 컨텍스트는 줄지만 대신 잃는 게 있다.
지금 어떤 규칙이 켜져 있는지 파악하기 어려워진다. 파일 하나만 열면 되던 게 어떤 파일을 읽었느냐에 따라 달라진다. Claude 의 행동이 이상할 때 원인을 좁히는 난이도가 올라간다. 문서는 InstructionsLoaded hook 으로 어떤 지시 파일이 언제 로드됐는지 로그를 남기는 방법을 안내한다. 나는 아직 붙여보지 않았다.
규칙이 파일을 읽어야 켜진다는 점도 대가다. 코드를 열지 않고 판단하는 상황, 예를 들어 어디에 새 파일을 만들지 정하는 단계에서는 paths 규칙이 없는 것과 같다. 파일을 열기 전에 필요한 규칙은 CLAUDE.md 본체에 남겨야 한다.
파일이 늘수록 모순이 생길 확률도 올라간다. 모순되는 규칙 둘을 만나면 Claude 는 하나를 임의로 고른다. 쪼갤수록 전체를 훑어보는 일이 드물어지고, 낡은 규칙이 조용히 남는다.
확인한 범위도 밝혀둔다. 로딩 동작은 전부 공식 문서 기준이고, 내가 검증한 건 /context 목록으로 확인 가능한 부분까지다. 대규모 모노레포에서 지연 로딩이 얼마나 절감되는지는 측정하지 않았다.
정리
CLAUDE.md 는 덮어쓰기가 아니라 이어붙이기이고, 컨텍스트를 줄이는 수단은 @import 가 아니라 paths 다. 작업 디렉터리 아래의 파일은 그 디렉터리를 건드리기 전까지 존재하지 않는 것과 같다.
다음에 규칙이 안 먹히면 지우기 전에 /context 부터 연다. Memory files 에 파일이 있으면 묻힌 것이고, 그때는 줄이는 게 답이다. 목록에 없으면 위치 문제이고, 줄여봐야 아무것도 달라지지 않는다.
'AI 개발 > 컨텍스트 엔지니어링' 카테고리의 다른 글
| [컨텍스트 엔지니어링] compact 뒤에 스킬은 어떻게 되나 (0) | 2026.09.23 |
|---|---|
| [컨텍스트 엔지니어링] CLAUDE.md 안전하게 줄이는 5단계 (0) | 2026.07.29 |
| [컨텍스트 엔지니어링] 시스템 프롬프트 80%를 지웠는데 성능은 그대로였다 (0) | 2026.07.28 |