• 팀원들이 리더를 거치지 않고 서로 직접 대화할 수 있게 해주는 세 가지 도구 TeamCreate, TaskCreate, SendMessage를 다룬다.

3인이 넘으면 리더가 무너진다.

  • 리더는 한 번에 한 사람과만 대화할 수 있으니, 3인이 넘는 경우 순차 파이프라인으로 퇴행해서 병목이 발생한다.

리더는 이벤트 루프, 팀원은 피어

  • 잘 설계된 오케스트레이터는 리더를 중개자가 아니라 수신자이자 통합자의 위치에 둔다.
    • 왼쪽 그림의 리더는 모든 메시지를 받아 ‘누구에게 전달할지’를 판단하는 중앙 브로커이다.
    • 오른쪽 그림의 리더는 팀원들이 스스로 조율하는 동안 기다리다가, 작업이 끝나거나 막혔을 때 알림을 받는 수신자이다.
  • 리더는 이벤트 루프에 가깝다.
    • 이벤트가 들어올 때만 반응하고, 오케스트레이터도 팀의 상태를 계속 확인하지 않는다.
    • 이 차이의 핵심은 성능 문제가 아니라, 병렬성이다. 리더 중심의 통신은 구조적으로 순차화를 만든다.
  • 클로드 코드 에이전트 팀의 세 가지 기본 요소: 팀, 태스크, 메시지

세 가지 기본 도구: 팀을 데이터 전달 방식으로 보기

  • 마지막 행의 파일 기반 전달은 도구가 아니라 규약이다. 다만 실무에서는 앞 세 가지 도구와 함께 자연스럽게 섞인다.

TeamCreate: 팀은 상수가 아니라 세션 객체

  • 에이전트 정의는 ‘어떤 사람이 있는가’의 템플릿이고, 팀은 ‘이번 세션에서 누구를 부를 것인가’의 구체적인 인스턴스이다.
  • 실제 클로드 코드 구현에서 팀 구성은 두 단계로 나뉜다.
    • TeamCreate로 팀 메타데이터를 만들고
    • 각 팀원은 AgentTool을 team_name 필드와 함께 호출해 개별적으로 생성한다.
  • AgentTool의 name: 팀 내부 주소. 같은 팀 안에서 SendMessage({ to: "security-reviewer" }) 형태로 이 이름의 목적지가 된다.
  • model(생략 가능): 팀원별로 다르게 잡을 수 있다. 감독저는 opus, 단순 추출자는 haiku, 복잡 분석은 다시 opus 식이다. 명시하지 않으면 부모 세션의 모델을 상속한다.
  • prompt: 런타임 작업 지시이다. 에이전트 정의 파일의 본문과 합쳐져서 실제 system prompt가 구성된다.에이전트 파일에 정의된 역할과 호출 시점의 작업 컨텍스트가 분리된다는 점이 중요하다. 같은 security-reviewer 에이전트를 다른 팀에서는 다른 prompt로 호출할 수 있따.
  • isloation: "worktree": 파일 격리 옵션이다. 팀원이 서로 작업 중인 파일을 덮어쓰지 않도록 git worktree로 격리한다. 클로드 코드 공식 템플릿이 이 필드를 명시적으로 채택했다.

TaskCreate: 공유 작업 큐와 depends_on

  • 할 일은 세 가지 속성을 동시에 갖고 있다.
    • 소유자
    • 상태
    • 의존성
  • 이 세 가지를 메시지로만 관리하면 같은 장부를 복사본으로 들고 있어야되고, 서로가 보는 장부가 어긋나는 순간 팀은 막힌다.
  • TaskCreate는 이 장부를 팀 모두가 공유하는 단일 소스로 제공한다.
    • 동시 시작 가능한 작업은 동시에 시작한다.
    • depends_on이 있는 작업은 전제 작업이 끝날 때까지 대기한다.
    • 팀원은 장부를 직접 읽고 쓴다.
    • 리더는 TaskGet으로 전체 진행률을 확인한다.

SendMessag: 리더를 거치지 않는 peer-to-peer 채널

  • to: "*"는 전체 팀원에게 전송한다. 팀원 수에 비례해 토큰 비용이 늘어나기 때문에 특정 팀원 둘에게만 관련있는 정보를 *로 뿌리면 나머지 팀원은 무관한 컨텍스트를 받아 자기 작업 토큰을 낭비한다.
    • 관련 있는 팀원에게만 유니캐스트로 보내는 것이 기본이다.
  • 에이전트 정의 파일을 만들 때 ‘## 팀 통신 프로토콜’을 작성해 팀원이 SendMessage를 언제, 누구에게 보낼지를 미리 적어둘 수 있다.

