
subagent에게 '통째로 맡기는 지시'로 겪은 5가지 지뢰와 프롬프트 구조로 해결한 이야기
요약
Claude Code의 subagent 호출 시 발생하는 문제점과 이를 해결하기 위한 프롬프트 구조화 전략을 다룹니다. subagent의 컨텍스트 격리 특성을 이해하고, 명확한 목표와 출력 포맷, 도구 제한 등을 통해 제어하는 방법을 제시합니다.
핵심 포인트
- subagent는 호출 시점의 프롬프트가 동작의 전부임
- 명확한 Objective와 Output format 지정 필수
- 사용 가능한 도구와 금지된 도구를 명시적으로 구분
- 탐색 경계(Boundary)와 수치화된 Token cap 설정 필요
「subagent가 잘못됐다」고 생각했는데, 지시하는 쪽의 문제였다
Claude Code의 Task tool로 subagent를 호출하기 시작했을 때, 이런 경험을 하지 않으셨나요?
- 같은 의뢰를 두 번 던졌더니, 전혀 다른 포맷으로 돌아왔다
- 「조사만 하면 될 텐데」라고 했는데
Edit로 멋대로 파일을 수정해 버렸다 node_modules/이하를 통째로 탐색하느라 토큰이 녹아내렸다- 「간결하게」라고 썼는데, 500줄짜리 리포트가 돌아왔다
처음에는 「subagent의 동작이 불안정하다」고 생각했지만, 근본적인 원인은 전부 이쪽의 호출 프롬프트 (Prompt) 사양 부족이었습니다.
subagent는 「context isolation (컨텍스트 격리)」을 위한 도구
우선 전제로, Task tool을 「병렬 실행으로 빨라지는 메커니즘」이라고 생각하면 판단을 그르칩니다.
실제로는 호출한 쪽의 컨텍스트로 돌아오는 것은 subagent의 최종 출력 (Final Output) 뿐입니다. 중간 과정인 Read / Grep / WebFetch 로그는 메인 세션으로 흘러 들어오지 않습니다. 이것이 본질이며, 「결과만 필요하다・중간 과정은 메인에 보여주고 싶지 않은 탐색이나 생성」을 분리하기 위한 도구입니다. 병렬 실행은 부수적인 효과에 불과합니다.
편리한 만큼 대충 호출하면 큰 대가를 치르게 되는 이유가 여기에 있습니다. 메인이 subagent의 움직임을 감시할 수 없기 때문에, 호출 시점의 프롬프트가 전부가 됩니다.
대충 던진 dispatch (디스패치)가 일으키는 5가지 패턴
실제로 발생했던 트러블을 정리하면 다음과 같습니다.
| 증상 | 근본 원인 |
|---|---|
| 끝없이 계속 탐색함 | Objective (목표)에 종료 조건이 없음 |
node_modules/에 잠입함 | 제외 경계 (Exclusion Boundary)를 작성하지 않음 |
| 답변 포맷이 매번 다름 | Output format (출력 포맷)을 지정하지 않음 |
모두 「subagent가 똑똑하지 않아서」가 아니라, 「지시가 모호해서 subagent가 판단한」 결과입니다.
해결책: 5가지 요소를 프롬프트에 고정하기
호출 프롬프트에 반드시 포함할 요소를 5가지로 압축했습니다.
1. Objective (단일하고 명확한 목표)
「X를 조사한다」가 아니라, 「Y가 A인지 B인지 판정한다」라고 작성합니다. 완료 조건이 자명해야 한다는 것이 조건입니다.
# Bad
JWT 사용법을 조사한다
# Good
...
2. Output format (기대하는 구조)
JSON schema, Markdown의 섹션 구성, 글자 수 상한을 명시합니다.
JSON: { files: [{ path, has_try_catch, line }] }
「결과를 보고해 주세요」라고 하면, 같은 subagent에게 같은 의뢰를 두 번 던져도 다른 형태로 돌아옵니다. 이를 경험하면 Output format의 중요성을 뼈저리게 느끼게 됩니다.
3. Tools (사용 가능한 tool과 금지된 tool)
탐색만 하는 태스크라면 Bash / Write / Edit를 명시적으로 금지합니다.
사용 가능: Read, Grep, Glob
금지: Bash, Write, Edit, WebFetch
부작용의 여지를 물리적으로 없애는 것이 운용상의 요령입니다.
4. Boundary (건드려서는 안 되는 경계)
vendor/, node_modules/, dist/의 제외, git 조작 금지 등을 작성합니다. 경계를 작성하지 않으면 subagent는 「센스 있게」 주변을 건드리러 갑니다.
5. Token cap (측정 가능한 상한)
이것이 가장 놓치기 쉬운 부분입니다. 「간결하게」는 token cap이 아닙니다. 글자 수・건수・파일 수 중 하나로 숫자를 적습니다.
출력: 1500 단어 이내
최대 탐색 파일 수: 20
검색 결과는 상위 10건까지
실제로 적용한 순간, dispatch 부근의 평균 token 소비가 눈에 띄게 줄었습니다. 역으로 말하면, 작성하기 전까지는 무의식적으로 토큰을 흘려보내고 있었던 셈입니다.
5가지 요소를 정리한 템플릿
5가지 요소를 한 번에 작성할 수 있는 템플릿을 공통 참조 파일에 두고, 각 skill에서 참조하는 형태로 만들었습니다.
Task(
subagent_type: "general-purpose",
description: "Short 3-5 word description",
...
왜 이 템플릿이 되었는가
처음에는 "필요할 때만 작성하면 된다"고 생각했습니다. 하지만 skill이 늘어나면서 "이 dispatch는 Token cap(토큰 제한)이 있었나?"와 같은 리뷰 비용이 쌓여갔습니다. 템플릿을 "항상 모든 항목을 작성하는" 형태로 바꾸고 나서야, 리뷰가 "있는지/없는가"를 체크하는 것만으로 끝날 수 있게 되었습니다.
| 접근 방식 | 장점 | 단점 |
|---|---|---|
| 필요할 때만 작성 | 기술량(記述量)이 적음 | 매번 리뷰 비용이 발생함 |
| 항상 모든 항목을 작성 | 리뷰가 체크리스트화됨 | 초기 기술량이 늘어남 |
Skill이 10개를 넘어가는 시점부터는 "모든 항목을 작성하는 것"이 명확하게 비용이 더 낮아졌습니다.
실전에서 깨달은 점: 5요소를 작성하면 skill 본체가 정리된다
5요소를 작성하려고 하면, "이 Objective(목표)에서 원하는 것이 file path(파일 경로) 리스트인가, 아니면 위반 사항에 대한 판정인가"라는 질문에 답하게 됩니다.
이것은 의외의 부작용이자, I/O(입출력)가 모호했던 skill을 재설계하는 계기가 되었습니다. 템플릿을 채우려다 보니 "애초에 이 skill은 무엇을 반환하고 싶었던 거지?"라는 의문이 생겨, skill 본체의 책임을 정리하게 된 경험이 몇 번 있었습니다.
commit(커밋)이 늘어나면 lint(린트)뿐만 아니라 설계 품질도 담보하고 싶어집니다. 이를 위한 "구조적인 강제"로서, 템플릿은 생각보다 효과적입니다.
요약: 나는 이렇게 사용하고 있다
subagent의 호출 품질은 호출하는 측에서 결정됩니다. 5요소 템플릿을 "모든 dispatch의 최소 기준"으로 삼은 이후,
- "왠지 답변이 이상하다"라는 디버깅 시간이 줄어들었다
- Token(토큰) 소비를 dispatch당 예측하기 쉬워졌다
- 리뷰가 "템플릿의 모든 항목이 채워져 있는가"만으로 끝난다
라는 변화가 있었습니다. subagent의 동작을 안정시키고 싶다면, 먼저 호출 측을 정돈하라. 이것이 개인적인 결론입니다.
원문 기사
이 기사는 에이전트에게 "통째로 맡기는 지시"를 그만두기 —— Claude Code의 subagent 운용 규칙의 핵심 부분을 재구성한 것입니다. 원문 기사에서는 다음과 같은 내용을 더 다루고 있습니다:
- 태스크 성격에 따른 subagent routing(라우팅) 표 (탐색 heavy / 구현 / plan / review / 병렬의 구분 사용)
- 모든 SKILL.md를 스캔하여 5요소를 강제하는 CI lint의 구현 상세
- lint 도입을 통해 skill 본체의 I/O 설계가 정리된 경위
Discussion

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