Claude가 실제로 따르는 CLAUDE.md 작성법
요약
Claude가 실제로 준수할 수 있는 CLAUDE.md 작성법을 다룹니다. 모호한 스타일 지침 대신 구체적이고, 검증 가능하며, 이진적(binary)인 지침을 작성하여 LLM의 행동을 효과적으로 제어하는 방법을 제시합니다.
핵심 포인트
- 모호한 열망 대신 구체적이고 실행 가능한 지침을 작성해야 함
- 스칼라적 지침보다 이진적(binary) 지침이 더 효과적임
- 판단의 여지를 남기지 말고 명확한 산출물을 명시할 것
- 함수 길이 제한 등 수치화된 기준을 활용할 것
요약 (TL;DR) — CLAUDE.md는 강력하지만, 대부분의 사람들은 Claude가 인지한 뒤 무시해 버리는 모호한 선호 사항들로 이를 채웁니다. 실제로 지켜지는 지침은 스타일이 아니라 구체적이고, 검증 가능하며, 이진적(binary)인 것입니다. 이 포스트에서는 예시와 함께 그 차이점을 보여줍니다.
무시당했던 CLAUDE.md
저의 첫 번째 CLAUDE.md는 30줄에 달했습니다. 다음과 같은 내용들이었죠:
- 깨끗하고 읽기 쉬운 코드를 작성할 것.
- 함수는 작고 집중된 상태를 유지할 것.
- 베스트 프랙티스 (best practices)를 따를 것.
...
Claude는 이를 읽었습니다. 매 세션마다 해당 파일을 인지하곤 했습니다. 그러고 나서 400줄짜리 설명을 늘어놓고, 네 가지 일을 동시에 수행하는 함수를 만들며, 아무도 요청하지 않은 세 단계의 추상화 (abstraction) 계층이 포함된 솔루션을 내놓았습니다.
저는 Claude를 탓했습니다. 하지만 진짜 문제는 저였습니다. 저는 주니어 엔지니어의 PR (Pull Request)을 리뷰할 때조차 강제할 수 없는 지침들을 작성해 두었던 것입니다. "간결하게 작성하라"는 것은 실행 가능한 (actionable) 지침이 아닙니다. 그것은 하나의 열망일 뿐입니다. 그리고 열망은 LLM (Large Language Model)의 행동을 제약하지 못합니다. 그저 자신감 있고 그럴듯하지만 틀린 출력을 만들어내는 특유의 주변적인 공손함 속으로 흡수될 뿐입니다.
대부분의 CLAUDE.md 지침이 지켜지지 않는 이유
LLM은 매우 남의 비위를 맞추고 싶어 하는 사람이 모호한 조언을 따르는 방식과 유사하게 지침을 따릅니다. 즉, 자신이 이미 하려던 행동과 일치하는 방식으로 지침을 해석합니다. "깨끗한 코드를 작성하라"는 거의 모든 행동과 일치할 수 있습니다. "과도한 엔지니어링 (over-engineer)을 하지 마라"는 무엇을 과도한 엔지니어링으로 간주하느냐에 전적으로 달려 있으며, 모델은 당신이 무효화하려고 했던 바로 그 자신의 판단력을 사용하여 이를 평가할 것입니다.
실제로 행동을 변화시키는 지침들은 몇 가지 공통된 속성을 공유합니다:
1. 스칼라(scalar)가 아닌 이진적(binary)이어야 합니다.
"간결하게 작성하라"는 스칼라적입니다. 즉, 스펙트럼이 존재하며 모델이 그중 어디에 위치할지를 결정합니다. 반면 "앞으로 할 일을 요약하는 도입부 문단을 작성하지 마라"는 이진적입니다. 도입부 문단이 있거나, 없거나 둘 중 하나입니다. 이진적 지침은 강제할 수 있지만, 스칼라적 지침은 해석될 뿐입니다.
2. 특정 산출물(artifact)이나 행동을 명시해야 합니다.
"함수를 작게 유지하세요(Keep functions small)"는 모호합니다. "함수가 40줄을 초과하면, 반환하기 전에 분리하세요"는 Claude가 확인할 수 있는 구체적인 사항을 명시합니다. 품질(quality)보다는 산출물(output)을 더 많이 묘사할수록 Claude가 이를 더 잘 따를 수 있습니다.
3. 판단의 여지(wiggle room)를 남기지 마세요.
"상속보다 구성을 선호하세요(Prefer composition over inheritance)"는 Claude가 언제 구성이 더 바람직한지 결정하도록 유도합니다. "이 리포지토리(repo)에서는 클래스 상속을 사용하지 마세요 — 구성을 사용하세요"는 판단의 루프를 차단합니다. 재량권(discretion)의 여지를 남겨두는 지침은 모델의 재량으로 채워지게 될 것입니다.
일반적인 지침의 Before/After 비교
앞서 언급한 세 가지 속성을 적용하여 CLAUDE.md를 다시 작성한 예시입니다:
Before: - 간결한 설명을 작성하세요.
After: - 내가 질문을 하면, 내가 명시적으로 상세한 설명을 요구하지 않는 한 3문장 이내로 답변하세요. 대화형 응답에서는 불렛 리스트(bullet lists)를 사용하지 마세요.
Before: - 프로젝트의 코드 스타일을 따르세요.
After: - 코드를 작성하기 전에, 해당 디렉토리에서 가장 가까운 기존 파일을 읽고 그 파일의 임포트(import) 스타일, 공백, 명명 규칙(naming)을 정확히 일치시키세요. 새로운 패턴을 도입하지 마세요.
Before: - 요청하지 않은 기능을 추가하지 마세요.
After: - 내 요청에서 언급하지 않은 파일은 수정하지 마세요. 인접한 변경 사항이 도움이 될 것이라고 생각된다면, 마지막에 한 문장으로 설명만 하세요 — 직접 수정하지는 마세요.
Before: - 데이터베이스 변경 시 주의하세요.
After: - 롤백(rollback) 없이 마이그레이션(migration)을 생성하지 마세요. 모든 마이그레이션 파일은 나에게 보여주기 전에 반드시 up함수와down 함수를 모두 포함해야 합니다.
오른쪽 열이 더 긴 이유는 더 철저하기 때문이 아닙니다. 구체성(specificity)을 확보하는 데 더 많은 단어가 필요하기 때문입니다. 하지만 오른쪽의 각 지침은 정확히 단 하나의 해석만을 가집니다.
CLAUDE.md 지침의 두 가지 카테고리
제 지침들을 몇 번 다시 작성해 본 결과, 지침은 다음과 같은 두 가지 유용한 카테고리로 나뉜다는 것을 발견했습니다:
출력에 대한 제약 사항 (Constraints on output) — Claude가 생성해야 하거나 생성해서는 안 되는 것들입니다. 이러한 제약 사항은 이진적(binary)이고 한눈에 검증 가능할 때 효과적입니다. "요청하지 않는 한 코드에 주석을 추가하지 마세요"는 출력에 대한 제약 사항입니다. "모든 함수는 반드시 반환 타입 어노테이션 (return type annotations)을 가져야 합니다"나 "파일을 분할하지 않고 200줄이 넘는 파일을 생성하지 마세요"도 마찬가지입니다.
절차적 지침 (Procedural instructions) — Claude가 주요 작업을 수행하기 전에 반드시 거쳐야 하는 단계입니다. "함수를 작성하기 전에 해당 모듈의 테스트 파일을 읽으세요"는 절차적 지침입니다. "코드베이스에 관한 질문에 답하기 전에, 관련 심볼(symbol)에 대해 grep을 실행하고 파일:줄(file:line)을 인용하세요"도 마찬가지입니다. 절차적 지침이 효과적인 이유는 Claude에게 다음에 수행할 작업의 형태를 결정짓는 구체적인 첫 단계를 제공하기 때문입니다.
잘 작동하지 않는 것들: 가치 판단 문구, 품질 형용사, 상대적인 선호도("X를 선호하세요", "Y하려고 노력하세요", "Z를 고려하세요"). 이러한 것들은 흡수되어 버립니다. 제약 역할을 하지 못합니다.
상단에 배치해야 할 내용
CLAUDE.md 지침에는 유효 범위가 있습니다. 파일의 아래쪽에 위치할수록 긴 작업 수행 시 우선순위에서 밀려날 가능성이 높습니다. 가장 중요한 제약 사항을 상단에 배치하세요. 서론이나 서문 형태가 아니라, Claude가 마주치는 첫 번째 실제 규칙으로서 배치해야 합니다.
현재 저의 CLAUDE.md는 이진적이고 구체적이며, 그렇지 않으면 매 세션마다 반복해서 보게 될 실수들을 다루는 세 줄로 시작합니다:
# Rules (always follow)
1. Do not modify files I did not explicitly mention. If a related change seems useful, list it at the end and wait.
...
이 세 줄은 다른 40개의 지침을 모두 합친 것보다 제 세션의 질을 더 많이 변화시켰습니다.
작동 여부 테스트하기
작성한 지침으로 방지하고자 했던 행동이 더 이상 나타나지 않을 때, 당신의 CLAUDE.md가 제대로 작동하고 있다는 것을 알 수 있습니다. 당연한 소리처럼 들리겠지만, 대부분의 사람들은 CLAUDE.md를 한 번 작성하고 나서 그것이 실제로 무엇을 변화시켰는지 확인하지 않은 채, 변화가 있었을 것이라고 가정해 버립니다.
실질적인 테스트: CLAUDE.md를 업데이트한 후, 새로운 지침이 처리하고자 했던 바로 그 시나리오를 실행해 보세요. 이전에는 원치 않는 동작을 유발했을 법한 요청을 작성해 봅니다. 만약 그 동작이 여전히 나타난다면, 해당 지침이 충분히 이진적(binary)이지 않거나, 충분히 구체적이지 않거나, 혹은 파일의 너무 아래쪽에 위치해 있는 것입니다. 그 동작이 사라질 때까지 수정하세요.
CLAUDE.md는 문서(documentation)가 아닙니다. 그것은 설정(configuration)입니다. 테스트 스위트(test suite)처럼 취급하세요. 방지하려는 동작이 여전히 나타난다면, 설정이 잘못된 것입니다.
프리 에이전트(free agent) + 더 깊이 알아보기
만약 여러분이 진정한 CLAUDE.md 기반의 워크플로(workflow)를 구축하고 있다면, 서브 에이전트(subagents)에게도 동일한 설계 철학이 적용됩니다: 좁은 범위(narrow scope), 이진적 제약(binary constraints), 명시적인 거부 규칙(explicit refusal rules). 이 저장소에 있는 자유로운 shipping-coach 에이전트는 이러한 접근 방식의 작동 예시입니다. 이 에이전트는 단순히 기능뿐만 아니라 그 구조를 파악하기 위해 읽어볼 가치가 있는 50줄짜리 .md 파일입니다:
👉 github.com/allcanprophesy-ops/claude-code-shipping-coach
동일한 방식으로 구축된 몇 가지 다른 에이전트들(pr-surgeon, regression-sentinel)은 이 패턴이 단일 에이전트를 넘어 어떻게 확장되는지 확인하고 싶다면 README에서 링크를 통해 확인할 수 있습니다. 하지만 먼저 자신의 CLAUDE.md를 읽으며 다음과 같이 질문하는 것부터 시작하세요: 이 지침들 중 어떤 것이 이진적(binary)인가? 어떤 것들이 모델이 스스로 결정할 여지를 남겨두고 있는가? 두 번째 카테고리를 먼저 수정하세요.
여러분의 CLAUDE.md에서 여러 번 표현을 바꿔가며 시도해 보았음에도 여전히 작동하지 않는 단 하나의 지침은 무엇인가요? 댓글로 남겨주세요. 제가 이진적(binary)인 방식으로 다시 작성하는 것을 제안해 드리겠습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기