리더의 역할

  • 통합, 유휴 알림 처리, 에러 개입
  • 에러가 들어왔을 때 리더의 개입은 다음 3단계 전략을 가진다.
  • “모든 것이 성공한다"고 가정하는 오케스트레이터는 프로덕션에서 가장 먼저 무너진다.

데이터 흐름

  • 작고 즉시 쓸 정보: SendMessage
  • 소유자와 상태가 있는 일: TaskCreate, TaskUpdate
  • 큰 산출물이나 Phase를 넘겨야 할 자료: 파일

실전 예제: PR 리뷰 오케스트레이터 SKILL.md

  • 팀을 너무 크게 만들면 메모리가 한계에 도달하고, 메시지 큐가 무관한 컨텍스트로 가득 차며, 오히려 품질이 떨어진다.
  • 공식 가이드의 권장 기준은 다음과 같다.

TeamDelete와 정리: 세션한 한 팀, shutdown 필수

  • TeamDelete를 파라미터 없이 호출하는 이유: 세션당 활성 팀이 하나로 제한되어 있기 때문
    • 이유: 팀원이 작업을 완료하지 못한 채 강제 종료되면, 진행 중이던 파일 쓰기가 잘리거나 락을 남길 수 있다. shutdown_request는 팀원 각자가 작업을 안전하게 마무리할 기회를 주는 협조적 종료다.
  • 팀을 정리해도 _workspace/는 삭제하지 않는다.

언제 팀 프리미티브를 도입할까

  • 2인, 생성-검증 구도, 실시간 피드백 불필요라는 세 조건에서는 팀 프리미티브가 오히려 과한 설계다.

관측과 경계면: 팀을 바깥에서 보기

  • 리더에게는 새로운 차원의 책임이 더해진다.
    • 관측과 경계면
  • 관측: 반복 수준 로깅
    • 팀원 각자 PostToolUse 훅으로 append-only JSONL에 기록하는 것이 표준이다.
    • 오케스트레이터의 관측 역할은 크게 둘이다.
      • 각 팀원의 훅이 남긴 로그를 중앙 한 곳에 모은다.
        • isolation: "worktree로 격리된 팀원의 로그도 공통 경로로 모여야 교차 질문이 가능하다.
      • 임계치를 넘어설 때 개입한다.
        • 같은 파일을 N회 수정한 팀원이 있으면 “다른 접근을 시도하세요"라는 한 줄 메시지를 SendMessage로 주입한다.
        • 컨텍스트가 180k에 근접하면 세션 분할을 결정한다. 자율적인 팀은 스스로 멈출 이유를 잘 찾지 못한다.
  • 경계면: 팀원 둘이 각자는 맞지만 합이 틀릴 때
    • 오케스트레이터의 설계 책임은 경계면을 명확히 하는 일이다.
      • 1순위: 에이전트 정의 파일의 ‘입출력 프로토콜’ 섹션
      • 2순위: 팀 통신 프로토콜의 송신/수신 쌍
    • 팀 환경에서 특히 자주 어긋나는 경계면 4가지
    • 각 주요 Phase 직후에 QA 체크포인트를 둔다.

안티패턴

  • shutdown 없이 TeamDelete 호출
    • 해결방법: 각 팀원에게 shutdown_request 메시지를 보내고, 팀원이 TaskUpdate로 “shtting down” 상태를 표시할 때 까지 기다린 뒤 TeamDelete를 호출한다.
  • 리더가 모든 결정을 독점
    • 해결방법: 에이전트 정의 파일의 ‘## 팀 통신 프로토콜’ 섹션에 수평 통신 규약을 명시. 리더의 프롬프트에는 “팀원 간 교차 확인은 직접 SendMessage로 처리하고, 리더에게는 TaskUpdate만 보고한다"를 명시하. 리뷰 지표는 “리더 메일함 점유율 ㅡ 40%” 같은 수치로 잡을 수 있다.
  • 브로드캐스트 남발
    • 해결 방법: 기본은 유니캐스트다. ‘모두가 알아야 할 상태’는 파일 또는 TaskUpdate로 표시하고, 팀원들은 필요할 떄 TaskGet으로 읽는다. 진짜 브로트캐스트가 필요한 경우에만 *를 쓴다.
  • 팀 크기 과대
    • 해결 방법: 7명 이상이면 Phase를 쪼개고 팀을 교체한다. _workspace/의 파일을 Phase 간 다리로 활용한다.