이 글은 Claude Opus 4.5 을 이용해 초안이 작성되었으며, 이후 퇴고를 거쳤습니다.

예상 소요 시간: 1시간 난이도: ⭐⭐⭐ 사전 요구사항: Part 1, 2 완료 Claude Code 버전: 2.1.x (Hot Reload 지원)


1. Skills란 무엇인가?#

1.1 CLAUDE.md vs Skills의 핵심 차이#

CLAUDE.md는 항상 로드되는 “기본 매뉴얼"입니다. 반면 Skills는 필요할 때만 로드되는 “전문 레시피북"입니다.

💡 Claude Code 2.1+ 새 기능: Hot Reload - Skills를 수정하면 Claude Code를 재시작하지 않아도 즉시 반영됩니다. ~/.claude/skills/ 또는 .claude/skills/ 디렉토리의 변경사항이 실시간으로 적용됩니다.

flowchart LR
    subgraph ClaudeMD["📄 CLAUDE.md"]
        direction LR
        C1["• 항상 전체 내용이 로드됨"]
        C2["• 프로젝트 기본 정보 (빌드, 테스트, 구조)"]
        C3["• 모든 대화에 적용되는 규칙"]
        C4["• 간결하게 유지해야 함 (Part 2 참조)"]
    end

    ClaudeMD -->|"보완"| Skills

    subgraph Skills["🧠 Skills"]
        direction LR
        S1["• 필요할 때만 로드됨 (Progressive Disclosure)"]
        S2["• 특정 작업에 대한 상세 지식"]
        S3["• Claude가 description 보고 자동 판단"]
        S4["• 토큰 효율적"]
    end

    style ClaudeMD fill:#bbdefb,color:#000000
    style Skills fill:#c8e6c9,color:#000000
    style C1 fill:#e3f2fd,color:#000000
    style C2 fill:#e3f2fd,color:#000000
    style C3 fill:#e3f2fd,color:#000000
    style C4 fill:#e3f2fd,color:#000000
    style S1 fill:#e8f5e9,color:#000000
    style S2 fill:#e8f5e9,color:#000000
    style S3 fill:#e8f5e9,color:#000000
    style S4 fill:#e8f5e9,color:#000000

1.2 Progressive Disclosure: 필요할 때만 로드되는 지식#

Skills는 2단계 로딩 시스템을 사용합니다:

flowchart TB
    subgraph LoadingMechanism["🔄 Skills 로딩 메커니즘"]
        direction TB

        subgraph Phase1["1단계: 메타데이터 스캔 (항상)"]
            Meta["name: go-error-handling<br/>description: Go 에러 처리 패턴.<br/>에러 핸들링, 에러 래핑,<br/>커스텀 에러 작업 시 사용"]
            Token1["~100 토큰"]
        end

        Match{"description이<br/>현재 작업과<br/>매칭되면"}

        subgraph Phase2["2단계: 전체 내용 로드 (필요시에만)"]
            Content["# Go Error Handling Patterns<br/><br/>## 기본 원칙<br/>- 에러는 즉시 처리<br/>- fmt.Errorf로 컨텍스트 추가<br/>...<br/>(상세 내용)"]
            Token2["<5k 토큰"]
        end

        Phase1 --> Match
        Match -->|Yes| Phase2
    end

    style Phase1 fill:#e3f2fd,color:#000000
    style Phase2 fill:#c8e6c9,color:#000000
    style Meta fill:#bbdefb,color:#000000
    style Content fill:#a5d6a7,color:#000000
    style Match fill:#fff9c4,color:#000000
    style Token1 fill:#e0e0e0,color:#000000
    style Token2 fill:#e0e0e0,color:#000000

1.3 토큰 절약 효과#

구분 토큰 사용 언제
메타데이터 ~100 토큰/Skill 항상 (모든 대화)
전체 내용 <5,000 토큰 활성화 시에만

