k
korAI
고급 전체
🔥 고급2026-04-1710분

멀티 에이전트 — Orchestrator-Worker 패턴으로 복잡 작업 분해

한 모델이 다 하지 말고, 계획자-실행자-검증자로 분리. 병렬화·특화·감사 로그가 따라온다.

agentarchitecture

왜 하나로 안 되나

  • 컨텍스트가 뒤엉킨다 (계획 + 실행 중간 상태 + 결과 검증)
  • 각 단계 모델 선택이 강제 일원화된다 (전부 Opus면 비용, 전부 Haiku면 품질)
  • 디버깅 불가 — 어디서 틀렸는지 추적 어려움

Orchestrator-Worker 구조

[Orchestrator (Opus 4.7)]
   │  1) 계획 수립
   │  2) Worker에 하위 작업 할당
   │  3) 결과 수집 + 합성
   ↓
[Worker A (Sonnet)]  [Worker B (Sonnet)]  [Worker C (Haiku)]
   파일 읽기           코드 수정             린트 체크

구현 스켈레톤

interface SubTask { id: string; type: string; input: any }
interface SubResult { id: string; output: any; ok: boolean }

async function orchestrate(goal: string) {
  // 1. 계획 수립 — Opus가 하위 작업 리스트 생성
  const plan = await client.messages.create({
    model: "claude-opus-4-7",
    system: "너는 Orchestrator다. 목표를 받아 JSON 배열로 하위 작업을 나눈다.",
    max_tokens: 2048,
    tools: [PLAN_TOOL],
    tool_choice: { type: "tool", name: "make_plan" },
    messages: [{ role: "user", content: goal }],
  })
  const tasks: SubTask[] = extractToolInput(plan).tasks

  // 2. Worker에 병렬 분배
  const results = await Promise.all(
    tasks.map(t => runWorker(t))
  )

  // 3. Orchestrator가 합성
  return client.messages.create({
    model: "claude-opus-4-7",
    max_tokens: 2048,
    messages: [{
      role: "user",
      content: `원래 목표: ${goal}\n\n하위 결과:\n${JSON.stringify(results)}\n\n최종 답을 작성하라.`,
    }],
  })
}

async function runWorker(t: SubTask): Promise<SubResult> {
  const model = t.type === "lint" ? "claude-haiku-4-5" : "claude-sonnet-4-6"
  // ... 작업 실행
}

핵심 설계 결정

  1. Worker는 독립적 — 다른 Worker의 결과를 모른다. 공유 상태 금지
  2. Orchestrator만 전체 컨텍스트 — Worker 프롬프트엔 하위 작업 정보만
  3. 병렬화 가능한 것만 병렬 — 순서 의존이 있으면 Orchestrator가 순차 호출
  4. 실패 격리 — Worker 하나 죽어도 다른 Worker는 돌아감

운영 주의점

  • 비용: Worker 수 × 각 컨텍스트. 10개 병렬이면 10× 비용. 예산 필수.
  • 감사 로그: 각 Worker의 input/output을 trace ID로 묶어 저장
  • 재시도 격리: 실패한 Worker만 다시, Orchestrator 전체 재시작 금지
  • LLM-as-judge: 별도 Verifier Worker가 결과 검증 후 재루프 트리거

체크리스트

  • [ ] Orchestrator / Worker 모델 분리
  • [ ] Worker 간 공유 상태 없음
  • [ ] trace ID로 모든 호출 묶임
  • [ ] 병렬 한도 (e.g. 동시 5개)
  • [ ] Worker 실패가 세션 전체를 죽이지 않음