퍼랜 대표 이상민님의 프로필 사진

퍼랜 대표 이상민

@sangmin_perlan

🤝 믿을 수 있는 전문가 찾기 SNS 전문가 매칭 플랫폼, 퍼펙트랜서 💳 최저 수수료 부터 안전거래까지 창업 · 운영 · 브랜딩 · 실행 기록

perfectlancer.kr
웹 개발앱 개발AI/머신러닝

클로드 스킬(Claude Skills)로 천재 AI 직원 고용해 최적화 블로그 글 자동화하기
안녕하세요. 퍼펙트랜서 에디터 이상민입니다. 오늘은 스킬 파일 하나만 만들어두면, 다음에 “이 주제로 글 써줘”한마디로 최적화 블로그 글을 자동화하는 모든 과정을 알려드릴게요. 총 3개 챕터로 진행됩니다. Chapter 1. 실제 스킬 파일 생성해서 블로그 글 자동화하기 (NOW!) Chapter 2. 스킬 개선을 위한 테스트 및 공유하는법 Chapter 3. Skillsmp.com 에서 다른 사람의 스킬 써보기 왜 AI는 매번 형식을 잊어버릴까요? AI는 대화가 끝나면 말했던 내용을 잊어버립니다. 사람처럼 기억하지 않아요. 이를 해결하기 위에 기존엔 지침안에 "일하는 방식"을 전부 적었습니다. 그러나 처음엔 10~20줄이던 지침이 가이드라인, 글쓰기 원칙, 좋은 글 예시등 여러 지침이 붙다보면 어느새 500~1,000줄이 넘어갔죠. 문제는 지침은 모든 대화에서 처음부터 끝까지 다 읽힌다는 거예요. 비용이 낭비되고, 정작 필요한 내용이 묻혀버립니다. 스킬은 다릅니다. 필요한 순간에 필요한 파일만 꺼내 읽습니다. 스킬이 작동하는 3단계 1단계 항상 로드 스킬 이름과 설명만 읽기 모든 스킬의 이름과 한 줄 설명이 시스템에 항상 포함됩니다. Claude는 이걸 보고 "이 요청엔 어떤 스킬이 필요하지?"를 판단해요. 2단계 요청 시 로드 SKILL.md 전체 읽기 "블로그 써줘"라는 말이 오면, 그때만 SKILL.md 전체를 불러옵니다. 다른 스킬은 건드리지 않아요. 3단계 필요 시 탐색 scripts/, references/, assets/ 파일 꺼내기 폴더 안 템플릿이나 코드가 필요할 때만 접근합니다. SKILL.md는 가볍게 유지하면서도 복잡한 작업이 가능한 이유입니다. 직접 만들어봐 - 이번 실습에서 만들것 "이 주제로 블로그 글 써줘" 한마디로 완성도 높은 초안을 .html 파일로 저장하는 스킬입니다. 시중의 블로그 자동화 도구들이 SEO 키워드 삽입 수준에 머문다면, 실제로 읽히는 글이 목표입니다. 이번에 만들 폴더 구조 실습을 위해 아래 링크에서 실습 파일을 다운로드 해주세요 https://drive.google.com/file/d/1EF0TO88nMn9H0pBbqZ0p64czOUghJrcM/view?usp=sharing 파일 1 - SKILL.md 스킬의 두뇌 역할을 합니다. 맨 위 description이 트리거예요. Claude가 대화를 보고 이 스킬을 켤지 말지 여기서 판단합니다. ▶SKILL.md 확인--- name: blog-writer description: > 블로그 글 써줘, 포스팅 초안 만들어줘, 이 주제로 글 작성해줘 라고 하면 자동으로 사용. 주제를 주면 references/writing-guide.md 원칙으로 초안 작성 후 scripts/save_blog.py 실행해서 HTML 파일 저장. 일반 질문이나 요약 작업에는 사용하지 않음. --- # 블로그 글쓰기 ## 절대 규칙 - 반드시 scripts/save_blog.py 실행해서 .html 파일로 저장 - 텍스트 답변으로 끝내지 말 것. 파일 저장까지가 완료 - writing-guide.md의 나쁜 예 → 좋은 예 패턴을 반드시 따를 것 - 금지 표현이 나오면 즉시 고쳐서 다시 쓸 것 - 글 본문에 CTA 블록 절대 쓰지 말 것 ## 입력 형식 이 주제로 블로그 글 써줘 제목 방향: [제목] 주제: [주제] 타깃 독자: [독자 상황] 분량: [글자수] 카테고리: [카테고리1] | [카테고리2] 발행: [발행자 이름] ## save_blog.py에 넘길 JSON 필드 - title: 제목 방향 기반으로 확정한 제목 - topic: 주제 그대로 - sub: 제목과 다른 한 줄 부제목 (직접 작성) - publisher: 발행 그대로 - content: 작성한 글 (META, HERO, 시각 요소 태그 포함) ## 참조 파일 - 글쓰기 원칙 + 시각 요소 기준 → references/writing-guide.md - 파일 저장 → scripts/save_blog.py 파일 2 - references/writing-guide.md 글쓰기 원칙을 여기 전부 적습니다. 이 파일만 고치면 Claude의 글쓰기 스타일이 바뀌니 SKILL.md는 건드릴 필요 없습니다. ▶writing-guide.md 확인# 블로그 글쓰기 가이드 이 가이드의 "좋은 예"가 곧 목표 문체다. 원칙만 읽지 말고 예문의 리듬과 길이를 몸에 익혀서 써라. ## 오프닝 공식 좋은 예 A — 상황 직접 묘사: 매주 월요일, 똑같은 프롬프트를 다시 입력하고 있다. "아, 지난번에 쓴 거 어디 뒀더라." 복붙하고, 조금 고치고, 다시 붙여넣고. 그게 쌓이면 결국 AI 쓰는 게 귀찮아진다. 좋은 예 B — 짧은 단언: 스킬은 다릅니다. 필요한 순간에 필요한 파일만 꺼내 읽습니다. 나쁜 예: AI를 활용하면 업무 생산성을 크게 높일 수 있습니다. 오늘은 Claude 스킬에 대해 알아보겠습니다. ## 문장 원칙 - 한 문장에 하나의 생각만. 이상적으로 20자 이내. - 단락 하나에 3문장 이내 - 수동태 금지 → 능동태로 좋은 예: Claude는 대화가 끝나면 모든 내용을 잊어버립니다. 사람처럼 기억하지 않아요. 나쁜 예: Claude는 대화 세션이 종료되면 이전 내용을 기억하지 못하기 때문에 매번 동일한 설명을 반복해야 하는 불편함이 있습니다. ## H2 섹션 제목 좋은 예: 스킬이 지침이랑 다른 진짜 이유 좋은 예: 직접 만들어봐요 — 3단계면 됩니다 좋은 예: 안 된다면 이것만 확인해보세요 나쁜 예: Claude 스킬의 개념과 특징에 대한 설명 ## CTA / 참여 유도 "~봐요" 패턴 사용: 직접 스킬 만들어봐요. 만든 파일들, Claude.ai에 올려봐요. 나쁜 예: 앞으로 Claude 스킬을 활용하여 업무 효율을 향상시키시기 바랍니다. ## 시각 요소 종류와 사용 기준 [META: 카테고리1 | 카테고리2 | 읽기시간분 | 독자설명] [HERO]: 독자 공감 대화 — 반드시 포함 [IMAGE]: 화면, 폴더 구조 등 봐야 이해 빠른 것 [CALLOUT-TIP]: "이것만 알면 됩니다" 수준의 핵심 [CALLOUT-WARN]: 모르면 반드시 실수하는 것 [CALLOUT-INFO]: 참고 정보 [COMPARE]: 스킬 전/후, 좋은 예/나쁜 예 [STEPS]: 순서대로 따라해야 하는 것 [QUOTE]: 독자가 캡처하고 싶은 문장. 글 전체를 한 문장으로. 시각 요소는 반드시 2개 이상 포함할 것. [HERO] ME: 사용자 메시지 AI: AI 답변 (문제 있는 답변) FEEDBACK: "독자 내면의 불만" ME2: 사용자가 다시 설명하는 메시지 [/HERO] [COMPARE] BEFORE: 항목1 / 항목2 AFTER: 항목1 / 항목2 [/COMPARE] [STEPS] 1. 단계 제목 | 설명 [/STEPS] ## 금지 표현 이처럼, 이로써, 따라서 → 짧은 문장 두 개로 나누기 혁신적인, 획기적인 → 구체적 수치나 예시로 ~에 대해 알아보겠습니다 → 바로 시작 ~인 것 같습니다 → 단언으로 (~입니다) ~하시기 바랍니다 → ~하면 됩니다 / ~해보세요 다양한, 여러 가지 → 3가지, 2가지 (숫자로) ## 분량 기준 전체: 1,500~2,500자 / 오프닝: 100~150자 H2 섹션 하나: 150~300자 / CTA: 50~100자 파일 3 - scripts/save_blog.py 완성된 글을 .html 파일로 저장해줍니다. 브라우저에서 바로 열면 예쁜 블로그처럼 보입니다. ▶save_blog.py 확인""" 블로그 초안 저장 스크립트 [IMAGE], [CALLOUT], [COMPARE], [STEPS], [QUOTE] 태그를 시각적인 HTML 요소로 변환해서 저장합니다. 실행: python scripts/save_blog.py '{"title":"...", "content":"...", "topic":"..."}' """ import sys, json, re from datetime import datetime from pathlib import Path def make_filename(title): clean = re.sub(r'[^가-힣\w\s]', '', title).strip() return f"{datetime.now().strftime('%Y%m%d')}_{re.sub(r'\s+', '_', clean)}.html" def parse_content(text): # 커스텀 태그 → HTML 변환 순서 text = re.sub(r'\[IMAGE:\s*(.+?)\]', lambda m: f'<div class="img-slot">📸 {m.group(1).strip()}</div>', text) text = re.sub(r'\[CALLOUT-(\w+):\s*(.+?)\]', lambda m: f'<div class="cl cl-{m.group(1).lower()}"><p>{m.group(2).strip()}</p></div>', text, flags=re.DOTALL) text = re.sub(r'\[COMPARE\](.*?)\[/COMPARE\]', parse_compare, text, flags=re.DOTALL) text = re.sub(r'\[STEPS\](.*?)\[/STEPS\]', parse_steps, text, flags=re.DOTALL) text = re.sub(r'\[QUOTE:\s*(.+?)\]', lambda m: f'<blockquote class="pq"><p>{m.group(1).strip()}</p></blockquote>', text, flags=re.DOTALL) return parse_md(text) def parse_compare(m): inner = m.group(1) bm = re.search(r'BEFORE:\s*(.+?)(?=AFTER:)', inner, re.DOTALL) am = re.search(r'AFTER:\s*(.+?)$', inner, re.DOTALL) if not bm or not am: return m.group(0) bi = ''.join(f'<div class="ci"><span>✕</span>{i.strip()}</div>' for i in bm.group(1).split('/') if i.strip()) ai = ''.join(f'<div class="ci"><span>✓</span>{i.strip()}</div>' for i in am.group(1).split('/') if i.strip()) return f'<div class="cmp"><div class="cb"><b>전</b>{bi}</div><div class="ca"><b>후</b>{ai}</div></div>' def parse_steps(m): items = re.findall(r'\d+\.\s*(.+?)\|(.+?)(?= \d+\.|\Z)', m.group(1)+' ', re.DOTALL) rows = ''.join(f'<div class="step"><div class="sn">{i}</div><div><b>{t.strip()}</b><p>{d.strip()}</p></div></div>' for i,(t,d) in enumerate(items,1)) return f'<div class="steps">{rows}</div>' def parse_md(text): out, in_ul = [], False for ln in text.split(' '): if ln.startswith('## '): if in_ul: out.append('</ul>'); in_ul=False out.append(f'<h2>{ln[3:]}</h2>') elif ln.startswith('- '): if not in_ul: out.append('<ul>'); in_ul=True out.append(f'<li>{ln[2:]}</li>') elif ln.strip()=='': if in_ul: out.append('</ul>'); in_ul=False out.append('') elif ln.startswith('<'): if in_ul: out.append('</ul>'); in_ul=False out.append(ln) else: if in_ul: out.append('</ul>'); in_ul=False out.append(f'<p>{re.sub(r"\*\*(.+?)\*\*", r"<strong>\1</strong>", ln)}</p>') return ' '.join(out) CSS = """ :root{--black:#111;--gd:#3a3a3a;--gm:#888;--gl:#f5f5f3;--gline:#e8e8e4; --accent:#ff5c35;--abg:#fff2ee;--teal:#1d9e75;--tbg:#e8f8f2; --amber:#d97706;--ambg:#fffbeb;--blue:#2563eb;--bbg:#eff6ff} *{box-sizing:border-box;margin:0;padding:0} body{font-family:'Apple SD Gothic Neo','Noto Sans KR',sans-serif; max-width:700px;margin:60px auto;padding:0 24px 80px; color:var(--black);line-height:1.8} h1{font-size:28px;font-weight:700;line-height:1.3;letter-spacing:-.02em;margin-bottom:10px} h2{font-size:21px;font-weight:700;margin:52px 0 14px;padding-top:48px; border-top:1px solid var(--gline);letter-spacing:-.01em} p{font-size:16px;color:var(--gd);margin-bottom:16px;line-height:1.9} ul{padding-left:22px;margin-bottom:16px} li{font-size:16px;color:var(--gd);margin-bottom:6px} strong{font-weight:700;color:var(--black)} .meta{font-size:13px;color:var(--gm);margin-bottom:44px; padding-bottom:20px;border-bottom:2px solid var(--black)} .img-slot{background:var(--gl);border:2px dashed #ccc;border-radius:10px; padding:28px 20px;text-align:center;margin:20px 0; font-size:14px;color:var(--gm)} .cl{border-radius:10px;padding:14px 18px;margin:20px 0} .cl p{font-size:15px;margin:0;line-height:1.7} .cl-tip{background:var(--tbg);border-left:3px solid var(--teal)} .cl-tip p{color:#1a5a40} .cl-warn{background:var(--ambg);border-left:3px solid var(--amber)} .cl-warn p{color:#7a4a00} .cl-info{background:var(--bbg);border-left:3px solid var(--blue)} .cl-info p{color:#1e3a7a} .cmp{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin:20px 0} .cb{background:#fff5f5;border:1px solid #ffd0c8;border-radius:10px;padding:16px 18px} .ca{background:var(--tbg);border:1px solid #a0ddc5;border-radius:10px;padding:16px 18px} .cb b,.ca b{font-size:11px;font-weight:700;letter-spacing:.05em;display:block;margin-bottom:8px} .cb b{color:var(--accent)}.ca b{color:var(--teal)} .ci{font-size:14px;line-height:1.7;display:flex;gap:8px;margin-bottom:5px} .cb .ci span{color:var(--accent)}.ca .ci span{color:var(--teal)} .steps{display:flex;flex-direction:column;gap:10px;margin:20px 0} .step{display:flex;gap:14px;padding:14px 17px;background:var(--gl);border-radius:10px} .sn{width:26px;height:26px;border-radius:50%;background:var(--black);color:#fff; display:flex;align-items:center;justify-content:center; font-size:11px;font-weight:700;flex-shrink:0;margin-top:2px} .step b{font-size:15px;font-weight:700;color:var(--black);display:block;margin-bottom:4px} .step p{font-size:14px;color:var(--gd);margin:0;line-height:1.6} blockquote.pq{border-top:2px solid var(--black);border-bottom:2px solid var(--black); padding:20px 24px;margin:28px 0} blockquote.pq p{font-size:19px;font-weight:700;color:var(--black);line-height:1.5;margin:0} """ def save_blog(data): title = data.get("title", "제목 없음") body = data.get("content", "") topic = data.get("topic", "") now = datetime.now().strftime("%Y년 %m월 %d일") html = f"""<!DOCTYPE html><html lang="ko"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1.0"> <title>{title}</title> <link href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@400;500;700&display=swap" rel="stylesheet"> <style>{CSS}</style></head> <body><h1>{title}</h1> <div class="meta">{now} · {topic}</div> {parse_content(body)}</body></html>""" fn = make_filename(title) Path(fn).write_text(html, encoding="utf-8") print(f"✅ {fn} 저장 완료 / {len(body):,}자") return fn if __name__ == "__main__": raw = sys.argv[1] if len(sys.argv) > 1 else sys.stdin.read() save_blog(json.loads(raw)) 파일 4 - assets/logo.png(선택) assets 폴더에 로고 이미지를 넣어두면 저장되는 .html 파일 상단에 자동으로 삽입됩니다. 없어도 스킬은 정상 작동합니다. 만든 파일들, Claude.ai에 올려봐요 1. blog-writer 폴더 안에 파일 전부 저장 blog-writer 폴더를 생성 후 안에 모든 파일들을 넣어주세요. 2. 압축 후 Claude.ai 에 업로드 해주세요 사용자 지정 → 스킬 → 스킬 만들기 → 스킬 업로드 → blog-writter.zip 선택 3. 스킬 켜기 목록에 blog-writter 스킬이 나타나면 토글을 켜고, 새 대화에서 "이 주제로 블로그 글 써줘"라고 입력해보세요. 3. 블로그 글 작성하기 Claude를 켜고 새 대화에서 아래 형식으로 입력합니다. 복붙해서 내용만 바꾸면 돼요. 이 주제로 블로그 글 써줘 제목 방향: Claude한테 같은 말 반복하다 지쳤다면 주제: Claude 스킬로 반복 업무 자동화하기 타깃 독자: Claude 써봤는데 매번 같은 설명 다시 하다가 그냥 안 쓰게 된 사람 분량: 2,500자 내외 카테고리: Claude 스킬 | 업무 자동화 발행: 퍼펙트랜서 에디터 이상민타깃 독자 잘 쓰는 법 "직장인"보다 "Claude 써봤는데 매번 같은 설명 다시 하다가 그냥 안 쓰게 된 사람"이 훨씬 좋습니다. 독자가 아니라 지금 어떤 상황인 사람으로 써주세요 4. 짜잔~ 이제 Claude가 스킬을 자동으로 감지해 블로그 글이 생성됩니다. 👉 결과물 바로 확인하기 결과가 아쉽다면? 개선 순서대로 스킬을 올렸는데 결과가 별로라면, 아래처럼 개선해보세요 아래로 내려갈수록 효과가 더 강력해요! 방법 1 — 참고할 블로그 링크 넣기 writing-guide.md 맨 아래에 이렇게 추가합니다. ## 참고 블로그 (이 스타일로 써줘) - https://blog.example.com/post-1 - https://blog.example.com/post-2 위 링크들의 문체, 단락 구조, 제목 패턴을 참고해서 글을 써줄 것. 방법 2 — 내가 잘 쓴 글 샘플 넣기 링크는 Claude가 읽지 못할 수 있습니다. 실제로 잘 쓴 내 글 텍스트를 파일로 넣어두는 게 훨씬 효과적입니다. references/my-best-posts.md (새 파일) # 내가 잘 쓴 글 샘플 이 파일의 문체와 구조를 그대로 따라 쓸 것. 제목 패턴, 오프닝 방식, 단락 길이를 참고할 것. ## 샘플 1: [글 제목] [글 내용 그대로 붙여넣기] ## 샘플 2: [글 제목] [글 내용 그대로 붙여넣기] 방법 3 — 독자 페르소나 파일 만들기 references/reader-persona.md (새 파일) # 독자 페르소나 나이: 28~35세 직업: 마케터, 기획자, 콘텐츠 제작자 AI 경험: Claude, ChatGPT 써본 적 있음 현재 상황: 매번 같은 설명 반복하다 AI 쓰는 게 귀찮아진 상태 원하는 것: 설명 없이 바로 써먹을 수 있는 방법 읽는 환경: 점심시간, 이동 중 (스마트폰) 글을 쓸 때 이 사람이 "맞아, 나 얘기네"라고 느끼는 순간을 반드시 만들 것. 방법 4 — 나쁜 결과를 스킬에 반영하기 결과물을 받고 "이런 문장이 자꾸 나와"라는 패턴이 보이면 writing-guide.md에 바로 추가합니다. writing-guide.md — 개선 예시 ## 이런 문장 나오면 다시 써줘 - "~하는 방법에 대해 알아보겠습니다" → 삭제하고 바로 시작 - "많은 분들이" → "10명 중 7명은"처럼 구체적 숫자로 - "도움이 되셨으면 합니다" → 삭제 - 문단이 5줄 넘어가면 → 두 단락으로 쪼개기 방법 6 — Claude A/B 개선법 Anthropic 공식 가이드에서 권장하는 방법으로 두 개의 Claude를 사용합니다. Claude A 스킬 개선 담당. "이 SKILL.md 보고 더 좋게 고쳐줘"라고 요청 Claude B 실제 테스트 담당. A가 고친 스킬을 실제로 써보고 결과 확인 A가 설계하고, B가 테스트합니다. 처음부터 완벽한 스킬은 없으니 이 루프를 3~5번 반복하면 확실히 결과가 좋아져요! 스킬로 지속적으로 축적되는 작업 자산 만들기 스킬은 한 번 만들어두면 계속 씁니다. 오늘 만든 파일이 다음 달에도, 내년에도 같은 퀄리티를 내요. 처음부터 완벽할 필요 없습니다. 일단 만들고, 결과 보고, 지속적으로 점차 개선 해나가는거에요. 그게 쌓이면 나만의 글쓰기 엔진이 됩니다. 글 핵심 30초만에 요약보기 AI는 대화가 끝나면 모든 걸 잊는다. 지침에 쌓아두는 방식은 한계가 있다. 스킬은 필요한 순간에만 읽히지만, 지침은 항상 전부 읽힌다. SKILL.md엔 "언제 켜지는지, 어떤 파일 참고할지"만 담는다. 내용은 references/, scripts/에 분리한다. description을 잘 써야 한다. 스킬을 켤지 말지 판단하기 때문이다. 타깃 독자는 "누구"가 아니라 "지금 어떤 상황인 사람"으로 쓴다. 처음부터 완벽할 필요 없다. 스킬을 계속 수정해나가자
0