10개의 Skill이 있어도 메타데이터만 ~1,000 토큰. 실제로 사용되는 Skill만 전체 로드됩니다.


2. Skills vs Subagents: 언제 무엇을 쓸까?#

2.1 개념 비교#

flowchart TD 
    subgraph Comparison["Skills vs Subagents"]
        subgraph SkillsBox["📖 Skills (레시피)"]
            SK_Icon["📖 지식/패턴"]
            SK1["• 메인 컨텍스트에 주입"]
            SK2["• 자동 호출 (description)"]
            SK3["• 가벼운 참조 지식"]
            SK4["• 도구 제한 가능"]
            SK_Ex["예: 코딩 컨벤션, API 패턴"]
        end
        subgraph SubagentsBox["👨‍💼 Subagents (전문가)"]
            SA_Icon["👨‍💼 독립 에이전트"]
            SA1["• 격리된 컨텍스트 윈도우"]
            SA2["• 명시적 위임 또는 자동"]
            SA3["• 복잡한 워크플로우 처리"]
            SA4["• 도구 권한 별도 설정"]
            SA_Ex["예: 코드 리뷰어, 디버거"]
        end
    end

    style SkillsBox fill:#c8e6c9,color:#000000
    style SubagentsBox fill:#fff9c4,color:#000000
    style SK_Icon fill:#a5d6a7,color:#000000
    style SA_Icon fill:#fff59d,color:#000000
    style SK_Ex fill:#e8f5e9,color:#000000
    style SA_Ex fill:#fffde7,color:#000000

2.2 선택 기준#

flowchart TB 
    subgraph Choice["🤔 무엇을 선택할까?"]

        Title["이 작업은..."]

        Q1["참조용 지식이 필요하다<br/>(패턴, 컨벤션, 가이드)"] --> A1["📖 Skill 사용"]

        Q2["독립적인 분석/처리가<br/>필요하다"] --> A2["👨‍💼 Subagent 사용"]

        Q3["여러 단계의 복잡한<br/>워크플로우다"] --> A3["👨‍💼 Subagent 사용"]

        Q4["메인 대화의 컨텍스트를<br/>오염시키고 싶지 않다"] --> A4["👨‍💼 Subagent 사용"]

        Q5["다른 에이전트/대화에서도<br/>재사용하고 싶다"] --> A5["📖 Skill 사용 (포터블)"]
    end

    style Title fill:#e3f2fd,color:#000000
    style Q1 fill:#fff9c4,color:#000000
    style Q2 fill:#fff9c4,color:#000000
    style Q3 fill:#fff9c4,color:#000000
    style Q4 fill:#fff9c4,color:#000000
    style Q5 fill:#fff9c4,color:#000000
    style A1 fill:#c8e6c9,color:#000000
    style A2 fill:#ffccbc,color:#000000
    style A3 fill:#ffccbc,color:#000000
    style A4 fill:#ffccbc,color:#000000
    style A5 fill:#c8e6c9,color:#000000

2.3 함께 사용하기#

Skills와 Subagents는 상호 보완적입니다:

flowchart TD
    User["👤 사용자: '이 PR을 리뷰해줘'"]

    User --> Subagent

    subgraph Subagent["👨‍💼 code-reviewer (Subagent)"]
        direction TB
        Analyze["격리된 컨텍스트에서 PR 분석"]

        subgraph SkillCall["📖 go-conventions (Skill) 호출"]
            Convention["Go 코딩 컨벤션 참조"]
        end

        Analyze --> SkillCall
        SkillCall --> Result["리뷰 결과 생성"]
    end

    Subagent --> Return["✅ 메인 대화에 결과만 반환<br/>(컨텍스트 오염 없음)"]

    style User fill:#e3f2fd,color:#000000
    style Subagent fill:#fff9c4,color:#000000
    style Analyze fill:#fffde7,color:#000000
    style SkillCall fill:#c8e6c9,color:#000000
    style Convention fill:#e8f5e9,color:#000000
    style Result fill:#fffde7,color:#000000
    style Return fill:#a5d6a7,color:#000000

