서브 에이전트
복잡한 작업을 전문 에이전트에게 위임하고 병렬로 실행하는 방법을 알아봅니다.
개요
서브 에이전트란?
서브 에이전트는 특정 작업을 전문으로 하는 에이전트입니다:
- 메인 에이전트: 사용자와 직접 소통, 작업 조율
- 서브 에이전트: 특정 작업 수행 (데이터 분석, 파일 처리 등)
위임 아키텍처
사용자
↓
메인 에이전트 (Coordinator)
├─→ 서브 에이전트 A (데이터 분석)
├─→ 서브 에이전트 B (파일 처리)
└─→ 서브 에이전트 C (웹 검색)
↓
결과 집계
위임 패턴
1. 직접 위임 (Direct Delegation)
단일 작업을 서브 에이전트에게 위임:
// 메인 에이전트
export default {
name: 'main-agent',
async execute(context) {
const task = 'data.csv 파일을 분석해줘';
// 서브 에이전트에게 위임
const result = await this.delegate({
agent: 'data-analyzer',
task: task
});
return {
success: true,
result: `분석 완료: ${result.summary}`
};
}
};
2. 병렬 위임 (Parallel Delegation)
여러 작업을 동시에 수행:
// 메인 에이전트
export default {
name: 'parallel-coordinator',
async execute(context) {
// 병렬로 작업 위임
const results = await Promise.all([
this.delegate({
agent: 'data-analyzer',
task: 'sales-data.csv 분석'
}),
this.delegate({
agent: 'web-scraper',
task: '경쟁사 가격 수집'
}),
this.delegate({
agent: 'report-generator',
task: '월간 보고서 작성'
})
]);
return {
success: true,
results: {
analysis: results[0],
prices: results[1],
report: results[2]
}
};
}
};
3. 순차 위임 (Sequential Delegation)
순서대로 작업을 위임:
// 메인 에이전트
export default {
name: 'sequential-coordinator',
async execute(context) {
// 1. 데이터 수집
const data = await this.delegate({
agent: 'data-collector',
task: '최신 뉴스 수집'
});
// 2. 데이터 분석 (이전 결과 사용)
const analysis = await this.delegate({
agent: 'data-analyzer',
task: `뉴스 분석: ${data.summary}`
});
// 3. 보고서 작성 (분석 결과 사용)
const report = await this.delegate({
agent: 'report-generator',
task: `보고서 작성: ${analysis.insights}`
});
return { success: true, report };
}
};
전문 에이전트 타입
1. 데이터 분석가 (Data Analyst)
// 서브 에이전트: data-analyzer
export default {
name: 'data-analyzer',
role: '데이터 분석 전문가',
skills: ['file-read', 'pandas', 'statistics'],
async execute(context) {
const { task } = context;
// CSV 파일 읽기
const data = await this.readFile('data.csv');
// 분석 수행
const analysis = {
rowCount: data.length,
average: this.calculateAverage(data),
trends: this.detectTrends(data)
};
return {
success: true,
summary: `${analysis.rowCount}행 데이터 분석 완료`,
data: analysis
};
}
};
2. 웹 스크래퍼 (Web Scraper)
// 서브 에이전트: web-scraper
export default {
name: 'web-scraper',
role: '웹 데이터 수집 전문가',
skills: ['web-scrape', 'web-search', 'file-write'],
async execute(context) {
const { task } = context;
// 웹사이트 스크래핑
const results = await this.scrapeWebsite(task.url);
// 파일로 저장
await this.writeFile('scraped-data.json', results);
return {
success: true,
summary: `${results.length}개 항목 수집 완료`,
data: results
};
}
};
3. 리포트 작성자 (Report Generator)
// 서브 에이전트: report-generator
export default {
name: 'report-generator',
role: '보고서 작성 전문가',
skills: ['file-write', 'template-engine'],
async execute(context) {
const { task } = context;
// 템플릿 로드
const template = await this.loadTemplate('monthly-report.md');
// 데이터 채우기
const report = this.renderTemplate(template, task.data);
// 파일 저장
await this.writeFile('report-2026-02.md', report);
return {
success: true,
summary: '월간 보고서 작성 완료',
file: 'report-2026-02.md'
};
}
};
위임 설정
에이전트 구성
{
"agents": {
"main": {
"model": "claude-opus-4-20250514",
"temperature": 0.7,
"role": "coordinator"
},
"subAgents": {
"data-analyzer": {
"model": "claude-sonnet-4-20250514",
"temperature": 0.3,
"skills": ["file-read", "pandas"],
"timeout": 300
},
"web-scraper": {
"model": "claude-sonnet-4-20250514",
"temperature": 0.5,
"skills": ["web-scrape", "web-search"],
"timeout": 600
},
"report-generator": {
"model": "claude-sonnet-4-20250514",
"temperature": 0.8,
"skills": ["file-write", "template-engine"],
"timeout": 180
}
}
}
}
에러 처리
개별 에이전트 실패 처리
export default {
name: 'fault-tolerant-coordinator',
async execute(context) {
const tasks = [
{ agent: 'analyzer', task: 'data.csv 분석' },
{ agent: 'scraper', task: '웹사이트 수집' },
{ agent: 'generator', task: '보고서 작성' }
];
// 병렬 실행 + 에러 처리
const results = await Promise.allSettled(
tasks.map(t => this.delegate(t))
);
// 성공/실패 분리
const successful = results
.filter(r => r.status === 'fulfilled')
.map(r => r.value);
const failed = results
.filter(r => r.status === 'rejected')
.map(r => r.reason);
return {
success: true,
completed: successful.length,
failed: failed.length,
errors: failed,
results: successful
};
}
};
재시도 전략
async executeWithRetry(agent, task, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await this.delegate({ agent, task });
} catch (error) {
if (i === maxRetries - 1) {
throw error;
}
console.log(`Retry ${i + 1}/${maxRetries}...`);
await this.sleep(1000 * (i + 1));
}
}
}
성능 최적화
작업 분할
대용량 작업을 작은 단위로 분할합니다:
const chunkSize = 10000;
const chunks = [];
for (let i = 0; i < 100; i++) {
chunks.push(
this.delegate({
agent: 'analyzer',
task: `데이터 ${i * chunkSize} ~ ${(i + 1) * chunkSize}행 분석`
})
);
}
const results = await Promise.all(chunks);
캐싱
반복 작업은 캐시를 활용합니다:
async delegateWithCache(agent, task) {
const cacheKey = `${agent}:${task}`;
const cached = await this.getCache(cacheKey);
if (cached) {
return cached;
}
const result = await this.delegate({ agent, task });
await this.setCache(cacheKey, result, 3600);
return result;
}
모범 사례
단일 책임 원칙을 적용합니다:
// 하나의 에이전트는 하나의 작업만
{ agent: 'data-loader', task: '데이터 로드' }
{ agent: 'data-analyzer', task: '데이터 분석' }
명확한 인터페이스를 사용합니다:
const result = await this.delegate({
agent: 'analyzer',
input: { file: 'data.csv', format: 'json' },
expect: { summary: 'string', metrics: 'object' }
});
적절한 타임아웃을 설정합니다:
{
"data-analyzer": { "timeout": 300 },
"web-scraper": { "timeout": 600 },
"quick-task": { "timeout": 60 }
}
에러 처리를 항상 포함합니다:
try {
const result = await this.delegate({ agent: 'analyzer', task: '...' });
} catch (error) {
console.error('분석 실패:', error);
// 대안 계획 실행
}
참고: