
AI에게 전달하는 규칙은 모순되어 있어도 작동해 버린다 — 설정 파일 정리 기술
요약
Claude Code 사용 시 CLAUDE.md의 @ 참조 파일과 Skills 형식이 충돌할 때 발생하는 모순과 위험성을 다룹니다. 오래된 규칙이 삭제되지 않고 항상 포함될 경우, AI가 상충하는 지시를 동시에 수행하여 코드 품질을 저하시킬 수 있음을 경고합니다.
핵심 포인트
- CLAUDE.md의 @ 참조 파일은 세션 시작 시 항상 포함되어 우선순위가 높음
- 오래된 규칙과 새로운 규칙이 공존할 경우 AI는 모순된 지시를 동시에 수용함
- 규칙 업데이트 시 반드시 기존의 @ 참조 파일을 삭제하여 충돌을 방지해야 함
- AI는 파일의 수정 날짜를 기준으로 최신성을 판단하지 않음
지난번, CLAUDE.md의 @로 불러오던 파일이 전부 세션 시작 시에 포함되어 있었다는 이야기를 썼습니다.
그 뒷이야기입니다. 전부 포함되어 있었기 때문에, 오래된 규칙과 새로운 규칙이 동시에 살아있었습니다. 게다가 에러는 전혀 발생하지 않습니다. 깨닫게 된 계기와 정리한 결과를 남깁니다.
jQuery 규칙이 두 곳에 있었다
제 환경에는 jQuery 작성 규칙이 두 가지 있었습니다.
skills/jquery.md— CLAUDE.md에서@로 참조. 항상 전문이 포함됨jquery-responsive— 공식 Skills 형식. 필요할 때만 읽힘
같은 영역을 다루고 있어서 단순한 중복이라고 생각했습니다. 나란히 놓고 비교해 보니 그렇지 않았습니다.
skills/jquery.md (항상 포함) | jquery-responsive (Skill) |
|---|---|
| 셀렉터 (Selector) | data 속성 우선 |
| 스무스 스크롤 (Smooth Scroll) | .animate()를 사용하는 구현 예시 게재 |
| 애니메이션 (Animation) | 기술 없음 |
오래된 파일에는 권장 패턴으로 다음과 같이 적혀 있었습니다.
// 스무스 스크롤
$("[data-scroll]").on("click", function(e){
e.preventDefault();
...
새로운 쪽에서는 .animate() 사용을 금지하고 있습니다. 즉, 제가 직접 작성한 권장 코드가 제가 스스로 정한 금지 사항을 어기고 있는 상태였습니다.
곤란한 점은, 항상 포함되어 있는 쪽이 오래된 규칙이라는 점입니다. Skill이 작동하지 않는 상황에서는 오래된 방식으로 작성되고, 작동하는 상황에서는 새로운 방식으로 작성됩니다. 동일한 프로젝트의 코드 안에서 작성 방식이 흔들립니다. 게다가 둘 다 에러가 나지 않기 때문에, 리뷰에서 알아차리지 못하는 한 섞인 채로 납품됩니다.
규칙을 업데이트했을 때, 저는 새로운 Skill 쪽만 수정하고 오래된 @ 참조 파일을 지우는 것을 잊었습니다. 지우지 않은 파일이 확실하게 읽힌다. 이것이 가장 무서운 부분입니다.
폼(Form) 쪽은 더 심각했다
같은 구도가 폼에도 있었습니다.
skills/form-builder.md—@참조. 항상 포함됨contact-form— Skills 형식
이쪽은 모순보다 **결락(누락)**이 문제였습니다.
form-builder.md | contact-form |
|---|---|
| 전송 후 | 페이지 전환 없이 감사 메시지 표시 |
| 유효성 검사 (Validation) | HTML5 + jQuery 둘 다 |
form-builder.md에는 서버 측 유효성 검사(Server-side validation)에 대한 기술이 단 한 줄도 없었습니다. 적혀 있는 대로 구현하면 클라이언트 측 검증만으로 끝납니다. 폼으로서는 말이 안 되는 상황입니다.
contact-form 쪽에는 헤더 인젝션(Header Injection) 대책도, 허니팟(Honeypot)도, 시간 체크도 적혀 있습니다. 나중에 정비한 것입니다. 다만 오래된 파일을 지우지 않았기에, 양쪽이 동일한 비중으로 Claude에게 전달되고 있었습니다.
인간이라면 "오래된 것은 무시해"라고 하면 끝납니다. Claude는 어느 것이 새로운지 알 수 없습니다. 파일의 수정 날짜를 보고 판단해 주는 것도 아닙니다. 동시에 전달된 두 개의 지시로서 취급됩니다.
다행히 실질적인 피해가 나오기 전에 알아차렸지만, Skill이 작동하지 않는 상황에서 폼을 구현하게 했다면 서버 측 검증이 빠진 결과물이 나왔을 가능성이 충분히 있습니다.
정리 순서
한 일은 단순합니다.
1. 대조하여 어느 쪽이 옳은지 결정한다
모순되는 항목을 표로 나열했습니다. 이유가 명확한 쪽을 남깁니다. 폼 전송 후의 동작이라면, contact-form의 리다이렉트에는 "이중 전송 방지"라는 이유가 있으므로 이쪽이 옳습니다.
2. 역할이 다른 부분은 옮긴다
form-builder.md에는 폼 항목 리스트(이름, 회사명, 이메일...)도 적혀 있었습니다. 이것은 구현 규칙이 아니라 **프로젝트의 사양(Specification)**입니다. 프로젝트마다 달라지므로 DESIGN.md로 옮겼습니다.
접근성 요구사항(label 연결, aria-invalid, role="alert")은 accessibility.md로 통합했습니다. 원래 절반 정도는 작성되어 있었기에 부족한 부분만 추가했습니다.
3. 오래된 파일은 줄 단위로 삭제한다
CLAUDE.md의 @ 참조를 삭제하고, 파일 본체도 삭제했습니다. skills/jquery.md와 skills/form-builder.md 두 개입니다.
정리 후 /context all로 확인한 결과, Memory files가 9개에서 7개로 줄어들었고, accessibility.md는 247에서 319로, DESIGN.md는 1.3k에서 1.4k로 늘어났습니다. 옮긴 내용이 제대로 반영되었습니다. 이 확인 작업까지 포함하여 작업입니다.
모순은 제로로 만들 수 없다
여기까지가 한 단락인 줄 알았는데, 아직 남아 있었습니다. 프로젝트의 CLAUDE.md/DESIGN.md와 범용 Skill 사이의 모순입니다.
| 값 | |
|---|---|
CLAUDE.md (프로젝트) | 브레이크포인트(Breakpoint) 768px / 1360px |
jquery-responsive (범용) | 브레이크포인트 768px / 1200px (늘리지 않음) |
DESIGN.md (프로젝트) | 폰트 Noto Sans JP |
jquery-responsive (범용) | 폰트는 Noto Sans JP 하나로 고정하지 않음 |
이것은 앞선 두 사례와는 성격이 다릅니다. Skill은 다른 프로젝트에서도 사용하는 범용 규칙이므로, 한쪽을 삭제해서 해결할 문제가 아닙니다. 1200px도, "Noto 하나로 고정하지 않음"도 범용 규칙으로서는 올바릅니다.
그래서 우선순위를 명시하는 방향으로 정했습니다.
CLAUDE.md 측 (항상 포함되므로 어떤 상황에서도 적용됨)
## 규칙의 우선순위
프로젝트 고유의 값(브레이크포인트, 폰트, 컬러 등)은
DESIGN.md와 CLAUDE.md의 기술 내용을 우선한다.
...
Skill 측 (다른 프로젝트에서도 사용하므로 예외 조항을 적어둠)
- 브레이크포인트는 **768px / 1200px** 두 가지 (늘리지 않음)
(※ 프로젝트의 DESIGN.md / CLAUDE.md에 지정이 있는 경우는 해당 내용을 우선한다)
양쪽 모두에 적는 것이 포인트입니다. CLAUDE.md에만 적으면, Skill을 읽은 Claude가 순순히 1200px로 계산할 여지가 남습니다. Skill에만 적으면, Skill이 호출되지 않는 상황에서는 효과가 없습니다.
교훈
- 같은 영역의 규칙을 두 곳에 두지 않는다. 두어야 한다면 어느 쪽이 옳은지 명시한다.
- 오래된 파일은 삭제한다. 남겨두면 업데이트한 쪽과 잊어버린 쪽이 동시에 살아남는다.
- 사양(Specification)과 구현 규칙을 섞지 않는다. 프로젝트마다 변하는 것은 프로젝트 문서로.
- 범용 규칙과 프로젝트 규칙의 충돌은 삭제하는 것이 아니라 우선순위로 해결한다.
- 정리했다면 숫자가 변했는지
/context로 확인하여 반영 여부를 체크한다.
이전 글과 공통되는 점은, 에러가 발생하지 않기 때문에 알아차릴 수 없다는 점입니다. 모순된 지시를 전달해도 Claude는 멈추지 않습니다. 둘 중 하나를 선택해 아무 일도 없었다는 듯이 동작합니다. 한쪽이 오래되었다는 사실도, 한쪽에 중대한 누락이 있다는 사실도 알려주지 않습니다.
코드라면 린터(Linter)나 테스트가 잡아줄 부분을, 설정 파일은 스스로 확인하러 갈 수밖에 없습니다. 정기적으로 나란히 놓고 읽는 시간을 갖는 것이 현재로서는 유일한 대책이라고 생각합니다.
Discussion

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