3. 첫 번째 Skill 만들기#

3.1 디렉토리 구조#

~/.claude/skills/              # 전역 Skills (모든 프로젝트)
└── my-skill/
    └── SKILL.md

.claude/skills/                # 프로젝트 Skills
└── project-skill/
    ├── SKILL.md              # 필수
    ├── scripts/              # 선택: 실행 스크립트
    │   └── helper.py
    └── resources/            # 선택: 참조 파일
        └── template.json

3.2 SKILL.md 작성법#

SKILL.md는 두 부분으로 구성됩니다:

---
name: skill-name
description: 이 스킬이 무엇을 하는지, 언제 사용하는지 설명
---

# Skill 제목

여기에 Claude가 따라야 할 상세 지침을 작성합니다.

## 섹션 1
...

## 섹션 2
...

3.3 YAML Frontmatter 필드#

필드 필수 설명
name Skill 이름 (슬래시 커맨드가 됨: /skill-name)
description Claude가 자동 호출 판단에 사용
disable-model-invocation true면 자동 호출 비활성화
allowed-tools 사용 가능한 도구 제한
user-invocable 메뉴에 표시 여부

💡 Claude Code 2.1+ 새 기능: Skills 내에서 ${CLAUDE_SESSION_ID} 변수를 사용하여 현재 세션 ID에 접근할 수 있습니다. 세션별 로깅이나 상태 관리에 유용합니다.

3.4 기본 예제: 코드 설명 Skill#

---
name: explain-code
description: 코드를 시각적 다이어그램과 비유로 설명합니다.
             코드 동작 방식을 설명하거나, 코드베이스를 가르치거나,
             "이게 어떻게 동작해?" 질문에 사용합니다.
---

# 코드 설명 Skill

코드를 설명할 때 항상 다음 구조를 따르세요:

## 1. 비유로 시작
코드를 일상생활의 무언가에 비유하여 시작합니다.

## 2. 다이어그램 그리기
ASCII 아트로 흐름, 구조, 관계를 시각화합니다.

## 3. 단계별 설명
코드가 어떻게 동작하는지 단계별로 설명합니다.

## 4. 주의점 하이라이트
흔한 실수나 오해를 짚어줍니다.

## 예시

사용자: "이 함수 어떻게 동작해?"

응답:
"이 함수는 식당의 주문 시스템과 비슷합니다.

주문 접수 → 주방 전달 → 조리 → 서빙 │ │ │ │ validate enqueue process return


단계별로 보면..."

4. 실전 Skills 예제#

4.1 Java 프로젝트용 테스트 작성 Skill#

---
name: java-test-writer
description: Java 테스트 코드를 작성합니다.
             JUnit 5, MockK, Given-When-Then 패턴을 사용합니다.
             "테스트 작성해줘", "테스트 코드", "단위 테스트" 요청 시 사용.
---

# Java Test Writing Skill

## 테스트 클래스 구조

@ExtendWith(MockKExtension.class)
class {TargetClass}Test {

    @MockK
    private lateinit var dependency: DependencyType

    @InjectMockKs
    private lateinit var sut: TargetClass  // System Under Test

    @BeforeEach
    fun setUp() {
        // 공통 설정
    }

    @Test
    fun `should 결과 when 조건`() {
        // Given
        val input = ...

        // When
        val result = sut.methodUnderTest(input)

        // Then
        assertThat(result).isEqualTo(expected)
    }
}

## 네이밍 규칙

- 클래스: `{대상클래스}Test`
- 메서드: `should_{기대결과}_when_{조건}` (백틱 사용)
- 변수: `sut` (System Under Test)

## Given-When-Then 패턴

