본문으로 이동
문서 탐색서브에이전트 오케스트레이션
핵심 개념레퍼런스

서브에이전트 오케스트레이션

포그라운드 fan-out과 독립 롤아웃을 가진 내구성 있는 depth-one 자식 협업입니다.

부모 에이전트가 delegate_task 또는 spawn_agent를 호출하면 core/agent/sub_agent.py SubAgentManager가 격리된 서브에이전트를 띄웁니다. 실행은 core/orchestration/isolated_execution.py IsolatedRunner가 맡습니다. 독립 작업은 실제로 병렬 실행되며 서브에이전트 경로에 별도 TaskGraph는 없습니다. 스폰과 종료마다 SUBAGENT_STARTED / SUBAGENT_COMPLETED / SUBAGENT_FAILED 훅이 발화합니다. 장기 자식의 완료는 SQLite mailbox를 통해 안전한 부모 루프 경계에 전달됩니다.

백그라운드 협업

delegate_task는 완료까지 기다리는 fan-out/best-of-N 도구입니다. 장기 작업은 spawn_agent로 안정적인 task_id를 받고 부모 작업을 계속합니다. 제어 도구는 각각 list_agents, wait_agent, interrupt_agent, send_message, followup_task입니다. 대기 시간이 끝나도 자식은 취소되지 않습니다.

동작의미
send_message새 세대를 시작하지 않고 실행 중인 자식에게 컨텍스트를 큐잉
followup_task실행 중이면 다음 루프 경계에 전달하고, 종료 상태면 같은 자식 세션을 재개

최신 상태와 메일박스 전달은 프로젝트 sessions.db collaboration_runscollaboration_mailbox에 저장합니다. 이 둘은 제어 상태를 투영하며 별도 transcript를 만들지 않습니다. 자식의 대화, 도구 호출, 훅, trajectory는 messages와 append-only session_events에 독립 롤아웃으로 남습니다. mailbox는 자식 checkpoint 저장 뒤 승인됩니다. 재개는 완료된 도구 호출을 런타임이 자동 재생하지 않지만 모델이 같은 부작용을 다시 요청할 수 있으므로 exactly-once 계약은 아닙니다.

한도

노브기본값비고
max_depth1서브에이전트는 다시 서브에이전트를 띄울 수 없습니다. 깊이 가드가 오류 결과를 반환합니다
max_total_subagents15부모 세션당 고유 자식 상한; manager 재생성·resume에도 유지
timeout_s600초GEODE_SUBAGENT_TIMEOUT_S env로 조절, [10, 3600]으로 clamp
time_budget_s0 (꺼짐)선택적 wall-clock 예산
denied_tools / working_dirs비어 있음도구 차단 목록과 샌드박스 작업 디렉터리 추가

레인: 동시성의 단위

모든 실행 경로는 core/orchestration/lane_queue.py의 레인을 통과합니다. SessionLane이 같은 세션 키를 직렬화하고(다른 키는 병렬), 그 다음 글로벌 레인이 전체 동시성을 잡습니다.

레인동시성비고
globalmax_concurrent=50프로덕션 기본값 (core/wiring/container.py)
gateway설정값메신저 인바운드
anthropic-api레인별 설정Anthropic PAYG API 동시성 보호
seed-generation레인별 설정시드 파이프라인

SessionLane은 세션 키 256개까지 유지하고 유휴 키를 정리합니다.

격리의 실제 경계

격리는 프로세스와 산출물 수준에서 일어납니다. 서브에이전트는 별도 워커 프로세스로 돌고, 산출물은 <run_dir>/sub_agents/<task_id>/ 아래에 쌓이며, 부모는 반환된 요약만 받습니다 (core/orchestration/isolated_execution.py).

메모리 쓰기 격리는 툴킷 구성으로 통제합니다. 기본 _default 툴킷은 읽기 전용이라 서브에이전트는 공유 메모리에 쓸 수 없습니다. 단, memory_save가 포함된 툴킷(예: general_purpose)을 명시하면 공유 ProjectMemory에 직접 기록됩니다. 동시 쓰기를 피하려면 쓰기 도구가 없는 툴킷을 주는 것이 통제 수단입니다.

도구와 능력의 상속

서브에이전트가 받는 것은 선언된 툴킷으로 해석된 네이티브 도구 핸들러입니다. frontmatter의 toolkit: 이름이 먼저, 레거시 tools: 목록이 다음, 둘 다 없으면 읽기 전용 _default입니다. 부모의 MCP 연결과 스킬 레지스트리는 워커 프로세스로 전달되지 않습니다 (core/agent/worker.py는 네이티브 핸들러만 구성). 자세한 해석 규칙은 도구와 툴셋을 참고합니다.

선택적 적대적 검토

중요한 문서, 설계, PR, 공개 결론을 반증 관점에서 검토할 때는 기존 reviewer 역할을 선택합니다. 부모가 최종 산출물의 판본, 목표, 판정 계약, 원근거와 제외 범위를 먼저 고정합니다. 작성자의 설명이나 이전 리뷰 점수는 검토에 필요한 경우에만 전달합니다. 다음은 delegate_task의 요청 인자 예시입니다.

{
  "task_type": "analyze",
  "role": "reviewer",
  "task_description": "Review the frozen artifact and source evidence supplied with this task against its stated goal and acceptance contract."
}

core/agent/subagent_roles.py의 역할은 grep_filesread_document만 허용합니다.core/agent/subagent_protocol.py 프롬프트 소스 디렉터리reviewer.md를 워커에 전달합니다. 새 역할이나 승격 게이트는 아닙니다.

결과는 기존 findings JSON입니다. 형식 검증 성공이나 빈 목록은 PASS 또는 병합 승인이 아닙니다. 부모가 근거를 대조하고 미확인 범위를 별도로 기록하며, 필요한 테스트와 CI는 그대로 수행합니다.

결과와 오류 분류

완료 봉투는 SubResult 하나입니다. success, output, error, duration과 사용량 롤업 (prompt_tokens, completion_tokens, usd_spent)을 담습니다. 구독이나 CLI 레인에서 사용량을 제공하지 않으면 0으로 기록됩니다.

실패 모드

증상원인해법
서브에이전트가 또 위임하려다 실패max_depth=1 가드의도된 동작입니다. 위임 구조를 부모에서 평탄화합니다
10분쯤에서 timeout 상태로 종료기본 timeout_s=600GEODE_SUBAGENT_TIMEOUT_S를 올립니다 (상한 3600)
실행 중인 자식에게 보낸 메시지가 즉시 반영되지 않음메일박스는 안전한 루프 경계에서 소비됨wait_agent로 상태를 확인하고, 필요하면 followup_task로 다음 세대를 시작합니다
자식 실행 중 소유 런타임이 종료됨실행 중 프로세스는 다른 런타임이 인계하지 않음상태가 interrupted로 복구되면 부작용을 확인한 뒤 명시적으로 followup_task를 호출합니다

다음