본문 바로가기

개발/Claude Code

[Claude Code] 서브에이전트(Subagent) (8)

실습 목표: 곁가지 작업을 별도의 공간에서 처리하게 해서, 주 대화가 지저분해지지 않게 만드는 것.

 

Step 1. 서브에이전트는 무엇을 하는가?

이전에 컨텍스트를 책상 위에 쌓이는 서류에 비유했다. 한 번 올라간 서류는 대화가 끝날 때까지 계속 실려 다닌다.
문제는 결과만 필요한데 과정이 통째로 남는 경우이다.
예를 들어 "이 프로젝트에서 금액 계산이 어디서 일어나는지 찾아줘"라고 시키면 클로드는 여러 파일을 읽는다. 
정작 필요한 답은 "pricing.py의 checkout 함수" 한 줄인데, 읽은 파일 내용 전부가 대화에 남는다. 
그 뒤로 이어지는 모든 프롬프트에 그 파일들이 계속 따라다니게 된다.
서브에이전트는 이 문제를 해결하는 장치이다. 
별도의 대화 공간에서 작업하고, 결과 요약만 주 대화로 보낸다. 
읽은 파일 내용은 서브에이전트가 작업한 공간에 남고 주 대화 쪽으로 넘어오지 않는다.

[주 대화] 	 "금액 계산이 어디서 일어나는지 찾아줘"

              		↓ 위임

[서브에이전트의 별도 공간] 파일 5개 읽기, 검색 3회        ← 이 내용은 여기 남음

	                ↓ 요약만 반환

[주 대화] 	 "pricing.py의 checkout 함수입니다"

 

Step 2. 이미 서브에이전트를 쓰고 있었다?

클로드 코드에는 내장 서브에이전트가 있고, 지금까지 실습하는 동안 이미 쓰였을 가능성이 높다.

이름 역할
Explore 코드베이스를 빠르게 검색. 읽기 전용 — 파일을 쓰거나 고칠 수 없음
Plan Plan 모드에서 계획을 세우기 전에 자료를 모음. 읽기 전용
General-purpose 탐색과 수정이 모두 필요한 복잡한 작업

 

Explore와 Plan은 한 가지 특별한 점이 있다. 탐색을 가볍고 빠르게 유지하기 위해서 CLAUDE.md를 읽지 않는다. 
나머지 서브에이전트는 전부 CLAUDE.md를 읽는다.

 

Step 3. 서브에이전트를 직접 만들어 보자.

같은 종류의 작업을 반복해서 시키게 되면, 그때가 전용 서브에이전트를 정의할 때이다.

 

다음 명령어들을 터미널에서 실행한다.

cd ~/shop-api && mkdir -p .claude/agents
cat > .claude/agents/code-reviewer.md <<'EOF'
---
name: code-reviewer
description: 코드 변경사항을 검토하고 문제를 지적한다. 코드를 수정한 직후에 사용한다.
tools: Read, Grep, Glob, Bash
model: inherit
---

당신은 코드 리뷰 담당자다. 코드를 수정하지 않고 검토만 한다.

호출되면 다음 순서로 진행한다.

1. `git diff HEAD` 를 실행해 아직 커밋하지 않은 변경사항을 확인한다.
2. 변경된 부분에 집중해서 검토한다.

검토 항목:
- 금액 계산 규칙을 CLAUDE.md에 적힌 대로 지키고 있는가
- 경계값 처리가 빠지지 않았는가
- 입력값 검증이 필요한 곳에 들어가 있는가
- 변경에 대응하는 테스트가 있는가
- 예외 처리가 누락되지 않았는가

결과를 세 단계로 나누어 보고한다.
- 반드시 고쳐야 할 것
- 고치는 편이 좋은 것
- 검토해볼 만한 것

각 항목마다 해당 파일과 줄 번호, 그리고 어떻게 고치면 되는지를 함께 적는다.
EOF

 

스킬과 마찬가지로 --- 사이가 프론트매터, 그 아래가 본문이다. 다만 본문의 역할이 다르다.

  스킬 서브에이전트
본문이 무엇이 되나 클로드에게 전달되는 지시 서브에이전트의 성격 설정
실행되는 곳 주 대화 안에서 별도의 대화 공간에서

 

서브에이전트의 본문은 "이번에 이걸 해라"가 아니라 "너는 어떤 역할이고 어떻게 일하는 사람이다"를 적는 곳이다.
그래서 위 파일이 당신은 코드 리뷰 담당자다로 시작한다.

 

프론트매터 항목

항목 뜻
name 서브에이전트의 이름. 소문자와 하이픈만. (필수 항목)
description 언제 이 서브에이전트에게 맡길지. (필수 항목)
tools 쓸 수 있는 도구 목록. 여기 없는 도구는 못 씀
model 쓸 모델. inherit은 주 대화와 같은 모델을 상속

