
CLAUDE.md의 「수시 참조」는 수시가 아니었다 — @import와 Skills의 차이
요약
Claude Code의 CLAUDE.md 내 @import 방식과 Skills 기능의 동작 차이를 분석합니다. @import는 세션 시작 시 파일 전체를 문맥에 포함시키지만, Skills는 필요할 때만 본문을 읽는 지연 로딩(Lazy Loading) 방식으로 동작함을 확인했습니다.
핵심 포인트
- CLAUDE.md의 @import는 파일 전체를 즉시 문맥에 포함함
- Skills 기능은 프론트매터의 설명문만 상주시키고 필요 시 본문을 로드함
- 토큰 절약보다는 모델의 문맥 집중도와 정확도 측면에서 차이가 발생함
지난번에는 Claude Code가 .htaccess를 건드리지 못하게 하는 Hook 설정을 작성했습니다. 이번에는 「불필요한 것을 읽히지 않는」 측면의 이야기입니다.
결론부터 말하자면, 제가 「수시 참조 (On-demand reference)」라고 생각하며 작성했던 설정은 수시로 이루어지고 있지 않았습니다. /context를 통해 실측해보고 깨달았기에, 그 기록을 남깁니다.
진행했던 설정
웹 제작 프로젝트에서 CLAUDE.md에 다음과 같이 작성했습니다.
## Skills (상시 참조)
@DESIGN.md
@CLIENT.md
...
의도는 명확했습니다. 항상 필요한 코딩 규약은 상시 읽게 하고, 공정별 규칙은 해당 공정일 때만 읽게 한다. 그렇게 하면 문맥 (Context)이 깔끔해질 것이라고 생각했습니다.
헤드라인에 「수시 참조」라고 적어두었기에, 저는 계속 그렇게 동작하고 있다고 믿고 있었습니다.
/context로 확인하니 전부 포함되어 있었다
Claude Code에는 /context라는 명령어가 있어, 현재 무엇이 문맥을 차지하고 있는지 확인할 수 있습니다. /context all을 입력하면 세부 내역까지 전개됩니다.
실행 결과는 다음과 같습니다.
Memory files · /memory
├ CLAUDE.md: 1.1k tokens
├ DESIGN.md: 1.3k tokens
...
「수시 참조」라고 적었을 5개의 파일이 전부 포함되어 있습니다. 세션을 연 직후, 아직 아무런 작업도 지시하지 않은 단계에서 말입니다.
이유는 간단합니다. CLAUDE.md의 @파일명은 import 표기법이기 때문입니다. Claude Code는 세션 시작 시 CLAUDE.md를 읽고, 그 안의 @를 전개하여 참조 대상의 내용을 통째로 문맥에 포함시킵니다. 헤드라인에 무엇이라고 적혀 있는지는 로딩 타이밍에 전혀 영향을 주지 않습니다.
당연한 이야기라면 당연하지만, 저는 「수시 참조」라는 스스로 작성한 헤드라인을 스스로 믿어버리고 있었습니다.
진짜 지연 로딩 (Lazy Loading)은 같은 화면에 찍혀 있었다
흥미로운 점은 동일한 /context all 출력의 조금 아래 부분입니다.
Skills · /skills
User
├ jquery-responsive: ~50 tokens
...
이것은 Claude Code의 공식적인 Skills 기능으로 등록한 것입니다. 하나당 40~50 토큰 정도밖에 되지 않습니다.
이것은 본문이 포함되어 있지 않기 때문입니다. Skills는 SKILL.md의 프론트매터 (Frontmatter)에 작성한 name과 description만을 상주시키고, Claude가 「이번에는 이것이 필요하다」라고 판단했을 때 비로소 본문을 읽으러 갑니다. 설명문만을 목차로서 가지고 있다가, 필요해지면 페이지를 여는 이미지입니다.
공식 문서에도 기동 시 프론트매터의 name과 description이 시스템 프롬프트 (System Prompt)로 읽히며, 본문 등의 파일은 필요 시에 읽힌다고 적혀 있습니다 (Skill authoring best practices). 실측한 수치는 정확히 이 사양대로였습니다.
즉, 같은 화면에 두 가지 방식이 나란히 찍혀 있었던 셈입니다.
| 상주하는 것 | 1건당 내용 | |
|---|---|---|
@ import | 본문 통째로 | 226~367 tokens |
| Skills | 설명문만 | 40~50 tokens |
다만, 용량의 문제는 아니다
이 부분은 솔직하게 적어두겠습니다. 「수시 참조」로 설정했던 5개 파일의 합계는 1,615 토큰입니다. 전체 문맥은 100만 토큰이 있으므로, 비율로 따지면 0.2%도 되지 않습니다. 절약 효과로서는 거의 오차 범위입니다.
따라서 「토큰을 절약합시다」라는 이야기는 하지 않겠습니다. 효과가 나타나는 곳은 다른 곳입니다.
항상 포함되어 있는 것은 항상 영향을 미칩니다. 저는 「만드는 역할」의 규칙과 「검토하는 역할」의 체크리스트를 별도 파일로 나누어 두었습니다. 리뷰용 체크리스트가 구현 중에도 계속 문맥에 존재하는 상태는, 파일을 나눈 의미를 퇴색시킵니다.
그리고 또 하나, 오래된 파일도 확실하게 계속 읽히게 됩니다. 이 부분은 실제로 사고가 날 뻔했기에, 다음번에 정리해서 쓰겠습니다.
Skills 형식으로 옮기는 법
정말로 수시로 읽게 하고 싶다면, 공식 Skills 형식을 사용하면 됩니다. 디렉토리를 만들고 SKILL.md를 두기만 하면 됩니다.
~/.claude/skills/
└ jquery-responsive/
└ SKILL.md
SKILL.md
의 서두에 프론트매터 (Front Matter)를 작성합니다. 필수 항목은 name과 description 두 가지뿐입니다.
---
name: jquery-responsive
description: jQuery로 햄버거 메뉴나 스무스 스크롤을 구현할 때의 기법 규칙. data 속성 셀렉터, .on() 사용, 플러그인을 사용하지 않는 방침을 포함함.
...
name은 디렉토리 이름과 일치시킵니다.
그리고 description이 전부입니다. 여기에 적은 내용만을 보고 Claude가 실행 여부를 판단하기 때문에, '언제 사용하는 것인지'를 읽어낼 수 있는 문장으로 만들어야 합니다. 단순히 'jQuery 규칙'이라고만 적으면 어떤 상황에서 필요한지 판단할 수 없습니다. 구현할 때, 수정할 때와 같이 구체적인 상황까지 적는 것이 요령이었습니다.
이전 후에는 반드시 /context에서 확인하십시오. 토큰 수가 40~50 정도라면 설명문만 올라와 있는 상태입니다.
어느 쪽을 구분해서 사용할 것인가
모두 Skills로 만들면 된다는 이야기는 아닙니다. 저는 현재 다음과 같이 정리하고 있습니다.
@ import가 적합한 것
- 프로젝트의 전제 조건 그 자체 (DESIGN.md, 클라이언트 정보)
- 항상 준수해야 하는 코딩 규약 (Coding Convention)
- 로드되지 않으면 사고로 이어지는 것
Skills가 적합한 것
- 특정 공정에서만 사용하는 절차 (견적, 검사, 납품 전 체크)
- 호출되지 않아도 실질적인 해가 없는 것
- 설명문으로 용도를 한 문장으로 정의할 수 있는 것
구분 기준은 '로드되지 않았을 때 곤란한가'입니다. 곤란하다면 @, 곤란하지 않다면 Skills입니다. 상시 참조하는 3개 파일은 이 기준에 따라 남겨두었습니다.
요약
- CLAUDE.md의
@는 import 표기법. 세션 시작 시 본문 전체가 포함됨 - 헤더에 '수시 참조'라고 적어도 동작은 변하지 않음 - Skills는
description만 상주하며, 필요할 때 본문을 읽음. 이것이 진정한 지연 로딩 (Lazy Loading) - 실제 측정은/context all로 수행. 추측만으로 운용하지 말 것 - 중요한 것은 용량이 아니라, 무엇이 항상 적용되고 있는가 하는 점
지난번 Hook 때도 그랬지만, AI 관련 설정은 작성한 의도와 실제 동작이 어긋나 있어도 에러가 발생하지 않기 때문에 알아차릴 수 없습니다. 동작하고 있는 것처럼 보일 뿐입니다. 그래서 정기적으로 실제 측정하는 습관이, 올바른 설정을 외우는 것보다 더 중요하다고 생각합니다.
다음에는 이 '전부 올라와 있는' 상태가 실제로 일으킨 사고에 대해 쓰겠습니다. 오래된 규칙과 새로운 규칙이 동시에 살아있어서, 하마터면 유효성 검사 (Validation)가 빠진 폼이 만들어질 뻔했습니다.
Discussion

AI 자동 생성 콘텐츠
본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기