역할이 아니라 컨텍스트 격리 | Custom Agent
서브에이전트가 역할 분담이 아니라 컨텍스트 오염을 격리하는 도구임을 이해하고, .claude/agents/에 test-planner를 직접 만들어 봅니다
Overview
앞 레슨에서 Hook으로 AI 행동을 가로채는 방법을 다뤘습니다. 이번 레슨은 반대 방향의 문제를 다룹니다. AI가 너무 많은 파일을 읽어 메인 컨텍스트가 오염될 때입니다.
서브에이전트를 "프론트엔드 담당", "백엔드 담당"처럼 역할로 나누면 자연스러워 보입니다. 그런데 이 방식은 동작하지 않습니다. 서브에이전트의 진짜 용도는 역할 분담이 아니라 컨텍스트 오염 격리입니다.
학습 목표
- 역할 분담과 컨텍스트 격리가 다른 문제임을 구별합니다
- Subagent가 메인 컨텍스트를 보호하는 원리를 이해합니다
.claude/agents/에 전문 Custom Agent를 정의할 수 있습니다- test-planner Custom Agent를 만들어 실행해 봅니다
시작하기 전 확인사항
- Claude Code 설치 완료 (
claude --version) - 프로젝트에
.claude/폴더 존재 - 실습 프로젝트 시작 브랜치 (
git checkout ch08-02)
역할 분담이 동작하지 않는 이유
새로 합류한 동료를 "프론트엔드 전문가"라고 불러도, 첫날 우리 프로젝트의 src/components/ 구조를 알고 있을 리는 없습니다. 매번 코드를 직접 열어 봐야 합니다.
서브에이전트도 같습니다. "프론트엔드 에이전트", "백엔드 에이전트"처럼 이름을 붙여도, 각 에이전트는 매번 빈 상태에서 시작합니다. LLM은 상태가 없어서, 라벨을 붙이는 것만으로는 아무것도 기억하지 못합니다. 결국 매번 파일을 처음부터 찾아 읽습니다.
진짜 문제는 역할 이름이 아니라, 그 탐색 과정에서 메인 컨텍스트에 쌓이는 코드입니다.
"이 프로젝트의 인증 코드를 전부 찾아서 정리해줘"
이 한 줄 요청에 AI는 10~20개 파일을 읽습니다. 각 파일의 내용이 컨텍스트에 누적되어, 탐색이 끝날 때쯤 수천 줄의 코드가 쌓여 있습니다. 그런데 여러분이 실제로 필요한 것은 "인증은 src/auth/token-manager.ts에서 JWT로 처리되고, 갱신 로직은 142번째 줄에 있다"는 한 문단 요약뿐입니다.
입력은 짧고 결론도 짧지만, 중간 과정이 컨텍스트를 부풀립니다. 이 코드가 컨텍스트에 남아 이후 작업의 정확도를 떨어뜨립니다. 에이전트에 어떤 역할 이름을 붙여도 탐색 과정에서 쌓이는 코드는 그대로입니다.
Subagent: 메인과 분리된 컨텍스트로 위임
이번에는 동료에게 조사를 맡기는 방식을 생각해봅니다.
"결제 모듈 구조를 파악해서, A4 한 장으로 정리해줘."
동료가 같은 3시간을 들여 조사합니다. 하지만 여러분의 책상에 오는 것은 A4 한 장짜리 요약뿐입니다. 조사 과정에서 펼쳤던 수십 개의 파일은 동료의 책상에 남습니다.
Subagent(서브에이전트)는 메인과 완전히 분리된 자체 컨텍스트 윈도우에서 작업하고, 작업이 끝나면 결론만 반환하는 AI 세션입니다. 탐색 중 읽은 수십 개 파일은 Subagent의 컨텍스트에 남고, 메인에는 결론 텍스트만 추가됩니다.
Subagent 안에서 파일을 20개 읽든 100개 읽든, 메인 컨텍스트에는 영향이 없습니다. Subagent의 컨텍스트는 작업이 끝나면 폐기되고, 메인에는 결론만 남습니다.
Claude Code의 내장 Subagent
Claude Code에는 용도별로 미리 정의된 Subagent가 있습니다.
| Subagent | 용도 | 특징 |
|---|---|---|
| Explore | 코드베이스 검색, 파일 구조 파악 | 읽기 전용, 빠른 모델 사용 |
| Plan | 구현 계획 수립 조사 | 읽기 전용, 코드를 수정하지 않음 |
| general-purpose | 복잡한 다단계 작업 | 모든 도구 사용 가능 |
Claude Code는 요청 성격에 따라 적합한 Subagent를 자동으로 선택합니다. "이 프로젝트의 폴더 구조를 알려줘"라고 하면 Explore가, "리팩토링 계획을 세워줘"라고 하면 Plan이 활성화됩니다.
Subagent는 중첩되지 않습니다
Subagent 안에서 또 다른 Subagent를 띄울 수 없습니다. 한 단계의 컨텍스트 격리만 보장됩니다.
Custom Agent: 미리 만드는 Subagent
내장 Subagent는 범용 도구라서, 같은 분석을 반복할 때마다 분석 기준과 출력 형식을 프롬프트에 매번 새로 적어야 합니다. Custom Agent는 .claude/agents/ 디렉토리에 마크다운 파일 하나로 그 지침을 미리 정의해두는 전문 Subagent입니다.
.claude/
├── agents/
│ ├── test-planner.md # 테스트 계획 전문
│ ├── code-reviewer.md # 변경 사항 리뷰 전문
│ └── bug-investigator.md # 버그 원인 추적 전문
├── commands/
└── settings.json파일 이름이 Agent의 호출 이름이 됩니다. test-planner.md를 만들면 test-planner라는 이름으로 호출됩니다.
test-planner Custom Agent를 만들어 두면, 다음과 같이 자연어로 요청해도 됩니다.
"테스트 계획 세워줘"
Claude가 description을 보고 이 Agent가 적합하다고 판단하면 자동으로 선택합니다.
[실습] 테스트 계획 전문 Agent 만들기
테스트 커버리지 분석은 Subagent의 대표적인 활용 사례입니다. 소스 코드 파일을 하나씩 읽고, 테스트 파일과 대조하고, 빠진 부분을 정리하는 과정에서 대량의 코드가 컨텍스트에 쌓입니다.
Custom Agent로 이 작업을 격리하면, 메인 컨텍스트에는 테스트 계획 요약만 남습니다.
Step 1: Agent 파일 작성
.claude/agents/test-planner.md를 다음과 같이 작성합니다.
---
name: test-planner
description: "소스 코드와 테스트 파일을 대조하여 테스트가 부족한 영역을 찾고 테스트 계획을 수립합니다. 테스트 계획, 테스트 분석, 테스트가 부족한 부분 찾기, 어떤 테스트가 필요한지 요청 시 사용합니다."
model: sonnet
tools: Read, Grep, Glob, Bash
---
# Test Planner
소스 코드와 기존 테스트를 대조 분석하여, 테스트가 부족한 영역을 찾고 우선순위별 테스트 계획을 제공합니다.
## 분석 프로세스
1. 소스 코드 파일과 테스트 파일 목록을 각각 수집합니다
2. 함수/컴포넌트별로 대응하는 테스트 존재 여부를 대조합니다
3. 테스트가 없는 항목을 아래 기준에 따라 분류합니다
## 분류 기준
- **High**: 상태를 변경하는 핵심 로직 (생성, 수정, 삭제)
- **Medium**: 조건 분기가 있는 로직 (필터링, 정렬, 검증)
- **Low**: 단순 표시 로직 (포맷팅, UI 렌더링)
## 출력 형식
다음 구조로 분석 결과를 작성합니다.
**커버리지 현황**: 소스 파일 수, 테스트가 있는 파일 수, 비율
**우선순위별 테스트 필요 항목**:
- High: [파일:함수] 이유
- Medium: [파일:함수] 이유
- Low: [파일:함수] 이유
**추천 테스트 케이스**: 가장 시급한 항목 3개의 구체적 시나리오
## 규칙
- 테스트 코드를 직접 작성하지 않습니다 — 계획만 제공합니다
- 유틸리티보다 비즈니스 로직 테스트를 우선합니다
- 테스트가 충분하면 "추가 테스트 불필요"라고 명확히 표시합니다Agent 마크다운 파일은 YAML frontmatter + 본문으로 구성됩니다.
| 필드 | 필수 | 설명 |
|---|---|---|
name | O | Agent 식별자 (파일명과 일치) |
description | O | Claude가 자동 위임 시 참고하는 설명. 이 값을 보고 작업에 맞는 Agent를 선택합니다. |
model | X | 사용할 모델 (sonnet, opus, haiku). 생략하면 메인과 동일 모델 |
tools | X | Agent가 사용할 수 있는 도구 제한. 생략하면 모든 도구 사용 가능 |
본문은 Agent의 시스템 프롬프트입니다. 역할, 작업 방식, 출력 형식, 규칙을 정의합니다.
description 작성 팁
description은 Claude가 자동 위임 여부를 판단하는 유일한 단서입니다. 어떤 작업에 적합한지, 어떤 키워드를 보고 호출해야 하는지를 구체적으로 적어 두면 자동 선택 정확도가 올라갑니다.
Step 2: Agent 로드
Agent 파일은 세션 시작 시점에 로드됩니다. 새 파일을 추가하거나 수정했다면 다음 중 하나를 해야 합니다.
- 세션을 재시작합니다. (
/exit후claude다시 실행) - 또는 실행 중인 세션에서
/agents명령을 실행해 즉시 다시 로드합니다.
Step 3: Agent 실행
Agent를 호출하는 방법은 두 가지입니다.
- 자연어 요청: "테스트가 부족한 부분을 분석해줘". Claude가
description을 보고 적합한 Agent를 자동으로 선택합니다. - 명시적 지정: "test-planner 에이전트로 테스트 계획을 세워줘"
Subagent가 활성화되면 터미널에 별도 세션 표시가 나타나고, 작업이 완료될 때까지 Agent가 자율적으로 파일을 읽고 분석합니다.
Step 4: 결과 확인
Agent가 작업을 마치면, Step 1에서 정의한 출력 형식에 따라 구조화된 테스트 계획이 메인 컨텍스트에 추가됩니다.
**커버리지 현황**: 소스 파일 8개 중 테스트가 있는 파일 3개 (37%)
**우선순위별 테스트 필요 항목**:
- High: [todoService.ts:deleteTodo] 삭제 후 상태 갱신 로직에 테스트 없음
- High: [todoService.ts:toggleTodo] 완료 상태 토글의 엣지 케이스 미검증
- Medium: [TodoFilter.tsx:filterTodos] 빈 목록, 전체 완료 등 경계 조건 미검증
**추천 테스트 케이스**:
1. deleteTodo 호출 후 목록에서 실제 제거 확인
2. toggleTodo로 완료/미완료 반복 전환 시 상태 일관성
3. 할 일이 0개일 때 필터 동작같은 작업을 Subagent 없이 메인 컨텍스트에서 수행했다면, 8개 소스 파일과 3개 테스트 파일의 전체 코드가 메인에 그대로 남았을 것입니다. Custom Agent를 사용하면 테스트 계획 요약만 남습니다. 이후 계획을 보고 테스트 코드를 작성할 때, 메인 컨텍스트가 깨끗해서 테스트 작성에 집중할 수 있습니다.
Subagent를 피해야 하는 경우
Subagent도 만능은 아닙니다. 별도 AI 세션을 여는 만큼 준비 시간이 들고, 메인의 대화 맥락 전체를 알지 못합니다.
오염이 작은 작업은 메인이 더 빠릅니다. "이 함수 뭐하는 거야?"처럼 한두 파일만 보면 끝나는 질문은 메인에서 바로 처리하는 게 빠릅니다. Subagent를 띄우는 오버헤드가 더 큽니다.
직전 대화 맥락이 필요한 작업도 부적합합니다. Subagent는 호출 시점에 작업 요청과 CLAUDE.md 등 일부 정보만 받습니다. 이전 대화의 흐름이나 결정 과정을 모르므로, "방금 우리가 합의한 방향대로" 같은 요청은 Subagent에 전달하기 어렵습니다.
판단 기준은 단순합니다. 컨텍스트 오염 정도입니다. 입력이 방대하고 결론이 짧은 작업이라면 Subagent로, 그렇지 않다면 메인에서 직접 처리하는 게 낫습니다.
| 작업 | 하는 일 | 부모에게 반환하는 것 |
|---|---|---|
| 리서치 | 코드베이스에서 특정 기능 동작 추적 | 관련 파일 경로, 줄 번호, 호출 체인 요약 |
| 테스트 분석 | 테스트 돌리고 결과 분석 | 실패한 테스트명, 에러 핵심 |
| 빌드 검증 | 빌드 돌리고 에러 분석 | 에러 원인 요약, 수정 필요 파일 |
| 의존성 조사 | 특정 함수/모듈 사용처 추적 | 사용처 목록, 영향 범위 |
핵심 포인트 정리
- 역할 분담이 아니라 컨텍스트 격리: Subagent는 역할을 나누는 도구가 아닙니다. LLM은 상태가 없어 라벨을 붙여도 매번 처음부터 시작하므로, 역할 분담 자체가 문제를 해결하지 못합니다. 진짜 용도는 컨텍스트 오염을 별도 공간에서 격리하는 데 있습니다.
- 메인 컨텍스트 보호: Subagent는 자체 컨텍스트 윈도우에서 탐색하고, 메인에는 결론 텍스트만 추가됩니다. 입력이 짧고 결론도 짧지만 중간이 컨텍스트를 부풀리는 작업에 효과적입니다.
- Custom Agent는 미리 정의한 Subagent:
.claude/agents/에 마크다운 한 장으로 분석 기준과 출력 형식을 미리 정의해두면, 매번 설명하지 않아도 일관된 결과를 받습니다. 자주 반복하는 분석은 Custom Agent로 미리 정의해두길 권장합니다.
FAQ
-
Q: Custom Agent가 메인 컨텍스트의 대화 내용을 볼 수 있나요?
- A: Subagent는 호출 시점에 자체 시스템 프롬프트와 CLAUDE.md 정도만 받고, 부모의 이전 대화는 보지 못합니다. 필요한 맥락은 호출 시 작업 요청에 직접 포함해야 합니다.
-
Q: Custom Agent와 Custom Command는 어떻게 다른가요?
- A: Custom Command는 메인 컨텍스트에서 실행되는 프롬프트 단축키입니다. Custom Agent는 별도 컨텍스트에서 실행되는 전문 Subagent입니다. 컨텍스트를 많이 소비하는 작업은 Agent로, 메인 안에서 처리할 짧은 반복 작업은 Command로 구분합니다.
-
Q: Agent 파일을 수정하면 바로 반영되나요?
- A: 아니요, Agent 파일은 세션 시작 시점에 한 번 로드됩니다. 새 파일을 추가하거나 내용을 수정한 뒤에는 세션을 재시작하거나
/agents명령으로 다시 로드해야 변경사항이 반영됩니다.
- A: 아니요, Agent 파일은 세션 시작 시점에 한 번 로드됩니다. 새 파일을 추가하거나 내용을 수정한 뒤에는 세션을 재시작하거나
이어서 배울 내용
Hook으로 AI 행동을 가로채고, Custom Agent로 탐색을 격리하는 방법까지 다뤘습니다. Part 2에서 지나온 네 챕터(Plan/Task, Rules·Commands·Skills, 외부 연결, 실행 제어)를 다음 레슨에서 한 장으로 정리합니다.
- Part 2 네 챕터의 큰 테마 복습
- Part 3가 풀 문제의 예고