Claude Skills 완벽가이드 6편: 고급 기능 활용편

요약#

핵심 요지#

  • 문제 정의: 5편에서 배운 단일 파일 스킬로는 복잡한 작업을 감당하기 어려움
  • 핵심 주장: 멀티 파일 구조는 “필요할 때만” 도입하며, Progressive Disclosure1 원칙을 따르면 누구나 설계할 수 있다
  • 주요 근거: Anthropic 공식 문서의 멀티 파일 아키텍처 + 단계별 판단 기준

문서가 설명하는 범위#

  • 멀티 파일이 필요한 순간 판단하기
  • 실제 500줄 이상 스킬을 단계별로 분리하는 전체 과정
  • 5개 채널별 reference 파일 구성 방법
  • scripts/ 폴더 활용법 + Claude에게 스크립트 요청하는 방법
  • 선택적 필드(license, compatibility, metadata) 활용
  • 트러블슈팅과 디버깅

읽는 시간: 15분 | 난이도: 중급-고급


참고 자료#


이런 경험 있으세요?#

“스킬이 잘 동작하는데, SKILL.md가 500줄이 넘어가니까 관리가 안 돼요.”

“참고 자료를 스킬에 넣고 싶은데, 너무 길어서 토큰 낭비 같아요.”

“Python 스크립트로 검증하고 싶은데, 스킬에서 어떻게 연결하죠?”

5편에서 단일 파일 스킬을 만드는 방법을 배웠습니다. 하지만 스킬이 복잡해지면 단일 파일로는 한계가 옵니다.

이 글에서는 실제 500줄 이상의 스킬을 단계별로 분리하면서, 멀티 파일 구조를 익힙니다.


멀티 파일이 필요한 순간#

판단 기준: 이 중 하나라도 해당되면 고려하세요#

멀티 파일 구조는 필요할 때만 도입합니다. 무조건 복잡하게 만드는 게 좋은 게 아닙니다.

flowchart TD A[현재 SKILL.md] --> B{500줄 이상?} B -->|Yes| C[멀티 파일 고려] B -->|No| D{참고 자료가 있는데<br/>매번 로드할 필요 없음?} D -->|Yes| C D -->|No| E{스크립트 실행이<br/>필요함?} E -->|Yes| C E -->|No| F[단일 파일 유지] C --> G[이 글을 계속 읽으세요] F --> H[5편으로 충분합니다]

체크리스트로 확인해보세요

상황해당 여부필요한 조치
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 1name + description~100 tokens항상 (스킬 목록 표시)
Level 2SKILL.md body<5K tokens스킬 활성화 시
Level 3reference/, scripts/필요시Claude가 참조할 때만

핵심 아이디어: SKILL.md는 “목차” 역할만 하고, 상세 정보는 별도 파일에 분리합니다.


실전: 500줄 이상 스킬을 단계별로 분리하기#

이제 실제로 해봅시다. Moodturn 포토카드 생성 스킬을 예시로 전체 과정을 보여드립니다.

현재 상태 분석: 왜 분리가 필요한가?#

분리하기 전에 현재 스킬의 구조를 분석합니다. 500줄 이상의 단일 파일이 왜 문제인지 이해해야, 분리 후에도 같은 실수를 반복하지 않습니다.

SKILL.md (분리 전 - 500줄 이상)
SKILL.md (분리 전 - 500줄 이상)
---
name: moodturn-photocard
description: 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 argparse
import os
import sys
from datetime import datetime
from pathlib import Path
from typing import Tuple, Optional
try:
from PIL import Image, ImageDraw, ImageFont
except 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줄만 로드되고, 나머지는 필요할 때만 로드됩니다.

