Claude Code에서 서브 에이전트의 중첩 깊이 테스트: 기본값은 3단계, 하지만 같은 세션의 처음 4회만 1단계에 머물렀다
요약
Claude Code의 서브 에이전트 메커니즘을 테스트한 결과, 지정된 환경 변수 `CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH`에 따라 손주 및 증손주까지 성공적으로 생성할 수 있음을 확인했습니다. 초기 4회 세션에서만 예외적으로 깊이가 제한되었으나, 동일 설정 재시도 시 정상 작동하는 것으로 나타났습니다.
핵심 포인트
- 서브 에이전트의 최대 중첩 깊이는 환경 변수로 제어 가능합니다.
- 지정된 값(1~5)에 관계없이 13회 모두 성공적으로 도달했습니다.
- 초기 세션에서만 발생한 얕은 깊이 제한 현상은 일시적인 문제로 보입니다.
Claude Code에는 '서브 에이전트(subagent)'라는 메커니즘이 있습니다. 부모 AI가 다른 AI를 호출하여 하청을 주는 기능입니다. 그렇다면 그 하청이 또 하청을 줄 수 있을까요? 즉, 손주까지 만들 수 있을까요?
결론부터 말씀드립니다. 이 환경(Claude Code 2.1.285)에서는 손주와 증손주까지 만들 수 있었습니다. 지정하지 않으면 3단계까지 도달합니다. 다만 같은 작업 세션의 처음 4회만 1단계에 머물렀고, 동일한 설정을 나중에 다시 시도했을 때는 통했습니다. 설정은 단 1바이트도 변경하지 않았습니다.
그리고 깊이를 결정하는 것은 CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH라는 환경 변수(명령을 실행하기 전에 외부에서 전달할 수 있는 설정값)였습니다. 1부터 5까지 값을 지정해 본 결과, 13회 모두 지정한 값대로의 깊이에 도달했습니다.
3은 천장이 아닙니다.
먼저, 어떻게 측정했는지
'AI가 그렇게 말했다'를 근거로 하면 아무것도 확인할 수 없으므로, 기계가 출력하는 숫자만으로 세었습니다. 사용한 것은 --output-format json으로 반환되는 subagent_stats라는 집계란입니다.
cd "$RUN" && env -u MAX_THINKING_TOKENS -u CLAUDE_EFFORT -u CLAUDE_ADDITIONAL_DIRECTORIES \
-u CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD -u CLAUDE_CODE_SESSION_ID \
timeout 900 claude -p 'Delegate to the subagent of type "layer1" with the prompt "go". Then reply with the text it returned, nothing else.' \
...
장치는 간단합니다. layer1은
refused: {'depth_limit': 0, 'concurrency_limit': 0, 'budget': 0}
(이것도 집계란에서 해당 부분만 발췌한 형태입니다.)
즉, "너무 깊어서 거절했습니다"라는 기록은 남지 않습니다. 상한 계층의 AI에게는 애초에
'하청을 내보내는 도구'가 전달되지 않았기 때문이라고 해석할 수 있습니다. 실행 파일 안에, 바로 그 설명문이
들어 있었습니다(제품이 가지고 있는 문구를 그대로 인용합니다. "통상적으로 제공되지는 않는다"라고 쓰여 있으며,
단정은 아닙니다).
depth_limit stays near zero in practice: a subagent at the nesting limit
is normally not offered the tool at all.
얕은 곳에서 조용히 멈추기 때문에, "왜 손주가 움직이지 않는지"를 찾을 때 오류를 찾아도 발견할 수 없습니다.
이것은 저 자신도 빠졌던 함정입니다.
영향(Impact): cap=1,2,3,4,5로 지정했을 때와 도달한 값이 13/13회 일치. refused.depth_limit는 39회 모두 0
처음 4번만 1개 계층이었다 (원인은 알지 못함)
솔직히 말씀드립니다. 이 검증에서 가장 어려웠던 부분이 여기입니다.
작업을 시작한 직후의 4번은, 깊이를 지정하지 않았음에도 1개 계층에서 멈췄습니다. 게다가
에이전트의 tools:
(사용할 수 있는 도구 목록)에 호출용 도구만 적었던 3번은,
서브 에이전트 자체가 기동되지 않아 failed=1
이 되었습니다.
run t+sec depth byS fail
probe 0.0 1 0 1
t_Task 29.1 1 0 1
...
처음에는 "tools:의 작성법을 잘못한 것이 아닐까"라고 생각하여, 작성법을 여러 가지로 시도했습니다. 그런데
시간이 지나서, 처음에 실패했던 것과 같은 설정을 다시 돌리니 7번 모두 통과하는 것입니다(
(`tools:
그래서 '지금 실행되는 것이 자식인지 손자인지'를 외부에서 알고 싶다면, 직접 레이어 이름을 붙여 놓을 수밖에 없습니다.
이번에 layer1과 layer2로 레이어를 나눈 것은 이 때문입니다. agent_type에는 그 이름이 들어가기 때문에,
거기가 유일하게 의지할 수 있는 부분입니다.
또 다른, 숫자를 세는 사람들을 위한 함정이 있습니다. 실행에 실패한 3번은 SubagentStart가 울렸지만 SubagentStop이 울리지 않았습니다(기록은 1건과 0건). '시작에서 +1, 종료에서 -1하여 동시 수를 센다'는 방식을 사용하면, 실패가 섞일 때마다 1개씩 틀어집니다. 나머지 36번은 시작과 종료 건수가 일치했습니다.
영향: 후크 175행의 모든 키에 깊이 및 부모 ID는 0건. 실행 실패 3회는 시작 1건, 종료 0건으로, 36회는 일치함
'이 버전부터 사용 가능합니다'를 믿고 조사하면 제거됨
주제로 삼은 게시물에는 'v2.1.219 이후'라는 버전 경계가 적혀 있었습니다. 그래서 각 버전의 실행 파일을 가져와서, 안에 문자열이 있는지 여부만 세어보았습니다.
처음에 막힌 것은, 다운로드한 패키지가 22,971바이트밖에 되지 않았다는 점입니다. 내용은 도입용 스크립트뿐이고, 실행 파일은 들어있지 않았습니다. 실체는 optionalDependencies에 나열된 OS별 패키지(개당 약 265MB)에 있었습니다.
디스크를 채우고 싶지 않아서 저장하지 않고 흘려보내면서 세었습니다.
url=$(npm view "@anthropic-ai/[email protected]" dist.tarball)
curl -fsSL "$url" | tar xzO package/claude | grep -a -c 'CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH'
| 버전 | 중첩 상한 메시지 | 깊이 환경 변수 |
|---|---|---|
| 2.1.150 / 2.1.170 / 2.1.185 | 0건 | 0건 |
| ... |
중첩 상한을 나타내는 문구는, 문자열로서는 2.1.185에 없고 2.1.190에 있습니다. 올리거나 내리는 데 사용되는 환경
「2.1.219 이후」의 행동 경계(구버전을 구동하여 비교한 것은 아님), refused.depth_limit
이 증가하는 경로, 상한을 올렸을 때의 안전성 및 권장 값, 대화 화면이나 다른 머신에서의 재현성. 사용된 모델 이름도 출력에 두 개 나란히 있어 어느 것이 본체인지 규정적인 구별법으로 확정할 수 없었기 때문에, 본문에서는 주장하지 않았습니다.
Claude Code를 실제로 구동하여 확인한 범위만을 비엔지니어에게도 알기 쉬운 말로 작성했습니다(numarn).
Discussion

AI 자동 생성 콘텐츠
본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기