본문으로 건너뛰기

© 2026 Molayo

Qiita헤드라인2026. 06. 15. 10:33

Claude Code의 서브 에이전트가 폭주하여 할당량을 모두 소진한 사고——이를 막는 하나의 hook과 사라진 성과의 복구

요약

Claude Code의 서브 에이전트가 재귀적으로 자식 에이전트를 생성하며 토큰 할당량을 급격히 소진하는 폭주 사고와 그 대응책을 다룹니다. 환경 변수가 무시되는 결함을 해결하기 위해 PreToolUse hook을 활용한 제어 방법과 비용 방지를 위한 설정법을 제시합니다.

핵심 포인트

  • 서브 에이전트의 재귀적 생성으로 인한 토큰 폭주 및 과금 사고 발생
  • CLAUDE_CODE_FORK_SUBAGENT 설정이 무시되는 결함 확인
  • PreToolUse hook을 사용하여 서브 에이전트 기동을 강제로 차단 가능
  • 비용 폭주 방지를 위해 Console 지출 상한 설정 및 자동 보충 비활성화 권장
  • cc-safe-setup의 nested-spawn-inflight-guard.sh 활용 제안

2026년 6월 15일의 과금 분리(프로그래밍적 이용이 Pool 2의 종량제 할당량으로 나뉘는 변경)가 적용된 당일에, 가장 금액이 큰 사고 중 하나가 접수되었습니다. 서브 에이전트(Sub-agent)가 재귀적으로 자식 에이전트를 계속 생성하며, 멈추지 않은 채 토큰 할당량을 모두 태워버리는 사고입니다.

이 기사는 해당 사고가 "왜 발생하는가", "어떻게 멈추는가", "소진된 후에 성과를 어떻게 되찾는가"를 실제 기기에서 확인한 범위 내에서 정리합니다. 적용 전에는 할당량을 빨리 다 써버리는 것에 그쳤지만, 적용 후에는 동일한 폭주가 Pool 2의 실비를 자동으로 추가 구매하는 형태로 이어질 수 있기 때문에 대처의 우선순위가 높아졌습니다.

접수된 #68430 사례의 사용자는 서브 에이전트가 50층이 넘는 깊이까지 재귀적으로 자식 에이전트를 생성하여, 약 30분 만에 120만 토큰 이상을 소비했다고 보고했습니다. 다른 사례에서는 Pro Max 20x의 8시간 할당량을 5분 미만으로 모두 소진했다고 합니다. 작업 내용은 "리포지토리(Repository)를 clone 하여 .sol 파일을 찾는" 정도의, 본래는 1회의 git clone으로 끝날 일이었습니다.

보고자의 분석에 따르면, 5가지 결함이 연쇄적으로 발생하고 있습니다.

  • CLAUDE_CODE_FORK_SUBAGENT=0을 설정해도 무시되어, 서브 에이전트가 자식을 생성하는 것을 멈출 수 없음.
  • 권한 거부가 "정지"가 아닌 "회피를 위한 자식 에이전트의 기동"을 트리거함. 거부될 때마다 자식을 생성하고, 그 자식도 동일한 벽에 부딪혀 손자 에이전트를 생성함.
  • 서브 에이전트의 권한 요구가 사용자에게까지 전달되지 않아, 첫 번째 거부 시점에서 멈출 기회가 없음.
  • 리포지토리 파일을 clone이 아닌 파일 하나씩 HTTP로 취득하며, 그때마다 전체 문맥(Context)을 다시 보냄.
  • 폭주를 멈추기 위해 중단하면, 중간 단계까지의 모든 에이전트 성과가 버려짐.