SKILL.md (분리 후 - ~65줄)
---
name: moodturn-photocard
description: 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
reference/BRAND-ESSENCE.md
# Moodturn 브랜드 에센스
## 슬로건
**"감정이 지칠 때, 따뜻한 쉼표가 되어드립니다"**
## 핵심 가치
- **공감 (Empathy)**: 판단 없이 있는 그대로 받아들인다
- **성장 (Growth)**: 작은 변화도 의미 있게 여긴다
- **연결 (Connection)**: 혼자가 아님을 느끼게 한다
## 톤 앤 매너
| 상황 | 톤 | 예시 |
| ----------- | ------------------- | ---------------------------------------- |
| 일상 공감 | 따뜻한, 곁에 있는 | "오늘 하루도 수고 많으셨어요" |
| 위로/공감 | 부드러운, 판단 없는 | "그럴 수 있어요. 충분히 힘드셨을 거예요" |
| 성장 격려 | 응원하는, 진심어린 | "작은 한 걸음도 큰 의미가 있어요" |
## 문체 규칙
**DO**
- "~네요", "~어요" 등 친근한 종결어미
- 독자의 감정을 먼저 인정하기
- "괜찮아요", "충분해요" 등 수용의 표현
**DON'T**
- 가르치려는 톤 ("~해야 해요")
- 판단하는 표현 ("그건 잘못된")
- 과장된 긍정 ("무조건 좋아질 거예요!")
## 금지어
| 금지어 | 이유 | 대체어 |
| ------------------- | -------------- | ------------------------- |
| 힘내세요 | 강요, 부담 | "곁에 있을게요" |
| 긍정적으로 생각해요 | 감정 부정 | "그 마음 충분히 이해해요" |
| ~해야 해요 | 명령, 강요 | "~해보는 건 어떨까요" |
| 무조건 | 단정적 | "때로는", "어쩌면" |
reference/VISUAL-GUIDE.md
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
reference/MESSAGE-GUIDE.md
# Moodturn 메시지 가이드
## 문구 작성 원칙
1. **2-3줄** 이내로 간결하게
2. **줄바꿈**으로 여백 만들기
3. 첫 줄에서 **공감**, 마지막 줄에서 **위로**
4. 의문문 또는 "~네요" 종결 권장
## 감정별 문구 예시
### 지침/피로
오늘 하루,
아무것도 못 한 것 같아서
자책하고 계신가요?
숨 쉬고, 버텼잖아요.
그것만으로 충분해요.
### 불안/걱정
"괜찮아?"라는 말에
"응, 괜찮아"라고 대답했지만
사실은 괜찮지 않았던 날들.
괜찮지 않아도 괜찮아요.
### 일상 공감
월요일 아침,
일어나는 것만으로도
충분히 대단해요.
오늘 하루도 수고 많으셨어요.
### 성장/희망
작은 한 걸음도
큰 의미가 있어요.
천천히 가도 괜찮아요.
## 문구 체크리스트
- [ ] 2-3줄 이내인가?
- [ ] 금지어가 없는가?
- [ ] 판단하는 느낌이 없는가?
- [ ] 읽는 사람이 위로받는 느낌인가?

채널별 가이드 (5개 파일)

각 채널에 맞는 콘텐츠 스타일, 문구 길이, 예시를 제공합니다. Claude가 특정 채널 요청을 받으면 해당 파일만 읽습니다.

