Claude Code TDD 서브에이전트와 하네스 구축기 — 7개 에이전트, 18종 회귀 평가
들어가며
안녕하세요. 비브로스에서 백엔드 개발을 담당하고 있는 김예림입니다.
TDD 실무에서 사용한 경험이 있으신가요? 저는 거의 없습니다. 일정압박과 일단 처음의 요구사항이 그대로 유지된적이 거의 드물고 기획과 같이 개발을 하는 방향으로 많이 일했어서 그런지 TDD를 많이 써보지는 못했습니다.
AI와 함께 하는 지금, AI가 만든 결과물이 내가 요구한 테스트에 확실히 통과하는지에 대한 의문에 대한 해답과 테스트가 개발을 이끄는 구조는 분명 필요했고, 그 방식을 AI와 함께 일하는 환경에 맞게 다시 만들어보고 싶었습니다.
이 글은 Claude Code에 TDD를 붙여보겠다는 질문에서 시작해, 7개의 서브에이전트와 그 에이전트들을 검증·통제하는 하네스를 만든 기록입니다. CLAUDE.md 규칙과 Plan Mode를 보다가 서브에이전트로 넘어간 과정, refactorer와 orchestrator가 생긴 이유, 18종 회귀 평가·권한 훅·사이클 메타데이터로 만든 하네스, 그리고 YAML 파일을 import하여 가시성을 높인 대시보드 제작까지 제가 고민한 순서대로 정리했습니다.
1. 왜 TDD였나
왜 하필 TDD 였나에 대해서 얘기해보고자 합니다.
첫 번째는 AI를 실무에 적용하면서 반복해서 본 문제였습니다. Claude Code로 신규 기능을 개발하다 보면 비슷한 일이 자주 생겼습니다. "이거 구현해줘"라고 던지면 빠르게 코드가 나오긴 하는데, 막상 받아보면 엣지 케이스를 빠뜨려서 다시 요청하거나, 테스트가 코드를 따라가거나, "이참에 같이" 하면서 요청하지 않은 부분까지 손대기도 했습니다.
두 번째는 AI 시대에도 기존 방법론을 사용할 수 있는 방법이 있지않을지 고민이 많았습니다. 기존 방법론이 완전히 사라지는 게 아니라, AI와 함께 일하는 방식의 뿌리가 될 거라고 생각했습니다. TDD는 저의 게으름으로 방법론만 알고있었고 실무에서는 거의 써보지 못했었고 AI와 함께라면 쉽게 시작할 수 있을것같다고 생각이 들었습니다. 그래서 그 출발점으로 TDD를 도입해보고싶었습니다.
마지막은 QA를 통과한 기능에서 터진 엣지 케이스 버그였습니다. 분명 검증을 거쳤는데도, 운영에 올라가니 누구도 떠올리지 못한 조건 조합에서 문제가 터졌습니다. QA 이전, 개발 단계에서 최대한 촘촘하게 검증할 수 있는 구조가 필요하다는 생각이 강해졌습니다.
이런 고민을 안고 5월 초, Claude에게 질문을 던졌습니다.

