
Claude Code의 CLAUDE.md 계층적 로드와 @import 구현 ― 우선순위·순환 참조·상대 경로의 3가지 주의점【2026】
요약
Claude Code의 CLAUDE.md 파일이 계층적으로 병합되는 구조와 @import 기능을 통한 파일 참조 방식을 설명합니다. 우선순위 충돌, 상대 경로 해석 방식, 순환 참조 시의 동작 등 실제 사용 시 주의해야 할 3가지 핵심 포인트를 다룹니다.
핵심 포인트
- CLAUDE.md는 Enterprise, Project, User 순으로 병합되어 컨텍스트에 병기됨
- @import 사용 시 상대 경로는 현재 파일의 위치를 기준으로 해석됨
- 깊은 중첩이나 순환 참조 발생 시 무한 루프를 방지하기 위해 로드가 중단됨
- 규칙 충돌을 방지하기 위해 역할(개인/프로젝트)에 따라 작성 위치를 분리 권장
Claude Code의 CLAUDE.md는 「프로젝트 규칙을 AI에게 읽히는 파일」로 사용하는 사람이 많을 것이라 생각되지만, 사실 여러 곳에 배치된 파일이 계층적으로 병합되는 구조로 되어 있다. 게다가 @path/to/file.md라는 표기법으로 파일을 불러오는 import 기능도 있다.
이 기사에서는 이 계층적 로드와 @import를 실제로 구동하여, 다음과 같은 3가지 주의점(ハマりどころ)을 겪은 기록을 남긴다.
상정 독자: Claude Code를 업무나 개인 개발에서 사용하고 있으며, CLAUDE.md를 단일 파일로만 사용해 본 사람.
전제 환경:
-
Claude Code v2.x 계열 (2026년 8월 시점의 최신 계열)
-
macOS / Linux 모두 재현 가능 (경로 표기만 차이 있음)
-
CLAUDE.md는 enterprise → project → user 순으로 여러 곳에서 읽히며, 나중에 읽힌 것이 우선된다 (덮어쓰기가 아닌 "병기"에 가까운 동작) -
@path/to/file.md로 다른 파일을 읽어올 수 있다. 상대 경로는 「읽어오는 원본 파일의 위치」를 기준으로 해결된다 (cwd 기준이 아님) -
import의 재귀는 무한히 파고들지 않는다. 깊은 중첩이나 순환 참조는 도중에 멈추기 때문에, 의도치 않게 일부만 읽히지 않는 케이스가 있다.
Claude Code는 기동 시에 다음 장소를 순서대로 탐색하여 CLAUDE.md를 읽는다 (존재하는 것만).
# 1. 엔터프라이즈 정책 (관리자가 배치, 통상 개인 개발에서는 무관)
/Library/Application Support/ClaudeCode/CLAUDE.md # macOS의 경우
# 2. 프로젝트 루트 (git 관리하에 두는 경우가 많음)
...
실제로 어떤 것이 읽히고 있는지는 세션 중에 확인할 수 있다.
# 프로젝트 루트에 최소한의 CLAUDE.md를 배치
cat > ./CLAUDE.md <<'EOF'
# Project Rules
...
이 상태에서 Claude Code를 기동하면, 두 규칙이 동시에 유효해진다. 한쪽이 다른 쪽을 덮어쓰는 것이 아니라, 양쪽 모두 컨텍스트에 올라간다. "프로젝트 측에 썼는데 글로벌 측의 지시가 우선되어 곤란하다"라는 상담을 가끔 보게 되는데, 실체는 덮어쓰기가 아닌 병기이므로, 모순되는 규칙을 양쪽에 모두 쓰면 프롬프트(Prompt) 내에서 지시가 충돌한다. 이것이 첫 번째 주의점이다.
회피책: 같은 관점의 규칙은 한 곳으로 모은다. 프로젝트 고유의 이야기는 프로젝트 측에, 개인의 작업 스타일은 사용자 측에, 라고 역할을 나누어 작성한다.
CLAUDE.md 안에서 다음과 같이 작성하면, 별도 파일의 내용을 그 자리에 전개할 수 있다.
# CLAUDE.md
@docs/architecture.md
@../shared/coding-rules.md
...
대규모 프로젝트에서 CLAUDE.md가 비대해지는 것을 방지하는 데 편리하며, 팀 공통 규칙을 shared/로 분리하여 여러 프로젝트에서 import 하는 구성도 자주 사용된다.
mkdir -p /tmp/claude-import-demo/shared
cat > /tmp/claude-import-demo/shared/coding-rules.md <<'EOF'
## 공통 코딩 규칙
...
project-a에서 Claude Code를 기동하면 shared/coding-rules.md의 내용이 전개된 상태로 읽힌다.
@../shared/coding-rules.md
이 경로는 「Claude Code를 기동한 디렉토리」로부터의 상대 경로가 아니라, 「이 @import를 작성하고 있는 CLAUDE.md 자신의 위치」로부터의 상대 경로로서 해결된다.
내가 빠졌던 함정은, 서브 디렉토리의 docs/CLAUDE.md에서 @../../shared/x.md와 같이 작성하려 했으나, 실제로는 docs/CLAUDE.md에서 본 상대 경로였기에 한 계층 정도 어긋나 있었던 케이스였다. 에러 메시지는 특별히 나오지 않고, 단순히 해당 파일이 읽히지 않고 조용히 무시되기 때문에, "규칙을 썼는데 반영되지 않는다"는 상태가 되어 원인 규명에 시간을 허비했다.
회피책: import 시 원래 파일 경로를 기점으로, 실제로 ls 명령어로 경로를 따라가며 확인한 뒤 작성한다. 가능한 한 깊은 중첩(nesting) 구조에서 @../../를 남용하는 것은 피하고, import 되는 대상 파일들을 프로젝트 루트(project root) 직하로 집약시킨다.
a.md가 b.md를 import 하고, b.md가 다시 a.md를 import 하는 식의 순환(cycle) 구조를 만들면, 당연하게도 무한 루프에 빠지는 대신 중간에 읽기가 중단된다. 마찬가지로 import의 연쇄가 일정 계층보다 깊어지면 그 이상은 전개되지 않는다.
<!-- a.md -->
@b.md
<!-- b.md -->
...
이러한 구성을 의도적으로 만드는 경우는 거의 없지만, "공통 규칙 파일들을 가로질러 상호 참조하게 만드는" 설계(예: architecture.md와 conventions.md가 서로 링크되는 경우)를 하면 자신도 모르는 사이에 순환에 가까운 구조가 되기 쉽다. 나의 경우, 3개의 파일이 A→B→C→A 형태로 순환하고 있었는데, C의 내용만 컨텍스트(context)에 포함되지 않고 있다는 사실을 깨닫지 못한 채 며칠 동안 그대로 운용해 버렸다.
회피책: import 의존 관계는 단방향 트리 구조(root CLAUDE.md → 각 토픽별 파일, 토픽별 파일끼리는 서로 import 하지 않음)로 설계한다.
@path.md 표기법은 텍스트 내 어디에 작성하더라도 전개 대상으로 인식되기 때문에, 코드 블록(code block) 내에서 @sample.md와 같은 문자열을 샘플로 작성했을 경우에도 import로 처리되어 버리는 경우가 있다.
## 사용 예시
다음과 같이 작성하면 import할 수 있습니다:
```markdown
...
이 케이스에서 `example-config.md`라는 실제 파일이 존재하지 않으면 그냥 무시되지만, 우연히 프로젝트 내에 동일한 이름의 파일이 존재한다면 **설명을 위한 샘플이었던 것이 실제로 그 내용이 전개되어 버린다**. 문서 내에서 `@import` 작성법 자체를 설명하고 싶을 때 주의가 필요하다.
**회피책**: 설명용 샘플 코드에서는 `@` 직후에 제로 너비 공백(zero-width space)을 삽입하거나, `` `@path.md` `` (인라인 코드) 대신 이미지나 다른 표기법을 사용하는 등 실제 import 표기법과 구별할 수 있는 방식으로 작성한다.
이러한 사양이 된 이유는, `CLAUDE.md`가 "팀과 공유하면서도 개인의 작업 스타일을 얹을 수 있는" 것을 목표로 설계되었기 때문이라고 생각된다. enterprise → project → user로 이어지는 순서 또한 조직의 정책을 토대로 프로젝트 고유 규칙, 나아가 개인의 습관을 쌓아 올릴 수 있도록 하기 위한 것일 것이다.
이 계층 구조를 이해해 두면 "팀 전체의 규칙은 project 측에, 나만의 메모는 user 측에" 깔끔하게 분리할 수 있으며, `CLAUDE.md`가 하나의 거대한 파일로 비대해지는 것을 방지할 수 있다.
-
- `CLAUDE.md`는 enterprise/project/user의 여러 곳에서 **병기(併記)되는** 것이며, 덮어쓰기가 아니다.
- `@path`의 상대 경로는 **import 하는 원본 파일의 위치 기준**이며, cwd(현재 작업 디렉토리) 기준이 아니므로 주의해야 한다.
- 순환 참조 및 깊은 중첩은 조용히 중단된다. import 구조는 단방향 트리로 만든다.
- 읽히지 않거나 반영되지 않을 때는 에러가 발생하지 않는 경우가 많으므로, 실제로 `ls`로 경로를 따라가며 확인하는 것이 결국 가장 빠르다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기