reference/CHANNEL-INSTAGRAM.md
reference/CHANNEL-INSTAGRAM.md
# Instagram 포토카드 가이드
## 이미지 스펙
| 항목 | 값 |
| -------- | --------------------- |
| 크기 | 1080 × 1080 (정사각형) |
| 비율 | 1:1 |
| 용도 | 피드 포스트 |
## 콘텐츠 스타일
**특징**
- 정사각형으로 피드에서 가장 눈에 잘 띔
- 여백이 충분해서 텍스트가 잘 읽힘
- 저장/공유가 쉬운 포맷
**문구 가이드**
- 2-3줄 권장 (너무 길면 읽기 어려움)
- 중앙 배치로 여백 활용
- 해시태그는 캡션에 별도 작성
## 해시태그 가이드
**필수 해시태그**
- #무드턴
- #마음쉼표
**콘텐츠별 선택**
| 유형 | 해시태그 |
| ----------- | ------------------------------- |
| 일상 공감 | #오늘하루 #수고했어요 #일상공감 |
| 위로 메시지 | #괜찮아요 #위로 #마음돌봄 |
| 성장/희망 | #천천히 #한걸음씩 #성장 |
## 예시 문구
### 일상 공감
오늘 하루도
수고 많으셨어요.
쉬어가도 괜찮아요.
### 위로
괜찮지 않아도
괜찮아요.
그 마음, 충분히 이해해요.
### 응원
작은 한 걸음도
큰 의미가 있어요.
천천히 가도 괜찮아요.
reference/CHANNEL-X.md
reference/CHANNEL-X.md
# X (트위터) 포토카드 가이드
## 이미지 스펙
| 항목 | 값 |
| -------- | -------------------- |
| 크기 | 1200 × 675 (가로형) |
| 비율 | 16:9 |
| 용도 | 트윗 이미지 |
## 콘텐츠 스타일
**특징**
- 타임라인에서 가로로 넓게 펼쳐짐
- 짧고 강렬한 메시지가 효과적
- 리트윗 시 텍스트와 함께 공유됨
**문구 가이드**
- 1-2줄 권장 (빠르게 읽히도록)
- 임팩트 있는 한 문장이 효과적
- 간결하고 여운 있게
## X 특화 스타일
**DO**
- 짧고 강렬한 메시지
- 공감을 부르는 질문형
- 여운이 남는 마무리
**DON'T**
- 긴 설명
- 과한 해시태그 (이미지 안에 넣지 않음)
- 너무 많은 줄바꿈
## 예시 문구
### 짧은 공감
지친 하루 끝,
숨 쉬는 것만으로 충분해요.
### 질문형
오늘 하루, 스스로에게
수고했다고 말해주셨나요?
### 한 줄 위로
괜찮지 않아도, 괜찮아요.
### 여운
당신은 이미
충분히 잘하고 있어요.
reference/CHANNEL-THREADS.md
reference/CHANNEL-THREADS.md
# Threads 포토카드 가이드
## 이미지 스펙
| 항목 | 값 |
| -------- | -------------------- |
| 크기 | 1080 × 1350 (세로형) |
| 비율 | 4:5 |
| 용도 | 스레드 포스트 |
## 콘텐츠 스타일
**특징**
- 세로로 길어서 스크롤 중 눈에 잘 띔
- 인스타보다 더 많은 텍스트 가능
- 대화체/일기체가 잘 어울림
**문구 가이드**
- 3-4줄도 가능 (세로 여백 활용)
- 일기 쓰듯 편안한 톤
- 스토리텔링 형식 권장
## Threads 특화 스타일
**DO**
- 일기/편지체 스타일
- 개인적인 톤
- 공감 포인트로 시작
**DON'T**
- 딱딱한 어조
- 광고 느낌
- 해시태그 남용
## 예시 문구
### 일기체
오늘 하루,
아무것도 못 한 것 같아서
자책하고 있었어요.
그런데 생각해보니
숨 쉬고, 버텼잖아요.
그것만으로 충분해요.
### 편지체
요즘 많이 지치셨죠?
괜찮아요.
그 마음, 충분히 이해해요.
천천히 쉬어가세요.
### 공감
"나만 이렇게 힘든 건가?"
그런 생각이 들 때가 있죠.
아니에요.
다들 각자의 무게를 안고 있어요.
reference/CHANNEL-FACEBOOK.md
reference/CHANNEL-FACEBOOK.md
# Facebook 포토카드 가이드
## 이미지 스펙
| 항목 | 값 |
| -------- | -------------------- |
| 크기 | 1200 × 630 (가로형) |
| 비율 | 1.91:1 |
| 용도 | 페이스북 공유 |
## 콘텐츠 스타일
**특징**
- 링크 공유 시 og:image와 같은 비율
- 다양한 연령층이 보는 플랫폼
- 공유/태그가 활발해서 확산력 높음
**문구 가이드**
- 2줄 권장 (가로 형태에 맞게)
- 보편적인 공감 포인트
- 세대를 아우르는 표현
## Facebook 특화 스타일
**DO**
- 보편적인 공감대
- 따뜻하고 친근한 어조
- 가족/친구에게 공유하고 싶은 메시지
**DON'T**
- 지나치게 개인적인 표현
- 특정 세대만 아는 표현
- 자극적인 톤
## 예시 문구
### 보편적 공감
오늘 하루도 수고 많으셨어요.
쉬어가도 괜찮아요.
### 가족/친구용
혼자 힘들어하지 마세요.
곁에 있을게요.
### 응원
작은 한 걸음도 의미 있어요.
천천히 가도 괜찮아요.
### 안부
요즘 어떻게 지내세요?
잘 쉬고 계신가요?
reference/CHANNEL-BLOG.md
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
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 sys
import os
from 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}")

실행 결과 예시

Terminal window
$ 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 비교

항목BeforeAfter
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의 동작 과정

  1. moodturn-photocard 스킬 활성화 → SKILL.md (~65줄) 로드
  2. “블로그 썸네일” 키워드 감지 → reference/CHANNEL-BLOG.md 참조
  3. “위로” 키워드 감지 → reference/BRAND-ESSENCE.md에서 톤 확인
  4. 문구 작성 후 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-content
description: 브랜드 가이드라인을 적용한 마케팅 콘텐츠 작성.
version: 2.1.0
metadata:
author: 마케팅팀
updated: 2024-01-15
tags: [marketing, brand, content]
---
외부 라이브러리 필요한 스킬
---
name: generating-charts
description: 데이터 시각화 차트 생성.
compatibility:
requires:
- python-pptx>=0.6.21
- matplotlib>=3.5.0
---

