팀 & 스웜

멀티 에이전트 팀 구성, 메일박스 라우팅, 권한 동기화, 정리까지.

01

개요

스웜은 여러 Claude 인스턴스가 팀으로 구성되어 협업하는 멀티 에이전트 아키텍처입니다. 각 팀메이트는 독립적인 세션에서 실행되며, 메일박스를 통해 메시지를 교환하고, 권한 상태를 동기화합니다.

다루는 소스 파일: TeamCreateTool.tsTeamDeleteTool.tsmailbox.tsteamBackend.tspermissionSync.ts

스웜의 핵심 구성 요소:

02

TeamCreateTool 5단계

TeamCreateTool은 새로운 팀을 생성하는 도구로, 다음 5단계를 순서대로 실행합니다.

  1. 팀 이름 검증: 이름 충돌과 유효성을 확인
  2. 설정 파일 생성: ~/.claude/teams/<name>/config.json에 팀 설정 저장
  3. 백엔드 감지: 사용 가능한 백엔드(tmux/iTerm2/in-process)를 자동 감지
  4. 팀메이트 스폰: 각 팀메이트를 선택된 백엔드에서 실행
  5. 메일박스 초기화: 팀메이트 간 통신 채널 설정
flowchart TD A["TeamCreateTool 호출"] --> B["1. 팀 이름 검증"] B --> C["2. config.json 생성"] C --> D["3. 백엔드 감지"] D --> E{"백엔드 선택"} E -->|"tmux 내부"| F["tmux 백엔드"] E -->|"iTerm2 + CLI"| G["iTerm2 백엔드"] E -->|"폴백"| H["in-process 백엔드"] F & G & H --> I["4. 팀메이트 스폰"] I --> J["5. 메일박스 초기화"] style A fill:#c47a50,color:#1a1816 style J fill:#6e9468,color:#1a1816
03

3가지 백엔드와 감지 알고리즘

팀메이트 프로세스를 관리하는 세 가지 백엔드가 있으며, 감지 알고리즘이 환경에 맞는 최적의 백엔드를 자동으로 선택합니다.

백엔드 감지 우선순위

  1. tmux (최고 우선순위): TMUX 환경 변수가 설정되어 있으면, 즉 현재 tmux 세션 내부에 있으면 tmux 백엔드가 선택됩니다. tmux 내부에서 iTerm2를 사용해도 tmux가 우선합니다.
  2. iTerm2: macOS에서 iTerm2 터미널이 활성화되어 있고 Python API가 사용 가능한 경우
  3. in-process (폴백): 위 조건을 모두 만족하지 않을 때 동일 프로세스 내에서 실행
// 백엔드 감지 알고리즘
function detectBackend(): Backend {
  if (process.env.TMUX) {
    return 'tmux'     // tmux 내부 → 항상 tmux
  }
  if (isIt2CliAvailable()) {
    return 'iterm2'   // iTerm2 Python API 활성
  }
  return 'in-process' // 폴백
}
딥 다이브 — isIt2CliAvailable()--version 대신 session list를 실행하는 이유

it2 CLI의 --version 플래그는 iTerm2의 Python API가 비활성 상태에서도 종료 코드 0을 반환합니다. 이 경우 백엔드가 iTerm2를 선택하지만, 이후 session split 호출이 실패합니다. session list는 실제 Python API 연결을 시도하므로, API가 비활성이면 올바르게 실패하여 정확한 감지가 가능합니다.

04

메일박스 메시징

팀메이트 간 통신은 메일박스 시스템을 통해 이루어집니다. 7종의 메시지 타입이 정의되어 있으며, 각 타입은 특정 목적에 맞게 설계되었습니다.

7종 메시지 타입

isActive: false의 의미

팀메이트의 isActive 플래그가 false이면 해당 팀메이트가 유휴 상태임을 의미합니다. 영구적으로 종료된 것이 아니라, 현재 턴의 작업이 종료된 상태입니다. 새로운 메시지가 메일박스에 도착하면 깨어나서 작업을 재개합니다.

05

권한 동기화

리드 세션(사용자가 직접 상호작용하는 세션)에서 내린 권한 결정은 모든 팀메이트에 자동으로 전파됩니다. 사용자가 한 번 허용한 도구 실행은 다른 팀메이트가 동일한 도구를 사용할 때 다시 묻지 않습니다.

06

4단계 생명주기

팀의 생명주기는 네 단계로 구성됩니다:

  1. 생성 (Create): TeamCreateTool이 설정, 백엔드, 메일박스를 초기화
  2. 실행 (Run): 팀메이트가 메일박스를 통해 작업을 수행하고 결과를 교환
  3. 유휴 (Idle): 작업이 없는 팀메이트는 isActive: false로 대기
  4. 삭제 (Delete): TeamDeleteTool이 모든 팀메이트 프로세스를 종료하고 리소스를 정리

