CLAUDE.md를 구조화하는 방법: 문서가 아니라 로딩 정책입니다
요약
Claude Code의 CLAUDE.md 파일을 단순한 문서가 아닌 효율적인 로딩 정책(loading policy) 관점에서 구조화하는 방법을 설명합니다. 파일의 위치와 계층에 따라 로딩 방식과 비용이 달라지므로, 이를 전략적으로 구성해야 합니다.
핵심 포인트
- CLAUDE.md는 단순 문서가 아닌 로딩 정책으로 접근해야 함
- 파일 위치에 따라 항상 로드되거나 필요 시 로드되는 계층(Tier)이 나뉨
- 루트 디렉토리의 설정은 매 세션 비용을 발생시키므로 주의 필요
- 하위 디렉토리의 CLAUDE.md는 필요할 때만 로드되는 게으른(lazy) 방식임
한 개발자가 [BUG] Claude Code가 CLAUDE.MD 파일을 지속적으로 무시함이라는 제목의 버그를 보고했을 때, Anthropic은 이를 '계획되지 않음(not-planned)'으로 종료하고 area:model이라는 라벨을 붙였습니다. 이는 버그 트래커에서 _우리가 패치할 수 있는 결함이 아님_을 의미하는 약어입니다 (anthropics/claude-code#34197). 해당 보고서에는 문제를 일으킨 세션에서 그대로 복사된 자백이 포함되어 있었습니다:
CLAUDE.md와 메모리 파일에 규칙이 명확히 적혀 있습니다. 저는 그것들을 읽었고 알고 있음에도 불구하고 여전히 규칙을 위반했습니다.
— GitHub: anthropics/claude-code#34197
만약 모델이 규칙을 알고 있음에도 불구하고 이를 어긴다면, 더 길고 엄격한 CLAUDE.md를 만드는 것은 해결책이 아닙니다. 해결책은 구조적인 것입니다. CLAUDE.md는 당신이 채워 넣는 문서가 아니라, 당신이 구성하는 로딩 정책 (loading policy)입니다. 문제가 발생하는 대부분의 이유는 콘텐츠가 잘못된 계층 (tier)에 위치하여, 해당 세션에 필요 여부와 상관없이 모든 세션에 비용이 청구되기 때문입니다.
Claude Code가 이미 실행 중인 세 가지 로딩 계층 (Loading Tiers)
CLAUDE.md에 무엇을 넣을지 결정하기 전에, 그것이 어디에서 로드되는지 살펴보십시오. Claude Code는 이미 당신의 지침을 세 가지 계층으로 분류하고 있으며, 어떤 계층에 속하느냐에 따라 비용이 결정됩니다.
작업 디렉토리 상위의 디렉토리 계층에 있는 CLAUDE.md 및 CLAUDE.local.md 파일은 실행 시 전체가 로드됩니다. 하위 디렉토리에 있는 파일은 Claude가 해당 디렉토리의 파일을 읽을 때 필요에 따라 (on demand) 로드됩니다.
— Claude Code Docs: How Claude remembers your project
이로 인해 당신의 설정은 세 가지 다른 비용을 가진 세 가지 계층으로 나뉩니다:
| 계층 (Tier) | 포함 내용 | 로딩 시점 | 비용 부담 |
|---|---|---|---|
| 항상 로드됨 (Always-loaded) | 루트 및 조상 CLAUDE.md, @-임포트 (imports), 범위가 지정되지 않은 .claude/rules/ | 실행 시 전체 로드 | 매 세션 |
| ... |
읽기당 비용이 발생하는 (pay-per-read) 계층은 시작 시 스캔하는 방식이 아니라, 게으른 (lazy) 방식이며 파일 액세스에 의해 트리거됩니다. Claude Code의 제작자는 하위 디렉토리 로딩을 즉시 (eager) 수행하도록 하는 요청을 거절하며 이를 확인했습니다: Claude는 해당 디렉토리의 파일들을 작업할 때 하위 디렉토리의 CLAUDE.md를 자동으로 읽습니다 (anthropics/claude-code#4275). 벤더(vendor)의 대규모 코드베이스 (large-codebases) 가이드라인에서도 동일한 가산적 (additive) 동작을 설명합니다 — "전체적인 그림을 위한 루트 파일, 로컬 컨벤션 (local conventions)을 위한 하위 디렉토리 파일" (Claude by Anthropic: Large codebases). 트리거당 비용이 발생하는 (pay-per-trigger) 계층은 수치화되어 있습니다: 하나의 스킬 (skill)은 약 100 토큰의 항상 로드되는 메타데이터 비용이 들며, 5k 토큰 미만의 본문은 해당 스킬이 실행될 때만 컨텍스트 윈도우 (context window)에 진입합니다 (Anthropic: Agent Skills overview).
이것이 바로 컨텍스트 엔지니어링 (context engineering)이며, Anthropic은 이를 다음과 같이 정의합니다: "따라서 컨텍스트는 한계 효용이 체감되는 유한한 자원으로 취급되어야 합니다." 여기서 CLAUDE.md는 "처음에 컨텍스트에 순진하게(naively) 던져지는" 부분인 반면, glob과 grep은 나머지를 적시 (just-in-time) 방식으로 가져옵니다 (Anthropic: Effective context engineering). 항상 로드되는 계층은 정확히 그 역할을 수행합니다 — 당신이 단 한 마디를 입력하기도 전, 매 세션의 시작 시점에 컨텍스트에 포함되어 있습니다 (Claude by Anthropic: Using CLAUDE.md files).
실제 파일을 가져와 봅시다. 한 개발자가 2,100줄짜리 CLAUDE.md를 150줄의 핵심 파일과 다섯 개의 @-임포트된 문서( testing.md (270줄), typescript.md (305줄), code-style.md (370줄), workflow.md (671줄), 그리고 examples.md (278줄))로 분할했습니다. 이는 모든 '간결하게 유지하라(keep it lean)' 가이드가 권장하는 깔끔하고 모듈식 레이아웃입니다 (anthropics/claude-code#11759). 이를 표에 매핑하면 정돈된 느낌이 사라집니다. @-임포트는 로드 시점에 불러와지므로, 여섯 개의 파일 모두 항상 로드되는 계층(always-loaded tier)을 이용합니다. 분할은 파일 브라우저를 바꿨을 뿐, 청구서(bill)는 바꾸지 못했습니다. 이 코퍼스(corpus)는 아래 모든 섹션에서 반복되는데, 이미 초보적인 수정 방법을 시도하고 그 결과를 측정했습니다.
자신만의 환경에서 Pay-Per-Read 계층 검증하기
Pay-per-read 계층은 문서화된 설계이지만, 신뢰성 관련 주의사항이 있습니다. 이 기능을 기반으로 디렉터리 규칙에 의존하기 전에 반드시 확인해야 합니다. 작동하지 않는다는 보고가 해결되지 않은 상태로 존재합니다:
- 하위 디렉터리 규칙이 조용히 무시될 경우, 환경(surface)을 의심하십시오. 중첩 로딩은 VS Code 확장 프로그램에서 오작동했다고 보고되었으며, CLI는 작동하는 것으로 알려져 있습니다 (anthropics/claude-code#24987). 이전의 macOS 관련 보고서는 수정 없이 계획되지 않은 사항으로 닫혔습니다 (anthropics/claude-code#2571).
- 중첩된 파일에 의존하기 전에
/memory를 실행하십시오. 이 명령어는 현재 세션에서 로드되는 모든 CLAUDE.md, CLAUDE.local.md 및 규칙 파일을 나열합니다. 예상하는 파일이 목록에 없다면, Claude가 이를 볼 수 없습니다 (Claude Code Docs: How Claude remembers your project). - 지연 계층(lazy tiers)은 Just-in-Time (JIT) 검색으로 취급하고, JIT의 실패 모드를 염두에 두십시오. 이들은 Claude가 탐색함에 따라 콘텐츠를 가져옵니다. 강력하지만, 조용히 깨질 수 있는 방법들이 있으며, 이는 지연 검색이 조용히 실패하는 경우에 대한 별도 게시물의 주제입니다.
너무 상세하게 지정된 CLAUDE.md는 명명된 실패 모드이다
정돈함(tidiness)이 아니라 준수(adherence)를 기준으로 CLAUDE.md를 가지치기하세요. 파일의 어텐션 예산(attention budget)을 초과하면, 추가하는 모든 규칙은 이미 존재하는 규칙의 비중을 깎아먹습니다. 실제로 한 번에 변경 사항을 반영하는 데 필요한 규칙들은 결국 묻혀버리게 됩니다. Anthropic은 이 패턴을 직접적으로 명시하고 있습니다:
과도하게 상세하게 지정된 CLAUDE.md. 만약 CLAUDE.md가 너무 길면, 중요한 규칙들이 노이즈 속에 묻히기 때문에 Claude는 그중 절반을 무시합니다.
— Claude Code Docs: Best practices
이는 단순한 설화가 아니라 측정된 사실입니다. 단일 프롬프트를 10개에서 500개의 동시 지시사항으로 확장하는 벤치마크인 IFScale를 통해 확인한 결과, 가장 뛰어난 프론티어 모델(frontier models)조차 지시사항이 500개에 도달하면 정확도가 68%에서 정체되는 것으로 나타났습니다. 또한 초기 지시사항에 대한 편향(bias)은 약 150~200개 사이에서 정점에 달합니다 (arXiv: How Many Instructions Can LLMs Follow at Once?). 지시사항의 한계치(instruction ceiling)는 실재하며 생각보다 가까이 있으며, 이것이 바로 루트 파일의 예산에 관한 동반 게시물에서 주장하는 핵심 내용입니다.
이 메커니즘은 잘 문서화되어 있으며 CLAUDE.md에만 국한된 것이 아닙니다. 18개의 모델을 대상으로 진행된 Chroma의 컨텍스트 부패(context-rot) 연구에 따르면, 입력 길이가 길어질수록 성능의 신뢰도가 떨어지며 방해 요소(distractors)가 늘어날수록 그 악영향이 가중되는 것으로 나타났습니다:
단 하나의 방해 요소만으로도 베이스라인(바늘만 있는 경우) 대비 성능이 저하되며, 4개의 방해 요소를 추가하면 이러한 성능 저하가 더욱 심화됩니다.
— Chroma: Context Rot
위치는 상황을 더 악화시킵니다. 모델은 긴 컨텍스트 (Context) 중간에 고립된 정보를 사용하는 데 가장 취약하며 (Liu et al.: Lost in the Middle), 단순한 길이 문제로 인해 상황은 더 나빠집니다. 한 연구에 따르면, 모델이 모든 관련 사실을 완벽하게 검색할 수 있는 상황에서도 입력값이 증가함에 따라 정확도가 13.9~85%까지 하락하는 것으로 측정되었습니다 (Du et al.: Context Length Alone Hurts LLM Performance). 단 하나의 무관한 문장만으로도 모델이 이전에는 깔끔하게 해결했을 문제를 탈선시키기에 충분합니다 (Shi et al.: Distracted by Irrelevant Context). 통제된 추론 벤치마크 (Reasoning benchmark)에서 방해 요소 (Distractors)가 1개에서 15개로 늘어남에 따라 단계별 정확도 (Step accuracy)는 26%에서 2%로 떨어졌습니다 (arXiv: GSM-DC).
이 논의가 과도해지는 것을 막아주는 정직한 주의 사항이 하나 있습니다. 작업과 전혀 관련이 없는 진정한 의미의 채우기용 텍스트(Filler) — 즉, 작업과 타당한 연관성이 없는 텍스트 — 는 정확도보다는 주로 지연 시간 (Latency) 비용을 발생시킵니다. 한 연구에서는 70B 모델에 15,000단어의 일반적인 노이즈를 포화시켜 보았을 때, 정확도는 98.5%에서 98%로 약간만 하락한 반면, 지연 시간은 719.64% 증가하는 것을 관찰했습니다 (Ponnusamy et al.: Context Discipline and Performance). 정확도에 손상을 입히는 것은 '그럴듯하지만 적용 불가능한' 선입니다. 예를 들어, bash 작업 중에 관련 있어 보이는 TypeScript 컨벤션 (Convention) 같은 것입니다. 따라서 규칙은 "모든 것을 삭제하라"가 아닙니다. 규칙은 다음과 같습니다: 모든 비보편적인 라인을 의심스러운 것으로 취급하십시오. 왜냐하면 적용될 법하게 읽히는 것들이 바로 실질적인 피해를 주기 때문입니다.
이것이 바로 위의 코퍼스 (Corpus)가 단일 덩어리 (Monolith)보다 더 나쁜 이유입니다. 작성자의 측정에 따르면 로드된 콘텐츠의 85~90%가 대부분의 대화와 무관합니다 (anthropics/claude-code#11759). 세션당 지불하는 비용의 대부분은 가이드가 아닌 방해를 사는 데 사용됩니다. 즉, 500개의 명령어가 채 되기도 전에 희박해지기 시작하는 어텐션 예산 (Attention budget)을 두고 2,100개의 라인이 경쟁하고 있는 것입니다.
@imports가 당신을 구원하지 못하는 이유
CLAUDE.md가 너무 길어지면, @path 임포트 (import)를 사용하여 파일을 분할하고 이를 효율적이라고 생각하는 것이 본능적인 반응입니다. 하지만 그 본능은 잘못되었으며, 구체적이고 측정 가능한 방식으로 틀렸습니다. 파일을 나누는 것은 조직화 (organization)일 뿐, 로딩 감소 (load reduction)가 아닙니다.
나쁜 예: 2,100라인의 파일을 150라인의 핵심 파일과 5개의 @docs/*.md 임포트로 분할하는 경우. 모듈식으로 보이지만, 로딩은 동일합니다. 즉, 모든 세션이 시작될 때 약 2,100라인 전체가 컨텍스트 (context)에 들어옵니다. 정확히 이 방식으로 분할을 구현했던 작성자는 그 결과를 다음과 같이 측정했습니다: "단일 파일(monolithic file)과 동일한 토큰을 사용하며, 조직화 측면의 이점만 제공한다" (anthropics/claude-code#11759).
좋은 예: 동일한 콘텐츠를 실제로 로딩을 제어하는 계층 (tiers)으로 이동하는 것입니다. typescript.md는 Claude가 .ts 파일을 다룰 때만 로드되는 경로 범위 규칙 (path-scoped rule)이 되고, workflow.md는 호출될 때만 로드되는 기술 (skill)이 됩니다. 이제 bash 전용 세션에서는 이 비용을 전혀 지불하지 않습니다.
문서에서는 이 메커니즘을 명확하게, 그리고 여러 번에 걸쳐 명시하고 있습니다:
@path 임포트로 분할하는 것은 조직화에는 도움이 되지만, 임포트된 파일은 시작 시점에 로드되기 때문에 컨텍스트 (context)를 줄여주지는 않습니다.
— Claude Code Docs: How Claude remembers your project
이것이 중요한 이유는 잘못된 모델이 능동적으로 학습되기 때문입니다. 한 인기 있는 가이드에서는 @-import를 순수하게 효율성을 높이는 방법으로 설명합니다. 즉, "상세한 지침을 별도의 마크다운 (Markdown) 파일에 작성한 다음 이를 참조하십시오. Claude는 관련이 있을 때 해당 콘텐츠를 가져옵니다" (Builder.io: How to Write a Good CLAUDE.md). 하지만 "관련이 있을 때"라는 표현은 import가 작동하는 방식과 정확히 다릅니다. import는 관련 여부와 상관없이 실행 시점에 로드됩니다. 작동 메커니즘을 정확하게 설명하는 가이드조차도 — import는 "콘텐츠가 인라인 (inline)으로 확장되어 여전히 활성 창 (active window)에 포함되기 때문에 컨텍스트 (context) 사용량을 줄이지 않는다" (Bijit Ghosh: The Complete Guide to CLAUDE.md) — 메커니즘 설명에서 멈출 뿐, 이를 배치 규칙 (placement rule)으로 전환하지는 않습니다. 그 규칙이 다음 섹션에서 다뤄집니다.
필요한 세션에 따라 모든 라인을 경로 지정하십시오
여기 실제로 효과가 있는 해결책이 있습니다. CLAUDE.md의 모든 라인에 대해 한 가지 질문을 던지십시오. "어떤 세션이 이것을 필요로 하는가?" — 그리고 그 답변에 따라 티어 (tier)를 결정하십시오. 이것은 Anthropic의 자체 지침이기도 합니다: "만약 항목이 다단계 절차이거나 코드베이스의 특정 부분에만 중요하다면, 대신 스킬 (skill)이나 경로 범위 규칙 (path-scoped rule)으로 이동하십시오" (Claude Code Docs: How Claude remembers your project).
| 콘텐츠 클래스 | 경로 | 로드 시점 |
|---|---|---|
| 모든 세션에 필요한 사실 (Facts every session needs) — 빌드 명령, "항상 X를 수행할 것", 중요한 주의 사항 (gotchas) | 루트 CLAUDE.md, 짧게 유지 | 실행 시 전체 로드 |
| ... |
기술 (skills) 행은 문서가 가장 직접적인 부분입니다: "CLAUDE.md는 매 세션마다 로드되므로, 광범위하게 적용되는 사항만 포함하십시오. 도메인 지식이나 가끔만 관련이 있는 워크플로우의 경우, 대신 기술 (skills)을 사용하십시오" (Claude Code Docs: Best practices). 지정된 전문가 (Named practitioners) 또한 같은 곳에 위치합니다. 기술 (skill)은 "단 몇십 개의 추가 토큰만 차지하며, 사용자가 해당 기술이 해결하는 데 도움이 될 수 있는 작업을 요청할 때만 전체 세부 정보가 로드됩니다" (Simon Willison: Claude Skills). 루트 파일에 대한 원칙은 "간결하고 보편적으로 적용 가능하게" 유지하는 것입니다 (HumanLayer: Skill Issue).
따라서 라우팅(routing) 문제는 "이 규칙이 좋은가?"가 아니라 "어떤 세션이 그 비용을 지불해야 하는가?"입니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기