이 가이드에서는 스크립트, 템플릿, 참고 자료를 포함한 복잡한 Skill을 만드는 방법을 배웁니다.
Skill 구조 심화
1. 단순 Skill (5분용)
my-first-skill/
└── SKILL.md # 필수: 메타데이터 + 지침
지침 전체가 하나의 SKILL.md 파일에 들어갑니다.
2. 스크립트를 포함한 Skill
pdf-processor/
├── SKILL.md # 핵심 지침
├── scripts/ # 자동화 스크립트
│ ├── extract.py # PDF에서 텍스트 추출
│ ├── merge.py # PDF 병합
│ └── validate.py # 유효성 검사
└── templates/
├── invoice.pdf # 서식 PDF
└── report.docx # 보고서 템플릿
장점:
- 복잡한 작업을 자동화
- 코드 재사용성 증가
- Claude가 필요할 때 스크립트 실행
3. 참고 자료가 많은 Skill
data-analyzer/
├── SKILL.md # 기본 가이드 (간단)
├── REFERENCE.md # API 상세 문서
├── EXAMPLES.md # 실제 사용 사례
├── CONFIG.yaml # 설정 파일
└── data/
└── sample.csv # 샘플 데이터
장점:
- 점진적 공개 (Progressive Disclosure)
- Claude가 필요한 부분만 로드
- 맥락 효율성 증가
실전 예제 1: PDF 처리 Skill
시나리오
팀에서 자주 하는 작업:
- PDF에서 텍스트 추출
- 여러 PDF 병합
- PDF 폼 작성
이를 자동화하는 Skill을 만들어봅시다.
Step 1: 폴더 구조 생성
mkdir -p .claude/skills/pdf-processor/scripts
touch .claude/skills/pdf-processor/SKILL.md
touch .claude/skills/pdf-processor/REFERENCE.md
touch .claude/skills/pdf-processor/scripts/extract.py
touch .claude/skills/pdf-processor/scripts/merge.pyStep 2: SKILL.md 작성 (메인 지침)
---
name: pdf-processor
description: PDF에서 텍스트 추출, 여러 PDF 병합, PDF 양식 작성. PDF 파일 작업 시 텍스트 추출, 문서 결합 또는 양식 작성을 위해 사용합니다. pypdf 및 pdfplumber 패키지가 필요합니다.
---
# PDF 프로세서
## 설치 (처음 한 번)
```bash
pip install pypdf pdfplumber
```
## 빠른 시작
### 1. PDF에서 텍스트 추출
```python
import pdfplumber
with pdfplumber.open("document.pdf") as pdf:
# 첫 페이지의 텍스트
text = pdf.pages[0].extract_text()
print(text)
# 모든 페이지 추출
for i, page in enumerate(pdf.pages):
print(f"--- 페이지 {i+1} ---")
print(page.extract_text())
```
### 2. 표(테이블) 추출
```python
with pdfplumber.open("report.pdf") as pdf:
for page in pdf.pages:
# 테이블 찾기
tables = page.extract_tables()
if tables:
for table in tables:
# table은 리스트의 리스트
for row in table:
print(row)
```
### 3. PDF 병합
```python
from pypdf import PdfMerger
merger = PdfMerger()
merger.append("document1.pdf")
merger.append("document2.pdf")
merger.write("merged.pdf")
merger.close()
```
## 자동화 스크립트
더 복잡한 작업을 위해 준비된 스크립트:
- **scripts/extract.py** - 대량 텍스트 추출
- **scripts/merge.py** - 폴더의 모든 PDF 병합
- **scripts/validate.py** - PDF 무결성 검사
**사용법:**
```bash
python .claude/skills/pdf-processor/scripts/extract.py input.pdf output.txt
python .claude/skills/pdf-processor/scripts/merge.py input_folder/ output.pdf
```
더 자세한 정보는 [REFERENCE.md](REFERENCE.md)를 참고하세요.
## 일반적인 사용 사례
### 발송 인보이스 처리
```
발송된 인보이스 PDF들을 처리해줄래?
- 각 PDF에서 발송 금액 추출
- CSV로 정리
```
### 계약서 비교
```
이 두 계약서(PDF)의 차이를 분석해줄래?
```
### 양식 작성
```
이 PDF 양식을 채워줄래? 다음 정보를 사용해서:
- 회사명: ABC Corp
- 담당자: 김철수
```
## 팁과 주의사항
- PDF는 포맷이 다양해서 추출이 100% 정확하지 않을 수 있음
- 복잡한 레이아웃의 PDF는 먼저 스크린샷으로 확인하기
- 이미지 기반 PDF(스캔)는 OCR 도구 필요 (Tesseract 등)Step 3: REFERENCE.md 작성 (상세 API 문서)
# PDF 프로세서 - API 상세 문서
## pdfplumber API
### PDF 열기
```python
import pdfplumber
# 기본 열기
with pdfplumber.open("file.pdf") as pdf:
pages = pdf.pages # 모든 페이지
page = pdf.pages[0] # 첫 페이지
```
### 페이지 메서드
| 메서드 | 설명 | 반환값 |
|--------|------|--------|
| `page.extract_text()` | 페이지 텍스트 추출 | str |
| `page.extract_tables()` | 표 추출 | list[list[list[str]]] |
| `page.extract_table()` | 첫 표만 추출 | list[list[str]] |
| `page.chars` | 모든 문자 객체 | list |
| `page.lines` | 모든 선 객체 | list |
| `page.rects` | 모든 사각형 객체 | list |
### 텍스트 추출 옵션
```python
# x_tolerance: 문자 간 거리 (픽셀)
# y_tolerance: 라인 간 거리
text = page.extract_text(x_tolerance=3, y_tolerance=3)
# 레이아웃 유지
text = page.extract_text(layout=True)
```
### 테이블 추출 상세
```python
# 테이블 설정
table_settings = {
"vertical_strategy": "lines", # 선으로 열 구분
"horizontal_strategy": "lines", # 선으로 행 구분
}
tables = page.extract_tables(table_settings=table_settings)
```
## pypdf API
### PDF 병합
```python
from pypdf import PdfMerger
merger = PdfMerger()
# 파일 추가
merger.append("file1.pdf")
merger.append("file2.pdf", pages=[0, 2]) # 특정 페이지만
# 저장
merger.write("output.pdf")
merger.close()
```
### 페이지 추출
```python
from pypdf import PdfReader
reader = PdfReader("file.pdf")
# 페이지 정보
print(len(reader.pages)) # 페이지 수
# 특정 페이지 추출
page = reader.pages[0]
text = page.extract_text()
```
### 메타데이터
```python
reader = PdfReader("file.pdf")
# 문서 정보
info = reader.metadata
print(info.title)
print(info.author)
print(info.creation_date)
```
## 트러블슈팅
### 문제: PDF 텍스트 추출이 공백만 반환
**원인**: 이미지 기반 PDF (스캔된 문서)
**해결책**:
```bash
# Tesseract OCR 설치
pip install pytesseract pillow pdf2image
# OCR로 변환 후 추출
from pdf2image import convert_from_path
from pytesseract import image_to_string
images = convert_from_path("scanned.pdf")
for img in images:
text = image_to_string(img, lang='kor') # 한글 OCR
print(text)
```
### 문제: 표 구조가 복잡함
**해결책**: 표 추출 옵션 조정
```python
# 선이 없는 표의 경우
table_settings = {
"vertical_strategy": "text", # 텍스트 정렬로 열 구분
"horizontal_strategy": "text",
}
```
### 문제: 병합 후 파일이 손상됨
**해결책**: 파일 검증
```python
from pypdf import PdfReader
# 병합 후 검증
reader = PdfReader("merged.pdf")
print(f"Pages: {len(reader.pages)}")
print(f"Is PDF Valid: {reader.is_pdf}")
```Step 4: extract.py 스크립트
#!/usr/bin/env python3
"""
PDF에서 텍스트를 대량으로 추출하는 스크립트
사용법:
python extract.py input.pdf [output.txt]
"""
import sys
import pdfplumber
from pathlib import Path
def extract_pdf(input_path: str, output_path: str = None) -> None:
"""PDF 파일에서 모든 텍스트 추출"""
input_file = Path(input_path)
if not input_file.exists():
print(f"오류: 파일 '{input_path}'을(를) 찾을 수 없습니다")
sys.exit(1)
# 출력 파일명 자동 생성
if output_path is None:
output_path = input_file.stem + "_extracted.txt"
try:
with pdfplumber.open(input_file) as pdf:
print(f"PDF 열기: {input_file}")
print(f"총 {len(pdf.pages)}개 페이지")
all_text = []
for i, page in enumerate(pdf.pages, 1):
print(f" 페이지 {i} 처리 중...", end=" ")
text = page.extract_text()
all_text.append(f"--- 페이지 {i} ---\n{text}")
print("완료")
# 파일로 저장
with open(output_path, 'w', encoding='utf-8') as f:
f.write("\n\n".join(all_text))
print(f"\n추출 완료: {output_path}")
except Exception as e:
print(f"오류: {e}")
sys.exit(1)
if __name__ == "__main__":
if len(sys.argv) < 2:
print("사용법: python extract.py <input.pdf> [output.txt]")
sys.exit(1)
input_file = sys.argv[1]
output_file = sys.argv[2] if len(sys.argv) > 2 else None
extract_pdf(input_file, output_file)Step 5: merge.py 스크립트
#!/usr/bin/env python3
"""
폴더 내 모든 PDF를 순서대로 병합하는 스크립트
사용법:
python merge.py folder_path/ [output.pdf]
"""
import sys
from pathlib import Path
from pypdf import PdfMerger
def merge_pdfs(folder_path: str, output_path: str = None) -> None:
"""폴더 내 모든 PDF 병합"""
folder = Path(folder_path)
if not folder.is_dir():
print(f"오류: '{folder_path}'는 폴더가 아닙니다")
sys.exit(1)
# PDF 파일 찾기
pdf_files = sorted(folder.glob("*.pdf"))
if not pdf_files:
print(f"오류: '{folder_path}'에 PDF 파일이 없습니다")
sys.exit(1)
# 출력 파일명 자동 생성
if output_path is None:
output_path = folder.parent / f"{folder.name}_merged.pdf"
try:
merger = PdfMerger()
print(f"병합할 PDF 파일 {len(pdf_files)}개:")
for pdf_file in pdf_files:
print(f" - {pdf_file.name}")
merger.append(str(pdf_file))
merger.write(str(output_path))
merger.close()
print(f"\n병합 완료: {output_path}")
except Exception as e:
print(f"오류: {e}")
sys.exit(1)
if __name__ == "__main__":
if len(sys.argv) < 2:
print("사용법: python merge.py <folder_path> [output.pdf]")
sys.exit(1)
folder = sys.argv[1]
output = sys.argv[2] if len(sys.argv) > 2 else None
merge_pdfs(folder, output)실전 예제 2: 데이터 분석 Skill
구조
data-analyzer/
├── SKILL.md # 기본 가이드
├── EXAMPLES.md # 사용 예제
├── pandas_tips.md # Pandas 팁
└── templates/
└── analysis_template.py # 분석 템플릿
주요 포인트
---
name: data-analyzer
description: Excel, CSV 및 JSON 형식의 데이터를 분석합니다. 차트, 피벗 테이블, 통계 요약표를 생성합니다. 스프레드시트 분석, 데이터셋 작업 또는 데이터 시각화 생성 시 사용합니다.
---
# 데이터 분석
## 시작 (pandas)
```python
import pandas as pd
# CSV 읽기
df = pd.read_csv("data.csv")
# 기본 정보
print(df.head()) # 첫 5행
print(df.info()) # 데이터 타입
print(df.describe()) # 통계
```
... (자세한 내용) ...실전 예제 3: 팀 워크플로우 Skill
구조
git-workflow/
├── SKILL.md # Git 워크플로우 가이드
├── hooks/ # Git hooks
│ ├── pre-commit # 커밋 전 검사
│ └── commit-msg # 메시지 검증
└── scripts/
└── setup-hooks.sh # Hook 자동 설치
Skill 배포 팁
1. 스크립트 권한 설정
chmod +x .claude/skills/pdf-processor/scripts/*.py
chmod +x .claude/skills/git-workflow/scripts/*.sh2. 의존성 명시
SKILL.md에 필수 라이브러리 명시:
# SKILL.md에서
**필수 설치:**
```bash
pip install pypdf pdfplumber
```3. 상대 경로 사용
스크립트에서 파일 참조 시 상대 경로 사용:
# ❌ 절대 경로 (동작 안 함)
script_dir = "/Users/username/.claude/skills/pdf-processor"
# ✅ 상대 경로
from pathlib import Path
script_dir = Path(__file__).parent성능 최적화
1. 점진적 공개 (Progressive Disclosure)
Claude가 필요한 파일만 읽도록 SKILL.md를 간단히 유지:
# SKILL.md (짧고 간단)
기본 사용법만 포함.
자세한 내용: [REFERENCE.md](REFERENCE.md)2. 파일 크기 관리
각 파일을 작게 유지:
❌ 나쁜 구조:
SKILL.md (50KB, 모든 내용 포함)
✅ 좋은 구조:
SKILL.md (5KB, 핵심만)
├── REFERENCE.md (30KB, API 문서)
├── EXAMPLES.md (10KB, 예제)
└── TROUBLESHOOTING.md (5KB, 문제 해결)
3. 캐싱 활용
자주 변경되지 않는 참고 자료는 별도 파일로:
# SKILL.md는 변경 빈도가 낮음
# 다른 파일도 마찬가지권한 제어
allowed-tools를 통한 제어
---
name: safe-data-reader
description: Safely analyze data without modifying files
allowed-tools: Read, Grep, Glob
---도구별 권한
| 도구 | 기능 | 위험도 |
|---|---|---|
| Read | 파일 읽기 | 낮음 |
| Grep | 검색 | 낮음 |
| Glob | 패턴 검색 | 낮음 |
| Edit | 파일 수정 | 높음 |
| Bash | 터미널 명령 | 매우 높음 |
문제 해결
스크립트가 실행되지 않음
# 1. 권한 확인
ls -l .claude/skills/pdf-processor/scripts/extract.py
# 2. 권한 추가
chmod +x .claude/skills/pdf-processor/scripts/extract.py
# 3. 경로 확인
python .claude/skills/pdf-processor/scripts/extract.py test.pdf의존성 없다고 오류
SKILL.md에서 설치 지침 명확히:
# SKILL.md에 추가
**설치 필수:**
```bash
pip install pypdf pdfplumber
```파일 경로 오류
스크립트에서 상대 경로 사용:
from pathlib import Path
# __file__ = /Users/.../scripts/extract.py
# script_dir = /Users/.../scripts/
script_dir = Path(__file__).parent
# skill_dir = /Users/.../
skill_dir = script_dir.parent
# 템플릿 파일 참조
template = skill_dir / "templates" / "invoice.pdf"모범 사례 체크리스트
Skill 만들기 전 확인:
[ ] 목표가 명확한가? (무엇을 하는 Skill인가?)
[ ] 대상 사용자가 누구인가? (개인/팀/공개?)
[ ] description이 구체적인가? (언제 사용하는가?)
[ ] 필수 의존성을 명시했는가?
[ ] 예제를 충분히 포함했는가?
[ ] 폴더 구조가 논리적인가?
[ ] 스크립트 권한을 설정했는가?
[ ] 팀과 테스트했는가?
배포 전:
[ ] git에 추가했는가?
[ ] README/SKILL.md를 최신으로 유지?
[ ] 버전을 기록했는가?
[ ] 팀원들에게 공지했는가?
다음 단계
- 단순한 Skill부터 시작 - 하나의 기능만
- 점진적으로 확장 - 필요에 따라 파일 추가
- 팀의 피드백 수집 - 개선점 파악
- 버전 관리 - 변경사항 추적
더 많은 정보: Agent Skills - Claude Code Docs