Claude Code 에이전트 & 스킬 워크플로우
들어가며
Claude Code를 처음 사용했을 때는 단순한 코딩 어시스턴트였다. 질문하고, 코드를 받고, 붙여넣었다. 하지만 세 개의 프로젝트를 거치며 AI와 함께 개발하는 방식이 완전히 달라졌다.
이 글은 개인 모바일 앱(프로젝트 A) → 회사 팀 프로젝트(프로젝트 B) → 개인 풀스택 앱(프로젝트 C)을 거치며 에이전트와 스킬 기반 워크플로우를 구축한 여정을 정리한 것이다.
프로젝트 A — 패턴의 탄생
배경
첫 번째 프로젝트는 React Native(Expo) 기반 개인 모바일 앱이었다. iOS/Android 네이티브, 상태 관리, E2E 테스트까지 혼자 감당해야 할 영역이 넓었고, Claude Code에게 "전부 다 잘해줘"라고 하면 맥락이 흐려지는 문제를 체감했다.
핵심 아이디어: 역할 분리
해결책은 단순했다. 사람 팀처럼 역할을 나누자. .claude/agents/ 디렉토리에 에이전트 정의 파일을 만들기 시작했다.
.claude/agents/
├── orchestrator.md # 팀 리더 — 직접 코드 안 짬
├── pm-po.md # 기획 — 스펙 문서 작성
├── designer.md # 디자인 — UI/UX 설계
├── rn-developer.md # RN 개발 — 크로스 플랫폼
├── rn-ios-developer.md # iOS 전문
├── rn-android-developer.md # Android 전문
├── qa-engineer.md # QA — 테스트 & 검증
├── backend-developer.md # 백엔드
└── medical-reviewer.md # 도메인 전문가 (의약 정보 검증)
9개 에이전트. 많아 보이지만 각각의 책임이 명확했다.
게이트 시스템
에이전트를 만들고 나서 바로 부딪힌 문제가 있었다. 에이전트가 확인 없이 다음 단계로 넘어가는 것. 기획이 끝나지도 않았는데 코드를 쓰기 시작하는 일이 빈번했다.
그래서 도입한 것이 게이트(Gate) 시스템이다:
Gate 1: PM 스펙 완료 → 사용자 확인
Gate 2: 디자인 완료 → 사용자 확인
Gate 3: 구현 완료 → 린트/빌드/테스트 통과
Gate 4: QA 완료 → Ralph Loop (최대 3회 반복)
오케스트레이터가 각 게이트를 관리하고, 사용자 승인 없이는 다음 단계로 넘어가지 못하게 했다.
훅으로 강제하기
게이트를 정의해도 에이전트가 "무시"하는 경우가 있었다. 결국 **훅(Hook)**으로 물리적 강제를 시작했다:
.claude/hooks/
├── enforce-orchestrator.ts # 모든 요청을 오케스트레이터 경유 강제
├── pre-write-check.ts # .env 수정 차단, 파일 크기 경고
├── pre-commit-all-checks.ts # 커밋 전 lint + tsc 강제
├── post-write-format.ts # 파일 저장 후 자동 포매팅
├── inject-spec-context.ts # 에이전트에 관련 스펙 자동 주입
├── task-scope-limiter.ts # 탐색 태스크 15회 제한
├── task-quality-gate.ts # 태스크 완료 시 린트 검증
└── teammate-idle-check.ts # 유휴 에이전트 재작업 유도
특히 enforce-orchestrator는 게임 체인저였다. 사용자의 모든 요청이 반드시 오케스트레이터를 거치게 만들어서, 에이전트가 자기 역할을 벗어나는 일을 원천 차단했다.
스킬: 재사용 가능한 지식
에이전트에게 매번 같은 컨벤션을 반복 설명하는 비효율을 줄이기 위해 스킬을 도입했다:
.agents/skills/
├── react-native-conventions/ # Pressable, FlatList, SafeArea 패턴
├── expo-conventions/ # SDK 54, Config Plugin, Router 6
├── zustand-patterns/ # 스토어 생성, 셀렉터 (무한루프 방지!)
├── detox-e2e-testing/ # replaceText vs typeText, testID 규칙
├── biome/ # 린팅, 포매팅 설정
├── code-conventions/ # 네이밍, import 순서, testID
├── plan-first/ # 번호 매기기, [CONFIRM] 마커
├── ask-questions-if-underspecified/ # 불확실하면 질문하기
└── ci-fix/ # CI 실패 카테고리별 수정 가이드
스킬은 에이전트의 프롬프트에 자동으로 주입되어, 매번 설명할 필요 없이 일관된 코드를 생성하게 했다.
프로젝트 A에서 배운 것
- 오케스트레이터는 코드를 쓰면 안 된다 — 역할이 섞이면 품질이 떨어진다
- 게이트 없으면 에이전트가 폭주한다 — 확인 단계는 필수
- 훅 = 법률, 프롬프트 = 가이드라인 — 중요한 규칙은 훅으로 강제해야 한다
- 스킬은 재사용의 핵심 — 한 번 잘 정의하면 모든 에이전트가 혜택을 받는다
프로젝트 B — 체계의 정교화
배경
두 번째는 회사의 팀 프로젝트(Next.js 모노레포)였다. 프로젝트 A에서 확립한 패턴을 가져왔지만, 팀 환경과 규모에 맞게 여러 가지를 바꿔야 했다.
글로벌 vs 프로젝트 분리
프로젝트 A에서는 모든 에이전트가 프로젝트 안에 있었다. 하지만 회사 프로젝트를 시작하면서 깨달았다 — PM, 디자이너, QA, 아키텍트는 프로젝트에 상관없이 동일한 역할을 한다.
~/.claude/agents/ # 글로벌 — 프로세스 에이전트
├── pm.md # 모든 프로젝트 공통
├── architect.md # 아키텍처 설계 (새로 추가!)
├── designer.md # UI/UX
└── qa.md # 품질 보증
/project/.claude/agents/ # 프로젝트 — 기술 에이전트
├── orchestrator.md # 이 프로젝트 전용 오케스트레이터
├── ts-developer.md # 프로젝트 스택에 맞춤
└── ...
이 분리로 새 프로젝트를 시작할 때 프로세스 에이전트는 재사용하고, 기술 에이전트만 새로 정의하면 되었다.
아키텍트 에이전트 추가
프로젝트 A에서는 PM → 디자이너로 바로 넘어갔는데, 복잡한 프로젝트에서 아키텍처 결정이 빠지면 구현 단계에서 뒤엎어지는 일이 발생했다. 그래서 아키텍트 에이전트를 추가했다:
Gate 1: PM 스펙 → 사용자 확인
Gate 1.5: 아키텍처 설계 → 사용자 확인 ← 새로 추가!
Gate 2: 디자인 → 사용자 확인
Gate 3: 구현 → 린트/빌드/테스트
Gate 4: QA
아키텍트는 ADR(Architecture Decision Record)을 작성하고, 컴포넌트 인터페이스와 API 계약을 정의했다. 코드를 직접 쓰지 않고 문서만 생산하는 것이 원칙이었다.
메타 에이전트: 에이전트를 만드는 에이전트
프로젝트마다 에이전트 팀을 처음부터 구성하는 것이 번거로워져서, 에이전트 팀 생성기를 만들었다:
# agent-team-generator.md
1단계: CLAUDE.md → 기술 스택, 구조, 도메인 분석
2단계: 필요한 역할 제안 → 사용자 확인
3단계: 글로벌 에이전트(PM, QA 등) 연결 + 프로젝트 에이전트 생성
4단계: 오케스트레이터 생성 (게이트, 파일 소유권 매트릭스)
5단계: 거버넌스 훅 생성 (선택)
6단계: 검증 (파일 소유권 중복/누락 체크)/generate-team 스킬로 호출하면, CLAUDE.md를 분석해서 프로젝트에 맞는 에이전트 팀을 자동 생성해줬다.
Agent Teams: 게임 체인저의 등장
프로젝트 B 중반, Claude Code에 Agent Teams 기능이 추가되었다. 그 전까지는 오케스트레이터가 서브에이전트를 호출하는 방식이었는데, 서브에이전트는 결과만 상위에 보고할 수 있었다. 서브에이전트끼리는 대화할 수 없었다.
Agent Teams는 근본적으로 달랐다. 각 팀원이 독립된 Claude Code 인스턴스로 실행되며, 팀원끼리 직접 메시지를 주고받을 수 있었다.
서브에이전트 방식 (이전) Agent Teams 방식 (이후)
오케스트레이터 팀 리더
├→ 에이전트 A → 결과 보고 ├→ 팀원 A ←→ 팀원 B
├→ 에이전트 B → 결과 보고 ├→ 팀원 B ←→ 팀원 C
└→ 에이전트 C → 결과 보고 └→ 팀원 C ←→ 팀원 A
(일방향, 상위에만 보고) (양방향, 팀원 간 직접 통신)
활성화는 settings.json에 한 줄이면 됐다:
{
"env": {
"CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS": "1"
}
}그리고 tmux 분할 창 모드를 켜면 각 팀원이 자기만의 터미널 창에서 작업하는 모습을 실시간으로 볼 수 있었다.
기존 에이전트 시스템과의 통합은 자연스러웠다. 이미 에이전트 정의 파일(orchestrator.md, developer.md 등)이 있었기 때문에, 팀 리더가 팀원을 생성할 때 해당 에이전트 정의를 프롬프트로 전달하면 됐다. 공유 작업 목록(Task List)으로 작업을 분배하고, 파일 소유권 매트릭스로 충돌을 방지했다.
가장 큰 변화는 구현 단계의 병렬화였다. 이전에는 서브에이전트가 결과를 보고하면 오케스트레이터가 다시 분배하는 식이어서 병목이 있었다. Agent Teams에서는 프론트엔드, 백엔드, 테스트 팀원이 동시에 작업하면서 필요하면 서로 직접 물어봤다:
프론트엔드 팀원 → 백엔드 팀원: "인증 API 응답 형식이 어떻게 되나요?"
백엔드 팀원 → 프론트엔드 팀원: "{ token: string, expiresAt: number } 형태입니다"
리더를 거치지 않고도 팀원끼리 즉시 소통할 수 있으니, 조율 병목이 사라졌다.
다만 **위임 모드(Delegate Mode)**를 설정하는 것이 중요했다. 이걸 안 켜면 팀 리더가 팀원을 기다리지 않고 직접 코드를 쓰기 시작하는 일이 있었다. 위임 모드를 켜면 리더는 조율 전용 도구만 사용할 수 있어서, 오케스트레이터가 "코드를 쓰면 안 된다"는 원칙을 시스템 레벨에서 강제할 수 있었다.
세션 연속성
긴 작업을 여러 세션에 걸쳐 진행할 때 컨텍스트 유실 문제가 심각했다. 이를 해결한 두 가지 시스템:
1. HANDOFF.md — 자동 세션 인수인계
# Session Handoff
## Git Status
- Branch: feat/auth
- Last commit: abc1234 feat(auth): 로그인 API 연동
- Changes: 2 staged, 1 unstaged
## Completed This Session
- 로그인 폼 구현
- API 클라이언트 설정
## Remaining Work
- 토큰 갱신 로직
- 에러 핸들링
## Next Session Prompt
> "토큰 갱신 로직 구현부터 시작해줘"세션 종료 시 훅이 자동으로 Git 상태를 캡처하고, 다음 세션 시작 시 주입했다.
2. progress.txt — 실시간 컨텍스트 추적
목표: 인증 시스템 구현
제약: JWT 기반, refresh token rotation
구현완료: 로그인 API, 토큰 저장
다음구현: 토큰 갱신 인터셉터세션 중간에도 항상 최신 상태를 기록해서, 컨텍스트 윈도우가 압축되어도 핵심 정보를 잃지 않게 했다.
프로젝트 B에서 배운 것
- 글로벌/프로젝트 분리는 필수 — 프로세스는 재사용, 기술은 맞춤
- 아키텍트 없으면 구현에서 뒤엎어진다 — 중간 게이트의 가치
- 메타 에이전트는 시간을 아낀다 — 팀 생성 자동화
- Agent Teams = 진짜 병렬화 — 서브에이전트의 일방향 보고에서 양방향 협업으로
- 위임 모드는 필수 — 리더가 직접 구현하는 것을 시스템 레벨로 차단
- 세션 연속성 없으면 매번 처음부터 — HANDOFF + progress 시스템
프로젝트 C — 풀 자동화
배경
세 번째 프로젝트는 Next.js 기반 풀스택 앱으로, 5개의 독립적인 계산 엔진을 포함하는 복잡한 도메인을 다뤘다. 이전 두 프로젝트의 교훈을 모두 녹여 가장 정교한 워크플로우를 구축했다.
도메인 전문가 에이전트
이 프로젝트의 가장 큰 차별점은 도메인 전문가 에이전트였다. 각 계산 엔진마다 해당 분야의 전문 지식을 가진 에이전트를 배치했다:
.claude/agents/
├── orchestrator.md # 팀 리더
├── frontend-developer.md # Next.js 15 + i18n + Zustand
├── engine-developer.md # 공통 타입 + AI 인터프리터
├── domain-expert-1.md # 엔진 1 전문가
├── domain-expert-2.md # 엔진 2 전문가
├── domain-expert-3.md # 엔진 3 전문가
├── domain-expert-4.md # 엔진 4 전문가
└── domain-expert-5.md # 엔진 5 전문가
각 전문가 에이전트에는 해당 도메인의 핵심 개념, 계산 규칙, 엣지 케이스, 검증 포인트가 상세히 기술되어 있었다. 예를 들어 한 전문가 에이전트의 정의에는 이런 내용이 포함되었다:
## 핵심 검증 포인트
- 달력 변환 정확도 (윤달, 자정 보정)
- 절기 기반 월 결정
- 자정 경계 엣지 케이스
- 원소 균형 계산
- 주기 카운팅이렇게 도메인 지식을 에이전트에 직접 내장하니, 일반 AI가 빠지기 쉬운 도메인 특화 실수를 크게 줄일 수 있었다.
파일 소유권 매트릭스
에이전트가 늘어나면서 같은 파일을 여러 에이전트가 건드리는 충돌 문제가 생겼다. 해결책은 명시적 파일 소유권이었다:
| 디렉토리 | 소유자 |
|---|---|
apps/web/ | 프론트엔드 개발자 |
packages/core/ | 엔진 개발자 |
packages/engine-1/ | 도메인 전문가 1 |
packages/engine-2/ | 도메인 전문가 2 |
packages/i18n/ | 프론트엔드 개발자 |
| 루트 설정 파일 | 오케스트레이터 |
각 에이전트의 정의 파일에 **"이 디렉토리 외에는 수정 금지"**를 명시했다. 오케스트레이터가 이를 감시하고, 위반 시 차단했다.
1000점 감사 시스템
QA를 넘어서 도메인 정확도를 정량적으로 측정하는 감사(Audit) 시스템을 만들었다:
점수 구성 (1000점 만점)
├── 핵심 알고리즘 정확도 350점
├── 데이터 테이블/상수 250점
├── 도메인 완성도 200점
├── 엣지 케이스 처리 100점
└── 검증 신뢰도 100점
5개 엔진 각각에 대해 이 기준으로 감사를 수행하고, 점수와 등급을 매겼다:
엔진 1 ████████████████████████████ 872/1000 (Near-Production)
엔진 5 ██████████████████████████ 810/1000 (Near-Production)
엔진 3 █████████████████████████ 805/1000 (Near-Production)
엔진 2 ████████████████████████ 790/1000 (MVP)
엔진 4 ██████████████████████ 735/1000 (MVP)
─────────────────────────────────────────────
평균: 802.4/1000 | 전체 테스트: 302/302 통과
감사 리포트에는 P0(긴급), P1(높음) 우선순위의 개선 사항이 구체적으로 기록되어, 다음에 무엇을 고쳐야 하는지가 항상 명확했다.
프로덕션 스킬
프로젝트 C에서는 스킬도 크게 성숙했다. 단순한 컨벤션 모음이 아닌, 구체적인 에러 방지와 설계 패턴을 담았다:
.agents/skills/
├── frontend-design/ # "AI슬롭" 방지 — 대담한 디자인 원칙
├── tailwind-design-system/ # v4 디자인 토큰 체계
└── tailwind-v4-shadcn/ # 8가지 에러 방지 + 4단계 아키텍처
├── SKILL.md
├── references/
│ ├── architecture.md
│ ├── dark-mode.md
│ ├── common-gotchas.md
│ └── migration-guide.md
└── templates/ # 즉시 사용 가능한 설정 파일
특히 tailwind-v4-shadcn 스킬은 실제 프로덕션 배포에서 검증된 8가지 에러 방지 규칙을 포함해서, 같은 실수를 반복하지 않게 했다.
병렬 실행 파이프라인
모든 것이 합쳐져 만들어진 최종 파이프라인:
사용자 요청
↓
오케스트레이터 (exec_plan 생성)
↓
Gate 1: PM 스펙 → 사용자 확인
↓
Gate 1.5: 아키텍처 → 사용자 확인
↓
Gate 2: 디자인 → 사용자 확인
↓
Gate 3: 구현 (병렬!)
├── 프론트엔드 개발자 ──→ apps/web/
├── 엔진 개발자 ──────→ packages/core/
├── 도메인 전문가 1 ──→ packages/engine-1/
├── 도메인 전문가 2 ──→ packages/engine-2/
├── 도메인 전문가 3 ──→ packages/engine-3/
├── 도메인 전문가 4 ──→ packages/engine-4/
└── 도메인 전문가 5 ──→ packages/engine-5/
↓
Gate 4: QA (Ralph Loop, 최대 3회)
↓
감사 시스템 (1000점 점수)
설계 단계는 순차적(정보가 누적되어야 하므로), 구현 단계는 Agent Teams로 진짜 병렬(각 팀원이 독립 인스턴스, 파일 소유권 격리)로 실행되었다. 프로젝트 B에서 도입한 Agent Teams가 프로젝트 C에서 비로소 빛을 발한 순간이었다 — 7개 팀원이 동시에 각자의 tmux 분할 창에서 작업하며, 필요할 때 서로 직접 소통하는 모습은 말 그대로 AI 팀이 일하는 풍경이었다.
세 프로젝트를 관통하는 교훈
1. 에이전트는 "프롬프트 분리" 이상의 가치가 있다
처음에는 단순히 긴 프롬프트를 나누는 용도로 에이전트를 도입했다. 하지만 실제 가치는 책임의 격리에 있었다. 에이전트가 자기 영역만 집중하면 품질이 확연히 올라갔다.
2. 훅은 가드레일이다
프롬프트에 "이것 하지 마"라고 쓰는 것과 훅으로 물리적으로 차단하는 것은 하늘과 땅 차이다. 중요한 규칙은 반드시 훅으로 강제해야 한다.
| 단계 | 프롬프트 | 훅 |
|---|---|---|
| .env 수정 방지 | "수정하지 마세요" | pre-write-check → 차단 |
| 커밋 전 린트 | "린트 돌려주세요" | pre-commit-checks → 강제 |
| 오케스트레이터 경유 | "오케스트레이터를 거쳐주세요" | enforce-orchestrator → 차단 |
3. 스킬은 지식의 복리 효과를 만든다
한 프로젝트에서 배운 패턴을 스킬로 정리하면, 다음 프로젝트에서 검증된 지식으로 시작할 수 있다. 프로젝트 A의 Zustand 패턴이 프로젝트 C의 프론트엔드 스킬에 녹아든 것처럼.
4. 세션 연속성은 과소평가되어 있다
AI 코딩의 가장 큰 약점 중 하나가 세션 간 기억 상실이다. HANDOFF + progress 시스템을 도입한 후, 새 세션을 시작해도 이전 작업을 이어받는 것이 자연스러워졌다.
5. 점진적으로 시작하라
처음부터 8개 에이전트 + 9개 훅 + 9개 스킬을 만들 필요 없다. 추천 순서:
1단계: CLAUDE.md 정리 → 프로젝트 컨벤션 문서화
2단계: 오케스트레이터 + 1~2개 전문 에이전트
3단계: 핵심 훅 2~3개 (포매팅, 린트 강제)
4단계: 반복되는 지식을 스킬로 추출
5단계: 게이트 시스템으로 품질 관리
6단계: 세션 연속성 시스템
마치며
세 프로젝트를 거치며 "AI에게 일을 시키는 방식" 자체가 하나의 엔지니어링 문제라는 걸 깨달았다.
좋은 에이전트 시스템은 좋은 팀 구조와 같다. 역할이 명확하고, 소통 경로가 정해져 있고, 품질 게이트가 있고, 지식이 축적된다. 결국 AI 워크플로우를 설계하는 것은 소프트웨어 아키텍처를 설계하는 것과 다르지 않았다.
이제 새 프로젝트를 시작할 때 가장 먼저 하는 일은 코드를 쓰는 것이 아니다. CLAUDE.md를 쓰고, 에이전트를 정의하고, 게이트를 설계한다. 그러고 나면 AI는 단순한 코드 생성기가 아닌, 진짜 팀원이 된다.