Claude Skills 완벽가이드 6편: 고급 기능 활용편
요약
핵심 요지
- 문제 정의: 5편에서 배운 단일 파일 스킬로는 복잡한 작업을 감당하기 어려움
- 핵심 주장: 멀티 파일 구조는 “필요할 때만” 도입하며,
Progressive Disclosure1 원칙을 따르면 누구나 설계할 수 있다 - 주요 근거: Anthropic 공식 문서의 멀티 파일 아키텍처 + 단계별 판단 기준
문서가 설명하는 범위
- 멀티 파일이 필요한 순간 판단하기
- 실제 500줄 이상 스킬을 단계별로 분리하는 전체 과정
- 5개 채널별 reference 파일 구성 방법
- scripts/ 폴더 활용법 + Claude에게 스크립트 요청하는 방법
- 선택적 필드(license, compatibility, metadata) 활용
- 트러블슈팅과 디버깅
읽는 시간: 15분 | 난이도: 중급-고급
참고 자료
- Anthropic Agent Skills 공식 문서 - 멀티 파일 아키텍처
- Skill Authoring Best Practices - Progressive Disclosure 패턴
- Anthropic 공식 Skills 저장소 - 실제 스킬 구조 참고
이런 경험 있으세요?
“스킬이 잘 동작하는데, SKILL.md가 500줄이 넘어가니까 관리가 안 돼요.”
“참고 자료를 스킬에 넣고 싶은데, 너무 길어서 토큰 낭비 같아요.”
“Python 스크립트로 검증하고 싶은데, 스킬에서 어떻게 연결하죠?”
5편에서 단일 파일 스킬을 만드는 방법을 배웠습니다. 하지만 스킬이 복잡해지면 단일 파일로는 한계가 옵니다.
이 글에서는 실제 500줄 이상의 스킬을 단계별로 분리하면서, 멀티 파일 구조를 익힙니다.
멀티 파일이 필요한 순간
판단 기준: 이 중 하나라도 해당되면 고려하세요
멀티 파일 구조는 필요할 때만 도입합니다. 무조건 복잡하게 만드는 게 좋은 게 아닙니다.
체크리스트로 확인해보세요
| 상황 | 해당 여부 | 필요한 조치 |
|---|---|---|
| SKILL.md가 500줄 이상 | ☐ | 파일 분리 필요 |
| 참고 자료(가이드, 템플릿)가 있지만 매번 필요하진 않음 | ☐ | reference/ 폴더 |
| Python/JS 스크립트 실행이 필요함 | ☐ | scripts/ 폴더 |
| 여러 도메인의 규칙이 섞여 있음 (색상, 폰트, 레이아웃 등) | ☐ | 도메인별 분리 |
| 버전/호환성 정보를 명시하고 싶음 | ☐ | 선택적 필드 |
하나도 해당 안 되면? 5편의 단일 파일 스킬로 충분합니다.
Progressive Disclosure 이해하기
핵심 개념: 필요한 정보만 필요한 시점에
왜 이 개념이 중요한가요?
단일 파일 스킬의 문제점을 먼저 이해해야 합니다.
500줄짜리 스킬이 있다면, 인스타그램 포스트 하나 쓰려고 해도 500줄 전체가 Claude의 컨텍스트2에 로드됩니다.
- 인스타그램만 쓰고 싶어도 → X, Threads, Facebook, 블로그 가이드까지 로드
- 색상만 확인하고 싶어도 → 금지어 목록, 5채널 예시까지 전부 로드
- 결과:
토큰3 낭비 + 응답 품질 저하
Anthropic 공식 문서의 핵심 원칙이 이 문제를 해결합니다.
“Progressive disclosure ensures only relevant content occupies the context window at any given time.”
번역: 관련 있는 내용만 그 순간 컨텍스트 윈도우에 올라가도록 한다.
비유로 이해하기
| 나쁜 방식 | 좋은 방식 |
|---|---|
| 백과사전 전체를 들고 다니기 | 목차만 들고, 필요한 페이지만 펼치기 |
| 모든 정보가 항상 로드됨 | 핵심만 로드, 나머지는 필요할 때 |
3단계 정보 공개 전략
| 단계 | 파일 | 토큰 예산 | 로드 시점 |
|---|---|---|---|
| Level 1 | name + description | ~100 tokens | 항상 (스킬 목록 표시) |
| Level 2 | SKILL.md body | <5K tokens | 스킬 활성화 시 |
| Level 3 | reference/, scripts/ | 필요시 | Claude가 참조할 때만 |
핵심 아이디어: SKILL.md는 “목차” 역할만 하고, 상세 정보는 별도 파일에 분리합니다.
실전: 500줄 이상 스킬을 단계별로 분리하기
이제 실제로 해봅시다. Moodturn 포토카드 생성 스킬을 예시로 전체 과정을 보여드립니다.
현재 상태 분석: 왜 분리가 필요한가?
분리하기 전에 현재 스킬의 구조를 분석합니다. 500줄 이상의 단일 파일이 왜 문제인지 이해해야, 분리 후에도 같은 실수를 반복하지 않습니다.
SKILL.md (분리 전 - 500줄 이상)
---name: moodturn-photocarddescription: Moodturn 브랜드 포토카드 이미지 생성. '포토카드', '카드뉴스', '감성 이미지', '인스타 이미지', 'X 포스트' 요청 시 사용.---
# Moodturn 포토카드 생성 스킬
## Overview
Moodturn의 브랜드 컬러와 톤에 맞는 감성 포토카드를 생성한다.5개 채널(Instagram, X, Threads, Facebook, Blog)별 최적화된 이미지를 만든다.
## Instructions
### 1. 주제/감정 파악
사용자가 요청한 주제 또는 감정을 파악한다:- 지침/피로- 불안/걱정- 외로움- 일상 공감- 성장/희망
### 2. 문구 작성
브랜드 톤에 맞는 위로 문구를 작성한다.
### 3. 채널 확인
포토카드를 사용할 채널을 확인한다:- instagram: 1080×1080 (정사각형)- x: 1200×675 (16:9)- threads: 1080×1350 (4:5 세로형)- facebook: 1200×630 (1.91:1)- blog: 1200×630 (썸네일)
### 4. 이미지 생성
스크립트를 실행하여 포토카드를 생성한다.
### 5. 최종 확인
문구가 브랜드 톤에 맞는지, 금지어가 없는지 확인한다.
---
## 브랜드 에센스
**슬로건**: "감정이 지칠 때, 따뜻한 쉼표가 되어드립니다"
**핵심 가치**- **공감 (Empathy)**: 판단 없이 있는 그대로 받아들인다- **성장 (Growth)**: 작은 변화도 의미 있게 여긴다- **연결 (Connection)**: 혼자가 아님을 느끼게 한다
### 톤 앤 매너
| 상황 | 톤 | 예시 || ----------- | ------------------- | ---------------------------------------- || 일상 공감 | 따뜻한, 곁에 있는 | "오늘 하루도 수고 많으셨어요" || 위로/공감 | 부드러운, 판단 없는 | "그럴 수 있어요. 충분히 힘드셨을 거예요" || 성장 격려 | 응원하는, 진심어린 | "작은 한 걸음도 큰 의미가 있어요" |
### 금지어
| 금지어 | 이유 | 대체어 || ------------------- | -------------- | ------------------------- || 힘내세요 | 강요, 부담 | "곁에 있을게요" || 긍정적으로 생각해요 | 감정 부정 | "그 마음 충분히 이해해요" || ~해야 해요 | 명령, 강요 | "~해보는 건 어떨까요" |
---
## 시각 가이드
### 브랜드 컬러 (모노크롬)
| 이름 | HEX | 용도 || ----------- | ------- | -------------- || Deep Black | #111111 | 배경 (기본) || Pure White | #ffffff | 텍스트 || Dark Gray | #333333 | 악센트 바 || Medium Gray | #666666 | 워터마크 |
### 포토카드 레이아웃
- 상단: 악센트 바 (Dark Gray)- 중앙: 메인 텍스트 (Pure White, 2-3줄)- 하단: 워터마크 "Moodturn" + 악센트 바- 배경: Deep Black
### 채널별 이미지 크기
| 채널 | 크기 | 비율 | 용도 || ---------- | ------------- | ------- | ----------------- || instagram | 1080 × 1080 | 1:1 | 인스타그램 피드 || x | 1200 × 675 | 16:9 | X (트위터) || threads | 1080 × 1350 | 4:5 | 스레드 || facebook | 1200 × 630 | 1.91:1 | 페이스북 || blog | 1200 × 630 | 1.91:1 | 블로그 썸네일 |
---
## 메시지 가이드
### 문구 작성 원칙
1. **2-3줄** 이내로 간결하게2. **줄바꿈**으로 여백 만들기3. 첫 줄에서 **공감**, 마지막 줄에서 **위로**
### 감정별 문구 예시
**지침/피로**
오늘 하루,아무것도 못 한 것 같아서 자책하고 계신가요?숨 쉬고, 버텼잖아요. 그것만으로 충분해요.
**불안/걱정**
"괜찮아?"라는 말에 "응, 괜찮아"라고 대답했지만사실은 괜찮지 않았던 날들.괜찮지 않아도 괜찮아요.
---
## Instagram 가이드
### 이미지 스펙
| 항목 | 값 || -------- | --------------------- || 크기 | 1080 × 1080 (정사각형) || 비율 | 1:1 || 용도 | 피드 포스트 |
### 콘텐츠 스타일
**특징**- 정사각형으로 피드에서 가장 눈에 잘 띔- 여백이 충분해서 텍스트가 잘 읽힘- 저장/공유가 쉬운 포맷
**문구 가이드**- 2-3줄 권장 (너무 길면 읽기 어려움)- 중앙 배치로 여백 활용- 해시태그는 캡션에 별도 작성
### 해시태그 가이드
**필수 해시태그**- #무드턴- #마음쉼표
**콘텐츠별 선택**| 유형 | 해시태그 || ----------- | ------------------------------- || 일상 공감 | #오늘하루 #수고했어요 #일상공감 || 위로 메시지 | #괜찮아요 #위로 #마음돌봄 || 성장/희망 | #천천히 #한걸음씩 #성장 |
### 예시 문구
**일상 공감**오늘 하루도수고 많으셨어요.쉬어가도 괜찮아요.
**위로**괜찮지 않아도괜찮아요.그 마음, 충분히 이해해요.
**응원**작은 한 걸음도큰 의미가 있어요.천천히 가도 괜찮아요.
---
## X (트위터) 가이드
### 이미지 스펙
| 항목 | 값 || -------- | -------------------- || 크기 | 1200 × 675 (가로형) || 비율 | 16:9 || 용도 | 트윗 이미지 |
### 콘텐츠 스타일
**특징**- 타임라인에서 가로로 넓게 펼쳐짐- 짧고 강렬한 메시지가 효과적- 리트윗 시 텍스트와 함께 공유됨
**문구 가이드**- 1-2줄 권장 (빠르게 읽히도록)- 임팩트 있는 한 문장이 효과적- 간결하고 여운 있게
### X 특화 스타일
**DO**- 짧고 강렬한 메시지- 공감을 부르는 질문형- 여운이 남는 마무리
**DON'T**- 긴 설명- 과한 해시태그 (이미지 안에 넣지 않음)- 너무 많은 줄바꿈
### 예시 문구
**짧은 공감**지친 하루 끝,숨 쉬는 것만으로 충분해요.
**질문형**오늘 하루, 스스로에게수고했다고 말해주셨나요?
**한 줄 위로**괜찮지 않아도, 괜찮아요.
---
## Threads 가이드
### 이미지 스펙
| 항목 | 값 || -------- | -------------------- || 크기 | 1080 × 1350 (세로형) || 비율 | 4:5 || 용도 | 스레드 포스트 |
### 콘텐츠 스타일
**특징**- 세로로 길어서 스크롤 중 눈에 잘 띔- 인스타보다 더 많은 텍스트 가능- 대화체/일기체가 잘 어울림
**문구 가이드**- 3-4줄도 가능 (세로 여백 활용)- 일기 쓰듯 편안한 톤- 스토리텔링 형식 권장
### 예시 문구
**일기체**오늘 하루,아무것도 못 한 것 같아서자책하고 있었어요.
그런데 생각해보니숨 쉬고, 버텼잖아요.그것만으로 충분해요.
**편지체**요즘 많이 지치셨죠?괜찮아요.그 마음, 충분히 이해해요.천천히 쉬어가세요.
---
## Facebook 가이드
### 이미지 스펙
| 항목 | 값 || -------- | -------------------- || 크기 | 1200 × 630 (가로형) || 비율 | 1.91:1 || 용도 | 페이스북 공유 |
### 콘텐츠 스타일
**특징**- 링크 공유 시 og:image와 같은 비율- 다양한 연령층이 보는 플랫폼- 공유/태그가 활발해서 확산력 높음
**문구 가이드**- 2줄 권장 (가로 형태에 맞게)- 보편적인 공감 포인트- 세대를 아우르는 표현
### 예시 문구
**보편적 공감**오늘 하루도 수고 많으셨어요.쉬어가도 괜찮아요.
**가족/친구용**혼자 힘들어하지 마세요.곁에 있을게요.
---
## Blog 썸네일 가이드
### 이미지 스펙
| 항목 | 값 || -------- | -------------------- || 크기 | 1200 × 630 (가로형) || 비율 | 1.91:1 || 용도 | 블로그 og:image |
### 콘텐츠 스타일
**특징**- 블로그 대표 이미지로 사용- og:image로 소셜 공유 시 노출- 검색 결과에서 클릭률에 영향
**문구 가이드**- 1-2줄로 핵심만- 헤드라인처럼 임팩트 있게- 블로그 글 제목과 연계
### 예시 문구
**헤드라인 스타일**오늘 하루, 충분히 수고했어요.
**인용 스타일**"괜찮지 않아도 괜찮아요"
---
## 이미지 생성 스크립트
### 의존성
pip install Pillow
### 스크립트
#!/usr/bin/env python3"""Moodturn 포토카드 생성 스크립트
5개 채널별 최적화된 포토카드 이미지를 생성한다.브랜드 컬러와 레이아웃을 적용하여 일관된 디자인을 유지한다.
사용법: python create_photocard.py "문구" --channel instagram python create_photocard.py "문구" --channel x python create_photocard.py "문구" --channel threads python create_photocard.py "문구" --channel facebook python create_photocard.py "문구" --channel blog"""
import argparseimport osimport sysfrom datetime import datetimefrom pathlib import Pathfrom typing import Tuple, Optional
try: from PIL import Image, ImageDraw, ImageFontexcept ImportError: print("Error: Pillow 라이브러리가 필요합니다.") print("설치: pip install Pillow") sys.exit(1)
# ============================================================# 브랜드 컬러 정의 (모노크롬)# ============================================================
class BrandColors: """Moodturn 브랜드 컬러 팔레트"""
DEEP_BLACK = "#111111" # 배경 (기본) PURE_WHITE = "#ffffff" # 텍스트 DARK_GRAY = "#333333" # 악센트 바 MEDIUM_GRAY = "#666666" # 워터마크
@classmethod def hex_to_rgb(cls, hex_color: str) -> Tuple[int, int, int]: """HEX 컬러를 RGB 튜플로 변환""" hex_color = hex_color.lstrip('#') return tuple(int(hex_color[i:i+2], 16) for i in (0, 2, 4))
@classmethod def get_background(cls) -> Tuple[int, int, int]: """배경색 RGB 반환""" return cls.hex_to_rgb(cls.DEEP_BLACK)
@classmethod def get_text_color(cls) -> Tuple[int, int, int]: """텍스트 색상 RGB 반환""" return cls.hex_to_rgb(cls.PURE_WHITE)
@classmethod def get_accent_color(cls) -> Tuple[int, int, int]: """악센트 색상 RGB 반환""" return cls.hex_to_rgb(cls.DARK_GRAY)
@classmethod def get_watermark_color(cls) -> Tuple[int, int, int]: """워터마크 색상 RGB 반환""" return cls.hex_to_rgb(cls.MEDIUM_GRAY)
# ============================================================# 채널별 설정# ============================================================
CHANNELS = { "instagram": { "size": (1080, 1080), "description": "인스타그램 피드", "aspect_ratio": "1:1", "accent_bar_ratio": 12, # 높이의 1/12 "font_size_ratio": 20, # 높이의 1/20 "max_lines": 3, "line_height_ratio": 1.5, "watermark_size_ratio": 40, # 높이의 1/40 }, "x": { "size": (1200, 675), "description": "X (트위터)", "aspect_ratio": "16:9", "accent_bar_ratio": 15, "font_size_ratio": 22, "max_lines": 2, "line_height_ratio": 1.4, "watermark_size_ratio": 45, }, "threads": { "size": (1080, 1350), "description": "스레드", "aspect_ratio": "4:5", "accent_bar_ratio": 14, "font_size_ratio": 18, "max_lines": 4, "line_height_ratio": 1.6, "watermark_size_ratio": 38, }, "facebook": { "size": (1200, 630), "description": "페이스북", "aspect_ratio": "1.91:1", "accent_bar_ratio": 12, "font_size_ratio": 20, "max_lines": 2, "line_height_ratio": 1.4, "watermark_size_ratio": 42, }, "blog": { "size": (1200, 630), "description": "블로그 썸네일", "aspect_ratio": "1.91:1", "accent_bar_ratio": 10, "font_size_ratio": 18, "max_lines": 2, "line_height_ratio": 1.3, "watermark_size_ratio": 45, },}
# ============================================================# 폰트 설정# ============================================================
def get_font(size: int, bold: bool = False) -> ImageFont.FreeTypeFont: """시스템 폰트 로드""" font_paths = [ # macOS "/System/Library/Fonts/AppleSDGothicNeo.ttc", "/Library/Fonts/NanumGothic.ttf", "/Library/Fonts/NanumGothicBold.ttf", # Windows "C:/Windows/Fonts/malgun.ttf", "C:/Windows/Fonts/NanumGothic.ttf", # Linux "/usr/share/fonts/truetype/nanum/NanumGothic.ttf", "/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc", ]
for font_path in font_paths: if os.path.exists(font_path): try: return ImageFont.truetype(font_path, size) except Exception: continue
# 폴백: 기본 폰트 print("Warning: 한글 폰트를 찾을 수 없습니다. 기본 폰트를 사용합니다.") return ImageFont.load_default()
# ============================================================# 포토카드 생성 클래스# ============================================================
class PhotocardGenerator: """채널별 포토카드 이미지 생성기"""
def __init__(self, channel: str): if channel not in CHANNELS: raise ValueError(f"지원하지 않는 채널: {channel}")
self.channel = channel self.config = CHANNELS[channel] self.width, self.height = self.config["size"]
# 비율 기반 계산 self.accent_bar_height = self.height // self.config["accent_bar_ratio"] self.font_size = self.height // self.config["font_size_ratio"] self.watermark_size = self.height // self.config["watermark_size_ratio"] self.line_height = int(self.font_size * self.config["line_height_ratio"])
def create( self, text: str, output_path: Optional[str] = None ) -> str: """포토카드 이미지 생성"""
# 캔버스 생성 image = Image.new("RGB", (self.width, self.height), BrandColors.get_background()) draw = ImageDraw.Draw(image)
# 상단 악센트 바 self._draw_accent_bar(draw, position="top")
# 메인 텍스트 self._draw_main_text(draw, text)
# 워터마크 self._draw_watermark(draw)
# 하단 악센트 바 self._draw_accent_bar(draw, position="bottom")
# 저장 if output_path is None: output_path = self._generate_filename()
image.save(output_path, "PNG", quality=95) return output_path
def _draw_accent_bar(self, draw: ImageDraw.Draw, position: str): """악센트 바 그리기""" if position == "top": coords = [0, 0, self.width, self.accent_bar_height] else: # bottom coords = [0, self.height - self.accent_bar_height, self.width, self.height]
draw.rectangle(coords, fill=BrandColors.get_accent_color())
def _draw_main_text(self, draw: ImageDraw.Draw, text: str): """메인 텍스트 그리기 (중앙 정렬)""" font = get_font(self.font_size) lines = text.strip().split('\n')[:self.config["max_lines"]]
# 전체 텍스트 높이 계산 total_height = len(lines) * self.line_height
# 시작 Y 위치 (수직 중앙) start_y = (self.height - total_height) // 2
for i, line in enumerate(lines): # 텍스트 너비 계산 (중앙 정렬) bbox = draw.textbbox((0, 0), line, font=font) text_width = bbox[2] - bbox[0] x = (self.width - text_width) // 2 y = start_y + (i * self.line_height)
draw.text((x, y), line, font=font, fill=BrandColors.get_text_color())
def _draw_watermark(self, draw: ImageDraw.Draw): """워터마크 그리기""" font = get_font(self.watermark_size) watermark_text = "Moodturn"
bbox = draw.textbbox((0, 0), watermark_text, font=font) text_width = bbox[2] - bbox[0]
x = (self.width - text_width) // 2 y = self.height - self.accent_bar_height - self.watermark_size - 20
draw.text((x, y), watermark_text, font=font, fill=BrandColors.get_watermark_color())
def _generate_filename(self) -> str: """자동 파일명 생성""" timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") output_dir = Path("output") output_dir.mkdir(exist_ok=True) return str(output_dir / f"photocard_{self.channel}_{timestamp}.png")
# ============================================================# CLI 인터페이스# ============================================================
def parse_args(): """명령행 인수 파싱""" parser = argparse.ArgumentParser( description="Moodturn 포토카드 생성", formatter_class=argparse.RawDescriptionHelpFormatter, epilog="""예시: python create_photocard.py "오늘 하루도\\n수고 많으셨어요" --channel instagram python create_photocard.py "괜찮지 않아도 괜찮아요" --channel x python create_photocard.py "지친 하루 끝,\\n숨 쉬는 것만으로 충분해요" -c threads """ )
parser.add_argument( "text", help="포토카드에 표시할 문구 (줄바꿈: \\n)" )
parser.add_argument( "-c", "--channel", choices=list(CHANNELS.keys()), default="instagram", help=f"채널 선택 (기본값: instagram). 옵션: {', '.join(CHANNELS.keys())}" )
parser.add_argument( "-o", "--output", help="출력 파일 경로 (기본값: output/photocard_채널_타임스탬프.png)" )
parser.add_argument( "--list-channels", action="store_true", help="지원 채널 목록 표시" )
return parser.parse_args()
def list_channels(): """채널 목록 출력""" print("\n지원 채널:") print("-" * 50) for name, config in CHANNELS.items(): size = f"{config['size'][0]}×{config['size'][1]}" print(f" {name:12} {size:12} {config['description']}") print("-" * 50)
def main(): """메인 함수""" args = parse_args()
if args.list_channels: list_channels() return
# 줄바꿈 처리 text = args.text.replace("\\n", "\n")
print(f"\n[Moodturn 포토카드 생성]") print(f"채널: {args.channel} ({CHANNELS[args.channel]['description']})") print(f"크기: {CHANNELS[args.channel]['size'][0]}×{CHANNELS[args.channel]['size'][1]}") print(f"문구: {text[:30]}..." if len(text) > 30 else f"문구: {text}")
try: generator = PhotocardGenerator(args.channel) output_path = generator.create(text, args.output) print(f"\n✅ 생성 완료: {output_path}") except Exception as e: print(f"\n❌ 생성 실패: {e}") sys.exit(1)
if __name__ == "__main__": main()문제 보이시나요?
이 스킬은 500줄 이상입니다. 스킬이 활성화될 때마다 아래와 같은 문제가 발생합니다.
- 인스타그램 포토카드 하나 만들려 해도 5개 채널 전체 가이드가 로드
- X용 짧은 메시지 쓰는데 Threads, Facebook 스타일까지 로드
- 브랜드 에센스, 시각 가이드, 5개 채널 가이드가 매번 전체 로드
- 300줄짜리 Python 스크립트가 문구 작성할 때도 불필요하게 로드
결과: 토큰 낭비 + 응답 품질 저하
Step 1: 분리할 내용 식별하기
왜 이 단계가 필요한가?
무작정 파일을 나누면 오히려 관리가 어려워집니다. 먼저 “매번 필요한 것”과 “가끔 필요한 것”을 구분해야 합니다.
현재 스킬의 구조를 분석해봅시다.
| 섹션 | 줄 수 | 매번 필요? | 분리 후보 |
|---|---|---|---|
| Overview + Instructions | ~40줄 | ✓ 필요 | 유지 |
| 브랜드 에센스 | ~40줄 | 문구 작성 시만 | ✓ 분리 |
| 시각 가이드 | ~40줄 | 이미지 생성 시만 | ✓ 분리 |
| 메시지 가이드 | ~30줄 | 참고용 | ✓ 분리 |
| Instagram 가이드 | ~50줄 | 인스타그램 요청 시만 | ✓ 분리 |
| X 가이드 | ~50줄 | X 요청 시만 | ✓ 분리 |
| Threads 가이드 | ~50줄 | Threads 요청 시만 | ✓ 분리 |
| Facebook 가이드 | ~50줄 | Facebook 요청 시만 | ✓ 분리 |
| Blog 가이드 | ~50줄 | 블로그 요청 시만 | ✓ 분리 |
| 이미지 생성 스크립트 | ~300줄 | 실행 시에만 | ✓ 분리 |
결론: 채널별 가이드와 스크립트를 각각 분리하면 효율적입니다. SKILL.md에는 핵심 워크플로우만 남깁니다.
Step 2: 디렉토리 구조 설계
왜 이 단계가 필요한가?
파일을 어떻게 나눌지 미리 계획해야 합니다. 파일명은 “이 파일에 뭐가 있는지” 바로 알 수 있어야 합니다.
분석 결과를 바탕으로 구조를 설계합니다.
moodturn-photocard/├── SKILL.md # 핵심 워크플로우 (~65줄)├── reference/│ ├── BRAND-ESSENCE.md # 브랜드 슬로건, 핵심 가치, 금지어│ ├── VISUAL-GUIDE.md # 포토카드 레이아웃, 컬러│ ├── MESSAGE-GUIDE.md # 감정 카테고리별 문구 예시│ ├── CHANNEL-INSTAGRAM.md # 인스타그램 전용 가이드│ ├── CHANNEL-X.md # X (트위터) 전용 가이드│ ├── CHANNEL-THREADS.md # Threads 전용 가이드│ ├── CHANNEL-FACEBOOK.md # Facebook 전용 가이드│ └── CHANNEL-BLOG.md # 블로그 썸네일 가이드└── scripts/ └── create_photocard.py # 채널별 포토카드 생성 (Pillow)파일 분리 기준
- 공통 자료: 브랜드 에센스, 시각 가이드, 메시지 가이드
- 채널별 가이드: 각 플랫폼 특성에 맞는 별도 파일
- 스크립트: 5개 채널 지원하는 이미지 생성 코드
Step 3: SKILL.md 분리하기 (목차로 만들기)
왜 이 단계가 필요한가?
SKILL.md는 “목차” 역할만 해야 합니다. “어떤 파일을 언제 봐야 하는지”만 안내하고, 상세 내용은 reference/에 있습니다.
핵심 아이디어: 스킬이 활성화될 때 ~65줄만 로드되고, 나머지는 필요할 때만 로드됩니다.
---name: moodturn-photocarddescription: Moodturn 브랜드 포토카드 이미지 생성. '포토카드', '카드뉴스', '감성 이미지', '인스타 이미지', 'X 포스트' 요청 시 사용.---
# Moodturn 포토카드 생성 스킬
## Overview
Moodturn의 브랜드 컬러와 톤에 맞는 감성 포토카드를 생성한다.5개 채널(Instagram, X, Threads, Facebook, Blog)별 최적화된 이미지를 만든다.
## Reference Files
| 파일 | 내용 | 언제 참조 || ------------------------------ | ------------------- | ------------------------ || `reference/BRAND-ESSENCE.md` | 슬로건, 핵심 가치 | **모든 문구** 작성 전 || `reference/VISUAL-GUIDE.md` | 컬러, 레이아웃 | **이미지 생성** 시 || `reference/MESSAGE-GUIDE.md` | 감정별 문구 예시 | 문구 참고가 필요할 때 || `reference/CHANNEL-INSTAGRAM.md` | 인스타그램 가이드 | **인스타그램** 요청 시 || `reference/CHANNEL-X.md` | X/트위터 가이드 | **X/트위터** 요청 시 || `reference/CHANNEL-THREADS.md` | 스레드 가이드 | **스레드** 요청 시 || `reference/CHANNEL-FACEBOOK.md` | 페이스북 가이드 | **페이스북** 요청 시 || `reference/CHANNEL-BLOG.md` | 블로그 썸네일 가이드 | **블로그** 요청 시 |
## Scripts
| 파일 | 기능 | 실행 방법 || ----------------------------- | -------------------- | ------------------------------------------------ || `scripts/create_photocard.py` | 채널별 포토카드 생성 | `python create_photocard.py "문구" --channel 채널` |
**지원 채널**
| 채널 | 크기 | 설명 || --------- | ----------- | ----------------- || instagram | 1080×1080 | 인스타그램 피드 || x | 1200×675 | X (트위터) || threads | 1080×1350 | 스레드 || facebook | 1200×630 | 페이스북 || blog | 1200×630 | 블로그 썸네일 |
## Workflow
### Phase 1: 문구 작성
1. 사용자 요청에서 **감정/주제** 파악2. `reference/BRAND-ESSENCE.md` 읽고 톤 확인3. 필요시 `reference/MESSAGE-GUIDE.md`에서 예시 참고4. 1-3줄의 위로 문구 작성
### Phase 2: 채널 확인
1. **채널** 확인 (instagram/x/threads/facebook/blog)2. 해당 채널 가이드 파일 읽기 (예: `reference/CHANNEL-INSTAGRAM.md`)3. 채널 특성에 맞게 문구 조정
### Phase 3: 이미지 생성
1. `reference/VISUAL-GUIDE.md`에서 컬러/레이아웃 확인2. `scripts/create_photocard.py` 실행하여 이미지 생성3. 생성된 파일 경로를 사용자에게 안내
## Output Format
1. 작성된 위로 문구2. 생성된 포토카드 이미지 파일 경로3. 채널별 권장 해시태그/캡션 (해당 시)핵심 변화
- 500줄 이상 → ~65줄로 줄어듦
- “어떤 파일을 언제 봐야 하는지”만 안내
- 채널별 가이드를 별도 파일로 분리
- 실제 가이드 내용은 reference/에 분리
Step 4: reference/ 파일 분리하기
왜 이 단계가 필요한가?
각 reference 파일은 독립적으로 이해 가능해야 합니다. Claude가 파일 하나만 읽어도 해당 작업을 수행할 수 있어야 합니다.
reference/BRAND-ESSENCE.md
# Moodturn 브랜드 에센스
## 슬로건
**"감정이 지칠 때, 따뜻한 쉼표가 되어드립니다"**
## 핵심 가치
- **공감 (Empathy)**: 판단 없이 있는 그대로 받아들인다- **성장 (Growth)**: 작은 변화도 의미 있게 여긴다- **연결 (Connection)**: 혼자가 아님을 느끼게 한다
## 톤 앤 매너
| 상황 | 톤 | 예시 || ----------- | ------------------- | ---------------------------------------- || 일상 공감 | 따뜻한, 곁에 있는 | "오늘 하루도 수고 많으셨어요" || 위로/공감 | 부드러운, 판단 없는 | "그럴 수 있어요. 충분히 힘드셨을 거예요" || 성장 격려 | 응원하는, 진심어린 | "작은 한 걸음도 큰 의미가 있어요" |
## 문체 규칙
**DO**- "~네요", "~어요" 등 친근한 종결어미- 독자의 감정을 먼저 인정하기- "괜찮아요", "충분해요" 등 수용의 표현
**DON'T**- 가르치려는 톤 ("~해야 해요")- 판단하는 표현 ("그건 잘못된")- 과장된 긍정 ("무조건 좋아질 거예요!")
## 금지어
| 금지어 | 이유 | 대체어 || ------------------- | -------------- | ------------------------- || 힘내세요 | 강요, 부담 | "곁에 있을게요" || 긍정적으로 생각해요 | 감정 부정 | "그 마음 충분히 이해해요" || ~해야 해요 | 명령, 강요 | "~해보는 건 어떨까요" || 무조건 | 단정적 | "때로는", "어쩌면" |reference/VISUAL-GUIDE.md
# Moodturn 포토카드 시각 가이드
## 브랜드 컬러 (모노크롬)
| 이름 | HEX | 용도 || ----------- | ------- | ------------------ || Deep Black | #111111 | 배경 || Pure White | #ffffff | 메인 텍스트 || Dark Gray | #333333 | 상하단 악센트 바 || Medium Gray | #666666 | 워터마크 |
## 채널별 이미지 크기
| 채널 | 크기 | 비율 | 용도 || ---------- | ----------- | ------- | ----------------- || instagram | 1080×1080 | 1:1 | 인스타그램 피드 || x | 1200×675 | 16:9 | X (트위터) || threads | 1080×1350 | 4:5 | 스레드 || facebook | 1200×630 | 1.91:1 | 페이스북 || blog | 1200×630 | 1.91:1 | 블로그 og:image |
## 포토카드 레이아웃
- **배경**: Deep Black (#111111)- **상단 바**: Dark Gray (#333333), 높이 = 전체의 1/12- **하단 바**: Dark Gray (#333333), 높이 = 전체의 1/12- **메인 텍스트**: 중앙 배치, Pure White (#ffffff)- **워터마크**: "Moodturn", 하단 바 위, Medium Gray (#666666)
## 텍스트 규칙
- 폰트 크기: 이미지 너비의 1/20- 줄 간격: 폰트 크기의 1.6배- 최대 2-3줄 권장reference/MESSAGE-GUIDE.md
# Moodturn 메시지 가이드
## 문구 작성 원칙
1. **2-3줄** 이내로 간결하게2. **줄바꿈**으로 여백 만들기3. 첫 줄에서 **공감**, 마지막 줄에서 **위로**4. 의문문 또는 "~네요" 종결 권장
## 감정별 문구 예시
### 지침/피로
오늘 하루,아무것도 못 한 것 같아서자책하고 계신가요?
숨 쉬고, 버텼잖아요.그것만으로 충분해요.
### 불안/걱정
"괜찮아?"라는 말에"응, 괜찮아"라고 대답했지만사실은 괜찮지 않았던 날들.
괜찮지 않아도 괜찮아요.
### 일상 공감
월요일 아침,일어나는 것만으로도충분히 대단해요.
오늘 하루도 수고 많으셨어요.
### 성장/희망
작은 한 걸음도큰 의미가 있어요.
천천히 가도 괜찮아요.
## 문구 체크리스트
- [ ] 2-3줄 이내인가?- [ ] 금지어가 없는가?- [ ] 판단하는 느낌이 없는가?- [ ] 읽는 사람이 위로받는 느낌인가?채널별 가이드 (5개 파일)
각 채널에 맞는 콘텐츠 스타일, 문구 길이, 예시를 제공합니다. Claude가 특정 채널 요청을 받으면 해당 파일만 읽습니다.
reference/CHANNEL-INSTAGRAM.md
# Instagram 포토카드 가이드
## 이미지 스펙
| 항목 | 값 || -------- | --------------------- || 크기 | 1080 × 1080 (정사각형) || 비율 | 1:1 || 용도 | 피드 포스트 |
## 콘텐츠 스타일
**특징**- 정사각형으로 피드에서 가장 눈에 잘 띔- 여백이 충분해서 텍스트가 잘 읽힘- 저장/공유가 쉬운 포맷
**문구 가이드**- 2-3줄 권장 (너무 길면 읽기 어려움)- 중앙 배치로 여백 활용- 해시태그는 캡션에 별도 작성
## 해시태그 가이드
**필수 해시태그**- #무드턴- #마음쉼표
**콘텐츠별 선택**
| 유형 | 해시태그 || ----------- | ------------------------------- || 일상 공감 | #오늘하루 #수고했어요 #일상공감 || 위로 메시지 | #괜찮아요 #위로 #마음돌봄 || 성장/희망 | #천천히 #한걸음씩 #성장 |
## 예시 문구
### 일상 공감
오늘 하루도수고 많으셨어요.쉬어가도 괜찮아요.
### 위로
괜찮지 않아도괜찮아요.그 마음, 충분히 이해해요.
### 응원
작은 한 걸음도큰 의미가 있어요.천천히 가도 괜찮아요.reference/CHANNEL-X.md
# X (트위터) 포토카드 가이드
## 이미지 스펙
| 항목 | 값 || -------- | -------------------- || 크기 | 1200 × 675 (가로형) || 비율 | 16:9 || 용도 | 트윗 이미지 |
## 콘텐츠 스타일
**특징**- 타임라인에서 가로로 넓게 펼쳐짐- 짧고 강렬한 메시지가 효과적- 리트윗 시 텍스트와 함께 공유됨
**문구 가이드**- 1-2줄 권장 (빠르게 읽히도록)- 임팩트 있는 한 문장이 효과적- 간결하고 여운 있게
## X 특화 스타일
**DO**- 짧고 강렬한 메시지- 공감을 부르는 질문형- 여운이 남는 마무리
**DON'T**- 긴 설명- 과한 해시태그 (이미지 안에 넣지 않음)- 너무 많은 줄바꿈
## 예시 문구
### 짧은 공감
지친 하루 끝,숨 쉬는 것만으로 충분해요.
### 질문형
오늘 하루, 스스로에게수고했다고 말해주셨나요?
### 한 줄 위로
괜찮지 않아도, 괜찮아요.
### 여운
당신은 이미충분히 잘하고 있어요.reference/CHANNEL-THREADS.md
# Threads 포토카드 가이드
## 이미지 스펙
| 항목 | 값 || -------- | -------------------- || 크기 | 1080 × 1350 (세로형) || 비율 | 4:5 || 용도 | 스레드 포스트 |
## 콘텐츠 스타일
**특징**- 세로로 길어서 스크롤 중 눈에 잘 띔- 인스타보다 더 많은 텍스트 가능- 대화체/일기체가 잘 어울림
**문구 가이드**- 3-4줄도 가능 (세로 여백 활용)- 일기 쓰듯 편안한 톤- 스토리텔링 형식 권장
## Threads 특화 스타일
**DO**- 일기/편지체 스타일- 개인적인 톤- 공감 포인트로 시작
**DON'T**- 딱딱한 어조- 광고 느낌- 해시태그 남용
## 예시 문구
### 일기체
오늘 하루,아무것도 못 한 것 같아서자책하고 있었어요.
그런데 생각해보니숨 쉬고, 버텼잖아요.그것만으로 충분해요.
### 편지체
요즘 많이 지치셨죠?
괜찮아요.그 마음, 충분히 이해해요.
천천히 쉬어가세요.
### 공감
"나만 이렇게 힘든 건가?"그런 생각이 들 때가 있죠.
아니에요.다들 각자의 무게를 안고 있어요.reference/CHANNEL-FACEBOOK.md
# Facebook 포토카드 가이드
## 이미지 스펙
| 항목 | 값 || -------- | -------------------- || 크기 | 1200 × 630 (가로형) || 비율 | 1.91:1 || 용도 | 페이스북 공유 |
## 콘텐츠 스타일
**특징**- 링크 공유 시 og:image와 같은 비율- 다양한 연령층이 보는 플랫폼- 공유/태그가 활발해서 확산력 높음
**문구 가이드**- 2줄 권장 (가로 형태에 맞게)- 보편적인 공감 포인트- 세대를 아우르는 표현
## Facebook 특화 스타일
**DO**- 보편적인 공감대- 따뜻하고 친근한 어조- 가족/친구에게 공유하고 싶은 메시지
**DON'T**- 지나치게 개인적인 표현- 특정 세대만 아는 표현- 자극적인 톤
## 예시 문구
### 보편적 공감
오늘 하루도 수고 많으셨어요.쉬어가도 괜찮아요.
### 가족/친구용
혼자 힘들어하지 마세요.곁에 있을게요.
### 응원
작은 한 걸음도 의미 있어요.천천히 가도 괜찮아요.
### 안부
요즘 어떻게 지내세요?잘 쉬고 계신가요?reference/CHANNEL-BLOG.md
# Blog 썸네일 포토카드 가이드
## 이미지 스펙
| 항목 | 값 || -------- | -------------------- || 크기 | 1200 × 630 (가로형) || 비율 | 1.91:1 || 용도 | 블로그 og:image |
## 콘텐츠 스타일
**특징**- 블로그 대표 이미지로 사용- og:image로 소셜 공유 시 노출- 검색 결과에서 클릭률에 영향
**문구 가이드**- 1-2줄로 핵심만- 헤드라인처럼 임팩트 있게- 블로그 글 제목과 연계
## Blog 특화 스타일
**DO**- 간결하고 명확한 메시지- 호기심을 유발하는 문구- 블로그 주제와 일관성
**DON'T**- 너무 긴 문구- 글 내용과 무관한 메시지- 과도한 장식
## 예시 문구
### 헤드라인 스타일
오늘 하루, 충분히 수고했어요.
### 인용 스타일
"괜찮지 않아도 괜찮아요"
### 질문형
지금, 잘 쉬고 계신가요?
### 선언형
숨 쉬는 것만으로 충분합니다.핵심 포인트
- 각 파일이 독립적으로 사용 가능
- Claude가 하나만 읽어도 작업 수행 가능
- 공통 3개 + 채널별 5개 = 총 8개 파일로 체계적 관리
Step 5: scripts/ 폴더 — Claude가 코드를 실행할 수 있다
왜 스크립트가 필요한가?
reference/ 폴더가 “읽기 자료”라면, scripts/ 폴더는 실행 도구입니다.
Claude는 마크다운을 읽고 이해하는 것뿐 아니라, Python이나 JavaScript 코드를 직접 실행할 수 있습니다. 이 능력을 스킬과 연결하면 다음과 같은 것들이 가능해집니다.
| 단순 검증 | 고급 활용 |
|---|---|
| 금지어 검사 | API 호출 (날씨, 주가, 번역) |
| 글자 수 확인 | 파일 생성 및 저장 |
| 필수 태그 포함 여부 | 데이터 분석 및 시각화 |
| 맞춤법 검사 | 이미지/PDF 생성 |
핵심 개념: 스킬이 “무엇을 해야 하는지” 정의한다면, 스크립트는 “어떻게 해야 하는지”를 구현합니다. 스킬에서 “이 스크립트를 실행해서 결과를 확인하라”고 지시하면, Claude가 알아서 실행하고 결과를 해석합니다.
“저는 코딩을 몰라요” — 괜찮습니다
스크립트를 직접 커스터마이징하실 수 있다면 더 좋겠지만, 그렇지 않더라도 Claude에게 “이런 스크립트 만들어줘”라고 요청하면 됩니다.
Moodturn 브랜드용 포토카드 생성 스크립트를 만들어줘.
기능:1. 5개 채널별 이미지 크기 - 인스타그램: 1080x1080 (정사각형, 1:1) - X: 1200x675 (가로형, 16:9) - 스레드: 1080x1350 (세로형, 4:5) - 페이스북: 1200x630 (가로형, 1.91:1) - 블로그: 1200x630 (og:image용)
2. 브랜드 컬러 적용 (모노크롬) - 배경: Deep Black (#111111) - 악센트: Dark Gray (#333333) - 텍스트: Pure White (#ffffff) - 워터마크: Medium Gray (#666666)
3. 위로 메시지 텍스트를 이미지 중앙에 배치
사용법:- python create_photocard.py "메시지" --channel instagram- 결과물: output/photocard_instagram.png실제 스크립트 예시
아래는 Claude에게 요청해서 받은 포토카드 생성 스크립트입니다. 5개 채널을 지원하며, 각 채널별 최적화된 크기와 레이아웃을 적용합니다.
scripts/create_photocard.py
#!/usr/bin/env python3"""Moodturn 포토카드 생성 스크립트
Usage: python create_photocard.py "문구" --channel instagram python create_photocard.py "오늘 하루도\\n수고 많으셨어요" --channel x
Channels: instagram: 1080x1080 (정사각형, 1:1) x: 1200x675 (가로형, 16:9) threads: 1080x1350 (세로형, 4:5) facebook: 1200x630 (가로형, 1.91:1) blog: 1200x630 (블로그 썸네일)"""
import sysimport osfrom PIL import Image, ImageDraw, ImageFont
# Moodturn 브랜드 컬러 (모노크롬)COLORS = { "background": "#111111", # Deep Black "text": "#ffffff", # Pure White "accent": "#333333", # Dark Gray (상하단 바) "watermark": "#666666", # Medium Gray}
# 채널별 설정 (크기, 악센트 비율, 폰트 비율)CHANNELS = { "instagram": { "size": (1080, 1080), "description": "인스타그램 피드", "accent_ratio": 12, "font_ratio": 20, }, "x": { "size": (1200, 675), "description": "X (트위터)", "accent_ratio": 15, "font_ratio": 22, }, "threads": { "size": (1080, 1350), "description": "스레드", "accent_ratio": 14, "font_ratio": 18, }, "facebook": { "size": (1200, 630), "description": "페이스북", "accent_ratio": 12, "font_ratio": 20, }, "blog": { "size": (1200, 630), "description": "블로그 썸네일", "accent_ratio": 10, "font_ratio": 18, },}
def hex_to_rgb(hex_color: str) -> tuple: """HEX 컬러를 RGB 튜플로 변환""" hex_color = hex_color.lstrip("#") return tuple(int(hex_color[i : i + 2], 16) for i in (0, 2, 4))
def get_korean_font(size: int) -> ImageFont.FreeTypeFont: """한글 지원 폰트 로드 (macOS/Linux/Windows 호환)""" font_paths = [ "/System/Library/Fonts/AppleSDGothicNeo.ttc", "/Library/Fonts/AppleGothic.ttf", "/usr/share/fonts/truetype/nanum/NanumGothic.ttf", "C:/Windows/Fonts/malgun.ttf", ]
for path in font_paths: if os.path.exists(path): try: return ImageFont.truetype(path, size) except Exception: continue
print("⚠️ 한글 폰트를 찾지 못했습니다. 기본 폰트를 사용합니다.") return ImageFont.load_default()
def create_photocard( message: str, channel: str = "instagram", output_dir: str = "output") -> str: """Moodturn 포토카드 이미지 생성""" config = CHANNELS.get(channel, CHANNELS["instagram"]) width, height = config["size"]
# 컬러 변환 bg_color = hex_to_rgb(COLORS["background"]) text_color = hex_to_rgb(COLORS["text"]) accent_color = hex_to_rgb(COLORS["accent"]) watermark_color = hex_to_rgb(COLORS["watermark"])
# 이미지 생성 image = Image.new("RGB", (width, height), bg_color) draw = ImageDraw.Draw(image)
# 상하단 악센트 바 (채널별 비율 적용) accent_height = height // config["accent_ratio"] draw.rectangle([0, 0, width, accent_height], fill=accent_color) draw.rectangle([0, height - accent_height, width, height], fill=accent_color)
# 폰트 로드 (채널별 크기 적용) font_size = width // config["font_ratio"] font = get_korean_font(font_size) small_font = get_korean_font(font_size // 2)
# 메시지 줄 처리 lines = message.replace("\\n", "\n").split("\n")
# 텍스트 높이 계산 line_height = font_size * 1.6 total_height = len(lines) * line_height start_y = (height - total_height) // 2
# 각 줄 중앙 정렬로 그리기 for i, line in enumerate(lines): line = line.strip() if not line: continue bbox = draw.textbbox((0, 0), line, font=font) text_width = bbox[2] - bbox[0] x = (width - text_width) // 2 y = start_y + (i * line_height) draw.text((x, y), line, font=font, fill=text_color)
# 워터마크 (Moodturn) watermark = "Moodturn" bbox = draw.textbbox((0, 0), watermark, font=small_font) wm_width = bbox[2] - bbox[0] wm_x = (width - wm_width) // 2 wm_y = height - accent_height - font_size - 10 draw.text((wm_x, wm_y), watermark, font=small_font, fill=watermark_color)
# 출력 디렉토리 생성 os.makedirs(output_dir, exist_ok=True)
# 파일 저장 filename = f"photocard_{channel}.png" filepath = os.path.join(output_dir, filename) image.save(filepath, "PNG", quality=95)
return filepath
if __name__ == "__main__": if len(sys.argv) < 2: print(__doc__) sys.exit(1)
message = sys.argv[1] channel = "instagram"
if "--channel" in sys.argv: idx = sys.argv.index("--channel") if idx + 1 < len(sys.argv): channel = sys.argv[idx + 1].lower()
if channel not in CHANNELS: print(f"❌ 지원하지 않는 채널: {channel}") print(f" 지원 채널: {', '.join(CHANNELS.keys())}") sys.exit(1)
filepath = create_photocard(message, channel) config = CHANNELS[channel]
print("✓ 포토카드 생성 완료!") print(f" 채널: {channel} ({config['description']})") print(f" 크기: {config['size'][0]}x{config['size'][1]}") print(f" 저장: {filepath}")실행 결과 예시
$ python create_photocard.py "오늘 하루도\\n수고 많으셨어요" --channel instagram
✓ 포토카드 생성 완료! 채널: instagram (인스타그램 피드) 크기: 1080x1080 저장: output/photocard_instagram.png
$ python create_photocard.py "괜찮지 않아도, 괜찮아요." --channel x
✓ 포토카드 생성 완료! 채널: x (X (트위터)) 크기: 1200x675 저장: output/photocard_x.png생성된 이미지는 Moodturn 모노크롬 브랜드 컬러가 적용된 포토카드입니다.
- 배경: Deep Black (#111111)
- 상하단 악센트: Dark Gray (#333333) - 채널별 비율 최적화
- 메시지: 중앙 배치, Pure White (#ffffff)
- 워터마크: “Moodturn”
스크립트 요청 팁
- 원하는 기능을 구체적으로 나열하세요
- 브랜드 컬러, 크기 등 디자인 요소를 명시하세요
- 한번에 완벽할 필요 없어요 — 테스트하고 수정 요청하세요
- 라이브러리 설치:
pip install Pillow
Step 6: 최종 결과물 확인
분리가 완료되었습니다. 전체 구조를 확인해봅시다.
moodturn-photocard/├── SKILL.md # ~65줄 (워크플로우 + 참조 안내)├── reference/│ ├── BRAND-ESSENCE.md # 브랜드 슬로건, 톤, 금지어│ ├── VISUAL-GUIDE.md # 컬러, 레이아웃│ ├── MESSAGE-GUIDE.md # 감정별 문구 예시│ ├── CHANNEL-INSTAGRAM.md # 인스타그램 전용 가이드│ ├── CHANNEL-X.md # X (트위터) 전용 가이드│ ├── CHANNEL-THREADS.md # Threads 전용 가이드│ ├── CHANNEL-FACEBOOK.md # Facebook 전용 가이드│ └── CHANNEL-BLOG.md # 블로그 썸네일 가이드└── scripts/ └── create_photocard.py # 5채널 포토카드 생성 (Pillow)Before vs After 비교
| 항목 | Before | After |
|---|---|---|
| SKILL.md 크기 | 500줄 이상 | ~65줄 |
| 스킬 활성화 시 로드 | 전체 500줄+ | 핵심 65줄만 |
| 인스타그램 요청 시 | 5채널 모두 로드 | SKILL.md + CHANNEL-INSTAGRAM.md만 |
| X 포스트 요청 시 | 5채널 모두 로드 | SKILL.md + CHANNEL-X.md만 |
| 토큰 사용량 | 매번 최대 | 필요한 채널만큼만 |
| 유지보수 | 한 파일에서 수정 | 해당 채널 파일만 수정 |
| reference 파일 수 | 0개 (모두 통합) | 8개 (공통 3 + 채널 5) |
| 이미지 생성 | 불가능 | 5채널별 포토카드 자동 생성 |
실제 테스트: 스킬 사용해보기
분리한 스킬이 실제로 잘 동작하는지 테스트해봅시다.
프롬프트
moodturn-photocard 스킬 이용해서삶에 지친 사람들에게 위로하는 블로그 썸네일용 포토카드를 만들어줘!Claude의 동작 과정
moodturn-photocard스킬 활성화 → SKILL.md (~65줄) 로드- “블로그 썸네일” 키워드 감지 →
reference/CHANNEL-BLOG.md참조 - “위로” 키워드 감지 →
reference/BRAND-ESSENCE.md에서 톤 확인 - 문구 작성 후
scripts/create_photocard.py --channel blog실행
결과

- 채널: blog (1200×630)
- 문구: “지친 하루, 당신은 충분히 대단해요.”
- 브랜드 컬러: 모노크롬 (Deep Black 배경, Pure White 텍스트)
핵심 포인트
인스타그램도, X도, Threads도 아닌 블로그만 요청했기 때문에 아래와 같이 효율적으로 동작합니다.
- 다른 4개 채널 가이드는 로드되지 않음
- 필요한 파일만 참조: SKILL.md + CHANNEL-BLOG.md + BRAND-ESSENCE.md
- 토큰 절약 + 정확한 채널 맞춤 결과
이것이 Progressive Disclosure의 실제 효과입니다.
선택적 필드 활용하기
언제 선택적 필드가 필요한가?
| 필드 | 용도 | 필요한 상황 |
|---|---|---|
version | 스킬 버전 관리 | 팀에서 스킬 공유, 업데이트 추적 |
license | 라이선스 명시 | 공개 배포, 상업적 사용 |
compatibility | 호환성 정보 | 특정 도구/라이브러리 필요 |
metadata | 추가 정보 | 작성자, 태그, 카테고리 |
사용 예시
---name: writing-brand-contentdescription: 브랜드 가이드라인을 적용한 마케팅 콘텐츠 작성.version: 2.1.0metadata: author: 마케팅팀 updated: 2024-01-15 tags: [marketing, brand, content]------name: generating-chartsdescription: 데이터 시각화 차트 생성.compatibility: requires: - python-pptx>=0.6.21 - matplotlib>=3.5.0---선택적 필드는 정말 “선택”입니다.
개인 사용 스킬이라면 name과 description만으로 충분합니다.
트러블슈팅
문제 1: 스킬이 자동 활성화 안 됨
아래 순서로 진단합니다.
문제 2: reference 파일을 안 읽음
사고 과정
-
SKILL.md에 참조 문구가 있나? → “reference/GUIDE.md 참조” 명시 확인
-
참조 문구가 명령형인가? → ✕ “참고하면 좋다” (약함) → ✓ “반드시 읽고 적용한다” (강함)
-
그래도 안 읽으면? → 직접 요청: “GUIDE.md 읽어서 적용해줘”
해결책
인스타그램 가이드를 참고할 수 있다.인스타그램 콘텐츠 작성 시 **반드시** `reference/CHANNEL-INSTAGRAM.md`를 읽고 적용한다.문제 3: 스크립트 실행 오류
| 확인 항목 | 체크 |
|---|---|
| 파일 경로가 정확한가? | ☐ |
| 파일명에 오타가 없는가? | ☐ |
| Python 환경이 설정되어 있는가? | ☐ |
| 스크립트에 실행 권한이 있는가? | ☐ |
나만의 고급 스킬 만들기 체크리스트
| 단계 | 체크 항목 |
|---|---|
| 필요성 판단 | ☐ 500줄 이상이거나 분리가 필요한 상황인가? |
| ☐ 아니라면 5편의 단일 파일로 충분한가? | |
| 분리 설계 | ☐ 어떤 내용을 분리할지 식별했는가? |
| ☐ 매번 필요한 것 vs 선택적인 것 구분했는가? | |
| SKILL.md | ☐ “목차” 역할만 하는가? (5K tokens 이하) |
| ☐ reference 파일 참조가 명확한가? | |
| reference/ | ☐ 각 파일이 독립적으로 이해 가능한가? |
| ☐ 파일명이 내용을 명확히 설명하는가? | |
| scripts/ | ☐ 스크립트가 정말 필요한 상황인가? |
| ☐ Claude에게 요청해서 만들었는가? | |
| 테스트 | ☐ 분리 후에도 기존처럼 동작하는가? |
| ☐ reference 파일이 제대로 로드되는가? |
정리
| 개념 | 핵심 포인트 |
|---|---|
| 멀티 파일 필요 시점 | 500줄 이상, 선택적 참조 자료 있음, 스크립트 필요 |
| Progressive Disclosure | SKILL.md는 목차, 상세는 reference/에 분리 |
| 분리 과정 | 식별 → 구조 설계 → SKILL.md 축소 → reference 분리 → scripts 추가 |
| 스크립트 만들기 | Claude에게 검증 항목 명확히 설명하고 요청 |
| 핵심 원칙 | 필요할 때만 복잡하게, 단일 파일로 충분하면 단일 파일 유지 |
시리즈를 마치며
6편에 걸쳐 Claude Skills를 다뤘습니다.
| 편 | 내용 | 난이도 |
|---|---|---|
| 1편 | Skills란 무엇인가 | 초급 |
| 2편 | PPT 스킬 활용법 | 초급 |
| 3편 | 엑셀 스킬 활용법 | 초급 |
| 4편 | 커스텀 스킬 개념과 구조 | 초급-중급 |
| 5편 | 스킬 제작 실전 가이드 | 중급 |
| 6편 | 고급 기능 활용편 | 중급-고급 |
권장 학습 경로
- 5편으로 첫 스킬 만들기 (단일 파일)
- 스킬이 복잡해지면 이 글 다시 읽기
- 필요한 부분만 멀티 파일로 확장
기억하세요
- 처음부터 복잡하게 만들지 마세요
- 단일 파일로 시작하고, 한계가 오면 분리하세요
- 스크립트는 Claude에게 요청하면 됩니다
- “Concise is key” — 간결함이 핵심입니다
여기까지 읽어주셔서 감사합니다.
Footnotes
공유
이 글이 도움이 되었다면 다른 사람과 공유해주세요!