왜 단일 컨텍스트가 문제가 되는가
하나의 에이전트에 모든 작업을 밀어넣으면 컨텍스트 윈도우가 금방 오염된다. 검색 결과 전문, 파일 덤프, 중간 로그가 누적되면서 정작 중요한 지시가 뒤로 밀려나고, 모델은 앞뒤 맥락을 혼동한다. 토큰 비용은 대화 길이의 제곱에 가깝게 늘고, 무관한 정보가 많을수록 추론 정확도가 떨어지는 이른바 컨텍스트 희석이 발생한다. 특히 여러 하위 작업이 서로 다른 도메인 지식을 요구할 때, 한 컨텍스트 안에서는 지식이 충돌한다.
서브에이전트 분해의 핵심 원리
해법은 작업을 독립적인 하위 작업으로 쪼개고, 각각을 별도 컨텍스트를 가진 서브에이전트에 맡기는 것이다. 오케스트레이터는 계획과 취합만 담당하고, 실제 탐색·읽기·분석은 서브에이전트가 격리된 컨텍스트에서 수행한다. 핵심은 서브에이전트가 결론만 반환한다는 점이다. 수천 토큰의 파일 내용은 서브에이전트 컨텍스트 안에서 소비되고, 상위로는 요약된 결과 몇 줄만 올라온다.
컨텍스트 격리의 세 가지 경계
- 입력 격리: 서브에이전트에는 해당 작업에 필요한 최소 정보만 프롬프트로 전달한다.
- 실행 격리: 각 서브에이전트는 독립된 대화 이력을 가진다. 서로의 중간 산출물을 보지 않는다.
- 출력 격리: 반환값은 구조화된 스키마로 강제해, 자유 텍스트가 상위 컨텍스트를 오염시키지 않도록 한다.
오케스트레이터 구현 예시
아래는 파이썬으로 분해와 병렬 실행을 표현한 골격이다. 각 서브에이전트는 자신만의 메시지 배열로 시작한다.
import asyncio
from anthropic import AsyncAnthropic
client = AsyncAnthropic()
MODEL = "claude-sonnet-4-6"
async def subagent(task: str, scope: str) -> dict:
# 격리된 컨텍스트: 이 작업에 필요한 정보만 전달
msg = await client.messages.create(
model=MODEL,
max_tokens=1024,
system=f"너는 '{scope}' 담당자다. 결론만 JSON으로 반환하라.",
messages=[{"role": "user", "content": task}],
)
return {"scope": scope, "result": msg.content[0].text}
async def orchestrate(subtasks: list[tuple[str, str]]):
# 서로 다른 컨텍스트에서 동시 실행
results = await asyncio.gather(
*(subagent(t, s) for t, s in subtasks)
)
return results # 상위로는 요약 결과만 취합
asyncio.run(orchestrate([
("결제 모듈의 재시도 로직을 찾아라", "payment"),
("인증 토큰 만료 처리를 찾아라", "auth"),
]))
출력 스키마 강제
서브에이전트가 장황한 설명을 반환하면 격리 효과가 사라진다. 도구 호출 스키마로 반환 형식을 못 박는다.
tools = [{
"name": "report",
"description": "조사 결론을 구조화해 반환",
"input_schema": {
"type": "object",
"properties": {
"found": {"type": "boolean"},
"location": {"type": "string"},
"summary": {"type": "string", "maxLength": 300}
},
"required": ["found", "summary"]
}
}]
이렇게 하면 상위 컨텍스트에는 파일 전문이 아니라 summary 300자만 올라온다.
단일 vs 분해 방식 비교
| 항목 | 단일 에이전트 | 서브에이전트 분해 |
|---|---|---|
| 컨텍스트 오염 | 높음 | 낮음(격리) |
| 병렬성 | 없음 | 작업 단위 병렬 |
| 디버깅 | 원인 추적 어려움 | 작업별 격리로 용이 |
| 토큰 비용 | 누적 증가 | 작업별 상한 |
| 지연 시간 | 순차 | 동시 실행 시 단축 |
실무에서의 주의점
분해가 항상 이득은 아니다. 서브에이전트마다 시스템 프롬프트와 컨텍스트 셋업 비용이 발생하므로, 단순 작업을 과하게 쪼개면 오버헤드가 이득을 넘는다. 또한 서브에이전트가 상위 맥락을 모르기 때문에, 작업 프롬프트에 충분한 배경을 담지 않으면 엉뚱한 결론을 낸다. 반대로 배경을 너무 많이 넣으면 격리 의미가 사라진다. 이 균형점 찾기가 설계의 핵심이다.
취합 단계에서는 서브에이전트 결과가 서로 모순될 수 있음을 전제해야 한다. 오케스트레이터가 상충하는 결론을 감지하고 재질의하거나 검증 에이전트를 한 단계 더 두는 편이 안전하다. 마지막으로, 병렬 실행은 API 동시 요청 한도와 비용을 함께 끌어올리므로, 동시성 상한과 실패 시 부분 결과 처리 전략을 반드시 함께 설계한다.