@Test
fun `should return user when valid id provided`() {
    // Given - 테스트 데이터 및 Mock 설정
    val userId = 1L
    val expectedUser = User(id = userId, name = "John")
    every { userRepository.findById(userId) } returns expectedUser

    // When - 테스트 대상 메서드 실행
    val result = userService.getUser(userId)

    // Then - 결과 검증
    assertThat(result).isEqualTo(expectedUser)
    verify(exactly = 1) { userRepository.findById(userId) }
}

## Mock 사용 규칙

- MockK 사용 (Mockito 금지)
- `every { }` / `verify { }` 구문
- `answers { }` for complex stubbing

## 금지 사항

- `@Autowired` in tests (use `@InjectMockKs`)
- Real database connections
- Thread.sleep() for async tests

4.2 Go 프로젝트용 에러 핸들링 Skill#

---
name: go-error-handling
description: Go 에러 처리 패턴을 적용합니다.
             에러 래핑, 커스텀 에러, 센티넬 에러 작업 시 사용.
             "에러 처리", "error handling", "에러 래핑" 요청 시 활성화.
---

# Go Error Handling Patterns

## 기본 원칙

1. 에러는 즉시 처리하거나 래핑하여 반환
2. 에러 메시지에 컨텍스트 추가
3. 절대로 에러를 무시하지 않음

## 에러 래핑 패턴

// ✅ 좋은 예: 컨텍스트 추가
if err != nil {
    return fmt.Errorf("failed to create user %s: %w", username, err)
}

// ❌ 나쁜 예: 컨텍스트 없음
if err != nil {
    return err
}

// ❌ 최악: 에러 무시
result, _ := someFunction()

## 커스텀 에러 타입

// 도메인 에러 정의
type UserNotFoundError struct {
    UserID int64
}

func (e *UserNotFoundError) Error() string {
    return fmt.Sprintf("user not found: %d", e.UserID)
}

// 사용
func GetUser(id int64) (*User, error) {
    user, err := repo.Find(id)
    if err != nil {
        if errors.Is(err, sql.ErrNoRows) {
            return nil, &UserNotFoundError{UserID: id}
        }
        return nil, fmt.Errorf("failed to get user: %w", err)
    }
    return user, nil
}

## 센티넬 에러

// 패키지 레벨에 정의
var (
    ErrNotFound     = errors.New("not found")
    ErrUnauthorized = errors.New("unauthorized")
    ErrInvalidInput = errors.New("invalid input")
)

// 사용
if errors.Is(err, ErrNotFound) {
    // 404 처리
}

## 에러 체크 패턴

// errors.Is - 에러 체인에서 특정 에러 찾기
if errors.Is(err, sql.ErrNoRows) { ... }

// errors.As - 특정 타입으로 캐스팅
var notFoundErr *UserNotFoundError
if errors.As(err, &notFoundErr) {
    log.Printf("User %d not found", notFoundErr.UserID)
}

## 금지 패턴

// ❌ panic 남용
panic("something went wrong")  // 복구 불가능한 경우만 사용

// ❌ 에러 문자열 비교
if err.Error() == "not found" { ... }  // errors.Is 사용

// ❌ 에러 로그 후 반환
log.Println(err)
return err  // 중복 로깅 발생, 한 곳에서만 로그

4.3 Redis 캐시 패턴 Skill#

---
name: redis-cache-patterns
description: Redis 캐시 구현 패턴을 제공합니다.
             캐시 키 설계, TTL 전략, Cache-Aside 패턴 작업 시 사용.
             "Redis", "캐시", "caching" 관련 요청 시 활성화.
---

# Redis Cache Patterns

## 캐시 키 네이밍 규칙

{service}:{entity}:{identifier}:{optional-suffix}

예시:
- user-service:user:12345
- payment:transaction:uuid-here:status
- inventory:product:SKU123:stock

## 키 프리픽스 상수화

