Claude Code의 네이티브 팀 기능과 Oh My ClaudeCode(OMC)의 Team/Swarm은 상호 배타적이 아니라 레이어 관계다. OMC Team은 네이티브 인프라를 완전히 감싸는 래퍼(wrapper)로, 그 위에 오케스트레이션을 추가한다.
┌─────────────────────────────────────────┐
│ OMC Team (오케스트레이션 레이어) │
│ - 5단계 파이프라인 │
│ (plan → PRD → exec → verify → fix) │
│ - 자동 fix 루프 (최대 3회) │
│ - MCP Worker 브릿지 (Codex/Gemini) │
│ - 상태 관리 (.omc/state/) │
├─────────────────────────────────────────┤
│ Claude Code Native Team (기반 인프라) │
│ - TeamCreate / TeamDelete │
│ - TaskCreate / TaskUpdate / TaskList │
│ - SendMessage (DM, broadcast, shutdown)│
│ - ~/.claude/teams/ + ~/.claude/tasks/ │
└─────────────────────────────────────────┘
OMC Team은 별도의 인프라를 구축한 것이 아니다. Claude Code가 제공하는 TeamCreate, SendMessage, TaskCreate 등의 네이티브 도구를 그대로 사용하면서, 그 위에 자동화된 파이프라인과 상태 관리를 얹은 구조다.
Claude Code가 기본 제공하는 멀티 에이전트 협업 도구다. Multi-Agent 시스템의 실행 기반이 된다.
| 도구 | 역할 | 읽기 | 쓰기 |
|---|---|---|---|
| TeamCreate | 팀 초기화 | — | config.json, inboxes/, .lock |
| TaskCreate | 태스크 생성 | .highwatermark |
{taskId}.json |
| TaskList | 전체 태스크 조회 | {taskId}.json |
— |
| TaskGet | 단일 태스크 조회 | {taskId}.json |
— |
| TaskUpdate | 태스크 수정/할당 | {taskId}.json |
{taskId}.json |
| SendMessage | 메시지 전송 | — | inboxes/{agent}.json |
| TeamDelete | 팀 정리 | 전체 | 전체 삭제 |
~/.claude/teams/{team-name}/
├── config.json # 팀 메타데이터 + members 배열
└── inboxes/
└── {agent-name}.json # 에이전트별 메시지 큐
~/.claude/tasks/{team-id}/
├── .lock # 동시성 제어
├── .highwatermark # 태스크 ID 카운터
└── {taskId}.json # 개별 태스크 파일
각 에이전트는 {name}@{team-name} 형태의 고유 ID를 가지며, 독립 inbox와 전용 tmux pane을 할당받는다.
{
"agentId": "backend-dev@my-project",
"name": "backend-dev",
"agentType": "general-purpose",
"model": "claude-sonnet-4-5-20250929",
"tmuxPaneId": "%1",
"isActive": true
}
태스크는 blockedBy와 blocks 배열로 의존 관계를 표현한다.
{
"id": "3",
"subject": "API 엔드포인트 구현",
"status": "pending",
"owner": "backend-dev",
"blockedBy": ["1", "2"],
"blocks": ["4"]
}
Agent-A: SendMessage(type="message", recipient="Agent-B", content="...")
↓
inboxes/Agent-B.json에 메시지 추가 (read: false)
↓
Agent-B의 턴 종료 시 자동 전달
↓
Agent-B가 메시지 수신 후 처리
핵심 특성: 메시지는 턴 경계(turn boundary)에서 전달된다. 실시간 스트리밍이 아니라 비동기 큐 방식이다.
OMC Team은 네이티브 팀 인프라를 100% 활용하면서, 다음을 추가한다.
team-plan → explore + planner가 태스크 분해
↓
team-prd → analyst가 요구사항 정제 (선택)
↓
team-exec → executor/specialist 워커가 실제 작업
↓
team-verify → verifier + reviewer가 품질 검증
↓
team-fix → 실패 시 자동 수정 (최대 3회 루프)
태스크 할당: 리드가 TaskUpdate(taskId, owner="worker-1")로 사전 할당한 뒤 워커를 스폰한다. 워커는 자신에게 할당된 태스크만 처리한다.
Lead: TaskCreate(subject="Fix auth.ts")
Lead: TaskUpdate(taskId="1", owner="worker-1")
Lead: Task(team_name="my-team", name="worker-1", prompt="...")
↓
Worker-1: TaskList() → 자기 태스크 확인
Worker-1: TaskUpdate(taskId="1", status="in_progress")
Worker-1: (작업 수행)
Worker-1: TaskUpdate(taskId="1", status="completed")
Worker-1: SendMessage(recipient="team-lead", content="완료", summary="Task #1 완료")
네이티브 팀 상태와 별도로, OMC는 자체 상태 파일을 관리한다.
// .omc/state/team-state.json
{
"mode": "team",
"active": true,
"current_phase": "team-exec",
"state": {
"team_name": "fix-ts-errors",
"agent_count": 3,
"fix_loop_count": 1,
"max_fix_loops": 3,
"stage_history": "team-plan:T1,team-exec:T2,team-verify:T3"
}
}
OMC Team은 Claude 에이전트 외에 외부 CLI 도구를 팀원으로 통합할 수 있다.
| 구분 | Claude 팀원 | MCP Worker (Codex/Gemini) |
|---|---|---|
| 도구 접근 | Full (Read/Write/Edit/Bash) | 파일시스템 (CLI) |
| 통신 | SendMessage (DM, broadcast) | Outbox 파일 (단방향) |
| 팀 인식 | TaskList/TaskUpdate 가능 | 없음 (fire-and-forget) |
| 비용 | 높음 (Claude) | 낮음 (전문 특화) |
| 동시성 | 세션 기반 | git worktree 격리 |
OMC 4.2.2+ 기준,
/swarm은 내부적으로/team으로 라우팅된다. Swarm은 호환성 퍼사드(compatibility facade) 로만 존재한다.
Swarm은 SQLite(better-sqlite3) 기반으로 독립적인 태스크 큐를 운영했다.
-- 원자적 태스크 클레이밍
BEGIN IMMEDIATE;
SELECT id FROM tasks WHERE status='pending' ORDER BY id LIMIT 1;
UPDATE tasks SET status='claimed', claimed_by=?, claimed_at=? WHERE id=?;
COMMIT;
| 구분 | Swarm (레거시) | Team (현재) |
|---|---|---|
| 저장소 | .omc/state/swarm.db (SQLite) |
~/.claude/tasks/ (JSON) |
| 태스크 클레이밍 | 원자적 트랜잭션 | 리드의 사전 할당 |
| 에이전트 간 통신 | 없음 (fire-and-forget) | SendMessage |
| 외부 의존성 | better-sqlite3 npm |
없음 |
| 장애 복구 | 5분 리스 타임아웃 | 리드가 메시지로 감지 |
| 의존성 추적 | 없음 | blocks/blockedBy |
Swarm이 폐기된 이유:
better-sqlite3) 불필요 — 네이티브 JSON으로 충분blocks/blockedBy가 더 강력| 차원 | Claude Code Native | OMC Team | OMC Swarm (폐기) |
|---|---|---|---|
| 인프라 | 기반 도구 | Native 래핑 | 독립 SQLite |
| 태스크 저장 | ~/.claude/tasks/ JSON |
동일 (Native 사용) | .omc/state/swarm.db |
| 태스크 할당 | 수동 (자유) | 리드가 사전 할당 | 원자적 트랜잭션 |
| 에이전트 통신 | SendMessage | 동일 (Native 사용) | 없음 |
| 파이프라인 | 없음 | 5단계 자동 | 없음 |
| 검증 루프 | 없음 | verify → fix (최대 3회) | 없음 |
| 외부 워커 | 없음 | Codex/Gemini 브릿지 | 없음 |
| 상태 영속화 | 세션 내 | .omc/state/ 파일 |
SQLite DB |
| 외부 의존성 | 없음 | 없음 | better-sqlite3 |
| 현재 상태 | 활성 | 활성 (권장) | 폐기 → Team 라우팅 |
// 직접 제어 예시
TeamCreate("my-project")
TaskCreate("백엔드 API 구현")
TaskCreate("프론트엔드 UI 구현")
TaskUpdate(taskId="1", owner="backend-dev")
TaskUpdate(taskId="2", owner="frontend-dev")
Task(team_name="my-project", name="backend-dev", prompt="...")
Task(team_name="my-project", name="frontend-dev", prompt="...")
/team)을 사용하는 경우가장 효과적인 방법: OMC의 오케스트레이션 계층을 활용하되, 네이티브 도구의 동작을 이해하여 디버깅과 커스터마이징에 활용한다.
/team으로 시작 — 파이프라인, 검증 루프, 상태 관리 자동화~/.claude/teams/, ~/.claude/tasks/ 파일을 직접 확인하여 상태 진단# 팀 상태 확인
cat ~/.claude/teams/{team-name}/config.json | jq '.members[] | {name, isActive}'
# 태스크 상태 확인
ls ~/.claude/tasks/{team-id}/*.json | xargs -I {} sh -c 'echo "=== {} ===" && cat {} | jq {id, subject, status, owner}'
# OMC 상태 확인
cat .omc/state/team-state.json | jq .
# OMC Team 종료 시 자동 정리 흐름
SendMessage(type="shutdown_request", recipient="worker-1")
→ worker-1: SendMessage(type="shutdown_response", approve=true)
→ TeamDelete() # ~/.claude/teams/ + ~/.claude/tasks/ 제거
→ state_clear(mode="team") # .omc/state/team-state.json 제거
Race Condition: 네이티브 팀의 태스크 파일은 JSON 기반이라, 동시 쓰기 시 충돌 가능성이 있다. OMC는 리드의 사전 할당(pre-assignment)으로 이를 회피한다.
.lock파일이 존재하지만 완전한 트랜잭션 보장은 아니다.