테마
12. 클로드 하네스 구축
Claude Code를 잘 쓰는 핵심은 더 긴 프롬프트가 아니라 제어 장치를 만드는 것이다. 여기서 하네스는 AI 에이전트가 마음대로 달리지 않도록 방향, 제약, 검증, 피드백 루프를 묶어 둔 운영 체계를 뜻한다.
이 장은 앞에서 배운 CLAUDE.md, 설정 파일, Skill, Sub Agent, Hook, 개발 워크플로우를 하나의 실전 흐름으로 연결한다. 각각의 기능을 새로 설명하기보다, 실제 프로젝트에서 어떻게 조합해야 안정적인 AI 코딩 워크플로우가 되는지 정리한다.
1. 하네스는 도구 모음이 아니라 제어 시스템이다
AI 코딩에서 흔한 실수는 Claude Code에게 "알아서 잘 만들어줘"라고 맡기는 것이다. 처음에는 빠르게 보이지만, 요구사항이 애매하고 검증 기준이 없으면 수정이 반복되고 컨텍스트가 오염된다.
하네스는 이 문제를 줄이기 위한 장치다.
하네스가 있으면 Claude Code는 다음 기준 안에서 움직인다.
| 기준 | 질문 |
|---|---|
| 방향 | 무엇을 만들고 무엇은 만들지 않을 것인가? |
| 맥락 | 이 프로젝트의 구조, 철학, 제약은 무엇인가? |
| 절차 | 요구사항부터 머지까지 어떤 순서로 진행할 것인가? |
| 검증 | 어떤 테스트와 리뷰를 통과해야 완료인가? |
| 개입 | 사람은 어디에서 승인하고 어디에서 판단해야 하는가? |
즉, 하네스는 AI를 더 많이 자동화하기 위한 장치가 아니라 사람이 제어권을 유지하기 위한 구조다.
2. 각 장치를 어디에 써야 하는가
Claude Code에는 여러 확장 지점이 있다. 문제는 "무엇이든 CLAUDE.md에 넣자"가 아니라, 각 장치의 역할을 분리하는 것이다.
| 장치 | 역할 | 적합한 내용 | 관련 장 |
|---|---|---|---|
CLAUDE.md | 프로젝트의 장기 지침 | 기술 스택, 코딩 규칙, 워크플로우 순서, 금지 사항 | 05. 메모리 관리 |
settings.json | Claude Code 실행 설정 | 권한, Hook, 환경변수, 모델, 대화 언어 | 06. 설정 파일 |
| Skill | 반복 가능한 절차 | TDD Red, TDD Green, PR 생성, 디자인 시스템 적용 | 10. Claude Skill |
| Sub Agent | 독립 판단과 전문 검증 | PRD 검증, AC 검증, 보안 리뷰, 코드 리뷰 | 08. 서브에이전트 & 훅 |
| Claude Hook | Claude 이벤트 기반 자동 처리 | 도구 실행 전후 검사, 입력/종료 시점 처리 | 08. 서브에이전트 & 훅 |
| Git Hook | Git 이벤트 품질 게이트 | pre-commit lint, commit message 검사 | 이 장 |
| CI | 원격 환경 최종 검증 | clean install, lint, type check, test, audit | 09. 개발 워크플로우 |
좋은 하네스는 같은 규칙을 한 곳에 과도하게 몰아넣지 않는다. 예를 들어 "UI 작업은 디자인 시스템을 따라야 한다"는 원칙은 CLAUDE.md에 한 줄로 남길 수 있지만, 실제 디자인 토큰과 컴포넌트 규칙이 길다면 별도 문서나 Skill로 분리하는 편이 낫다.
3. 시작점은 /init이 아니라 검토다
기존 프로젝트에 Claude Code를 붙일 때 /init은 좋은 출발점이다. 프로젝트 구조를 분석해 초기 CLAUDE.md를 만들 수 있기 때문이다.
하지만 /init만 실행하고 끝내면 안 된다.
CLAUDE.md에는 다음 정도를 먼저 넣는다.
markdown
## 프로젝트 개요
- 무엇을 만드는 프로젝트인지
- 핵심 사용자와 주요 기능
## 기술 스택
- 런타임, 프레임워크, 테스트 도구
- 패키지 매니저와 실행 명령
## 코딩 규칙
- 파일 위치, 네이밍, 컴포넌트 분리 기준
- 상태 관리와 API 호출 패턴
## 작업 완료 기준
- lint, type check, test, build 명령
- PR 전 확인할 체크리스트
## AI 작업 규칙
- 계획 없이 대규모 수정 금지
- 테스트 없는 기능 구현 금지
- 임의 라이브러리 추가 전 확인핵심은 짧고 강한 규칙이다. CLAUDE.md가 길어질수록 매번 읽어야 할 컨텍스트가 늘고, 중요한 규칙이 묻힐 수 있다. 세부 절차는 Skill로 빼고, 프로젝트 전체 원칙만 남기는 편이 좋다.
4. 요구사항 인터뷰로 모호성을 먼저 줄인다
AI에게 바로 구현을 시키면, AI는 빈칸을 스스로 채운다. 문제는 그 빈칸이 사용자의 의도와 다를 수 있다는 점이다.
그래서 구현 전에는 Claude Code를 질문자로 세우는 것이 좋다.
text
이 기능 정의서는 초안이야.
코드베이스를 먼저 탐색하고, 구현 전에 확인해야 할 질문을 해줘.
기능 요구사항, 비기능 요구사항, UI 동작, 엣지 케이스를 나눠서 질문해줘.
한 번에 하나씩 질문하고, 추천안이 있다면 이유와 함께 제안해줘.이 방식의 목적은 단순히 답변을 얻는 것이 아니다.
- 사용자가 놓친 엣지 케이스를 발견한다.
- AI가 기존 코드 구조를 기준으로 현실적인 질문을 하게 만든다.
- 구현 전에 용어와 범위를 맞춘다.
- 이후 테스트 시나리오로 바꿀 수 있는 기준을 만든다.
초기 문서는 spec_original.md처럼 가볍게 시작해도 된다. 인터뷰가 끝난 뒤에는 확정본을 spec_fixed.md처럼 별도로 남긴다. 중요한 것은 "왜 그렇게 정했는가"까지 기록하는 것이다.
| 항목 | 나쁜 기록 | 좋은 기록 |
|---|---|---|
| 태그 개수 | 최대 5개 | 모바일 카드 폭을 고려해 태그는 최대 5개로 제한한다 |
| 입력 방식 | 엔터로 추가 | 쉼표 입력은 오동작 위험이 있어 엔터로 확정한다 |
| 삭제 방식 | X 버튼 | 칩 hover 시 X 버튼을 노출해 실수 삭제를 줄인다 |
이런 근거가 남아 있으면 나중에 다른 사람이 와도 같은 판단을 이어갈 수 있다.
5. PRD와 ADR은 기준점이다
요구사항이 확정되면 PRD와 ADR을 만든다.
PRD는 "무엇을 만들 것인가"를 정리한 기준 문서다. ADR은 "왜 이 구조를 선택했는가"를 남기는 기술 결정 기록이다. 둘은 AI와 사람이 공유하는 기준점이 된다.
PRD에 넣을 내용
| 항목 | 설명 |
|---|---|
| 개요 | 기능의 목적과 사용자 가치 |
| 목표 | 이번 범위에서 달성할 것 |
| 사용자 스토리 | 사용자가 어떤 상황에서 무엇을 할 수 있어야 하는지 |
| 기능 요구사항 | 실제 구현할 동작 |
| 비기능 요구사항 | 성능, 접근성, 보안, 호환성 같은 제약 |
| Out of Scope | 이번에 만들지 않을 것 |
| 용어 정의 | 기능 안에서 쓰는 단어의 의미 |
| 기술 결정 요약 | ADR로 연결되는 핵심 선택 |
ADR에 넣을 내용
| 항목 | 설명 |
|---|---|
| Context | 어떤 문제가 있었는가 |
| Decision | 어떤 선택을 했는가 |
| Alternatives | 어떤 대안을 비교했는가 |
| Consequences | 장점, 단점, 향후 영향은 무엇인가 |
ADR에서 가장 중요한 것은 사람이 최종 결정을 내린다는 점이다. Claude Code가 대안을 비교하게 할 수는 있지만, 프로젝트 철학과 장기 유지보수 방향은 사람이 판단해야 한다.
예를 들어 React 기능을 만들 때 Claude가 세 가지 구조를 제안할 수 있다.
| 안 | 특징 | 리스크 |
|---|---|---|
| 로컬 상태 확장 | 변경 범위가 작다 | 기능이 커지면 컴포넌트가 비대해질 수 있다 |
| Context 액션 추가 | 기존 상태 흐름과 맞다 | 전역 상태 의존이 커질 수 있다 |
| Custom Hook 분리 | 테스트와 재사용이 쉽다 | 파일 수가 늘고 초기 구조가 조금 커진다 |
선택 후에는 "왜 이 안을 택했는지"를 문서에 남긴다. 이 기록이 있어야 나중에 Claude Code가 임의로 다른 상태 관리 라이브러리를 추천하거나, 기존 방향과 다른 구조를 만들 확률을 줄일 수 있다.
6. 수직 슬라이싱으로 이슈를 나눈다
PRD가 크면 그대로 TDD를 시작하기 어렵다. 테스트할 단위가 너무 커지기 때문이다. 그래서 기능을 사용자에게 의미 있는 작은 단위로 나눈다.
이것이 수직 슬라이싱이다.
| 구분 | 수평 슬라이싱 | 수직 슬라이싱 |
|---|---|---|
| 나누는 기준 | 레이어 | 사용자 가치 |
| 예시 | API 먼저, UI 나중, 테스트 나중 | 태그 추가 기능 한 조각을 끝까지 |
| 검증 | 중간 산출물은 사용자에게 보이기 어렵다 | 하나의 기능을 바로 시연할 수 있다 |
| TDD 적합성 | 시나리오가 흐려질 수 있다 | Given-When-Then으로 바꾸기 쉽다 |
수직 슬라이스 하나는 다음 질문을 통과해야 한다.
text
이 이슈가 끝나면 사용자에게 보여줄 수 있는 동작이 생기는가?
이 이슈만으로 테스트 시나리오를 만들 수 있는가?
이 이슈의 완료 조건을 Given-When-Then으로 쓸 수 있는가?Acceptance Criteria는 이슈의 완료 조건이다. AI와 사람이 "완료"를 같은 뜻으로 이해하게 만드는 장치다.
gherkin
Given 노트 편집 화면에 태그 입력란이 비어 있고
When 사용자가 "react"를 입력한 뒤 Enter를 누르면
Then "react" 태그 칩이 화면에 표시된다
And 노트의 tags 배열에 "react"가 추가된다이렇게 쓰면 이후 테스트 시나리오와 테스트 코드로 자연스럽게 이어진다.
7. 품질 게이트는 여러 층에 둔다
검증을 마지막에 한 번만 하면 늦다. 하네스는 여러 지점에서 작은 검증을 반복한다.
각 게이트는 막는 대상이 다르다.
| 위치 | 대표 도구 | 막는 문제 |
|---|---|---|
| Claude 작업 전 | CLAUDE.md, Skill | 잘못된 절차, 과도한 범위 |
| Claude 이벤트 시점 | PreToolUse, PostToolUse, Stop Hook | 실행 전후 검사, 작업 종료 처리 |
| 커밋 전 | Husky, lint-staged | lint, format, staged 파일 오류 |
| 커밋 메시지 | commitlint | 일관성 없는 커밋 로그 |
| PR 전 | E2E Skill | 주요 사용자 흐름 깨짐 |
| 원격 CI | GitHub Actions | clean install, 타입, 테스트, 보안 문제 |
| 병합 전 | Branch Protection | 검증 실패 코드의 main 병합 |
Git Hook은 Git 자체에도 있지만 .git/hooks는 보통 팀에 공유되지 않는다. 그래서 팀 전체에 같은 커밋 전 검사를 적용하려면 Husky 같은 도구로 .husky/ 디렉토리를 저장소에 포함시키는 방식을 쓴다.
단, 도구 설치 명령은 시간이 지나며 바뀔 수 있다. 하네스 문서에는 "무엇을 검사할지"와 "어느 시점에 막을지"를 먼저 적고, 실제 설치 명령은 프로젝트 시점의 공식 문서를 확인해 적용하는 편이 안전하다.
8. 디자인 시스템도 하네스의 일부다
테스트는 동작을 잘 검증하지만, 시각적 일관성을 모두 보장하지는 못한다. 그래서 UI 작업이 있는 프로젝트라면 디자인 시스템 문서도 하네스 안에 넣어야 한다.
design.md에는 색상, 타이포그래피, 간격, 컴포넌트 규칙, 해야 할 것과 하지 말아야 할 것을 정리한다. 내용이 길면 colors.md, typography.md, components.md처럼 나눌 수 있다.
중요한 것은 Claude Code가 매번 거대한 디자인 문서를 읽지 않게 하는 것이다.
markdown
## UI 작업 규칙
- UI를 새로 만들거나 수정할 때는 design-system Skill을 먼저 사용한다.
- 디자인 시스템 문서를 임의로 무시하지 않는다.
- 없는 컴포넌트 변형을 만들기 전에는 사용자에게 확인한다.원칙은 CLAUDE.md에 짧게 두고, 상세 규칙은 Skill과 참고 문서로 분리한다. 이후 파일 수정 후 PostToolUse Hook으로 디자인 검사 스크립트를 실행하게 하면 사후 검증까지 붙일 수 있다.
9. TDD 하네스는 단계를 분리해야 한다
AI에게 "테스트도 만들고 구현도 해줘"라고 한 번에 요청하면, 테스트가 구현에 맞춰지는 문제가 생긴다. TDD 하네스를 만들 때는 단계를 분리한다.
테스트 시나리오 단계
테스트 코드를 쓰기 전에 시나리오를 먼저 만든다. 정상 케이스만 만들면 부족하다.
| 종류 | 예시 |
|---|---|
| 정상 | 유효한 태그를 입력하면 태그가 추가된다 |
| 경계 | 최대 길이와 최대 개수 바로 앞뒤를 검증한다 |
| 예외 | 빈 문자열, 중복 값, 공백 입력을 검증한다 |
| 회귀 | 기존 데이터에 새 필드가 없어도 깨지지 않는다 |
시그니처와 Stub 단계
TDD Red에서 중요한 것은 "올바르게 실패하는 테스트"다. 테스트 파일이 import 단계에서 깨지면 아직 테스트를 실행한 것이 아니다.
그래서 먼저 함수명, 파라미터, 반환 타입, 컴포넌트 props 같은 시그니처를 합의하고, 최소 Stub을 만든다.
| 실패 유형 | 의미 | 좋은 상태인가? |
|---|---|---|
| 테스트 수집 실패 | 테스트 파일을 읽거나 import하는 단계에서 오류 발생 | 아니다 |
| 테스트 실행 실패 | 테스트 케이스는 수집됐고 assertion이 실패 | 맞다 |
Red 단계의 목표는 "테스트가 모두 실패한다"가 아니라 테스트가 실행 가능한 상태에서 의도한 이유로 실패한다다.
Green 단계
Green 단계에서는 테스트를 통과시키는 최소 구현만 한다. 여기에서 욕심을 내면 테스트에 없는 기능이 들어가고, 이후 리팩토링과 검증 범위가 커진다.
text
이번 단계에서는 테스트를 통과시키는 최소 구현만 해줘.
테스트 시나리오에 없는 기능은 추가하지 말고, 새 라이브러리도 추가하지 마.AC Verifier 단계
테스트가 통과해도 PRD와 AC를 모두 만족한다고 볼 수는 없다. 테스트 자체가 빠뜨린 조건이 있을 수 있기 때문이다.
그래서 AC Verifier 같은 검증 에이전트를 둔다.
| 검증 항목 | 질문 |
|---|---|
| AC 충족 | Given-When-Then 조건이 모두 코드와 테스트에 반영됐는가? |
| 누락 | PRD에는 있지만 테스트에는 없는 조건이 있는가? |
| 과구현 | 이번 이슈 범위를 넘어선 기능이 들어갔는가? |
| 회귀 | 기존 동작을 깨뜨리지 않았는가? |
이 검증은 구현을 맡은 에이전트와 분리하는 것이 좋다. 만든 사람이 자기 결과를 검증하면 놓치는 지점이 생길 수 있다.
10. E2E와 CI는 마지막 안전망이다
단위 테스트가 함수와 컴포넌트를 빠르게 확인한다면, E2E 테스트는 사용자의 실제 흐름을 확인한다. 둘은 역할이 다르다.
| 구분 | 단위 테스트 | E2E 테스트 |
|---|---|---|
| 범위 | 함수, Hook, 컴포넌트 | 브라우저에서 전체 흐름 |
| 속도 | 빠름 | 느림 |
| 실패 원인 파악 | 쉬움 | 상대적으로 어려움 |
| 사용자 가치 검증 | 간접적 | 직접적 |
| 개수 | 많아도 됨 | 핵심 흐름 위주로 적게 |
E2E는 많이 만들수록 좋은 것이 아니다. 핵심 사용자 흐름을 소수로 유지하고, 세부 로직은 단위 테스트에서 잡는 편이 안정적이다.
PR을 만들 때는 다음 흐름을 하네스로 둘 수 있다.
CI에서는 로컬에서 놓친 문제를 잡는다. 예를 들어 로컬에는 남아 있던 캐시 때문에 통과했지만, 깨끗한 환경의 npm ci에서는 실패할 수 있다. 그래서 원격 CI는 하네스의 마지막 안전망이다.
11. 버그 수정도 같은 루프를 탄다
기능 개발 워크플로우와 버그 수정 워크플로우를 따로 만들 필요는 없다. 버그도 하나의 요구사항으로 보고 같은 하네스를 태우면 된다.
중요한 점은 버그를 바로 고치지 않는 것이다. 먼저 버그를 재현하는 테스트를 추가해야 한다. 그래야 같은 문제가 다시 생겼을 때 자동으로 잡을 수 있다.
버그 수정 프롬프트는 다음처럼 시작할 수 있다.
text
이 버그를 바로 수정하지 말고 원인을 먼저 분석해줘.
재현 가능한 테스트 시나리오를 만들고, TDD 흐름으로 수정 계획을 세워줘.
수정 후에는 기존 테스트와 회귀 테스트를 모두 실행해줘.12. 하네스도 유지보수 대상이다
하네스는 한 번 만들고 끝나는 것이 아니다. 프로젝트가 바뀌면 하네스도 바뀐다.
| 시점 | 점검할 것 |
|---|---|
| 새 프로젝트 시작 | /init 후 CLAUDE.md 검토, 기본 명령 정리 |
| 첫 기능 개발 전 | 요구사항 인터뷰, PRD/ADR, 디자인 시스템 정리 |
| 첫 이슈 완료 후 | TDD 단계가 적절했는지, Skill이 과하거나 부족한지 |
| PR 생성 후 | E2E와 CI가 실제로 필요한 문제를 잡았는지 |
| 버그 발생 후 | 어떤 AC나 테스트 시나리오가 빠졌는지 |
| 반복 사용 후 | 프로젝트 Skill을 글로벌 Skill로 옮길지 |
너무 많은 자동화는 오히려 위험하다. 승인 게이트가 필요한 단계까지 하나의 거대한 Skill로 묶으면, 사용자가 판단해야 할 지점을 지나칠 수 있다. 특히 요구사항 확정, ADR 선택, PR 승인, 보안 예외 판단은 사람이 개입하는 편이 안전하다.
하네스 유지보수의 원칙은 다음과 같다.
- 자주 반복되는 절차만 Skill로 만든다.
- 판단이 필요한 단계는 Agent나 사람 승인으로 분리한다.
- 프로젝트 전체 원칙은
CLAUDE.md에 짧게 남긴다. - 세부 자료는 별도 문서로 분리하고 필요할 때만 로드한다.
- 자동화가 실패했을 때 사람이 이해할 수 있는 로그를 남긴다.
- 완료된 기능 문서는 코드와 충돌하지 않도록 정리하거나 보관 위치를 명확히 한다.
13. 최소 하네스 체크리스트
처음부터 거대한 하네스를 만들 필요는 없다. 작은 프로젝트라면 다음 정도만 있어도 충분히 시작할 수 있다.
1단계: 프로젝트 기억
/init으로 시작하되 반드시 사람이 검토한다.CLAUDE.md에는 프로젝트 규칙과 완료 기준만 간결하게 둔다.- 긴 문서와 세부 절차는 Skill 또는
docs/로 분리한다.
2단계: 요구사항과 설계
- AI가 사용자에게 질문하도록 만든다.
- 기능 요구사항과 비기능 요구사항을 나눈다.
- PRD와 ADR로 기준점을 만든다.
- Out of Scope를 명확히 적는다.
3단계: 작업 분해
- 사용자 가치가 있는 수직 슬라이스로 나눈다.
- 각 이슈에 Given-When-Then AC를 둔다.
- 테스트 가능한 단위인지 점검한다.
4단계: 구현 루프
- 테스트 시나리오를 먼저 만든다.
- 시그니처와 Stub을 정의한다.
- Red, Green, Refactor를 분리한다.
- AC Verifier로 누락을 확인한다.
5단계: 병합 루프
- E2E는 핵심 사용자 흐름만 검증한다.
- PR 생성 전 테스트 계획을 확인한다.
- CI에서 깨끗한 환경으로 다시 검증한다.
- 실패하면 단위 테스트로 원인을 좁힌 뒤 수정한다.
핵심 요약
Claude 하네스는 AI 코딩을 통제하기 위한 운영 체계다. 핵심은 다음 다섯 가지다.
- 맥락을 고정한다.
CLAUDE.md와 문서로 프로젝트 규칙을 남긴다. - 절차를 반복 가능하게 만든다. Skill로 요구사항, TDD, PR 같은 반복 작업을 표준화한다.
- 판단을 분리한다. Agent와 사람 검토로 생성과 검증을 나눈다.
- 검증을 여러 층에 둔다. Hook, Git Hook, E2E, CI를 단계별 게이트로 둔다.
- 작게 반복한다. 수직 슬라이스 단위로 TDD 루프를 돌리고, 하네스 자체도 계속 다듬는다.
하네스의 목표는 Claude Code를 완전히 자동화하는 것이 아니다. 사람이 더 중요한 판단에 집중할 수 있도록 반복 절차와 품질 검사를 시스템에 맡기는 것이다.
다음 단계
이 장까지 읽었다면 Claude Code의 개별 기능을 하나의 개발 운영 흐름으로 묶을 수 있다. 실제 프로젝트에서는 먼저 작은 기능 하나를 골라 다음 순서로 적용해 보자.
text
요구사항 인터뷰 → PRD/ADR → 수직 슬라이스 → AC → TDD Red/Green
→ AC 검증 → Refactor/Security Review → E2E → PR/CI한 번에 완벽한 하네스를 만들려고 하지 말고, 한 기능을 끝까지 통과시키며 부족한 장치를 하나씩 추가하는 것이 가장 안전하다.