VS Code 에이전트 스킬(Agent Skills) 개발자 가이드
관련영상
Introducing Agent Skills in VS Code
들어가며
Visual Studio Code의 에이전트 스킬은 AI 기반 개발 환경에서 전문화된 작업을 자동화하기 위한 새로운 패러다임을 제시합니다. 기존의 일반적인 코딩 어시스턴트 방식을 넘어서, 특정 도메인이나 작업에 최적화된 워크플로우를 구축할 수 있게 해주는 이 기능은 개발자의 생산성을 획기적으로 향상시킬 수 있는 잠재력을 가지고 있습니다.
에이전트 스킬은 단순한 텍스트 기반 지침을 넘어서, 실행 가능한 스크립트, 리소스 파일, 그리고 체계적인 워크플로우를 하나의 패키지로 묶어 제공합니다. 이를 통해 AI 에이전트는 필요한 순간에 적절한 도구와 지식을 동적으로 로드하여 복잡한 작업을 수행할 수 있게 됩니다.
에이전트 스킬의 핵심 개념
온디맨드 전문성
에이전트 스킬의 가장 큰 특징은 필요할 때만 로드되는 ‘온디맨드(On-demand)’ 방식입니다. 모든 지식과 도구를 항상 메모리에 유지하는 대신, 특정 작업이 요청될 때 해당 작업에 필요한 스킬만 선택적으로 활성화됩니다. 이는 AI 에이전트의 컨텍스트 윈도우를 효율적으로 활용하면서도, 다양한 전문 분야에서 높은 수준의 성능을 발휘할 수 있게 해줍니다.
예를 들어, 개발자가 이미지 처리 작업을 요청하면 ImageMagick 관련 스킬이 로드되고, PRD(제품 요구사항 문서) 작성을 요청하면 문서 작성 워크플로우 스킬이 활성화됩니다. 이러한 방식은 각 작업에 대해 최적화된 전문성을 제공하면서도, 시스템 리소스를 효율적으로 사용할 수 있게 합니다.
워크플로우 중심 설계
에이전트 스킬은 단일 명령을 실행하는 것을 넘어서, 복잡한 작업을 여러 단계로 나누어 체계적으로 수행하도록 설계되었습니다. 각 스킬은 작업을 완수하기 위한 단계별 워크플로우를 정의하며, AI 에이전트는 이 워크플로우를 따라 순차적으로 작업을 진행합니다.
전형적인 워크플로우는 컨텍스트 수집 단계에서 시작하여, 초안 작성, 검증 및 개선, 최종 결과물 생성의 단계를 거칩니다. 이러한 구조화된 접근 방식은 일관성 있고 고품질의 결과물을 생성하는 데 크게 기여합니다.
개방형 표준과 이식성
에이전트 스킬은 특정 도구에 종속되지 않는 개방형 표준으로 설계되었습니다. VS Code에서 작성한 스킬은 GitHub Copilot 클라우드 에이전트, CLI 환경, 그리고 향후 추가될 다양한 도구에서도 동일하게 사용할 수 있습니다. 이는 한 번 작성한 스킬을 여러 환경에서 재사용할 수 있어, 투자 대비 효과를 극대화할 수 있습니다.
설치 및 환경 설정
기능 활성화
VS Code에서 에이전트 스킬 기능을 사용하기 위해서는 먼저 설정을 통해 이를 활성화해야 합니다. VS Code를 실행한 후 설정 화면으로 이동하여 ‘Use Agent Skills’ 옵션을 찾아 활성화합니다. 설정 화면은 Ctrl+,(Windows/Linux) 또는 Cmd+,(macOS) 단축키로 빠르게 열 수 있습니다.
설정 검색창에 ‘agent skills’를 입력하면 관련 옵션을 쉽게 찾을 수 있습니다. 체크박스를 활성화하면 VS Code는 에이전트 스킬을 인식하고 사용할 준비가 완료됩니다.
폴더 구조 구성
에이전트 스킬을 사용하기 위해서는 프로젝트 내에 특정한 폴더 구조를 만들어야 합니다. 루트 디렉터리 또는 AI 에이전트 프롬프트가 저장된 디렉터리에 skills라는 이름의 폴더를 생성합니다. 이 폴더가 모든 스킬의 컨테이너 역할을 하게 됩니다.
skills 폴더 내부에는 각 스킬마다 별도의 하위 폴더를 만듭니다. 폴더 이름은 스킬의 목적을 명확하게 나타내는 것이 좋습니다. 예를 들어, PRD 작성 스킬은 prd-writing, 이미지 처리 스킬은 image-magic, 웹 테스트 스킬은 web-testing과 같은 이름을 사용할 수 있습니다.
1
2
3
4
5
6
7
8
9
10
11
12
project-root/
├── skills/
│ ├── prd-writing/
│ │ ├── skill.md
│ │ └── template.md
│ ├── image-magic/
│ │ ├── skill.md
│ │ └── helpers.js
│ └── web-testing/
│ ├── skill.md
│ └── test-utils.js
└── [기타 프로젝트 파일들]
스킬 파일 구조와 구성 요소
skill.md 파일의 핵심 역할
모든 스킬 폴더에는 반드시 skill.md라는 이름의 파일이 있어야 합니다. 이 파일은 스킬의 정의서이자 실행 계획서로, AI 에이전트가 이 스킬을 어떻게 사용해야 하는지에 대한 모든 정보를 담고 있습니다. Markdown 형식을 사용하기 때문에 가독성이 뛰어나며, 동시에 구조화된 정보를 효과적으로 표현할 수 있습니다.
Front Matter: 메타데이터 정의
skill.md 파일의 상단에는 Front Matter 영역이 위치합니다. 이는 YAML 형식으로 작성되며, 스킬의 기본 정보를 정의합니다. Front Matter는 세 개의 대시(---)로 구분되며, 그 안에 스킬의 이름과 사용 조건을 명시합니다.
1
2
3
4
5
6
7
8
9
---
name: PRD Writer
description: 제품 요구사항 문서를 체계적으로 작성하는 스킬
when_to_use: |
사용자가 다음과 같은 요청을 할 때 이 스킬을 사용합니다:
- 새로운 기능이나 제품에 대한 PRD를 작성해달라고 요청할 때
- 제품 요구사항 문서가 필요하다고 언급할 때
- "요구사항 정리", "기능 명세서" 등의 키워드를 사용할 때
---
when_to_use 필드는 특히 중요합니다. AI 에이전트는 이 필드를 참조하여 사용자의 요청이 이 스킬과 관련이 있는지 판단합니다. 따라서 가능한 한 명확하고 구체적으로 작성하는 것이 좋습니다.
워크플로우 본문 작성
Front Matter 이후의 본문에는 AI 에이전트가 수행해야 할 구체적인 단계들을 기술합니다. 각 단계는 명확한 목표와 실행 방법을 포함해야 하며, 에이전트가 이해하고 실행할 수 있을 만큼 구체적이어야 합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
## 워크플로우
### 1단계: 컨텍스트 수집
먼저 사용자에게 다음 정보를 질문하여 수집합니다. 이 단계에서는 모든 질문을 한 번에 제시하지 말고, 사용자의 응답에 따라 자연스럽게 대화를 이어가며 필요한 정보를 파악합니다.
- 제품 또는 기능의 이름과 목적
- 주요 타겟 사용자 그룹
- 해결하고자 하는 핵심 문제
- 기대하는 비즈니스 임팩트
- 기술적 제약사항이나 의존성
사용자가 이미 일부 정보를 제공했다면, 그 정보를 바탕으로 부족한 부분만 추가로 질문합니다.
### 2단계: 문서 초안 작성
수집된 정보를 바탕으로 PRD의 초안을 작성합니다. 표준 PRD 템플릿을 따르되, 프로젝트의 특성에 맞게 섹션을 조정할 수 있습니다.
문서는 다음 섹션들을 포함해야 합니다:
- 개요 및 배경
- 목표 및 성공 지표
- 사용자 스토리
- 기능 요구사항
- 비기능 요구사항
- 기술 고려사항
- 출시 계획
각 섹션은 명확하고 측정 가능한 내용으로 작성하며, 모호한 표현은 피합니다.
### 3단계: 검증 및 개선
작성된 초안을 사용자에게 제시하고 피드백을 받습니다. 특히 다음 항목들이 충분히 다뤄졌는지 확인합니다:
- 요구사항이 구체적이고 실행 가능한가?
- 성공 지표가 명확하게 정의되었는가?
- 기술적 제약사항이 충분히 고려되었는가?
- 우선순위가 명확한가?
사용자의 피드백에 따라 문서를 수정하고 개선합니다.
### 4단계: 최종 문서 생성
모든 피드백을 반영한 최종 문서를 생성합니다. 문서는 Markdown 형식으로 작성하며, 팀원들이 쉽게 읽고 이해할 수 있도록 구조화합니다.
실전 스킬 구축 가이드
PRD 작성 스킬 구현
제품 요구사항 문서(PRD)를 작성하는 스킬은 소프트웨어 개발 프로세스에서 자주 필요한 작업입니다. 이 스킬을 구현함으로써 에이전트 스킬의 전체적인 구조와 작동 방식을 이해할 수 있습니다.
먼저 skills/prd-writing 폴더를 생성하고, 그 안에 skill.md 파일을 다음과 같이 작성합니다:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
---
name: PRD Writer
description: 제품 요구사항 문서를 체계적으로 작성
when_to_use: |
사용자가 PRD, 제품 요구사항 문서, 기능 명세서 작성을 요청할 때
---
# PRD 작성 스킬
이 스킬은 체계적이고 완전한 제품 요구사항 문서를 작성하는 데 도움을 줍니다.
## 작업 단계
### 컨텍스트 파악
사용자와 대화를 통해 다음 정보를 수집합니다:
1. 제품/기능 개요
2. 대상 사용자
3. 해결하려는 문제
4. 비즈니스 목표
5. 기술적 제약사항
### 문서 구조화
다음 표준 템플릿을 사용하여 문서를 작성합니다:
#### 1. 개요
- 제품/기능명
- 배경 및 동기
- 목적
#### 2. 목표 및 성공 지표
- 비즈니스 목표
- 측정 가능한 KPI
- 성공 기준
#### 3. 사용자 스토리
- As a [사용자 유형]
- I want [기능]
- So that [가치]
#### 4. 기능 요구사항
- Must Have (필수)
- Should Have (권장)
- Nice to Have (선택)
#### 5. 비기능 요구사항
- 성능
- 보안
- 확장성
- 접근성
#### 6. 기술 고려사항
- 아키텍처 개요
- 기술 스택
- 의존성
- 제약사항
#### 7. 일정 및 마일스톤
- 개발 단계
- 주요 마일스톤
- 출시 계획
### 검증 및 개선
작성된 문서를 다음 기준으로 검토합니다:
- 요구사항의 명확성
- 측정 가능성
- 실현 가능성
- 완전성
사용자의 피드백을 받아 지속적으로 개선합니다.
## 템플릿 참조
필요시 `template.md` 파일에 정의된 표준 템플릿을 활용하십시오.
같은 폴더에 template.md 파일을 추가하여 표준 템플릿을 제공할 수도 있습니다:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# [제품/기능명] PRD
## 1. 개요
### 배경
[이 제품/기능이 왜 필요한가?]
### 목적
[무엇을 달성하고자 하는가?]
## 2. 목표 및 성공 지표
### 비즈니스 목표
- 목표 1
- 목표 2
### KPI
| 지표 | 목표값 | 측정 방법 |
|------|--------|-----------|
| 예: 사용자 참여도 | 30% 증가 | Google Analytics |
## 3. 사용자 스토리
### 스토리 1
- **As a** [사용자 유형]
- **I want** [기능]
- **So that** [가치]
### 스토리 2
[반복...]
## 4. 기능 요구사항
### Must Have
1. 기능 1 - 상세 설명
2. 기능 2 - 상세 설명
### Should Have
1. 기능 3 - 상세 설명
### Nice to Have
1. 기능 4 - 상세 설명
## 5. 비기능 요구사항
### 성능
- 페이지 로드 시간: 2초 이내
- API 응답 시간: 500ms 이내
### 보안
- OAuth 2.0 인증
- HTTPS 필수
- 데이터 암호화
### 확장성
- 동시 사용자 10,000명 지원
- 수평적 확장 가능
## 6. 기술 고려사항
### 아키텍처
[시스템 아키텍처 개요]
### 기술 스택
- Frontend: React
- Backend: Node.js
- Database: PostgreSQL
### 의존성
[외부 시스템 및 라이브러리]
## 7. 일정
| 단계 | 기간 | 주요 산출물 |
|------|------|-------------|
| 설계 | 2주 | 상세 설계 문서 |
| 개발 | 8주 | 기능 완성 |
| 테스트 | 2주 | 테스트 완료 |
| 출시 | 1주 | 프로덕션 배포 |
## 8. 위험 요소 및 대응 방안
| 위험 | 영향도 | 대응 방안 |
|------|--------|-----------|
| 위험 1 | 높음 | 대응책 설명 |
이미지 처리 스킬 구현
ImageMagick을 활용한 이미지 처리 스킬은 실행 가능한 명령어와 스크립트를 포함하는 좋은 예시입니다. skills/image-magic 폴더를 생성하고 다음 내용으로 skill.md를 작성합니다:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
---
name: Image Magic
description: ImageMagick을 사용한 이미지 처리 및 변환
when_to_use: |
사용자가 다음을 요청할 때:
- 이미지 크기 조정, 리사이징
- 이미지 포맷 변환
- 배치 이미지 처리
- 이미지 품질 최적화
- 워터마크 추가
---
# ImageMagick 이미지 처리 스킬
이 스킬은 ImageMagick 도구를 사용하여 다양한 이미지 처리 작업을 자동화합니다.
## 사전 요구사항
ImageMagick이 시스템에 설치되어 있어야 합니다:
- macOS: `brew install imagemagick`
- Ubuntu/Debian: `sudo apt-get install imagemagick`
- Windows: 공식 웹사이트에서 설치
## 주요 작업
### 이미지 리사이징
사용자가 이미지 크기를 변경하고 싶어할 때, 다음 명령을 사용합니다:
**단일 이미지 리사이징:**
```bash
convert input.jpg -resize 1920x1080 output.jpg
```
**종횡비 유지하며 리사이징:**
```bash
convert input.jpg -resize 1920x1080\> output.jpg
```
(`\>` 기호는 원본보다 클 때만 축소함을 의미)
**배치 리사이징:**
```bash
for img in *.jpg; do
convert "$img" -resize 1920x1080\> "resized_$img"
done
```
### 포맷 변환
**JPEG를 PNG로:**
```bash
convert image.jpg image.png
```
**배치 포맷 변환:**
```bash
for img in *.jpg; do
convert "$img" "${img%.jpg}.png"
done
```
### 품질 최적화
**JPEG 품질 조정:**
```bash
convert input.jpg -quality 85 output.jpg
```
**Progressive JPEG 생성:**
```bash
convert input.jpg -interlace Plane output.jpg
```
### 워터마크 추가
**텍스트 워터마크:**
```bash
convert input.jpg -gravity southeast -pointsize 30 -fill white \
-annotate +10+10 'Copyright 2026' output.jpg
```
**이미지 워터마크:**
```bash
convert input.jpg watermark.png -gravity southeast -geometry +10+10 \
-composite output.jpg
```
### 고급 작업
**이미지 회전:**
```bash
convert input.jpg -rotate 90 output.jpg
```
**이미지 자르기:**
```bash
convert input.jpg -crop 800x600+100+100 output.jpg
```
**흑백 변환:**
```bash
convert input.jpg -colorspace Gray output.jpg
```
## 작업 워크플로우
1. **요구사항 파악**: 사용자가 원하는 이미지 처리 작업 확인
2. **파일 검증**: 대상 이미지 파일의 존재 및 포맷 확인
3. **명령 구성**: 적절한 ImageMagick 명령 생성
4. **실행**: 명령 실행 및 진행 상황 모니터링
5. **결과 검증**: 출력 파일 생성 확인 및 품질 체크
## 에러 처리
명령 실행 전 다음을 확인합니다:
- ImageMagick 설치 여부
- 입력 파일 존재 여부
- 출력 디렉터리 쓰기 권한
- 충분한 디스크 공간
에러 발생 시 명확한 메시지와 함께 해결 방법을 제시합니다.
helpers.js 파일을 추가하여 Node.js 환경에서 ImageMagick을 더 쉽게 사용할 수 있는 헬퍼 함수를 제공할 수도 있습니다:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
const { exec } = require('child_process');
const { promisify } = require('util');
const execAsync = promisify(exec);
/**
* 이미지 리사이징
* @param {string} inputPath - 입력 이미지 경로
* @param {string} outputPath - 출력 이미지 경로
* @param {string} dimensions - 크기 (예: "1920x1080")
*/
async function resizeImage(inputPath, outputPath, dimensions) {
const command = `convert "${inputPath}" -resize ${dimensions}\\> "${outputPath}"`;
try {
await execAsync(command);
return { success: true, output: outputPath };
} catch (error) {
return { success: false, error: error.message };
}
}
/**
* 배치 이미지 리사이징
* @param {string[]} inputPaths - 입력 이미지 경로 배열
* @param {string} outputDir - 출력 디렉터리
* @param {string} dimensions - 크기
*/
async function batchResize(inputPaths, outputDir, dimensions) {
const results = [];
for (const inputPath of inputPaths) {
const filename = inputPath.split('/').pop();
const outputPath = `${outputDir}/resized_${filename}`;
const result = await resizeImage(inputPath, outputPath, dimensions);
results.push({ input: inputPath, ...result });
}
return results;
}
/**
* 이미지 포맷 변환
* @param {string} inputPath - 입력 이미지 경로
* @param {string} outputPath - 출력 이미지 경로
* @param {string} format - 출력 포맷 (jpg, png, webp 등)
*/
async function convertFormat(inputPath, outputPath, format) {
const command = `convert "${inputPath}" "${outputPath}"`;
try {
await execAsync(command);
return { success: true, output: outputPath };
} catch (error) {
return { success: false, error: error.message };
}
}
module.exports = {
resizeImage,
batchResize,
convertFormat
};
웹 테스트 스킬 구현
Playwright를 활용한 웹 테스트 스킬은 브라우저 자동화와 테스트 작성을 도와줍니다. skills/web-testing 폴더에 다음 skill.md를 작성합니다:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
---
name: Web Testing with Playwright
description: Playwright를 사용한 웹 애플리케이션 테스트 자동화
when_to_use: |
사용자가 다음을 요청할 때:
- 웹 페이지 테스트 작성
- E2E 테스트 자동화
- 브라우저 자동화 스크립트
- UI 테스트 구현
---
# Playwright 웹 테스트 스킬
이 스킬은 Playwright를 사용하여 웹 애플리케이션의 테스트를 작성하고 자동화하는 데 도움을 줍니다.
## 설치
```bash
npm install -D @playwright/test
npx playwright install
```
## 기본 테스트 구조
Playwright 테스트는 다음과 같은 구조를 따릅니다:
```javascript
import { test, expect } from '@playwright/test';
test('테스트 설명', async ({ page }) => {
// 테스트 로직
});
```
## 일반적인 테스트 패턴
### 페이지 탐색
```javascript
test('홈페이지 방문', async ({ page }) => {
await page.goto('https://example.com');
await expect(page).toHaveTitle(/Example/);
});
```
### 요소 상호작용
**클릭:**
```javascript
await page.click('button#submit');
// 또는
await page.locator('button#submit').click();
```
**텍스트 입력:**
```javascript
await page.fill('input[name="username"]', 'testuser');
await page.fill('input[name="password"]', 'password123');
```
**드롭다운 선택:**
```javascript
await page.selectOption('select#country', 'Korea');
```
### 검증 (Assertions)
**텍스트 확인:**
```javascript
await expect(page.locator('.success-message')).toHaveText('로그인 성공');
```
**가시성 확인:**
```javascript
await expect(page.locator('.modal')).toBeVisible();
await expect(page.locator('.loading')).toBeHidden();
```
**URL 확인:**
```javascript
await expect(page).toHaveURL(/dashboard/);
```
## 실전 예제
### 로그인 테스트
```javascript
import { test, expect } from '@playwright/test';
test.describe('로그인 기능', () => {
test.beforeEach(async ({ page }) => {
await page.goto('https://example.com/login');
});
test('성공적인 로그인', async ({ page }) => {
await page.fill('input[name="email"]', 'user@example.com');
await page.fill('input[name="password"]', 'correctpassword');
await page.click('button[type="submit"]');
await expect(page).toHaveURL(/dashboard/);
await expect(page.locator('.user-name')).toHaveText('사용자명');
});
test('잘못된 비밀번호', async ({ page }) => {
await page.fill('input[name="email"]', 'user@example.com');
await page.fill('input[name="password"]', 'wrongpassword');
await page.click('button[type="submit"]');
await expect(page.locator('.error-message')).toHaveText('로그인 실패');
await expect(page).toHaveURL(/login/);
});
});
```
### 폼 제출 테스트
```javascript
test('회원가입 폼 제출', async ({ page }) => {
await page.goto('https://example.com/signup');
await page.fill('input[name="name"]', '홍길동');
await page.fill('input[name="email"]', 'hong@example.com');
await page.fill('input[name="password"]', 'SecurePass123!');
await page.fill('input[name="confirmPassword"]', 'SecurePass123!');
await page.check('input[name="terms"]');
await page.click('button[type="submit"]');
await expect(page.locator('.success-message')).toBeVisible();
await expect(page).toHaveURL(/welcome/);
});
```
### 동적 콘텐츠 대기
```javascript
test('API 응답 대기', async ({ page }) => {
await page.goto('https://example.com/data');
// 네트워크 요청 대기
await page.waitForResponse(response =>
response.url().includes('/api/users') && response.status() === 200
);
// 요소 나타남 대기
await page.waitForSelector('.user-list');
const userCount = await page.locator('.user-item').count();
expect(userCount).toBeGreaterThan(0);
});
```
## 워크플로우
테스트 작성 시 다음 단계를 따릅니다:
1. **시나리오 파악**: 사용자가 테스트하고 싶은 기능 확인
2. **테스트 계획**: 테스트 케이스 분해 (정상 케이스, 에러 케이스, 엣지 케이스)
3. **선택자 식별**: 테스트할 요소의 적절한 선택자 결정
4. **테스트 작성**: Playwright API를 사용하여 테스트 코드 작성
5. **검증 추가**: 적절한 assertion 추가
6. **실행 및 디버깅**: 테스트 실행 후 문제 수정
## 모범 사례
### 안정적인 선택자 사용
```javascript
// 좋음: 의미있는 속성 사용
await page.locator('[data-testid="submit-button"]').click();
// 나쁨: 불안정한 클래스명
await page.locator('.btn-primary-lg-rounded').click();
```
### Page Object Model 패턴
```javascript
class LoginPage {
constructor(page) {
this.page = page;
this.emailInput = page.locator('input[name="email"]');
this.passwordInput = page.locator('input[name="password"]');
this.submitButton = page.locator('button[type="submit"]');
}
async login(email, password) {
await this.emailInput.fill(email);
await this.passwordInput.fill(password);
await this.submitButton.click();
}
}
```
### 재사용 가능한 픽스처
```javascript
import { test as base } from '@playwright/test';
const test = base.extend({
authenticatedPage: async ({ page }, use) => {
await page.goto('https://example.com/login');
await page.fill('input[name="email"]', 'user@example.com');
await page.fill('input[name="password"]', 'password');
await page.click('button[type="submit"]');
await use(page);
}
});
test('인증된 사용자 테스트', async ({ authenticatedPage }) => {
await authenticatedPage.goto('/profile');
// 테스트 계속...
});
```
모범 사례 및 최적화
스킬 설계 원칙
효과적인 에이전트 스킬을 만들기 위해서는 몇 가지 핵심 원칙을 따라야 합니다. 첫째, 스킬은 단일 책임 원칙을 따라야 합니다. 하나의 스킬은 하나의 명확한 목적을 가져야 하며, 너무 많은 기능을 하나의 스킬에 담으려 하지 않아야 합니다. 예를 들어, 이미지 처리 스킬과 PDF 생성 스킬은 별도로 분리하는 것이 좋습니다.
둘째, 워크플로우는 명확하고 순차적이어야 합니다. AI 에이전트가 혼란스럽지 않도록 각 단계는 명확한 입력과 출력을 가져야 하며, 다음 단계로 자연스럽게 이어져야 합니다. 조건부 분기가 필요한 경우, 각 조건을 명확하게 정의하고 해당하는 행동을 구체적으로 기술해야 합니다.
셋째, 에러 처리와 예외 상황에 대한 가이드를 포함해야 합니다. 실제 환경에서는 예상치 못한 상황이 발생할 수 있으므로, 스킬은 이러한 상황에서 어떻게 대응해야 하는지 명시해야 합니다.
성능 최적화
스킬의 성능을 최적화하기 위해서는 불필요한 리소스 로딩을 피해야 합니다. 큰 파일이나 외부 리소스는 실제로 필요한 시점에만 참조하도록 설계합니다. 또한, 자주 사용되는 패턴이나 명령어는 헬퍼 스크립트로 분리하여 재사용성을 높이는 것이 좋습니다.
워크플로우 내에서 반복적인 작업이 있다면, 배치 처리나 병렬 처리를 고려합니다. 예를 들어, 여러 이미지를 처리하는 경우 순차적으로 처리하는 대신 병렬로 처리할 수 있는 방법을 제시하면 전체 작업 시간을 크게 단축할 수 있습니다.
문서화와 유지보수
스킬의 skill.md 파일은 단순히 명령어 나열이 아니라, 왜 그러한 접근 방식을 취하는지에 대한 설명을 포함해야 합니다. 이는 나중에 스킬을 수정하거나 다른 사람이 이해하는 데 큰 도움이 됩니다.
버전 관리를 위해 스킬의 변경 이력을 기록하는 것도 좋은 방법입니다. Front Matter에 버전 정보를 추가하거나, 별도의 CHANGELOG 파일을 유지할 수 있습니다.
1
2
3
4
5
6
7
8
9
---
name: Image Magic
version: 1.2.0
last_updated: 2026-01-15
changelog: |
1.2.0 - WebP 포맷 지원 추가
1.1.0 - 배치 처리 성능 개선
1.0.0 - 초기 릴리스
---
사용자 지정 지침과의 비교
적용 범위의 차이
사용자 지정 지침(Custom Instructions)은 모든 대화에 전역적으로 적용되는 일반적인 가이드라인입니다. 예를 들어, “항상 TypeScript를 사용하라”, “코드에 주석을 포함하라”와 같은 지침은 모든 상황에서 적용됩니다. 반면, 에이전트 스킬은 특정 작업이 요청될 때만 활성화되는 문맥 의존적인 도구입니다.
이러한 차이는 실용적인 의미를 가집니다. 사용자 지정 지침은 개발자의 일반적인 선호도와 코딩 스타일을 정의하는 데 적합하지만, 복잡한 워크플로우나 특정 도구를 사용하는 작업에는 한계가 있습니다. 에이전트 스킬은 이러한 한계를 보완하여, 특정 작업에 필요한 전문 지식과 도구를 제공합니다.
구성 요소의 차이
사용자 지정 지침은 주로 텍스트 기반의 지침으로 구성됩니다. 에이전트 스킬은 여기서 한 걸음 더 나아가, 실행 가능한 스크립트, 템플릿 파일, 헬퍼 함수 등 다양한 리소스를 포함할 수 있습니다. 이는 에이전트를 단순한 조언자가 아닌 실제 작업을 수행하는 실행자로 만들어줍니다.
예를 들어, 사용자 지정 지침으로는 “이미지를 최적화하라”고만 말할 수 있지만, 에이전트 스킬은 정확한 ImageMagick 명령어, 최적의 품질 설정, 그리고 배치 처리 스크립트까지 제공할 수 있습니다.
조합 활용
두 기능은 상호 보완적입니다. 사용자 지정 지침으로 전반적인 개발 철학과 스타일을 정의하고, 에이전트 스킬로 특정 작업에 대한 전문성을 제공하는 방식으로 조합하면 가장 효과적입니다. 예를 들어, 사용자 지정 지침에서 “보안을 최우선으로 한다”고 정의하고, 웹 테스트 스킬에서 구체적인 보안 테스트 방법을 제공하는 식입니다.
트러블슈팅
스킬이 활성화되지 않을 때
AI 에이전트가 스킬을 인식하지 못하는 경우, 먼저 Front Matter의 when_to_use 필드를 확인합니다. 이 필드가 너무 제한적이거나 모호하게 작성되면 에이전트가 스킬을 선택하지 못할 수 있습니다. 사용자가 사용할 가능성이 있는 다양한 표현과 키워드를 포함하도록 수정합니다.
또한, 폴더 구조가 올바른지 확인합니다. skills 폴더가 올바른 위치에 있고, 각 스킬 폴더에 skill.md 파일이 존재하는지 점검합니다. 파일명이 정확히 skill.md인지도 확인해야 합니다(대소문자 구분).
워크플로우 실행 오류
워크플로우 실행 중 에러가 발생하면, 각 단계의 전제 조건이 충족되었는지 확인합니다. 예를 들어, ImageMagick 스킬은 해당 도구가 시스템에 설치되어 있어야 합니다. 스킬의 시작 부분에 필요한 도구와 라이브러리를 명시하고, 설치 방법을 제공하는 것이 좋습니다.
또한, 파일 경로나 권한 문제가 없는지 확인합니다. 특히 Windows, macOS, Linux 간의 경로 구분자 차이나 권한 설정이 문제가 될 수 있으므로, 크로스 플랫폼 호환성을 고려해야 합니다.
성능 문제
스킬 실행이 느린 경우, 불필요하게 큰 리소스를 로드하고 있지 않은지 검토합니다. 특히 템플릿 파일이나 예제 데이터가 너무 크면 초기 로딩 시간이 길어질 수 있습니다. 필요한 경우, 리소스를 분할하거나 지연 로딩을 적용할 수 있습니다.
워크플로우의 각 단계가 너무 복잡하다면, 더 작은 단계로 나누는 것을 고려합니다. 이는 에이전트가 진행 상황을 더 명확하게 파악하고, 문제 발생 시 디버깅을 쉽게 만들어줍니다.
고급 활용 패턴
스킬 간 조합
여러 스킬을 조합하여 더 복잡한 작업을 수행할 수 있습니다. 예를 들어, 웹 테스트 스킬과 이미지 처리 스킬을 함께 사용하여 스크린샷 캡처와 이미지 비교 테스트를 자동화할 수 있습니다. 이를 위해 각 스킬의 출력이 다른 스킬의 입력으로 사용될 수 있도록 인터페이스를 설계합니다.
컨텍스트 공유
관련된 여러 스킬이 공통으로 사용하는 정보나 설정이 있다면, 상위 레벨의 설정 파일이나 공유 리소스 폴더를 만들 수 있습니다. 예를 들어, skills/shared 폴더에 공통 유틸리티나 설정 파일을 두고, 각 스킬에서 이를 참조하도록 할 수 있습니다.
동적 스킬 선택
복잡한 프로젝트에서는 상황에 따라 여러 스킬 중 하나를 선택해야 할 수 있습니다. 이런 경우, 메타 스킬을 만들어 사용자의 요청을 분석하고 적절한 하위 스킬로 라우팅하는 방식을 고려할 수 있습니다.
보안 고려사항
민감 정보 보호
스킬 파일에는 API 키, 비밀번호, 또는 기타 민감한 정보를 직접 포함하지 않아야 합니다. 대신 환경 변수를 사용하거나, 안전한 비밀 관리 시스템을 참조하도록 지침을 작성합니다.
1
2
3
4
5
6
7
8
9
10
11
### 인증 설정
API 키는 환경 변수에서 읽어옵니다:
- `IMAGE_API_KEY`: 이미지 처리 API 키
- `STORAGE_SECRET`: 스토리지 접근 시크릿
환경 변수 설정:
```bash
export IMAGE_API_KEY="your-key-here"
export STORAGE_SECRET="your-secret-here"
```
실행 권한 제어
스킬이 실행하는 명령어나 스크립트는 최소 권한 원칙을 따라야 합니다. 시스템 전체에 영향을 줄 수 있는 명령어는 피하고, 작업 디렉터리 내에서만 동작하도록 제한합니다.
입력 검증
사용자로부터 받은 입력을 외부 명령어에 전달하기 전에 반드시 검증하고 이스케이프 처리해야 합니다. 특히 셸 명령어에 사용자 입력을 직접 포함하는 경우, 인젝션 공격에 취약할 수 있으므로 주의가 필요합니다.
커뮤니티와 공유
스킬 공유하기
작성한 스킬이 다른 개발자에게도 유용할 것으로 판단되면, GitHub와 같은 플랫폼에 공유할 수 있습니다. 명확한 README 파일과 라이선스 정보를 포함하여, 다른 사람들이 쉽게 사용하고 기여할 수 있도록 합니다.
오픈소스 스킬 활용
이미 공개된 스킬을 찾아 프로젝트에 통합할 수도 있습니다. GitHub에서 ‘vscode agent skills’, ‘copilot skills’ 등의 키워드로 검색하면 커뮤니티에서 만든 다양한 스킬을 찾을 수 있습니다. 사용하기 전에 코드를 검토하고, 프로젝트의 요구사항에 맞게 수정하는 것이 좋습니다.
피드백과 개선
스킬을 사용하면서 발견한 문제점이나 개선 아이디어는 문서화하여 관리합니다. 버전 관리 시스템을 활용하여 변경 사항을 추적하고, 팀원들과 피드백을 공유하면 스킬의 품질을 지속적으로 향상시킬 수 있습니다.
미래 전망
에이전트 스킬은 아직 진화하고 있는 기술입니다. 앞으로 더 많은 IDE와 개발 도구가 이 표준을 지원하고, 더 풍부한 기능이 추가될 것으로 예상됩니다. 현재 시점에서 에이전트 스킬에 투자하는 것은 미래의 AI 기반 개발 환경에 대비하는 현명한 선택이 될 수 있습니다.
특히 주목할 만한 방향은 다음과 같습니다:
다중 에이전트 협업: 여러 스킬을 가진 에이전트들이 협력하여 더 복잡한 작업을 수행하는 시스템이 등장할 것입니다. 한 에이전트가 요구사항을 분석하면, 다른 에이전트가 설계를 하고, 또 다른 에이전트가 구현하는 식의 워크플로우가 가능해질 수 있습니다.
학습하는 스킬: 사용 패턴을 분석하여 스킬이 자동으로 최적화되거나, 새로운 패턴을 학습하는 기능이 추가될 수 있습니다. 이는 개발자의 작업 방식에 맞춰 점점 더 개인화된 지원을 제공할 수 있게 해줍니다.
시각적 스킬 편집기: 코드 없이 GUI를 통해 스킬을 만들고 편집할 수 있는 도구가 나올 가능성이 있습니다. 이는 기술적 배경이 적은 사용자도 자신만의 워크플로우를 자동화할 수 있게 해줄 것입니다.
결론
VS Code의 에이전트 스킬은 AI 기반 개발 도구의 새로운 장을 열고 있습니다. 단순히 코드를 자동 완성해주는 것을 넘어서, 복잡한 워크플로우를 자동화하고 전문화된 작업을 수행할 수 있는 이 기능은 개발자의 생산성을 크게 향상시킬 잠재력을 가지고 있습니다.
효과적인 스킬을 만들기 위해서는 명확한 설계 원칙을 따르고, 사용자의 실제 작업 패턴을 이해하며, 지속적으로 개선하는 자세가 필요합니다. 이 가이드에서 제시한 예제와 모범 사례를 참고하여, 여러분만의 유용한 스킬을 만들어보시기 바랍니다.
에이전트 스킬은 아직 초기 단계에 있지만, 그만큼 가능성도 무궁무진합니다. 지금 이 기술을 익히고 활용하는 개발자는 미래의 AI 기반 개발 환경에서 큰 경쟁 우위를 가질 수 있을 것입니다.
작성 일자: 2026-01-15