한 에이전트가 모든 파일을 직접 읽어야 할까

저장소에 수백 개의 파일이 있고, 그중 서로 관련 없는 세 모듈을 동시에 수정해야 하는 상황을 떠올려 보자. 하나의 에이전트가 파일을 하나씩 열고, 읽고, 수정하고, 다시 다음 파일로 넘어가는 방식은 느리다. 컨텍스트 윈도우에 쌓이는 토큰도 빠르게 불어나서, 작업 후반부에는 앞에서 읽은 내용이 압축되거나 밀려난다.

Claude Code의 서브에이전트는 이 병목을 해소하기 위한 구조다. 메인 에이전트가 모든 작업을 혼자 처리하는 대신, 독립적인 하위 에이전트를 띄워서 작업을 나눈다. 각 서브에이전트는 자기만의 컨텍스트 윈도우에서 작업하고, 끝나면 결과 요약만 메인에게 돌려준다.

한 가지 선을 먼저 긋자면, 이전에 다룬 Claude Agent SDK와는 다른 영역이다. Agent SDK는 Python이나 TypeScript 코드로 Claude Code를 외부에서 프로그래밍 방식으로 제어하는 도구이고, 서브에이전트는 Claude Code CLI 내부에서 자동으로 생성되고 관리되는 메커니즘이다. 별도 코드를 작성할 필요가 없다.


서브에이전트의 구조

메인 에이전트와 서브에이전트의 관계

서브에이전트의 동작 방식은 오케스트레이터/워커 패턴에 가깝다. 메인 에이전트가 작업을 분석하고, 적절한 서브에이전트에게 위임하고, 결과를 수집해서 다음 단계를 결정한다.