관련된 사고로, 병렬 분배(fan-out) 과정에서 다수의 서브 에이전트가 상위 모델을 계승하고, 할당량의 자동 보충과 맞물려 세금 포함 약 864달러의 자동 구매가 발생한 사례(#68285)도 있습니다.

5가지 결함은 제공 측의 문제이므로 당일에 바로 수정되지는 않습니다. 사용자 측에서 가장 먼저 해야 할 일은 폭주가 "실비"를 발생시키는 경로를 차단하는 것입니다.

적용 후, 폭주가 할당량만 소진하는 것이라면 추가 청구는 발생하지 않습니다(플랜의 할당량이 빨리 소진될 뿐입니다). 하지만 usage credits(Pool 2의 종량제 할당량)를 활성화해 두었고, 자동 보충까지 활성화되어 있다면 할당량이 소진될 때마다 자동으로 추가 구매됩니다. 병렬 폭주와 겹치면 보충이 연속적으로 일어나 고액이 청구됩니다. #68285의 약 864달러가 바로 이 경우입니다.

  • Console에서 지출 상한을 설정한다. 상한에 도달하면 자동 보충이 아닌 정지 상태로 전환됩니다.
  • 할당량 자동 보충(auto-reload)을 끄거나 낮게 설정한다.

이 두 가지 조치로 폭주가 "실비를 무한히 추가 구매하는" 상태에서 "멈추는" 상태로 바뀝니다.

CLAUDE_CODE_FORK_SUBAGENT=0이 무시되는 이상, 이 플래그에 의존해서는 안 됩니다. 대신 PreToolUse hook을 Task(서브 에이전트의 기동)에 맞춰 사용합니다. hook은 서브 에이전트가 기동하기 "전"에 실행되며, 그 기동을 거부할 수 있습니다. 하네스(Harness)가 도구의 경계에서 강제하므로, 환경 변수가 무시되더라도 상한 설정이 적용됩니다.

직접 작성해도 좋지만, 검증된 것이 cc-safe-setup에 있습니다(무료, MIT 라이선스). nested-spawn-inflight-guard.sh는 기동할 때마다 대화 기록을 스캔하여, 아직 결과가 반환되지 않은(실행 중인) Task 계열의 호출을 계산하고, CC_NESTED_SPAWN_BUDGET(기본값 5) 이상이면 exit 2로 기동을 거부합니다.

{
"hooks": {
"PreToolUse": [{
...

이 hook은 동시에 실행 중인 깊이의 상한을 설정하는 것이지, 생애 누적 비용을 막는 것은 아닙니다. 따라서 "Console의 지출 상한"과 조합해서 사용해야 합니다. 깨끗한 상태에서 테스트를 실행한 결과, 26건 모두 통과했습니다(실행 중인 수의 계산, 1턴 내 병렬 기동 거부, 손상된 기록에서의 안전한 통과 등).

참고로, 여기서 한 가지 중요한 미묘한 차이가 있습니다. 폭주한 세션에서도 hook 자체는 실행됩니다. 따라서 "세션 내부의 hook"으로는 막을 수 없습니다. 막는 것은 기동 "전"에 거부하는 PreToolUse 경로입니다.

#68430의 보고에서 간과하기 쉬운 점은 다섯 번째 항목인 "중단하면 모든 에이전트의 성과가 버려진다"는 점입니다. 화면상으로는 120만 토큰을 사용하고도 아무것도 남지 않은 것처럼 보입니다.

하지만 성과는 디스크에 남아 있습니다. 각 서브 에이전트(Sub-agent)는 자신의 기록을 1턴씩 다음 장소에 써 내려갑니다.

~/.claude/projects/<프로젝트>/<세션ID>/subagents/agent-<ID>.jsonl

이는 부모 에이전트가 결과를 받는지 여부와 관계없이 영속화(Persistence)됩니다. 따라서 폭주를 kill 한 후라도, 폭주하기 전에 업무를 마친 초기 에이전트의 성과는 이 파일 안에 남아 있습니다. 직접 확인해 본 결과, 제 환경에는 180건의 agent-*.jsonl 파일이 있었으며, 각각에 모델의 실제 출력 텍스트가 들어 있었습니다.

최근 1시간 내에 작성된 큰 파일부터 확인하려면 다음과 같이 합니다.

find ~/.claude/projects -path '*subagents*' -name 'agent-*.jsonl' \
-newermt '-1 hour' -printf '%s\t%p\n' | sort -rn | head

agent-*.jsonl은 1행 1레코드의 평문(Plain text)이며, 텍스트 성과는 message.content[].text 아래에 있습니다. 즉, "회수할 수 있는 성과가 제로"라는 말은 부모 에이전트의 관점에서는 맞을지 몰라도, 디스크 상에서는 틀린 말입니다.

다시 말씀드리지만, 발화(Trigger) 후에는 이 폭주가 플랜(Plan)의 할당량이 아닌 Pool 2의 종량제 할당량에서 차감되는 경로로 들어갈 수 있습니다. 그 경우 폭주는 "할당량을 빨리 다 쓰는 것"이 아니라 "실비를 자동으로 추가 결제하는 것"이 됩니다. 따라서 재무적 상한선(Console의 지출 상한 및 자동 충전 중지)을 먼저 설정하는 것이 발화 전보다 더 중요해졌습니다.

  • 발화 후 발생하는 가장 금액이 큰 사고 중 하나는 재귀적인 서브 에이전트의 폭주입니다 (#68430, #68285).
  • 5가지 결함은 제공 측의 문제이므로 당일에 바로 고쳐지지 않습니다. 이용자 측에서 할 수 있는 것은 (1) 재무적 상한선 설정 (Console의 지출 상한, 자동 충전 중지), (2) 고장 난 플래그에 의존하지 않는 PreToolUseTask hook을 통한 기동 상한 설정, (3) 사고가 터진 후에도 subagents/agent-*.jsonl에서 성과를 되찾는 것, 이 세 가지입니다.

6월 15일의 과금 분리 그 자체에 대한 대응(본인의 이용이 분리 대상인지, 4가지 대응 경로, 비용 견적)은 6월 15일 과금 분리에 대비하는 책(800엔, 제2장까지 무료)에 정리해 두었습니다. 발화 당일에 추가한 제8장에서는 이 폭주 사고에 대한 이용자 측의 대응을 포함하여, 발화 첫날의 세 가지 혼란을 다루고 있습니다. 데이터 소실과 복구 예방 가이드는 사고 방지 서적(800엔)에, 예방용 hook 모음은 cc-safe-setup(무료)에 있습니다.

AI 자동 생성 콘텐츠

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

원문 바로가기
0

댓글

0