[리뷰] Claude Code 잡도리하기
프롤로그
개발자의 세계에는 오래된 격언이 있습니다. “바퀴를 재발명하지 마라.” 그래서 우리는 늘 이미 있는 바퀴를 찾아 씁니다. 대부분의 경우 그게 맞습니다. 하지만 오래 일하다 보면 알게 됩니다 — 세상에 바퀴는 많지만, 나에게 딱 필요한 만큼의 바퀴가 없는 경우가 놀라울 정도로 많다는 것을. 기존 도구가 80%는 맞지만 나머지 20%가 안 맞아서 끝없이 워크어라운드를 쌓거나, 결국 포기하고 그 도구의 제약 안에서 타협하게 됩니다. “직접 만들면 되지”라는 생각은 늘 했지만, 만드는 데 드는 비용이 너무 컸습니다. AI 시대에 이것이 근본적으로 달라졌습니다. “나에게 딱 맞는 최적의 바퀴”를 만드는 데 주저함이 없어졌습니다. (블로그 글 중 발췌)
리뷰
최근에 인상 깊은 글을 하나 읽었다.
시니어 개발자분이 Claude Code와 함께 6개월 만에 25만 줄짜리 프로젝트를 만든 이야기였다. 소스 파일 1,271개, 커밋 1,185개의 프로젝트를 오조리 클로드 코드만을 활용하여 개발한 내용이었다.
여기까지만 보면 바이브 코딩을 한 것에 대한 단순한 이야기로 보였지만 그 뒤에 이 개발자분이 클로드를 어떤식으로 활용하여 수행했는지를 보며 많은 인사이트를 얻었다. 평소에 내가 실제로 많이 하는 고민들이기도 하여 많이 공감했고, 내가 앞으로 어떤식으로 사용하면 좋을지에 대해서도 많은 참고를 얻었다.
맞아, 나도 그렇던데
솔직히 말하면 Claude Code를 쓰면서 이런 경험을 여러 번 했다.
분명히 이러이러한 방향을 갖고 이러이러하게 수정해줘 라고 했는데 막상 보면 가끔 멋대로 추론으로 짠 것 같은 코드가 나온다. 인터페이스 메서드명이 살짝 다르거나, 이미 리팩토링된 패턴을 모르고 옛날 방식으로 작성하거나.
CLAUDE.md에 열심히 아키텍처 원칙을 적어뒀는데 대화가 길어지면 어느 순간 그걸 무시하는 것처럼 느껴진다. 또한, 항상 CLAUDE.md에 작업 후 바로 푸시하지말고 항상 나에게 컨펌을 받도록 했는데 이것도 가끔 무시하고 지 멋대로 푸시해버린다. (이건 꽤 크리티컬할 수 있다고 생각한다.)
구현이 끝났을 때 잘 됐겠지 하고 넘어갔다가 나중에 코드리뷰에서 Critical 이슈가 잡히는 것도 경험했다. 내가 먼저 잡아야 할 걸 외부 도구에서 지적받는 게 좀 창피하기도 하고.
이 글을 읽으면서 그게 왜 생겼는지, 어떻게 구조적으로 풀 수 있는지를 처음으로 명확하게 이해한 것 같다.
문제의 본질
글을 쓴 개발자분은 문제를 세 가지로 정리했다.
1. AI는 확인 없이 추론한다
파일을 열어볼 수 있는 도구가 있는데도, 실제로 열지 않고 "아마 이런 내용일 것"이라고 추론한 뒤 작업을 진행한다. 그리고 자신이 추론한 것과 실제로 읽은 것을 구분하지 못한다.
2. 문서는 특정 시점의 스냅샷일 뿐이다
코드는 매일 바뀐다. CLAUDE.md나 아키텍처 문서를 열심히 써도, 코드가 리팩토링되면 문서와 코드 사이에 불일치가 생긴다. 그 불일치가 쌓이면 AI가 오래된 패턴으로 새 코드를 짜기 시작한다.
3. AI의 기억은 불안정하다
컨텍스트가 길어지면 압축이 일어나고, 그 과정에서 CLAUDE.md의 지침도, 아키텍처 원칙도 희석된다. 프롬프트 수준의 약속은 시간이 지나면 흔들린다.
이 세 가지 모두 분명히 나도 종종 느꼈던 것들이었고, 애써 무시하며 그때마다 다시 스킬들을 정리했었다.
파이프라인
이에 대한 해결책은 이렇게 이어진다.
최소한의 CLAUDE.md
→ 도메인별 규칙 파일 분리
→ 독립 검증 에이전트 (Rule Guard)
→ Hooks로 기억 재주입
→ 관측 도구
각각이 하나의 문제를 해결한다. 그리고 이게 합쳐져서 "실패해도 복구되는 파이프라인"이 된다.
그렇다면 내가 앞으로 해야할 것들은?
글을 다 읽고 나서 바로 적용할 수 있는 것들을 정리했다.
1. CLAUDE.md 최소화하기
지금까지 CLAUDE.md에 뭐든 다 넣으려고 했다. 이유는 간단했다. Agent 입장에서 가장 직관적이고 잘 수행할 것이라 생각했기 때문이다. 아키텍처 설명, 원칙, 패키지 구조, 예외 처리 방식까지. 근데 길어질수록 컨텍스트 압축 시 핵심이 날아갈 확률이 높아진다.
이에 따른 앞으로의 방향은 방향은 이렇다.
# 프로젝트명 CLAUDE.md
## 아키텍처
- 레이어드 아키텍처 (interfaces → application → domain → infrastructure)
- DIP 준수: domain은 infrastructure를 모른다
## 규칙 위치
- 공통 원칙: docs/rules/principles.md
- 도메인별 규칙: docs/rules/{domain}.md
- 구현 전 반드시 해당 규칙 파일을 읽는다
## 구현 원칙
- 수정 대상 파일을 반드시 먼저 읽는다
- 계획을 먼저 설명하고 승인을 받은 뒤 구현한다
상세한 내용은 전부 docs/rules/ 에 넣는다.
2. 규칙 파일을 도메인별로 분리하기
문서를 코드와 동기화하려고 노력하는 대신, 애초에 코드가 시스템을 설명하게 만드는 게 목표다. 그러려면 코드 자체가 일관된 구조를 가져야 하고, 그 구조를 지키는 건 규칙이다.
docs/rules/
principles.md ← 레이어드 아키텍처, DIP, 단일책임 원칙
domain-rules.md ← 도메인 객체에 비즈니스 로직 캡슐화
application-rules.md ← Facade는 도메인 조립만, 비즈니스 로직 없음
infra-rules.md ← JPA, Redis 사용 규칙
CLAUDE.md에는 "domain 패키지를 건드릴 때는 domain-rules.md를 읽어라"는 포인터만 남긴다.
3. 구현 후 검증 에이전트를 돌리는 걸 습관화하기
글쓴이의 Rule Guard 핵심은 자기 코드를 자기가 심판하지 않는다는 것이다. 구현한 에이전트가 검증까지 하면 자기 합리화가 생긴다.
아키텍처 규칙 전용 검증 에이전트를 커스텀으로 만들면 이렇게 된다.
# .claude/agents/architecture-guard.md
당신은 순수 검증자입니다. 코드를 수정하지 않습니다.
검증 시 docs/rules/ 파일을 반드시 읽고 판정합니다.
추론으로 판단하지 않습니다.
매번 돌리지 않더라도, 구현이 끝나면 한 번은 무조건 돌리는 걸 루틴으로 만든다.
4. Hooks로 기억 소실을 막기
이전 것들은 어느정도 그렇게 해봐야지 라고 생각은 해봤지만, 이건 정말 생각도 못해봤기에 가장 인상 깊었던 부분이다.
컨텍스트 압축이 일어나는 그 순간에 훅을 걸러 핵심 지침을 기계적으로 재주입하는 것. 프롬프트로 부탁하는 게 아니라 인프라 수준의 강제다.
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"command": "echo '구현 전 docs/rules/ 의 해당 규칙을 먼저 확인하라'"
}
]
}
}
Edit이나 Write 도구를 쓰기 전마다 규칙 확인을 강제한다. AI가 잊든 말든 상관없이 동작한다.
5. 외부 리뷰 도구를 필수 단계로 만들기
관측할 수 없으면 통제할 수 없다. 지금 당장 쓸 수 있는 외부 관측 도구를 PR 단계에서 빠뜨리지 않는 것. 내가 못 잡은 이슈를 잡아주는 경험을 몇 번 하고 나면 이걸 선택이 아닌 필수로 만들게 된다.
더 좋은 AI가 나오길 기다리는 게 아니라, 지금 가진 AI와 일하는 방법을 계속 다듬어가는 것. 나에게 딱 맞는 바퀴는 기다린다고 생기지 않는다.