graph TD
    M["메인 에이전트
(오케스트레이터)"] --> A["서브에이전트 A"] M --> B["서브에이전트 B"] M --> C["서브에이전트 C"] A -->|결과 요약| D["메인 에이전트가 결과를 종합하여
다음 행동 결정"] B -->|결과 요약| D C -->|결과 요약| D

서브에이전트는 메인 에이전트의 대화 히스토리를 물려받지 않는다. 같은 프로젝트 디렉터리에서 실행되므로 CLAUDE.md 같은 프로젝트 설정에는 접근할 수 있지만, 대화 컨텍스트는 각자 별도로 갖는다. 덕분에 메인 에이전트의 컨텍스트 윈도우가 서브에이전트의 작업 내용으로 오염되지 않는다. 서브에이전트가 수백 줄의 테스트 로그를 읽더라도, 메인 에이전트에게 돌아오는 것은 압축된 요약뿐이다.

내장 서브에이전트 세 가지

Claude Code에는 용도별로 세 종류의 내장 서브에이전트가 있다.

  • Explore는 읽기 전용 탐색 에이전트다. Haiku 모델을 사용하며, Read, Glob, Grep 같은 읽기 도구만 쓸 수 있다. Write나 Edit는 차단되어 있어서 코드를 수정할 수 없다. 파일 검색, 코드 구조 파악, 키워드 탐색처럼 빠르게 정보를 훑어야 할 때 메인 에이전트가 자동으로 띄운다. 가벼운 모델을 쓰므로 비용도 낮다.
  • Plan은 설계 전용 에이전트다. 메인 에이전트의 모델을 그대로 상속하되, 역시 읽기 전용이다. Plan mode에서 코드베이스를 분석하고 구현 전략을 세울 때 사용된다. 직접 파일을 수정하지 않으므로 탐색 과정에서 실수로 코드가 바뀌는 일이 없다.
  • 범용(General-purpose)은 모든 도구를 사용할 수 있는 에이전트다. Read, Write, Edit, Bash 등 제한 없이 접근한다. 복잡한 멀티스텝 작업, 코드 수정이 필요한 리서치, 여러 파일에 걸친 리팩터링 등에 쓰인다. 메인 에이전트의 모델을 상속하며, 사실상 메인 에이전트와 동일한 능력을 가진 독립 워커다.

세 에이전트를 한눈에 비교하면 이렇다.

에이전트 모델 도구 범위 용도
Explore Haiku 읽기 전용 파일 탐색, 코드 검색
Plan 상속 읽기 전용 구조 분석, 설계
범용 상속 전체 코드 수정, 멀티스텝 작업

메인 에이전트는 언제 서브에이전트를 띄우는가

메인 에이전트가 서브에이전트를 띄우는 판단은 자동으로 이루어진다. 대체로 다음과 같은 상황에서 위임이 발생한다.

파일을 넓은 범위에서 탐색해야 할 때 Explore가 뜬다. “이 프로젝트에서 결제 관련 코드가 어디 있지?” 같은 질문이 그렇다. 메인 에이전트가 직접 Glob과 Grep을 반복하며 찾는 것보다, Explore에게 넘기면 메인의 컨텍스트를 아낄 수 있다.

작업이 서로 독립적인 여러 단위로 나뉠 때 범용 서브에이전트가 뜬다. 예를 들어 세 개의 모듈을 각각 수정해야 하는데 모듈 간 의존성이 없다면, 메인 에이전트가 범용 서브에이전트 셋을 띄워서 각각에게 하나씩 맡기는 식이다.

서브에이전트가 또 다른 서브에이전트를 띄우는 중첩은 허용되지 않는다. 깊이는 항상 1단계다.


워크트리 격리

여러 서브에이전트가 같은 저장소의 파일을 동시에 수정하면 충돌이 생길 수 있다. 워크트리 격리는 이 문제를 git worktree로 해결한다.

isolation: worktree 옵션이 설정된 서브에이전트는 .claude/worktrees/<이름>/ 경로에 임시 워크트리를 생성한다. 기본 원격 브랜치에서 분기한 worktree-<이름> 브랜치 위에서 작업하므로, 다른 서브에이전트나 메인 에이전트의 작업 디렉터리와 완전히 분리된다.

서브에이전트가 끝나면 두 가지 경로로 나뉜다. 변경 사항이 없으면 워크트리와 브랜치가 자동으로 정리된다. 변경 사항이 있으면 워크트리 경로와 브랜치 이름이 결과에 포함되어 돌아온다. 이후 해당 브랜치를 메인 브랜치에 병합할 수도 있고, 필요 없다면 워크트리를 제거할 수도 있다.

flowchart TD
    S["서브에이전트 작업 완료"] --> D{"변경 사항 있음?"}
    D -->|없음| C["워크트리 + 브랜치
자동 정리"] D -->|있음| K["워크트리 경로와
브랜치 이름 반환"] K --> MG["메인 브랜치에 병합"] K --> DEL["워크트리 제거"]

서브에이전트 세 개가 각각 다른 모듈을 수정하는 상황이라면, 셋 모두 워크트리 격리를 걸어 두는 편이 안전하다. 파일 충돌 없이 독립적으로 작업한 뒤, 메인 에이전트가 각 워크트리의 결과를 확인하고 병합 여부를 결정할 수 있다.


커스텀 서브에이전트 만들기

.claude/agents/ 디렉터리와 마크다운 포맷

내장 에이전트로 충분하지 않다면 직접 만들 수 있다. .claude/agents/ 디렉터리에 마크다운 파일을 추가하면 프로젝트 범위의 커스텀 서브에이전트가 등록된다. 사용자 전체에 적용하려면 ~/.claude/agents/에 둔다.

파일 형식은 YAML 프론트매터와 본문 프롬프트로 구성된다.

---
name: catalog-reviewer
description: 상품 카탈로그 코드를 리뷰하고 품질 피드백을 제공한다
tools: Read, Grep, Glob, Bash
model: sonnet
---

상품 카탈로그 모듈의 코드 리뷰어다.
catalog/ 디렉터리 아래의 코드를 분석하고,
네이밍 컨벤션, 예외 처리, 테스트 커버리지 관점에서 피드백을 제공한다.
파일을 직접 수정하지 않고 리뷰 결과만 텍스트로 돌려준다.

프론트매터의 주요 필드를 정리하면 아래와 같다.

  • name: 에이전트 이름. 소문자와 하이픈만 사용한다
  • description: 메인 에이전트가 위임 판단에 사용하는 설명
  • tools: 허용할 도구 목록
  • disallowedTools: 명시적으로 차단할 도구 목록
  • model: sonnet, opus, haiku 또는 inherit(상속)
  • isolation: worktree로 설정하면 워크트리 격리 적용
  • maxTurns: 에이전트가 반복할 수 있는 최대 턴 수
  • background: true로 설정하면 항상 백그라운드에서 실행

/agents 명령어로 인터랙티브하게 생성할 수도 있고, 파일을 직접 만들어도 된다. description이 정확할수록 메인 에이전트가 적절한 시점에 자동으로 위임한다.

도구 제한과 모델 선택

커스텀 서브에이전트의 핵심은 도구 범위와 모델을 목적에 맞게 좁히는 것이다.

읽기 전용 리뷰어를 만들고 싶다면 tools에 Read, Grep, Glob만 넣고 Write와 Edit를 빼면 된다. 이렇게 하면 에이전트가 아무리 파일을 수정하고 싶어도 도구 자체가 없으므로 불가능하다.

---
name: security-auditor
description: 보안 취약점을 탐지하는 읽기 전용 감사 에이전트
tools: Read, Grep, Glob
model: haiku
---

코드에서 하드코딩된 시크릿, SQL 인젝션 가능성, 인증 우회 패턴을 탐색한다.
발견한 문제를 심각도와 함께 보고한다. 코드를 직접 수정하지 않는다.

모델 선택도 비용과 직결된다. 단순 탐색이라면 haiku로 충분하고, 설계 판단이 필요한 작업이라면 opus가 적합하다. inherit로 설정하면 메인 에이전트의 모델을 그대로 쓴다.

특정 디렉터리만 담당하는 에이전트도 유용하다. 쇼핑몰 상품 카탈로그 시스템을 예로 들면, 상품 목록, 카테고리 분류, 재고 관리 각각에 전문 에이전트를 만들 수 있다.

---
name: inventory-specialist
description: 재고 관리 모듈 전문 에이전트. inventory/ 디렉터리의 코드를 수정한다
tools: Read, Write, Edit, Bash, Grep, Glob
isolation: worktree
---

inventory/ 디렉터리의 재고 관리 코드를 담당한다.
재고 차감, 입고 처리, 재고 부족 알림 로직을 이해하고 있다.
다른 모듈(catalog/, category/)은 건드리지 않는다.


실전 시나리오

멀티 모듈 코드 변경

쇼핑몰 플랫폼에서 상품 가격 표시 형식을 일괄 변경해야 하는 상황을 생각해 보자. 상품 목록(catalog/), 카테고리 필터(category/), 재고 관리(inventory/) 세 모듈이 각각 가격 포맷팅 로직을 갖고 있다. 모듈 간 의존성은 없고, 각 모듈 안에서 독립적으로 수정하면 된다.

메인 에이전트에게 “상품 가격 표시를 원화 포맷으로 통일해 줘”라고 요청하면, 메인 에이전트는 작업을 분석한 뒤 범용 서브에이전트 세 개를 띄울 수 있다. 각 서브에이전트가 워크트리 격리 상태에서 담당 모듈을 수정하고, 끝나면 변경 요약을 메인에게 보고한다.

graph TD
    M["메인 에이전트"] -->|catalog/| S1["서브에이전트 1"]
    M -->|category/| S2["서브에이전트 2"]
    M -->|inventory/| S3["서브에이전트 3"]
    S1 --> R1["가격 포맷 함수 3개 수정
테스트 통과"] S2 --> R2["필터 표시 로직 1개 수정
테스트 통과"] S3 --> R3["재고 단가 표시 2개 수정
테스트 통과"]

메인 에이전트가 직접 세 모듈을 순서대로 수정하는 것보다 빠르고, 각 서브에이전트의 작업 내용이 메인의 컨텍스트를 차지하지 않으므로 윈도우도 깨끗하게 유지된다.

코드 리뷰 + 테스트 생성

기존 코드에 테스트를 추가하는 작업에서도 서브에이전트 조합이 효과적이다.

먼저 Explore 서브에이전트가 변경된 파일의 영향 범위를 파악한다. “이 메서드를 호출하는 곳이 어디인지”, “관련된 설정 파일이 있는지”를 빠르게 훑어서 보고한다. Explore가 돌려준 범위 정보를 바탕으로, 메인 에이전트가 범용 서브에이전트에게 테스트 작성을 위임한다.

sequenceDiagram
    participant M as 메인 에이전트
    participant E as Explore
    participant G as 범용 서브에이전트
    M->>E: 변경된 파일의 영향 범위 파악
    E-->>M: 호출 위치 5곳, 설정은 application.yml
    M->>G: 범위 정보 기반 테스트 작성 위임
    G-->>M: 테스트 작성 완료

이 패턴의 장점은 탐색 과정에서 발생하는 대량의 파일 읽기 결과가 메인 컨텍스트에 쌓이지 않는다는 것이다. Explore가 수십 개 파일을 열어봤더라도 메인 에이전트에게 돌아오는 것은 “이 메서드는 5곳에서 호출되고, 설정은 application.yml에 있다”는 요약뿐이다.


한계와 주의점

서브에이전트 간 직접 통신은 불가능하다. 서브에이전트 A의 결과를 서브에이전트 B가 참조해야 한다면, A가 먼저 끝나고 메인 에이전트가 그 결과를 B의 프롬프트에 포함시켜야 한다. 에이전트 간 실시간 대화가 필요한 수준의 협업이라면 서브에이전트만으로는 부족하다.

서브에이전트는 결과를 요약해서 반환하므로, 세부적인 중간 과정은 메인 에이전트가 볼 수 없다. “왜 이렇게 수정했는지” 상세한 추론 과정이 필요하다면 서브에이전트의 트랜스크립트를 별도로 확인해야 한다.

토큰 비용도 간과하기 어렵다. 서브에이전트 하나가 자기만의 컨텍스트 윈도우를 소비하므로, 서브에이전트를 세 개 띄우면 대략 세 배의 토큰이 든다. 단순한 작업에 서브에이전트를 남발하면 메인 에이전트가 혼자 처리하는 것보다 비용이 더 나올 수 있다. 작업의 규모와 독립성을 따져서, 위임의 이득이 오버헤드보다 클 때만 활용하는 편이 합리적이다.

백그라운드로 실행하는 서브에이전트(background: true 또는 Ctrl+B)는 권한 프롬프트를 사용자에게 전달할 수 없다. 사전 승인되지 않은 도구를 호출하면 자동으로 거부되므로, 백그라운드 에이전트에는 필요한 도구를 미리 허용해 두어야 한다.


위임하는 에이전트가 더 멀리 간다

서브에이전트의 존재 이유는 결국 컨텍스트 격리에 있다. 하나의 에이전트가 모든 것을 알아야 할 필요는 없다. 탐색은 가벼운 에이전트에게, 수정은 전문 에이전트에게, 감사는 읽기 전용 에이전트에게 맡기면 각자의 컨텍스트 윈도우가 자기 작업에만 집중한다.

모든 작업에 서브에이전트가 필요한 것은 아니다. 파일 하나를 고치는 작업에 서브에이전트를 띄우면 오히려 느려진다. 반대로 탐색 범위가 넓거나 독립적인 수정이 여러 곳에 걸쳐 있을 때는, 위임하지 않는 쪽이 더 큰 비용을 치르게 된다. 그 경계를 감으로 잡아가는 과정이 이 도구에 익숙해지는 과정이 아닐까 싶다.


참고