public class CacheKeys {
    public static final String USER_PREFIX = "user-service:user:";
    public static final String SESSION_PREFIX = "user-service:session:";

    public static String userKey(Long userId) {
        return USER_PREFIX + userId;
    }
}

## Cache-Aside 패턴

public User getUser(Long userId) {
    String key = CacheKeys.userKey(userId);

    // 1. 캐시 조회
    User cached = redisTemplate.opsForValue().get(key);
    if (cached != null) {
        return cached;
    }

    // 2. DB 조회
    User user = userRepository.findById(userId)
        .orElseThrow(() -> new UserNotFoundException(userId));

    // 3. 캐시 저장
    redisTemplate.opsForValue().set(key, user, Duration.ofHours(1));

    return user;
}

## TTL 전략

| 데이터 유형 | TTL | 이유 |
|------------|-----|------|
| 세션 | 30분 | 보안 |
| 사용자 프로필 | 1시간 | 자주 변경되지 않음 |
| 상품 정보 | 5분 | 재고 등 변경 가능 |
| 설정값 | 24시간 | 거의 변경 없음 |

## 캐시 무효화

// 단일 키 삭제
public void evictUser(Long userId) {
    redisTemplate.delete(CacheKeys.userKey(userId));
}

// 패턴으로 삭제 (주의: 프로덕션에서 KEYS 명령 지양)
public void evictUserCache() {
    Set<String> keys = redisTemplate.keys("user-service:user:*");
    if (keys != null && !keys.isEmpty()) {
        redisTemplate.delete(keys);
    }
}

// 권장: SCAN 사용
public void evictByPattern(String pattern) {
    ScanOptions options = ScanOptions.scanOptions()
        .match(pattern)
        .count(100)
        .build();

    try (Cursor<String> cursor = redisTemplate.scan(options)) {
        while (cursor.hasNext()) {
            redisTemplate.delete(cursor.next());
        }
    }
}

## 주의사항

- 프로덕션에서 `KEYS *` 명령 금지 (블로킹)
- 대량 삭제 시 `SCAN` + 배치 삭제 사용
- 캐시 워밍업 전략 고려

4.4 API 설계 컨벤션 Skill#

---
name: api-conventions
description: REST API 설계 컨벤션을 제공합니다.
             API 엔드포인트 설계, 응답 형식, 에러 처리 시 사용.
             "API 만들어줘", "엔드포인트", "REST" 요청 시 활성화.
---

# REST API Design Conventions

## URL 설계 원칙

GET    /api/v1/users          # 목록 조회
GET    /api/v1/users/{id}     # 단일 조회
POST   /api/v1/users          # 생성
PUT    /api/v1/users/{id}     # 전체 수정
PATCH  /api/v1/users/{id}     # 부분 수정
DELETE /api/v1/users/{id}     # 삭제

# 하위 리소스
GET    /api/v1/users/{id}/orders
POST   /api/v1/users/{id}/orders

# 액션 (동사가 필요한 경우)
POST   /api/v1/users/{id}/activate
POST   /api/v1/orders/{id}/cancel

## 응답 형식

### 성공 응답

{
  "success": true,
  "data": {
    "id": 1,
    "name": "John Doe",
    "email": "john@example.com"
  },
  "meta": {
    "requestId": "req-uuid",
    "timestamp": "2025-01-23T10:00:00Z"
  }
}

### 목록 응답 (페이징)

{
  "success": true,
  "data": [...],
  "pagination": {
    "page": 1,
    "size": 20,
    "totalElements": 100,
    "totalPages": 5
  }
}

### 에러 응답 (RFC 7807 Problem Details)

{
  "success": false,
  "error": {
    "type": "https://api.example.com/errors/validation",
    "title": "Validation Error",
    "status": 400,
    "detail": "The request body contains invalid fields",
    "instance": "/api/v1/users",
    "errors": [
      {
        "field": "email",
        "message": "must be a valid email address"
      }
    ]
  }
}