tools에서 Edit과 Write를 뺀 것이 핵심이다. 목록에 없으니 이 서브에이전트는 파일을 고칠 수 없다. 
본문에 "수정하지 마"라고 적는 것과는 차원이 다르다. 
본문은 부탁이고, tools에서 빼는 것은 차단이다.

 

프론트매터 항목에 background: true을 설정하면 서브에이전트를 백그라운드에서 실행하도록 명시적으로 설정할 수 있다.

 

Step 4. 서브에이전트 실행 해보기

먼저 재시작이 필요하다. 

클로드 코드는 서브에이전트 폴더의 변경을 감시하지만, 대화가 시작될 때 없었던 폴더는 감시 대상이 아니다. 

방금 .claude/agents/를 처음 만들었으므로 이번만 재시작이 필요하다.

명령 팔레트(Cmd+Shift+P)에서 Developer: Reload Window를 실행한다.

 

그 다음 커밋하지 않은 변경사항을 하나 만든다.

 

이제 새 대화(Cmd+Shift+Esc)를 열고 다음 프롬프트를 보낸다.

code-reviewer 서브에이전트로 변경사항을 검토해줘.

 

그러면 다음과 같이 Agent 도구를 호출해 서브에이전트가 작업을 한 뒤 결과를 주 대화에 넘겨준다.

 

Step 5. 스킬과 서브에이전트의 차이

  스킬 서브에이전트
어디서 도나 주 대화 안에서 별도의 공간에서
주 대화에 남는 것 전 과정 결과 요약만
이전 대화 내용을 아는가 안다 모른다
적합한 작업 이어서 대화할 작업 한 번에 끝나는 작업

서브에이전트가 이전 대화를 모른다는 점이 중요하다. 매번 백지에서 시작한다. 

 

그래서 이런 작업에는 맞지 않는다.

  • 여러 번 주고받으며 다듬어야 하는 작업
  • 앞의 논의 맥락이 있어야 이해되는 작업
  • 빠르게 한 줄 고치는 작업 (백지에서 시작하느라 오히려 느리다)

이전에 /tdd 스킬을 서브에이전트로 만들지 않은 이유가 이것이다.

TDD 절차는 중간에 승인을 받고 계속 이어가야 하므로 주 대화에 있어야 한다.

반대로 코드 리뷰는 서브에이전트에 적합하다. 이전 맥락이 필요 없고, 한 번에 끝나고, 과정이 아니라 결과만 필요하다.

 

Step 6. 주의할 점

서브에이전트가 고친 파일은 /rewind로 되돌릴 수 없다. 

서브에이전트의 편집은 주 대화의 체크포인트 바깥에서 일어나므로 git으로 되돌려야 한다.

방금 만든 code-reviewer는 tools에서 Edit과 Write를 뺐으므로 이러한 문제가 없다. 

파일을 고치는 서브에이전트를 만들 때는 이 점을 염두에 두어야 한다.

 

 

핵심 정리

1. 서브에이전트는 곁가지 작업을 별도 공간에서 처리하고 결과만 돌려준다.
읽은 파일과 명령 출력은 그쪽에 남고 주 대화로 넘어오지 않는다.

2. 과정이 남지 않고 결과만 필요한 경우에 쓴다.
탐색, 검색, 테스트 실행, 로그 분석처럼 출력은 많고 결론은 짧은 작업.

3. 내장 서브에이전트가 이미 동작하고 있다.
Explore(읽기 전용 검색), Plan(계획 전 조사), General-purpose(복합 작업). Explore와 Plan은 CLAUDE.md를 읽지 않는다.

4. 파일은 .claude/agents/이름.md에 둔다.
name과 description이 필수. ~/.claude/agents/에 두면 모든 프로젝트에서 쓸 수 있다.

5. 본문은 지시가 아니라 성격 설정이다.
스킬 본문이 "이걸 해라"라면, 서브에이전트 본문은 "너는 어떤 역할이다"이다.

6. tools에서 제거하는 것은 부탁이 아니라 차단이다.
목록에 없는 도구는 쓸 수 없다. 본문에 "수정하지 마"라고 적는 것보다 확실하다.

7. 서브에이전트는 이전 대화를 모른다.
매번 백지에서 시작한다. 맥락이 필요한 작업, 주고받으며 다듬는 작업에는 맞지 않는다.

8. 스킬과의 구분 기준은 "과정도 필요한가"이다.
이어서 대화할 작업은 스킬(주 대화), 한 번에 끝나고 결과만 필요한 작업은 서브에이전트.

9. 서브에이전트의 편집은 /rewind로 안 돌아간다.
git으로 되돌려야 한다. 읽기 전용으로 만들면 이 문제 자체가 없어진다.