사업에서 문제는 속도가 느린 게 아니라 방향이 자주 흔들리는 거야 오늘은 기능, 내일은 마케팅, 모레는 브랜딩. 다 중요해 보여도 한 시점엔 하나만 생각해봐
0

서비스명은 예쁘게 짓는다고 끝이 나냐 검색, 상표, 도메인 이 3개가 더 중요해 이걸 놓치면,,, 브랜딩을 다시 해야 할 수도 있어 1/ 네이버 구글 검색 해보기 같은 이름이나 비슷한 발음 쓰는 곳 있으면 검색에서 밀릴 가능성이 커 2/ 영어 보단 한글로 짓기 사람들은 한글로 검색해서 한글 발음까지 꼭 같이 봐야해 3/ 상표, 도메인 검색하기 상표가 등록 되있거나 도메인이 겹치면 안돼 꼭 아래 사이트에서 검색 해봐! 상표 : https://www.kipris.or.kr 도메인 : https://domain.gabia.com 서비스명은 감각보다 검증이 먼저야 꼭 위 사항들을 지켜서 서비스 명을 지어봐!
0

요즘 느끼는 건 이거임. 내 서비스 장점 너무 많지만, 길어지면 아무도 안 읽더라. 나는 퍼펙트랜서! “SNS와 전문가 매칭을 결합해서, 콘텐츠 기반 신뢰 형성부터 안전거래까지 한번에 제공하는 플랫폼.” 이야. 다들 너희 서비스도 딱 한 줄만 남기고 가줘.
0

기존 전문가 매칭 플랫폼을 보면서 늘 답답했던 게 있어 가격은 먼저 보이는데 이 전문가가 괜찮은지는 보이지 않더라구 그 이상한 순서를 퍼펙트랜서가 180도 뒤집어볼게!
0



SNS에서 전문가를 찾는 건 쉬운데, 안전하게 맡기는 건 어렵다. 퍼펙트랜서는 “콘텐츠로 검증 → 견적 요청 → 안전거래”까지 한 번에 가는 흐름을 만들고 있어요.
0

1인 창업가가 외주 맡기다 망하는 패턴 - 요구사항을 머리로만 정리함(문서 없음) - 싸게 맡김(기준 없음) - 일정이 늦어짐(중간 산출물 없음) - 마음이 급해짐(추가 요구 폭발) - 관계가 깨짐(분쟁) 그니깐 제발.. 문서 + 중간 산출물 + 기준 3개는 만들고 시작해줘!
0