Claude의 답변은 꽤 구체적이었습니다. 테크스펙 → 시나리오 설계 → (사람 검토) → 테스트 작성(Red) → 구현(Green → Refactor)이라는 4단계 흐름과 함께, 지금 돌아보면 세 가지 조언이 특히 남았습니다.
- 단계마다 멈추게 할 것 — 한 번에 다 시키면 시나리오가 얕아지고, 구현 편의 위주로 테스트가 맞춰진다.
- 가장 흔한 실패 모드는 테스트 수정 — Claude가 테스트를 통과 못 하면 종종 테스트 자체를 고치려 든다. "테스트 수정 금지"를 강하게 박고, git diff로 테스트 파일 변경 여부를 매 사이클 체크하라.
- 서브에이전트로 역할을 분리할 것 — 구현자가 테스트를 못 보게 하거나, 시나리오 단계에서 구현 디테일에 휘둘리지 않게 하는 효과가 있다.
저는 각 단계에 대한 서브에이전트를 제작하는 걸 먼저 시작했습니다. 왜 서브 에이전트 제작을 먼저 시작하게 되었는지 그 배경에 대해서 설명하고자 합니다.
2. 준비
Claude가 첫 답변에서 제안한 출발점은 다음 조합이었습니다.
- CLAUDE.md에 TDD 규칙 박아두기 — "테스트 작성 단계에서는 프로덕션 코드 수정 금지", "구현 단계에서는 테스트 코드 수정 금지", "커밋은 Red/Green/Refactor 단위로 분리" 같은 규칙을 프로젝트 루트에 명시해 매번 반복하지 않기
- Plan Mode 활용 — Shift+Tab으로 Plan Mode에 들어가 시나리오 설계를 하면 파일 수정 없이 계획만 세우니, 시나리오 검토 단계에 딱 맞음
- 한 사이클 예시 명령어 — "1단계: 시나리오 작성 후 멈춤 → (검토 후) 2단계: 테스트 작성, 모두 fail 확인 → 3단계: 구현" 식으로 단계 끝마다 멈추게 하는 프롬프트
결론부터 말하면, 저는 이 조합을 채택하지 않았습니다. 규칙과 Plan Mode가 쓸모없어서가 아니라, 제가 만들고 싶은 컨셉과는 달랐기 때문입니다. 제가 원한 건 사용자가 매번 규칙을 기억하고 Plan Mode로 경계를 잡아주는 방식이 아니라, 역할과 권한이 구조적으로 분리되고 간섭하지 못하는 실행 환경이었습니다.
- CLAUDE.md 규칙은 약속이지 강제가 아닙니다. "구현 단계에서는 테스트 코드 수정 금지"라고 적을 수는 있지만, 실제로 수정 도구를 빼앗는 것은 아닙니다. 세션이 길어지거나 작업이 막히면 규칙은 쉽게 흐려질 수 있습니다.
- Plan Mode는 계획 단계의 경계만 만들어줍니다. "구현 전 계획"이라는 경계는 만들 수 있지만, 테스트 작성·구현·리뷰 단계 사이의 권한 분리는 해주지 못합니다. 모든 단계가 같은 컨텍스트에서 같은 도구를 쥐고 돌아갑니다.
- 사용자의 운영 부담이 남습니다. 단계 규칙·멈춤 지점·금지 사항을 사용자가 계속 기억하고, 매 사이클 프롬프트나 검토로 보완해야 합니다.
규칙을 "더 강하게 써붙이는" 방식은 제가 생각한 해결책이 아니었습니다. 다른 방법을 찾다가 Claude Code의 서브에이전트에 도달했습니다. 서브에이전트는 역할마다 격리된 컨텍스트에서 돌고, frontmatter의 tools:로 도구 자체를 제한합니다. "이 단계에서는 테스트를 수정하지 마"라고 채팅으로 부탁하는 대신, 수정 도구를 아예 주지 않는 구조를 만들었습니다.
컨텍스트가 격리되니 구현자가 시나리오 작성자의 고민에 끌려가는 일도 줄었습니다. 단계 규칙은 에이전트 정 의 파일에 한 번 넣어두면 매 사이클 적용됩니다. CLAUDE.md+Plan Mode에서 아쉬웠던 부분이 이 방식으로 꽤 줄었고, 첫 대화에서 받아둔 역할별 md 파일을 .claude/agents/에 올려 본격적으로 다듬기 시작했습니다.
처음 만든 에이전트 정의는 그럴듯해 보였지만 실전에서는 곳곳에서 샜습니다. 한 달간 실제 기능 구현에 투입하면서 test-writer가 assertion을 빼먹고 끝내거나, 막히면 as any로 도망가거나, implementer가 요청하지 않은 마이그레이션을 자발적으로 만드는 식의 실패 패턴을 하나씩 만났습니다. 그때마다 해당 에이전트 정의 파일에 금지 규칙과 자가 점검을 넣었습니다. 운영하면서 발견한 실패 패턴을 정의 파일에 누적시키는 것, 이게 이 시기에 자리 잡은 핵심 운영 방식이었어요.
정의 파일이 어느 정도 안정되자 팀원들도 같은 흐름을 쓰면 좋겠다고 생각했습니다. 그래서 팀에서 같은 방식으로 설치하고 업데이트할 수 있도록 사내 플러그인에 적용하기로 했고, 결국 역할은 서브에이전트, 진입점·절차는 플러그인 스킬로 나눴습니다.
- 에이전트 (플러그인 네이티브) — 파이프라인의 실행 주체들. 플러그인을 설치하면 어느 프로젝트에서든 바로 호출되고, 정의 개선은
/plugin update로 전 프로젝트에 자동 전파됩니다. - 스킬 —
/tdd-pipeline:install(하네스 설치)과/tdd-pipeline:run(파이프라인 진행) 두 개. 사용자 진입점이자 절차 안내 역할입니다.
사실 첫 버전은 이 결론이 아니었습니다. 처음에는 인스톨러 스킬이 에이전트 정의를 각 프로젝트의 .claude/agents/로 복사하는 구조였어요. 그런 데 운영해보니 비효율적이다고 생각이 들었어요.
거의 보통 에이전트 파일을 프로젝트별로 커스텀하며 수정하진 않을거라 생각이 들었습니다. 그리고 플러그인에서 정의를 개선해도 이미 설치된 프로젝트에는 전파되지 않고, 프로젝트마다 서로 다른 버전의 에이전트가 돌게 됐습니다. 그래서 에이전트를 플러그인 루트 agents/로 옮겨 네이티브 로드되게 바꿨고, 인스톨러는 "프로젝트별 측정 상태"인 하네스만 설치하도록 역할을 좁혔습니다.
전역으로 관리해야 하는 것(에이전트 정의)과 프로젝트에 누적되어야 하는 것(평가 결과·사이클 데이터)을 분리한다는 구분이 이 플러그인 구조의 뼈대가 됐습니다.
| 구분 | 정리 |
|---|---|
| 플러그인 네이티브(전역) | 에이전트 7개와 /tdd-pipeline:install, /tdd-pipeline:run 스킬을 둡니다. 정의 개선이 모든 프로젝트에 전파되어야 하므로, 에이전트 정의는 복사하지 않고 플러그인에서 직접 로드합니다. |
| 프로젝트별 하네스(로컬) | 회귀 평가, 권한 정책, 훅 설정, 사이클 메타데이터, 대시보드를 둡니다. 테스트 명령, 실패 이력, 누적 사이클은 프로젝트마다 다르므로 로컬 상태로 누적합니다. |
라우팅도 같은 원리로 정리했습니다. 예전에는 자동 발동을 막으려고 각 프로젝트 CLAUDE.md에 라우팅 규칙을 박아 넣었는데, 이제는 각 에이전트의 description frontmatter에 부정 지시문을 내장해 CLAUDE.md를 건드리지 않게 했습니다.
아직은 모든 프로젝트 진행 시 필수로 TDD를 사용할게 아니라서요.
description: MUST ONLY be invoked when the user explicitly requests TDD
workflow or directly mentions this agent by name. DO NOT auto-invoke for
general implementation, bug fixes, or refactoring tasks.