## HTTP 상태 코드

| 코드 | 의미 | 사용 시점 |
|------|------|----------|
| 200 | OK | GET 성공, PUT/PATCH 성공 |
| 201 | Created | POST 생성 성공 |
| 204 | No Content | DELETE 성공 |
| 400 | Bad Request | 요청 형식 오류, 유효성 검증 실패 |
| 401 | Unauthorized | 인증 필요 |
| 403 | Forbidden | 권한 없음 |
| 404 | Not Found | 리소스 없음 |
| 409 | Conflict | 중복, 상태 충돌 |
| 422 | Unprocessable Entity | 비즈니스 규칙 위반 |
| 500 | Internal Server Error | 서버 오류 |

## 쿼리 파라미터

# 페이징
GET /api/v1/users?page=1&size=20

# 정렬
GET /api/v1/users?sort=createdAt,desc

# 필터링
GET /api/v1/users?status=active&role=admin

# 검색
GET /api/v1/users?q=john

## 버전 관리

- URL 경로: `/api/v1/`, `/api/v2/`
- 주요 변경 시에만 버전 증가
- 이전 버전 최소 6개월 지원

5. Skills에 스크립트와 리소스 추가하기#

5.1 scripts/ 디렉토리 활용#

Skills는 실행 가능한 스크립트를 포함할 수 있습니다:

~/.claude/skills/codebase-visualizer/
├── SKILL.md
└── scripts/
    └── generate-tree.py

SKILL.md:

---
name: codebase-visualizer
description: 코드베이스의 인터랙티브 트리 시각화를 생성합니다.
             "코드 구조 보여줘", "프로젝트 구조 시각화" 요청 시 사용.
---

# Codebase Visualizer

코드베이스 구조를 시각화하려면 번들된 스크립트를 실행하세요:

python ~/.claude/skills/codebase-visualizer/scripts/generate-tree.py

생성된 HTML 파일을 브라우저에서 열어 인터랙티브하게 탐색할 수 있습니다.

5.2 resources/ 디렉토리로 템플릿 제공#

~/.claude/skills/api-scaffold/
├── SKILL.md
└── resources/
    ├── controller-template.java
    ├── service-template.java
    └── dto-template.java

SKILL.md:

---
name: api-scaffold
description: 새 API 엔드포인트를 위한 Controller, Service, DTO를 생성합니다.
             "새 API 만들어줘", "CRUD 생성" 요청 시 사용.
---

# API Scaffolding

템플릿 파일들을 참조하여 일관된 구조로 생성하세요:

- Controller: `resources/controller-template.java`
- Service: `resources/service-template.java`
- DTO: `resources/dto-template.java`

## 생성 순서

1. DTO 먼저 생성 (Request, Response)
2. Service 인터페이스 및 구현체
3. Controller
4. 테스트 코드

5.3 실행 가능한 유틸리티 스크립트 번들링#

더 복잡한 스킬은 여러 스크립트를 포함할 수 있습니다:

~/.claude/skills/db-migration-helper/
├── SKILL.md
└── scripts/
    ├── check-migration.sh      # 마이그레이션 상태 확인
    ├── generate-migration.py   # 새 마이그레이션 생성
    └── rollback.sh             # 롤백 실행

6. Skills 호출 제어#

6.1 invocation: auto vs manual#

기본적으로 Claude는 description을 보고 자동으로 Skill을 호출합니다. 이를 제어할 수 있습니다:

---
name: dangerous-operation
description: 위험한 작업을 수행합니다.
disable-model-invocation: true  # 자동 호출 비활성화
---

# 이 Skill은 /dangerous-operation으로만 호출 가능

6.2 allowed-tools로 도구 제한#

읽기 전용 Skill을 만들 수 있습니다:

---
name: safe-analyzer
description: 코드를 분석합니다 (수정 없음).
allowed-tools: Read, Grep, Glob
---