TeamDeleteTool과 비정상 종료

TeamDeleteTool은 정상적인 팀 종료를 처리합니다. 그러나 Ctrl-C로 리드 세션을 강제 종료하면 TeamDeleteTool이 호출되지 않을 수 있습니다.

// 비정상 종료 시 정리 — cleanupSessionTeams()
async function cleanupSessionTeams() {
  // 1. 모든 tmux 페인 강제 종료
  await killAllPanes(sessionId)

  // 2. 팀 디렉토리 제거
  await removeTeamDir(teamName)
}
주의사항

Ctrl-C로 리드 세션이 종료되어 TeamDeleteTool이 호출되지 않으면, cleanupSessionTeams()가 프로세스 종료 핸들러에서 실행됩니다. 이 함수는 tmux 페인을 강제 종료하고 팀 디렉토리를 제거하여 좀비 프로세스를 방지합니다.

07

핵심 요약

핵심 포인트

  • 스웜은 TeamFile, 메일박스, 백엔드로 구성된 멀티 에이전트 팀 아키텍처입니다
  • 백엔드 감지 우선순위는 tmux > iTerm2 > in-process이며, tmux 내부에서는 항상 tmux가 선택됩니다
  • isIt2CliAvailable()--version 대신 session list를 실행하는 이유는 --version이 Python API 비활성 시에도 0을 반환하기 때문입니다
  • 7종 메시지 타입(task, status, result, error, permission, heartbeat, control)으로 팀메이트 간 통신을 구조화합니다
  • isActive: false는 영구 종료가 아니라 유휴 상태이며, 새 메시지 수신 시 깨어납니다
  • 비정상 종료 시 cleanupSessionTeams()가 페인 킬 후 디렉토리를 제거하여 좀비를 방지합니다
  • TeamCreate 설정 파일은 ~/.claude/teams/<name>/config.json에 저장됩니다
08

지식 확인

퀴즈 — 5문제

Q1. tmux 세션 내부에서 iTerm2 터미널을 사용할 때 선택되는 백엔드는?

  • A) iTerm2
  • B) tmux — 내부 tmux가 최고 우선순위
  • C) in-process
  • D) 오류 발생
백엔드 감지 알고리즘은 TMUX 환경 변수를 최우선으로 확인합니다. tmux 세션 내부에서는 다른 터미널 에뮬레이터에 관계없이 항상 tmux 백엔드가 선택됩니다.

Q2. isActive: false인 팀메이트의 의미는?

  • A) 영구적으로 종료됨
  • B) 유휴 상태 — 현재 턴 종료, 새 메시지 시 깨어남
  • C) 오류 상태
  • D) 일시 중지
isActive: false는 팀메이트가 현재 턴의 작업을 완료하고 유휴 상태에 있음을 나타냅니다. 영구 종료가 아니며, 메일박스에 새 메시지가 도착하면 깨어나서 작업을 재개합니다.

Q3. TeamCreate의 설정 파일이 저장되는 위치는?

  • A) 프로젝트 루트
  • B) ~/.claude/teams/
  • C) ~/.claude/teams/<name>/config.json
  • D) /tmp
팀 설정 파일은 ~/.claude/teams/<name>/config.json에 저장됩니다. 팀 이름별로 디렉토리가 생성되어 설정이 격리됩니다.

Q4. isIt2CliAvailable()--version 대신 session list를 실행하는 이유는?

  • A) --version 플래그가 존재하지 않음
  • B) --version이 Python API 비활성 시에도 0을 반환하여 이후 session split 실패
  • C) session list가 더 빠름
  • D) 호환성 이유
it2 --version은 iTerm2의 Python API가 비활성화되어 있어도 종료 코드 0을 반환합니다. 이 경우 iTerm2 백엔드가 선택되지만 실제 session split 호출이 실패합니다. session list는 Python API 연결을 실제로 시도하므로 정확한 가용성 감지가 가능합니다.

Q5. Ctrl-C로 리드 세션을 종료했을 때 TeamDeleteTool이 호출되지 않으면?

  • A) 팀이 유지됨
  • B) 좀비 프로세스가 남음
  • C) cleanupSessionTeams()가 페인을 킬하고 디렉토리를 제거
  • D) 다음 세션에서 정리됨
프로세스 종료 핸들러에 등록된 cleanupSessionTeams()가 실행되어 모든 tmux 페인을 강제 종료하고 팀 디렉토리를 제거합니다. 이를 통해 좀비 프로세스가 방지됩니다.
0 / 5