Claude 팀 에이전트 첫 실전 — ERP 권한 체계를 하루 만에 뜯어고치다
📚 Claude Code 팀 에이전트 실전기 시리즈 (3편)
수동 오케스트레이션에서 Claude Agent Teams로 전환한 첫 실전. 듀얼 레포 ERP 시스템의 권한 체계를 프론트/백엔드 팀메이트와 병렬로 리팩토링한 8시간의 기록.
💡 Tip. 바쁜 분들을 위한 본문 요약
- 수동 오케스트레이션 → Agent Teams 전환 후 첫 실전 투입
- 프론트(React+Vite) + 백엔드(NestJS+TypeORM) 듀얼 레포 고객사 관리 시스템
- 8시간 만에: 권한 체계 리팩토링, synchronize 전환, Migration 도입, 퇴사자 관리 등
- 핵심 인사이트: 프로젝트 성숙도에 따라 최적 도구가 달라진다
왜 이 프로젝트에 팀 에이전트를 투입했나
모든 프로젝트에 팀 에이전트가 정답은 아니다.
사실 이 프로젝트 초반에는 수동 오케스트레이션이 더 나았다. 클라이언트와 개발자 사이에 요구사항 미스매치가 있듯이, 에이전트도 문서를 다르게 이해하는 경우가 많았다. 수동 중계 과정에서 이런 오해를 사람이 잡아낼 수 있었다.
하지만 프로젝트가 성숙해지면서 상황이 바뀐다. 방향성이 잡히고, 컨텍스트가 쌓이고, CLAUDE.md에 컨벤션이 정리되면 — 사람의 중계가 병목이 된다. 이 프로젝트는 정확히 그 시점이었다.
| 프로젝트 단계 | 최적 도구 | 이유 |
|---|---|---|
| 초기 (방향 탐색) | 수동 오케스트레이션 | 에이전트의 이해 오류를 사람이 검수 |
| 중기 (설계 확정) | 단일 에이전트 | 컨텍스트 유지하며 집중 구현 |
| 성숙기 (병렬 구현) | 팀 에이전트 | 설계가 확정되면 병렬이 효율적 |
이번 리팩토링은 “설계는 있고 구현만 안 된” 전형적인 성숙기 작업이었다.
셋업: 5분이면 팀이 뜬다
WSL tmux에서 Claude Code를 실행하고, 실험 플래그 하나 켜는 것으로 시작했다.
// ~/.claude/settings.json
{
"env": {
"CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS": "1"
}
}
TeamCreate로 팀을 만들고, Agent tool로 front/backend 팀메이트를 spawn했다. 각 팀메이트는 해당 레포 디렉토리에서 실행되면서 CLAUDE.md를 자동으로 로드한다. session-sync.md 같은 건 필요 없다 — SendMessage가 내장이다.
my-project 팀
├── orchestrator (리드 세션) — 조율/지시
├── front — React+Vite 프론트 담당
└── backend — NestJS+TypeORM 백엔드 담당
tmux split-pane 모드가 자동 감지돼서 각 팀메이트가 별도 패널에 뜬다. 리드에서 SendMessage로 지시하면 해당 팀메이트가 받아서 작업하고, 완료 보고가 자동으로 돌아온다.