# Code Analyzer

이 Skill은 코드를 읽고 분석만 합니다. 수정 권한이 없습니다.

사용 가능한 도구들:

  • Read: 파일 읽기
  • Write: 파일 쓰기
  • Edit: 파일 수정
  • Bash: 명령 실행
  • Glob: 파일 패턴 검색
  • Grep: 텍스트 검색

6.3 Permission 설정#

/permissions 명령으로 특정 Skill의 사용을 제어할 수 있습니다:

# 특정 Skill만 허용
Skill(commit)
Skill(review-pr:*)

# 특정 Skill 차단
Skill(deploy:*)

7. 실습: 기존 CLAUDE.md에서 Skills 분리하기#

7.1 Before: 모든 것이 CLAUDE.md에#

# CLAUDE.md (200줄)

## 프로젝트 정보
...

## 빌드/테스트
...

## Go 에러 처리 규칙 (50줄)
- 에러는 즉시 처리
- fmt.Errorf로 래핑
- ... (상세 규칙들)

## API 설계 규칙 (60줄)
- REST 원칙
- 응답 형식
- ... (상세 규칙들)

## 테스트 작성 규칙 (40줄)
- Given-When-Then
- ... (상세 규칙들)

7.2 After: Skills로 분리#

CLAUDE.md (50줄):

# User Service

Go 1.22 기반 사용자 관리 서비스

## 빌드 및 테스트

- 빌드: `go build ./cmd/server`
- 테스트: `go test ./...`
- 린트: `golangci-lint run`

## 프로젝트 구조

cmd/server/    # 진입점
internal/      # 내부 패키지
pkg/           # 공개 패키지
api/           # OpenAPI specs

## 핵심 규칙

IMPORTANT: 에러 처리, API 설계, 테스트 작성 시
해당 Skills가 자동으로 활성화됩니다.

.claude/skills/go-error-handling/SKILL.md:

---
name: go-error-handling
description: Go 에러 처리 패턴. 에러 래핑, 커스텀 에러 작업 시 사용.
---

(Part 4.2의 내용)

.claude/skills/api-conventions/SKILL.md:

---
name: api-conventions
description: REST API 설계 규칙. 엔드포인트, 응답 형식 설계 시 사용.
---

(Part 4.4의 내용)

.claude/skills/go-test-writer/SKILL.md:

---
name: go-test-writer
description: Go 테스트 작성. 테이블 기반 테스트, Mock 사용 시.
---

(테스트 관련 상세 규칙)

7.3 결과 비교#

항목 Before After
CLAUDE.md 크기 200줄 50줄
항상 로드되는 토큰 ~4,000 ~1,000 + (Skill 메타데이터 ~300)
에러 처리 코드 작성 시 전체 200줄 로드 필요한 Skill만 로드
유지보수 한 파일에서 관리 주제별 분리로 명확

8. 정리#

이번 파트에서 배운 것#

  1. Skills는 Progressive Disclosure: 메타데이터만 스캔, 필요시 전체 로드
  2. Skills vs Subagents: Skills는 참조 지식, Subagents는 독립 에이전트
  3. SKILL.md 구조: YAML Frontmatter + Markdown 지침
  4. 스크립트/리소스 번들링: 실행 파일과 템플릿 포함 가능
  5. 호출 제어: disable-model-invocation, allowed-tools

핵심 원칙#

CLAUDE.md에는 “항상 필요한 것"만, Skills에는 “때때로 필요한 것"을

다음 파트 예고#

Skills를 만들었다면, 이제 커뮤니티가 만든 플러그인을 활용하고 나만의 규칙과 조합하는 방법을 배웁니다. Part 4에서는 Plugins & Marketplace를 다룹니다.


참고 자료#


이전: Part 2: CLAUDE.md 최적화 다음: Part 4: Plugins & Marketplace