Multi-Agent Orchestration: Dynamic Workflows
Multi-Agent 오케스트레이션 — 동적 워크플로우와 병렬 에이전트
하나의 Claude 세션이 병렬로 16개의 서브에이전트를 동시에 실행하는 세상 — 이 멀티에이전트 패턴이 소프트웨어 개발의 속도와 범위를 재정의하고 있다.
Overview
2026년 5월, Anthropic은 Claude Code에 Dynamic Workflows를 출시했다. 이것은 단순한 기능 추가가 아니라 AI 개발 방식의 패러다임 전환이다. 오케스트레이션 로직이 컨텍스트 윈도우 안에 갇혀 있는 대신, 이제 코드로 작성되어 병렬 서브에이전트들을 지휘한다.
이제 가능한 것들: 대규모 코드베이스를 병렬로 분석하거나, 테스트를 병렬로 실행하거나, PR 전체를 여러 전문 에이전트가 각자의 관점에서 동시에 리뷰하거나, 한 에이전트가 계획하고 다른 에이전트가 구현하면서 세 번째 에이전트가 검증하는 파이프라인을 구축하는 것.
- Dynamic Workflows와 일반 에이전트 루프의 차이를 이해한다
- 리드 에이전트 + 스페셜리스트 에이전트 패턴을 설계한다
- Worktree 격리로 병렬 에이전트가 충돌 없이 작업하는 방법을 이해한다
- Claude가 계획하고 다른 모델이 리뷰하는 이중 AI 패턴을 구현한다
- Agent View 대시보드를 활용해 멀티에이전트 세션을 모니터링한다
Sections
Dynamic Workflows — 코드로 작성하는 오케스트레이션
Dynamic Workflows의 핵심은 오케스트레이션 로직을 JavaScript로 표현한다는 것이다.
export const meta = {
name: 'parallel-review',
description: 'PR을 여러 관점에서 병렬 리뷰',
}
const DIMENSIONS = [
{ key: 'bugs', prompt: '버그와 로직 오류를 찾아라' },
{ key: 'security', prompt: '보안 취약점을 찾아라' },
{ key: 'perf', prompt: '성능 문제를 찾아라' },
]
// 세 에이전트가 동시에 실행됨
const results = await parallel(
DIMENSIONS.map(d => () =>
agent(d.prompt, { label: `review:${d.key}`, schema: FINDINGS_SCHEMA })
)
)
parallel() 함수로 여러 에이전트가 동시에 실행된다. agent() 함수로 각 서브에이전트를 스폰한다. schema를 지정하면 에이전트가 구조화된 JSON을 반환한다.
규모: 한 워크플로우에서 최대 16개 동시 실행, 세션당 최대 1,000개 에이전트.
리드 에이전트 + 스페셜리스트 패턴
가장 강력한 멀티에이전트 패턴은 역할 분리다:
리드 에이전트: 전체 작업을 이해하고 분해한다. 각 스페셜리스트에게 구체적인 서브태스크를 할당한다.
스페셜리스트 에이전트: 하나의 구체적인 문제에만 집중한다. 자신만의 컨텍스트 윈도우, 도구, 모델을 가진다.
// 리드 에이전트가 작업 분해
const tasks = await agent(
'이 코드베이스의 버그를 찾아 태스크 목록으로 반환하라',
{ schema: TASKS_SCHEMA }
)
// 각 버그를 독립적인 스페셜리스트가 처리
const fixes = await pipeline(
tasks,
task => agent(
`이 버그를 수정하라: ${task.description}`,
{ isolation: 'worktree' } // 격리된 git worktree에서 실행
)
)
해외 고수들의 실제 패턴: Claude가 계획/분해를 담당하고, 특정 전문 모델(또는 같은 Claude의 다른 인스턴스)이 독립적으로 구현한다. 세 번째 에이전트가 각 결과를 검증한다. 이 파이프라인은 한 에이전트가 모든 것을 하는 것보다 결과 품질이 현저히 높다.
Worktree 격리 — 병렬 에이전트의 충돌 방지
여러 에이전트가 같은 파일을 동시에 수정하면 충돌이 발생한다. isolation: 'worktree' 옵션이 이 문제를 해결한다.
const results = await parallel(
bugList.map(bug => () =>
agent(
`이 버그를 수정하라: ${bug.description}`,
{
isolation: 'worktree', // 각 에이전트는 독립된 git 브랜치에서 작업
label: `fix:${bug.id}`
}
)
)
)
isolation: 'worktree'를 설정하면 에이전트마다 별도의 git worktree(격리된 작업 디렉토리)가 생성된다. 에이전트들은 서로의 작업에 방해받지 않고 병렬로 파일을 수정할 수 있다.
에이전트가 변경을 만들지 않으면 worktree는 자동으로 정리된다. 성공한 에이전트의 변경은 각자의 브랜치에 담기며, 이후 사람이 리뷰하고 머지를 결정할 수 있다.
비용 주의: Worktree 격리는 ~200-500ms 설정 시간 + 디스크 공간이 필요하다. 에이전트가 실제로 파일을 수정해야 하는 경우에만 사용하고, 읽기 전용 분석에는 격리 없이 실행하라.
Claude-plans-Codex-reviews 패턴
2026년 커뮤니티에서 주목받은 패턴 중 하나는 '계획은 Claude, 리뷰는 다른 AI'다.
왜 이것이 효과적인가: 같은 모델이 계획하고 구현하면, 자신의 blind spot을 자신이 리뷰할 때 놓치기 쉽다. 다른 모델(또는 다른 관점으로 설정된 같은 모델)이 독립적으로 리뷰하면 발견율이 높아진다.
// 1단계: Claude가 구현 계획 수립
phase('Plan')
const plan = await agent(
'이 기능을 구현할 상세 계획을 작성하라',
{ schema: PLAN_SCHEMA }
)
// 2단계: 계획 기반 구현
phase('Implement')
const implementation = await agent(
`이 계획을 구현하라:\n${plan.steps.join('\n')}`,
{ isolation: 'worktree' }
)
// 3단계: 독립적 검증 (다른 관점)
phase('Verify')
const verification = await parallel(
['correctness', 'security', 'edge-cases'].map(lens => () =>
agent(
`${lens} 관점에서 이 구현을 검증하라. 실패를 찾아내려 시도하라.`,
{ schema: VERDICT_SCHEMA }
)
)
)
세 가지 관점의 검증 에이전트를 동시에 실행하면, 단일 리뷰어보다 문제 발견율이 높아진다.
오케스트라에서 지휘자 혼자 모든 악기를 연주할 수는 없다. 하지만 지휘자가 없으면 수십 명의 연주자들이 각자의 템포로 연주해 소음이 된다. 지휘자의 역할은 전체 악보를 이해하고, 각 섹션에게 언제 무엇을 얼마나 강하게 연주할지 신호를 보내는 것이다.
Dynamic Workflows의 리드 에이전트가 정확히 지휘자 역할이다. 전체 태스크를 이해하고, 각 스페셜리스트 에이전트에게 구체적인 서브태스크를 할당하며, 결과들을 통합한다. 바이올린 섹션(버그 찾기 에이전트), 첼로 섹션(보안 분석 에이전트), 목관악기(성능 분석 에이전트)가 동시에 연주하고, 지휘자가 전체 결과를 하모니로 만든다.
Worktree 격리는 각 섹션이 자신의 악보만 보면서 연주하는 것과 같다 — 다른 섹션의 즉흥 연주가 자신의 파트를 방해하지 않는다.
PR 리뷰를 병렬 멀티에이전트로 수행하는 실제 워크플로우 예제다. pipeline과 parallel의 차이, schema를 통한 구조화된 반환값에 주목하라.
export const meta = {
name: 'adversarial-review',
description: 'PR을 다중 관점에서 병렬 검증',
phases: [
{ title: 'Find', detail: '각 관점에서 문제 탐색' },
{ title: 'Verify', detail: '발견 사항 교차 검증' },
],
}
const FINDINGS_SCHEMA = {
type: 'object',
properties: {
findings: {
type: 'array',
items: {
type: 'object',
properties: {
file: { type: 'string' },
line: { type: 'number' },
severity: { type: 'string', enum: ['high', 'medium', 'low'] },
description: { type: 'string' },
}
}
}
}
}
const DIMENSIONS = [
{ key: 'bugs', prompt: '로직 버그와 엣지 케이스를 찾아라' },
{ key: 'security', prompt: 'XSS, SQL injection 등 보안 문제를 찾아라' },
{ key: 'perf', prompt: 'N+1 쿼리, 불필요한 리렌더링 등을 찾아라' },
]
// Phase 1: 3개 관점을 pipeline으로 병렬 처리
// (barrier 없음 — 각 관점이 독립적으로 완료되는 즉시 다음 단계로)
const reviewed = await pipeline(
DIMENSIONS,
d => agent(d.prompt, {
label: `find:${d.key}`,
phase: 'Find',
schema: FINDINGS_SCHEMA
}),
// Phase 2: 각 관점의 발견 사항을 즉시 교차 검증
(findings, originalDim) => parallel(
findings.findings.map(f => () =>
agent(
`이 발견이 실제 문제인지 반박하려고 시도하라: ${f.description}`,
{ label: `verify:${f.file}:${f.line}`, phase: 'Verify' }
).then(verdict => ({ ...f, real: verdict.includes('confirmed') }))
)
)
)
const confirmed = reviewed.flat().filter(Boolean).filter(f => f.real)
log(`확인된 문제: ${confirmed.length}개`)
return { confirmed } pipeline()을 사용한 이유는 각 관점(bugs, security, perf)이 독립적으로 완료되는 즉시 검증 단계로 넘어갈 수 있기 때문이다. barriers(parallel로 모두 기다리기)를 사용하면 가장 느린 관점이 모두를 기다리게 만든다. pipeline은 bugs 분석이 끝나는 즉시 그 결과 검증을 시작하고, 그 사이 security, perf 분석이 동시에 진행된다.
✅ 시니어가 보는 것
- pipeline vs parallel의 선택 이유를 설명할 수 있는지
- Worktree 격리 비용을 인식하고 필요한 경우에만 사용하는지
- 스키마를 통한 구조화된 에이전트 반환값 설계
⚠️ 레드 플래그
- 모든 에이전트에 worktree 격리를 사용하는 경우 (불필요한 비용)
- barrier(parallel)를 무조건 사용하고 pipeline의 이점을 모르는 경우
- 에이전트 수를 무한정 늘리고 결과 품질을 검증하지 않는 경우
🎤 예상 인터뷰 질문
- pipeline과 parallel의 차이를 실제 사례로 설명해주세요.
- 에이전트 수가 늘어날 때 비용과 품질의 트레이드오프를 어떻게 관리하시나요?
- Claude-plans-Codex-reviews 패턴 같은 이중 AI 검증을 구현한 경험이 있나요?
Key Takeaways
오케스트레이션은 코드로 표현된다
Dynamic Workflows는 오케스트레이션 로직을 컨텍스트 윈도우가 아닌 JavaScript 코드로 표현한다. 결정론적이고 반복 가능하다.
pipeline이 기본, parallel은 예외
barrier가 진짜 필요할 때만 parallel 사용. 대부분의 경우 pipeline이 더 빠르고 효율적이다.
Worktree 격리는 비쌈
파일을 병렬로 수정해야 할 때만 사용. 읽기 전용 분석에는 격리 없이 실행하라.
독립 검증이 품질을 높인다
같은 에이전트가 계획하고 리뷰하면 blind spot이 생긴다. 독립적인 검증 에이전트가 발견율을 높인다.
스키마로 에이전트 출력을 구조화하라
schema 옵션을 쓰면 에이전트가 구조화된 JSON을 반환한다. 다음 단계 에이전트가 안정적으로 처리할 수 있다.