선택적 필드는 정말 “선택”입니다.
개인 사용 스킬이라면 name과 description만으로 충분합니다.


트러블슈팅#

문제 1: 스킬이 자동 활성화 안 됨#

아래 순서로 진단합니다.

flowchart TD A[자동 활성화 안 됨] --> B{직접 호출하면<br/>동작하나?} B -->|Yes| C[description 키워드 문제] B -->|No| D[스킬 구조/등록 문제] C --> E["description에<br/>트리거 키워드 추가"] D --> F["SKILL.md 문법 확인<br/>재업로드"]

문제 2: reference 파일을 안 읽음#

사고 과정

  1. SKILL.md에 참조 문구가 있나? → “reference/GUIDE.md 참조” 명시 확인

  2. 참조 문구가 명령형인가? → ✕ “참고하면 좋다” (약함) → ✓ “반드시 읽고 적용한다” (강함)

  3. 그래도 안 읽으면? → 직접 요청: “GUIDE.md 읽어서 적용해줘”

해결책

Before (약한 참조)
인스타그램 가이드를 참고할 수 있다.
After (강한 참조)
인스타그램 콘텐츠 작성 시 **반드시** `reference/CHANNEL-INSTAGRAM.md`를 읽고 적용한다.

문제 3: 스크립트 실행 오류#

확인 항목체크
파일 경로가 정확한가?
파일명에 오타가 없는가?
Python 환경이 설정되어 있는가?
스크립트에 실행 권한이 있는가?

나만의 고급 스킬 만들기 체크리스트#

단계체크 항목
필요성 판단☐ 500줄 이상이거나 분리가 필요한 상황인가?
☐ 아니라면 5편의 단일 파일로 충분한가?
분리 설계☐ 어떤 내용을 분리할지 식별했는가?
☐ 매번 필요한 것 vs 선택적인 것 구분했는가?
SKILL.md☐ “목차” 역할만 하는가? (5K tokens 이하)
☐ reference 파일 참조가 명확한가?
reference/☐ 각 파일이 독립적으로 이해 가능한가?
☐ 파일명이 내용을 명확히 설명하는가?
scripts/☐ 스크립트가 정말 필요한 상황인가?
☐ Claude에게 요청해서 만들었는가?
테스트☐ 분리 후에도 기존처럼 동작하는가?
☐ reference 파일이 제대로 로드되는가?

정리#

개념핵심 포인트
멀티 파일 필요 시점500줄 이상, 선택적 참조 자료 있음, 스크립트 필요
Progressive DisclosureSKILL.md는 목차, 상세는 reference/에 분리
분리 과정식별 → 구조 설계 → SKILL.md 축소 → reference 분리 → scripts 추가
스크립트 만들기Claude에게 검증 항목 명확히 설명하고 요청
핵심 원칙필요할 때만 복잡하게, 단일 파일로 충분하면 단일 파일 유지

시리즈를 마치며#

6편에 걸쳐 Claude Skills를 다뤘습니다.

내용난이도
1편Skills란 무엇인가초급
2편PPT 스킬 활용법초급
3편엑셀 스킬 활용법초급
4편커스텀 스킬 개념과 구조초급-중급
5편스킬 제작 실전 가이드중급
6편고급 기능 활용편중급-고급

권장 학습 경로

  1. 5편으로 첫 스킬 만들기 (단일 파일)
  2. 스킬이 복잡해지면 이 글 다시 읽기
  3. 필요한 부분만 멀티 파일로 확장

기억하세요

  • 처음부터 복잡하게 만들지 마세요
  • 단일 파일로 시작하고, 한계가 오면 분리하세요
  • 스크립트는 Claude에게 요청하면 됩니다
  • “Concise is key” — 간결함이 핵심입니다

여기까지 읽어주셔서 감사합니다.

Footnotes#

  1. Progressive Disclosure(점진적 공개): 사용자에게 필요한 정보만 필요한 시점에 제공하는 설계 원칙이다.

  2. context(컨텍스트): AI 모델이 대화나 작업을 처리할 때 참조하는 정보의 범위다.

  3. token(토큰): AI 모델이 텍스트를 처리하는 최소 단위로, 단어나 문자의 조각이다.

공유

이 글이 도움이 되었다면 다른 사람과 공유해주세요!

Claude Skills 완벽가이드 6편: 고급 기능 활용편
https://moodturnpost.net/posts/ai/claude-skills-custom-advanced/
작성자
Moodturn
게시일
2026-01-10
Moodturn

목차