위 도식이 이번 세션의 전체 구조다. 오케스트레이터가 SendMessage로 양쪽에 지시를 보내고, 각 팀메이트가 완료 보고를 돌려보낸다. 하단의 타임라인처럼 코드베이스 분석과 리팩토링이 병렬로 진행되고, 마지막에 QA와 배포를 합친다.
핵심은 오케스트레이터가 코드를 작성하지 않는다는 점이다. 지시와 판단만 한다. 코드는 팀메이트가 쓴다. 이 역할 분리가 깔끔해야 병렬성이 의미가 있다.
첫 작업: 코드베이스 파악을 병렬로
양쪽 팀메이트에게 동시에 코드베이스 분석을 지시했다. session-sync 시절이었으면 한쪽 끝날 때까지 기다렸다가 다음으로 넘겼을 일이다.
3분 뒤에 양쪽에서 보고가 동시에 들어왔다. 프론트 280개 소스 파일 분석, 백엔드 7개 모듈 구조.
오케스트레이터인 나는 양쪽 보고를 종합해서 다음 작업을 결정하기만 하면 됐다. 이전에는 내가 보고를 읽고 → 요약하고 → 전달했는데, 이제는 판단만 하면 된다.
발견: 프로덕션 DB에 synchronize: true
백엔드 팀메이트가 코드베이스를 분석하다가 심각한 구조적 문제를 선제적으로 찾아냈다. “위험요소를 찾아라”고 지시한 게 아니다. 코드베이스 전체를 파악하는 과정에서 스스로 판단해서 보고한 것이다.
TypeORM의 synchronize 옵션이 true인 채로 프로덕션 DB에 직접 연결돼 있었다.
엔티티 코드를 수정하고 서버를 재시작하면 프로덕션 테이블 스키마가 즉시 변경되는 구조.
💡 인사이트: 에이전트 자율성의 적정선
이 발견은 에이전트에게 적절한 자율성을 줬기에 가능했다. “ORM 설정을 검사해”라고 구체적으로 지시했다면 다른 문제는 놓쳤을 것이다. 반대로, 아무 가이드 없이 “알아서 해”라고 하면 중요도 판단이 흐려진다.
“코드베이스를 분석하고 구조적 위험요소가 있으면 우선 보고해” 수준의 지시가 가장 효과적이었다. 너무 강하게 강제하면 오히려 효율이 떨어진다는 건 Anthropic의 에이전트 설계 가이드에서도 언급하는 패턴이다.
이게 왜 남아있었냐면 — 흔한 개발자의 풍경이다. 작년에 dev 브랜치에서 개발 중이었는데 일정이 당겨지면서 프로덕션 배포 요청이 들어왔다. 거기에 다양한 케이스 추가 요청까지 쏟아졌고, 이후 다른 프로젝트에 할당되면서 기술부채로 남았다.
synchronize: true가 프로덕션에서 돌아간다는 걸 모른 게 아니라, 알면서도 손 못 대고 있었던 거다.
실제로 스키마 손상 이력도 있었다. 즉시 synchronize를 전부 false로 전환하고, TypeORM Migration을 도입했다. DB 백업 스크립트도 만들었다 — 풀백업 4.7GB에 3분, 테이블 단위 백업은 1초.
본 작업: 쌓인 기술부채를 한번에
이 시스템의 권한 체계도 같은 맥락의 기술부채였다. 원래 role 기반 권한 체계를 설계해둔 방향성은 있었지만, 구현되기 전에 프로덕션에 올라가 버렸다. 기능은 돌아가야 하니까 프론트에서 사용자 key를 하드코딩해서 때웠다.
// 실제 코드에 있던 것
switch (key) {
case 101: // 관리자 A
case 102: // 관리자 B
case 103: // 관리자 C
return new UserRole(0, ['all'], 'master')
case 201: // 운영자 D — 특정 고객사만
return new UserRole(1, ['ClientA'], 'admin')
// ... 7명의 key가 하드코딩
}
인사 변동이 생기면 코드를 수정하고 배포해야 하는 구조. 여기에 직책 문자열 비교, 부서명 하드코딩, 특정 고객사 특수 분기까지.
정리하면 이런 상태였다:
| 권한 체계 | 구현 방식 | 문제 |
|---|---|---|
| 사용자 식별 | DB key 하드코딩 (switch문) | 인사 변동마다 코드 수정+배포 |
| 직책 기반 | 문자열 비교 (if (title === '부장')) | 직책명 변경 시 전수 검색 |
| 부서 기반 | 부서명 하드코딩 | 조직개편 시 코드 수정 |
| 고객사 분기 | 특정 고객사 ID 상수 | 고객사 추가마다 분기문 추가 |
4개 체계가 혼재했다. 하지만 비즈니스 로직의 방향성은 이미 잡혀 있었다. 프로젝트별 PM 할당, 부서 단위 데이터 격리, role 기반 접근 제어. 설계는 있고 구현만 안 된 상태. 팀 에이전트로 프론트/백엔드를 동시에 돌리면, 이 방향성을 그대로 구현에 옮기는 게 가능했다.
팀 에이전트가 빛나는 순간: 프론트/백엔드 동시 작업
권한 체계 리팩토링은 전형적인 풀스택 작업이다. 백엔드에서 API를 바꾸면 프론트에서 연동을 맞춰야 한다. 수동 오케스트레이션이었다면 BE 완료 → 보고 → PM 정리 → FE 전달 순서로 직렬 처리했을 것이다.
팀 에이전트에서는 이렇게 했다:
- 양쪽에 동시에 현황 조사 지시 → 병렬로 결과 수신
- 오케스트레이터에서 종합 판단 → 백엔드에 API 설계 지시
- 백엔드 완료 보고 도착 → 즉시 프론트에 연동 지시 (API 스펙 포함)
- 프론트 작업 중에 백엔드에게 다음 작업 지시 → 병렬 진행
핵심은 3번이다. 백엔드 보고가 오면 내가 복붙하는 게 아니라, 보고 내용을 보고 프론트에게 “이 API 스펙대로 연동해”라고 지시만 하면 된다. API 타입이 빠질 일이 없다 — 백엔드 보고 원문이 대화 컨텍스트에 있으니까.
API 스펙 미스매치는 어떻게 처리했나
물론 양쪽이 알아서 완벽하게 맞추진 않았다. API 응답 필드명, 페이지네이션 파라미터, 에러 코드 규격 등에서 미스매치가 발생했다.
이런 부분은 사람이 판단해야 한다. 내부 규격이나 기존 코드 컨벤션, 비즈니스 상황에 따라 어느 쪽이 맞는지가 달라지기 때문이다.
처리 흐름은 이랬다:
- 미스매치 발견 → 양쪽 보고를 비교하다가 발견하거나, 프론트 팀메이트가 “백엔드 스펙과 다르다”고 보고
- 사람이 판단 → 기존 컨벤션과 비즈니스 맥락을 보고 어느 쪽 스펙을 따를지 결정
- 가이드 축적 → 결정 사항을 CLAUDE.md에 API 컨벤션으로 추가
- 이후 자동 준수 → 같은 패턴의 미스매치가 반복되지 않음
💡 인사이트: 컨텍스트가 가이드가 된다
이 과정을 반복하면 CLAUDE.md에 API 컨벤션이 쌓인다. 처음에는 매번 판단해줘야 하지만, 3~4번 반복하면 에이전트가 스스로 가이드를 참조한다. 팀 에이전트가 효율적으로 돌아가는 건 도구의 기능이 아니라 쌓인 컨텍스트의 힘이다.
약 8시간 동안 한 것
오전에 팀을 셋업하고, 저녁에 프로덕션 배포까지 마쳤다. 실제 투입 시간 약 8시간. 이 중 내가 한 건 방향 결정과 QA뿐이고, 코드는 팀메이트들이 작성했다.
| 작업 | 영역 | 비고 |
|---|---|---|
| synchronize: false 전환 | BE (38개 엔티티) | + Migration 도입 |
| DB 백업 스크립트 | BE | 풀백업 + 테이블 단위, Docker 기반 |
| 퇴사자 관리 기능 | Full-stack | 로그인 차단 + 조회 필터 + API + 관리 페이지 |
| PM 역할 DB화 | Full-stack | 하드코딩 key 제거, PM 매핑 테이블 |
| 테넌트별 view 분리 | Full-stack | 본사/고객사A/고객사B 라우트 + 서버 필터링 |
| 직책 관리 DB화 | Full-stack | Position 테이블 재설계 + CRUD |
| 버그 수정 + 문서 | 공통 | 5건 + 5종 |
백엔드 커밋 20+개, 프론트 커밋 15+개. migration 실행 8건. 프로덕션 배포 완료.
한계: 만능은 아니다
8시간 동안 쓰면서 느낀 팀 에이전트의 한계점도 분명하다.
세션 복구가 안 된다.
오케스트레이터는 claude --resume으로 복구할 수 있지만, 팀메이트는 일회성 인스턴스다.
세션이 끊기면 새로 spawn해야 하고, 이전 대화 맥락은 날아간다.
실제로 이번 작업 중에도 한 번 세션이 끊겼는데, 새 팀메이트를 spawn하고 “여기까지 했다”고 컨텍스트를 다시 주입하는 데 10분 가까이 걸렸다.
CLAUDE.md에 진행 상황을 기록해두는 습관이 없었다면 더 오래 걸렸을 것이다.
팀메이트가 실수한다.
cherry-pick 과정에서 코드가 유실되거나, 엔티티를 모듈에 등록 안 하거나, DB 값과 코드의 타입이 안 맞거나.
오케스트레이터가 결과를 검증하지 않으면 그대로 배포된다.
결국 사람이 리뷰해야 한다.
특히 TypeORM 엔티티를 새로 만들고 나서 module.ts의 imports에 등록하는 걸 빠뜨리는 실수가 두 번 있었다.
컴파일은 통과하지만 런타임에서 RepositoryNotFoundError가 터진다.
이런 패턴은 CLAUDE.md에 체크리스트로 추가해두면 이후 세션에서는 발생하지 않는다.
간헐적 idle 미응답. 대부분 재지시를 보내면 해결되지만, 간헐적으로 팀메이트를 종료하고 새로 spawn해야 하는 경우도 있었다. 8시간 중 2회 정도 발생했고, 각각 1~2분 내로 복구됐다. 실험 기능 특유의 불안정함이라 향후 개선될 것으로 기대한다.
컨텍스트 윈도우 한계. 팀메이트 하나가 긴 작업을 하다 보면 컨텍스트 윈도우가 차서 초반 지시를 잊는 경우가 있었다. 작업 단위를 잘게 쪼개서 지시하는 게 중요하다. “권한 체계 전체를 리팩토링해”보다 “PM 매핑 테이블 생성 → API 엔드포인트 추가 → 프론트 연동” 식으로 단계별 지시가 훨씬 안정적이었다.
수동 오케스트레이션 vs 팀 에이전트
| 수동 (session-sync) | 팀 에이전트 | |
|---|---|---|
| 병렬성 | 사실상 직렬 | 진짜 병렬 |
| 컨텍스트 전달 | 사람 중계 → 유실 위험 | 메시지 시스템 → 원문 전달 |
| 오케스트레이터 역할 | 전달자 (복붙+재가공) | 의사결정자 (판단+지시) |
| 오해 검출 | 중계 과정에서 사람이 잡음 | 결과물에서 사후 발견 |
| 적합 시점 | 프로젝트 초기~중기 | 프로젝트 성숙기 |
| 신뢰성 | 사람 실수 위험 | AI 실수 위험 (리뷰 필수) |
가장 큰 차이는 역할이 바뀐다는 거다. 수동에서는 내가 ‘전달자’였는데, 팀 에이전트에서는 ‘의사결정자’가 된다. 정보를 옮기는 시간이 줄고, 판단하는 시간이 는다.
그리고 이번 리팩토링이 가능했던 진짜 이유. 팀 에이전트의 생산성만이 아니라, 비즈니스 로직의 방향성이 미리 잡혀 있었기 때문이다.
AI가 아무리 빨라도 “뭘 만들어야 하는지” 모르면 소용없다. 반대로, 방향이 명확하면 팀 에이전트는 그 방향을 놀라운 속도로 구현에 옮긴다. 설계는 사람이, 구현은 팀이 — 이건 인간 팀에서도 마찬가지다.
📚 Claude Code 팀 에이전트 실전기 시리즈 (3편)
- 1. AI 4명을 부렸는데 결국 나만 바빴다 — 수동 오케스트레이션의 한계
- 2. Claude 팀 에이전트 첫 실전 — ERP 권한 체계를 하루 만에 뜯어고치다
- 3. Claude 팀 에이전트 완전 가이드 — 개념부터 실전 셋업까지