서브에이전트 하나로는 부족해서 그 안에서 또 서브에이전트를 굴리고 싶다면, v2.1.172부터 이게 공식으로 지원됩니다. 다만 무한정 깊어지는 건 아니고 5단계라는 명확한 상한이 있고, 이걸 모르고 설계하면 특정 깊이에서 에이전트가 갑자기 멈추는 걸 보고 당황하게 됩니다. 이번 글은 공식 문서 기준으로 중첩 서브에이전트를 실제로 어떻게 설정하고, 어디까지 제어할 수 있고, 어떤 함정이 있는지까지 파고들어 정리했습니다.
서브에이전트는 원래 메인 대화창을 오염시키지 않기 위한 장치입니다. 검색 결과나 로그, 파일 내용처럼 나중에 다시 참조하지 않을 정보를 서브에이전트가 자기 컨텍스트 안에서 처리하고, 메인 대화에는 요약만 돌려주는 방식입니다.
각 서브에이전트 호출은 매번 새 인스턴스를 생성해서 완전히 새로운 컨텍스트로 시작하는 게 기본 동작이고, 이게 서브에이전트가 메인 대화의 컨텍스트 윈도우를 아끼는 핵심 원리입니다. v2.1.172부터는 이 서브에이전트가 자기 자신의 서브에이전트를 또 부를 수 있게 됐습니다.
대표적인 활용 예시는 리뷰어 서브에이전트가 발견한 이슈마다 검증용 서브에이전트를 하나씩 다시 파견하는 구조인데, 이렇게 하면 중간 산출물이 메인 대화에 전혀 노출되지 않고 최상위 서브에이전트의 요약만 사용자에게 돌아옵니다. 중요한 건 깊이 제한입니다.
메인 에이전트로부터 5단계 아래에 있는 서브에이전트는 더 이상 새로운 서브에이전트를 파생시킬 수 없고, 이 제한은 포그라운드로 돌든 백그라운드로 돌든 동일하게 적용됩니다. 예전에는 포그라운드 서브에이전트가 이 제한을 우회해서 무한정 체인을 만들 수 있었던 버그가 있었는데, 이후 패치로 백그라운드와 동일한 5단계 상한을 따르도록 고쳐졌습니다.
또한 재개된 서브에이전트는 원래의 스폰 깊이를 그대로 복원하고, 포크된 서브에이전트(부모의 전체 대화 맥락을 물려받아 시작하는 서브에이전트)도 이 깊이 카운트에 포함된다는 점이 최근 패치로 명확해졌습니다.
즉 "새로 만들었으니 깊이가 리셋되지 않을까"라는 기대는 틀렸다는 뜻입니다.
실전 1: 중첩 서브에이전트 정의하기 — YAML 프런트매터로 위임 체인 짜기
서브에이전트는 .claude/agents/ 디렉토리 아래 마크다운 파일로 정의합니다.
중첩 서브에이전트도 최상위 서브에이전트와 정의 방식이 완전히 동일하고, 같은 스코프(프로젝트/사용자)에서 이름으로 해석됩니다. 핵심은 tools 필드에 Agent를 넣느냐 마느냐인데, 이게 곧 "이 서브에이전트가 또 다른 서브에이전트를 부를 수 있는가"를 결정합니다.
아래는 리뷰어가 이슈를 발견할 때마다 검증자를 파견하는 2단계 구조 예시입니다.
---
name: reviewer
description: 코드 변경사항을 검토하고 이슈별로 검증 서브에이전트를 파견합니다.
tools: Read, Grep, Glob, Agent
---
당신은 코드 리뷰어입니다. 발견한 각 이슈에 대해 verifier 서브에이전트를
개별적으로 파견해서 재현 가능성을 확인하세요. 최종적으로는 검증된 이슈만 요약해서 보고하세요.
---
name: verifier
description: 리뷰어가 발견한 이슈 하나를 받아 실제로 재현되는지 검증합니다.
tools: Read, Bash
---
전달받은 이슈를 재현하는 최소 테스트 케이스를 작성하고 실행해서, 실제 버그인지 오탐인지 판별하세요.
여기서 reviewer 서브에이전트는 tools에 Agent가 포함돼 있어서 verifier를 하위로 파생시킬 수 있지만, verifier는 Agent가 빠져 있어서 더 이상 아래로 내려가지 않습니다. 만약 tools 목록 자체에 Agent를 아예 안 넣으면 그 서브에이전트는 어떤 서브에이전트도 못 부릅니다.
여기서 흔히 헷갈리는 부분이 있는데, Agent(agent_type) 형태로 괄호 안에 특정 타입을 지정하는 허용목록 문법은 claude --agent로 메인 스레드를 실행할 때만 적용되고, 서브에이전트 정의 파일 안에서는 이 괄호 안 타입 목록이 무시됩니다. 즉 서브에이전트 안에서는 Agent를 넣느냐 마느냐만 의미가 있고, 세부 타입 제한은 걸리지 않습니다.
정의 파일을 어디에 두는지도 중요합니다. 프로젝트 전용 서브에이전트는 .claude/agents/에 두고 버전 관리에 커밋해서 팀 전체가 같은 정의를 공유하도록 하는 게 권장 방식입니다.
이 프로젝트 서브에이전트는 현재 작업 디렉토리에서 위로 거슬러 올라가며 탐색되기 때문에, 저장소 루트까지 가는 경로에 있는 모든 .claude/agents/가 스캔 대상이 됩니다. 만약 이 경로에서 같은 이름의 서브에이전트가 여러 군데 정의돼 있다면, 작업 디렉토리에 가장 가까운 정의가 우선 적용됩니다.
개인적으로 여러 프로젝트에서 공통으로 쓰고 싶은 서브에이전트라면 ~/.claude/agents/에 두는 사용자 서브에이전트 경로를 쓰면 되고, --add-dir로 추가한 디렉토리 안의 .claude/agents/도 프로젝트 서브에이전트와 나란히 로드됩니다.
우선순위 전체를 놓고 보면 managed(관리자 설정) > CLI 플래그 > project > user > plugin 순으로 적용되므로, 조직 차원에서 강제하고 싶은 서브에이전트가 있다면 managed 설정으로 올려서 개인이 덮어쓰지 못하게 막을 수 있습니다.
실전 2: 깊이 제한 때문에 막히는 상황 디버깅하기
5단계 제한에 걸리면 에이전트가 에러 메시지를 내는 게 아니라 그냥 조용히 더 이상 하위 서브에이전트를 만들지 못하는 방식으로 동작합니다. 이 상황을 진단하려면 /agents 명령으로 열리는 패널을 확인해야 합니다.
Running 탭은 현재 실행 중인 서브에이전트를 평면 리스트로 보여주는데, 여기서는 트리 구조가 안 보이기 때문에 몇 단계까지 내려갔는지 한눈에 파악하기 어렵습니다. 대신 프롬프트 입력창 아래에 뜨는 서브에이전트 패널에서는 각 행마다 (+N) 형태로 하위 자손 개수가 표시되고, v2.1.193부터는 특정 행을 열면 그 서브에이전트의 형제·직계 자식과 메인까지 이어지는 경로를 함께 볼 수 있습니다.
# 현재 실행 중인 서브에이전트 트리 확인
/agents
# Running 탭: 평면 리스트로 실행 중인 서브에이전트 확인
# 패널에서 특정 서브에이전트 행을 열면 (+N) 자손 수와 트리 경로 확인 가능
여기서 실무적으로 놓치기 쉬운 부분이 있습니다.
서브에이전트를 재개(resume)하는 경우와 포크(fork)하는 경우도 각각 깊이 카운트에 영향을 줍니다. 서브에이전트는 원래 매번 새 인스턴스로 시작해서 이전 작업 기록을 전혀 모르는 게 기본값인데, 완료된 서브에이전트의 작업을 이어가고 싶다면 그 에이전트의 ID를 받아서 재개를 요청할 수 있습니다.
이때 재개된 서브에이전트는 전체 대화 기록과 도구 호출, 추론 과정을 그대로 유지한 채 멈췄던 지점부터 다시 시작하는데, 이 재개 과정에서 원래 있던 스폰 깊이도 그대로 복원됩니다. 즉 5단계 깊이에서 멈춘 서브에이전트를 재개해도 그건 여전히 5단계이지 1단계로 리셋되지 않는다는 뜻입니다. 포크된 서브에이전트(부모의 전체 컨텍스트를 그대로 물려받아 시작하는 방식)도 마찬가지로 깊이 카운트에 포함되기 때문에, "새로 포크했으니 카운트가 초기화되겠지"라고 기대하면 예상과 다른 지점에서 파생이 막히는 걸 보게 됩니다.
설계 단계에서 애초에 5단계까지 갈 일이 없도록 작업을 구조화하는 게 가장 깔끔한 해법입니다. 공식 문서도 "중첩 위임이 필요한 워크플로우라면 Skills를 쓰거나, 메인 대화에서 서브에이전트를 체이닝하는 방식을 고려하라"고 명시하고 있는데, 이는 무한정 깊어지는 트리 구조보다 메인 대화가 오케스트레이션 역할을 맡는 편이 더 안정적이라는 뜻으로 읽힙니다.
실무에서는 리뷰어→검증자 정도의 2~3단계 구조로도 대부분의 작업이 커버되고, 그 이상으로 깊어진다면 애초에 작업 분해 방식 자체를 재검토하는 게 낫습니다.
실전 3: 특정 조건의 서브에이전트 생성을 세밀하게 막기
무조건 서브에이전트 생성을 껐다 켰다 하는 것 말고, 세밀한 조건으로 제한하고 싶을 때가 있습니다. 최근 추가된 Tool(param:value) 문법을 쓰면 도구 호출의 특정 파라미터 값을 기준으로 권한 규칙을 걸 수 있는데, 대표적인 예시가 Agent(model:opus)로 Opus 모델을 쓰는 서브에이전트 생성만 차단하는 겁니다. 비용이 큰 모델로 서브에이전트가 무분별하게 파생되는 걸 막고 싶을 때 유용합니다.
{
"permissions": {
"deny": [
"Agent(model:opus)"
]
}
}
이 설정을 settings.json에 넣으면 Opus 모델을 지정한 서브에이전트 파생 요청만 차단되고, 다른 모델(Sonnet, Haiku)을 쓰는 서브에이전트는 정상적으로 생성됩니다. 팀 전체에 이 규칙을 강제하고 싶다면 managed 설정으로 올려서 개인 프로젝트 설정보다 우선 적용되게 만드는 것도 가능합니다.
MCP 서버 접근도 서브에이전트 단위로 따로 제어할 수 있습니다. mcpServers 필드에 인라인으로 서버를 정의하면 그 서브에이전트가 시작할 때 연결되고 종료할 때 자동으로 끊깁니다. 반대로 문자열로 참조만 하면 부모 세션의 연결을 그대로 공유합니다.
---
name: db-auditor
description: 프로덕션 데이터베이스 스키마를 감사합니다. 읽기 전용 MCP 연결만 사용합니다.
tools: Read, Agent
mcpServers:
prod-db-readonly:
command: "npx"
args: ["-y", "@company/mcp-db-readonly"]
---
프로덕션 DB 스키마를 읽기 전용으로 점검하고 이상 패턴을 보고하세요.
메인 대화에서는 접근 못하게 해둔 민감한 MCP 서버를, 특정 서브에이전트에서만 한시적으로 열어주고 싶을 때 이 구분이 유용합니다. 예를 들어 프로덕션 DB에 직접 접근하는 MCP 서버는 메인 세션에서는 아예 등록하지 않고, 감사 목적의 서브에이전트가 실행되는 짧은 시간 동안만 인라인으로 연결시켰다가 작업이 끝나면 자동으로 끊어버리는 식입니다.
이렇게 하면 메인 대화의 나머지 흐름에서 실수로 프로덕션 DB에 접근하는 사고를 원천적으로 방지할 수 있습니다.
중첩 서브에이전트 핵심 규칙
| 항목 | 내용 |
| 지원 시작 버전 | v2.1.172 |
| 최대 깊이 | 메인 에이전트로부터 5단계 (포그라운드·백그라운드 동일 적용) |
| 하위 파생 허용 | tools에 Agent 포함 시 가능, 생략 시 불가 |
| 괄호 타입 제한 | Agent(agent_type) 문법은 claude --agent 메인 스레드에만 적용, 서브에이전트 정의 내에선 무시 |
| 조건부 차단 | Agent(model:opus) 같은 Tool(param:value) 문법으로 세밀 제어 가능 |
| 진행상황 확인 | /agents Running 탭(평면) 또는 서브에이전트 패널의 (+N) 트리(v2.1.193+) |
| 정의 파일 위치 | 프로젝트: .claude/agents/ (위로 탐색, 가까운 정의 우선) / 사용자: ~/.claude/agents/ |
| 우선순위 | managed > CLI 플래그 > project > user > plugin |
| 이름 충돌 시 | 작업 디렉토리에 가장 가까운 .claude/agents/ 정의가 우선(v2.1.178+) |
| 깊이 추적 | 재개된 서브에이전트는 원래 깊이를 복원, 포크된 서브에이전트도 깊이 카운트에 포함 |
| MCP 접근 | mcpServers 필드로 서브에이전트별 인라인 연결(시작 시 연결, 종료 시 해제) 가능 |
결론
중첩 서브에이전트는 강력하지만 무한정 깊어지는 구조가 아니라 5단계라는 명확한 상한이 있는 기능이고, 재개나 포크로 새 인스턴스를 만든다고 해서 이 깊이 카운트가 리셋되지도 않습니다.
이 제한을 모르고 재귀적으로 계속 파생되는 설계를 짜면 특정 깊이에서 조용히 멈추는 현상을 마주하게 되므로, 애초에 리뷰어→검증자 수준의 얕은 구조로 설계하고 필요할 때만 Agent 툴 포함 여부로 파생을 제어하는 게 안정적입니다.
비용이 큰 모델의 남용을 막고 싶다면 Agent(model:opus) 같은 파라미터 기반 권한 규칙을 걸어두고, 민감한 MCP 서버는 메인 세션이 아니라 특정 서브에이전트에만 한시적으로 열어주는 식으로 접근을 최소화하는 게 실무에서 바로 쓸 수 있는 방어선입니다.
결국 중첩 서브에이전트를 잘 쓰는 핵심은 "얼마나 깊게 팔 수 있는가"가 아니라 "얼마나 얕게 유지하면서도 작업을 제대로 분해하고, 권한은 최소한으로 열어주는가"에 있습니다.
'Claude' 카테고리의 다른 글
| Claude Sonnet 5 분석: 1M 컨텍스트보다 무서운 건 토크나이저 변경 (0) | 2026.07.02 |
|---|---|
| Claude Fable 5, 19일 만에 사용 재개 (0) | 2026.07.02 |
| Claude Code 다이나믹 워크플로우, 수백 개 서브에이전트가 어떻게 병렬로 도는가 (0) | 2026.07.02 |
| 클로드 소넷 5 (Sonnet 5) 마이그레이션 가이드, 이거 안 고치면 400 에러 납니다 (0) | 2026.07.01 |
| 클로드 소넷 5 (Sonnet 5) vs 오푸스 4.8 (Opus 4.8) 비교 정리 (0) | 2026.07.01 |