Claude의 오버엔지니어링 (over-engineering) 습관을 깨뜨리는 CLAUDE.md의 한 줄
요약
Claude가 반복적으로 과도한 추상화와 오버엔지니어링을 수행하는 문제를 해결하기 위해 CLAUDE.md에 명시적인 규칙을 추가하는 방법을 다룹니다. 부정문 대신 긍정문을 사용하고, 추상화 시점을 '두 번째 발생'으로 제한하는 구체적인 프롬프트 전략을 제안합니다.
핵심 포인트
- 부정어 대신 긍정문을 사용하여 AI의 행동 방향을 명확히 제시
- 요구사항을 충족하는 '가장 작은 변경'을 기본값으로 설정
- 추상화는 첫 번째가 아닌 두 번째 발생 시점에 도입하도록 제한
- CLAUDE.md를 활용해 AI의 코딩 습관을 영구적으로 교정
네 번째는 너무 늦습니다
이전 에피소드([CANONICAL URL #52: over-engineering-3-recadrages 푸시 후 완료 예정])에서, 저는 한 세션 내에서 세 번의 재조정(recadrage) — 더 단순하게, 더 단순하게, 더 단순하게 —을 거친 끝에, Claude가 인터페이스(interface), 레지스트리(registry), 그리고 세 개의 파일이 포함된 버전 대신 단 8줄로 끝나는 함수 버전을 제안하기까지의 과정을 이야기했습니다. 다음 날 아침 프로젝트를 다시 열고 동일한 모듈에 사소한 수정을 요청하자, 답변은 전날과 정확히 똑같은 구조로 돌아왔습니다. 전략 패턴(Strategy pattern), 레지스트리(registry), 세 개의 통합 테스트(integration tests). 재조정은 /clear 명령어를 견뎌내지 못했습니다. 그것이 살아남을 이유도 없었습니다. 어떤 파일도 이를 담고 있지 않았고, 습관이 다시 돌아왔을 때 이를 트리거할 메커니즘도 없었습니다.
네 번째는 너무 늦습니다. 세 번째에 새겨넣어야 합니다.
그 한 줄
저는 CLAUDE.md의 Conventions 섹션, Server Components 규칙 바로 위의 블록에 다음 내용을 추가했습니다:
Default to the smallest change that fits. Add abstractions only after the second occurrence, never the first.
(적합한 범위 내에서 가장 작은 변경을 기본값으로 합니다. 추상화(abstraction)는 첫 번째가 아닌, 두 번째 발생 이후에만 추가하세요.)
두 문장 안에 네 가지 선택지가 담겨 있습니다. 각각의 선택은 제대로 자리 잡기까지 여러 번의 시도가 필요했습니다.
왜 이 네 가지인가
avoid가 아닌 Default to. 제가 처음에 시도했던 버전은 _Avoid premature abstraction (조기 추상화 방지)_였으나, 실질적으로 아무것도 바꾸지 못했습니다. 부정어는 그것이 겨냥하는 대상을 활성화합니다. 에이전트는 _premature abstraction_을 읽고, 자신이 생성하도록 훈련된 결함인 abstraction 카테고리를 활성화합니다. 긍정문은 반대되는 습관을 명시하지 않으면서 방향을 제시합니다. 이는 이번 작업에서 가장 눈에 띄지 않는 디테일이었지만, 테스트의 결과를 뒤바꾼 핵심이었습니다.
단순히 smallest가 아닌 That fits. _The smallest change_만 단독으로 사용하면 해킹(hack)을 유도하게 됩니다. _The simplest solution_는 단순함에 대한 논쟁을 불러일으킵니다. _That fits_는 측정 기준을 명확히 합니다: 우아함이 아니라, 요구사항을 충족하는 것.
두 번째 발생 시, 세 번째가 아니다. Martin Fowler가 _Refactoring_에서 말한 '3의 법칙(Rule of three)'은 "유사한 작업을 세 번째 수행할 때 리팩터링(refactor)하라"고 말합니다. 저는 이를 두 번으로 낮추었는데, 이는 아마도 Claude Code를 단독 개발자(solo dev)로 사용하는 경우에만 해당할 법한 이유 때문입니다. PR 리뷰(PR review)가 없기 때문에, 두 번째 발생 시점이 제가 구현하려는 추상화(abstraction)에 대해 여전히 명료한 정신을 유지하고 있는 마지막 순간입니다. 세 번째가 되면 Claude는 자발적으로 제안하고, 저는 세션의 압박감에 이미 지쳐버려 확인도 하지 않은 채 승인해 버립니다.
Never the first (절대 첫 번째는 안 된다). 이 _never_는 의도적이며 아마도 과할 것입니다. 하지만 예외를 포함하여 명시된 결함은 오히려 추구되는 예외가 됩니다. _Never_는 내부적인 협상을 차단합니다. 정말 예외적인 상황이 발생할 때—그리고 그런 일은 실제로 일어납니다—저는 명시적으로 그 규칙에 반대하는 논거를 제시해야 하며, 이것이 바로 제가 의도한 마찰(friction)입니다.
지금까지 관찰한 내용
세 번의 세션, 세 가지 주제, 세 가지 서로 다른 모듈. Claude는 제가 지적하여 한 번의 대화 만에 철회하게 만든 조기 추상화(premature abstraction)를 제안했습니다. 이는 불과 일주일 전 세션당 서너 번씩 발생하던 일과 대조적입니다. 이것은 연구가 아닙니다. 관찰자이며, 확증 편향(confirmation bias)의 가능성이 있고, 표본도 터무니없이 적습니다. 하지만 매 시작 시 CLAUDE.md에 한 줄이 추가되면서, 기준선(baseline)의 압박이 이제 습관화된 결함에 대항하고 있습니다. Claude Code의 결과물에 대한 진정한 A/B 테스트는 이 시리즈의 후속 기사에서 다룰 예정입니다.
코다 (Coda)
CLAUDE.md의 교리는 단순한 모범 사례(best practices) 목록이 아닙니다. 그것은 네 번째 반복하기를 거부했던 교훈들을 물리적으로 쌓아 올린 것입니다. (추상화에 관한) Fowler의 3의 법칙을 (세션 중 구두 수정에 관한) 저의 3의 법칙에 적용한 것입니다. Claude에게 똑같은 말을 세 번째로 하게 되는 순간, 그 내용은 CLAUDE.md에 한 줄로 기록됩니다. 그렇지 않으면 다음 세션에서 다시 말하게 될 것이고, 그 교훈은 컨텍스트(context)와 함께 사라져 버릴 것입니다.
[CANONICAL URL #52: over-engineering-3-recadrages 푸시 후 작성 예정]의 후속 내용. Claude Code의 출력에 미치는 CLAUDE.md의 효과에 대한 A/B 테스트: 시리즈의 차후 기사 주제.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기