| name | blog-photo-draft |
| description | 여러 이미지(또는 디렉토리)의 흐름(시간·장면)을 분석해 사용자 제공 템플릿의 구조·톤에 맞춘 네이버 블로그 초안을 글 유형별(따라하기형·서사형·설명형 등)로 생성합니다. 대량·고해상도 이미지는 캡션 추출과 글쓰기를 배치로 분리해 컨텍스트 한계를 넘지 않게 처리합니다. 사진 블로그 초안, 이미지 블로그, 네이버 블로그 글쓰기, 따라하기 글, 포토 에세이, blog photo draft 작성 시 사용합니다. |
개요
여러 장의 이미지(맥북 스크린샷, 아이폰 Pro 사진 등)를 입력받아 **이미지의 흐름(시간·장면)**을 읽고, 사용자가 제공한 템플릿의 구조·톤에 맞춰 네이버 블로그 초안을 생성합니다.
- 입력: 개별 이미지 나열 또는
--dir로 디렉토리 일괄 수집 (jpg/jpeg/png/heic/webp).
- 흐름 파악: 비전(장면·객체·이미지 내 텍스트)과 메타데이터(EXIF 촬영시각 → 파일명 → mtime)를 결합해 순서를 잡습니다.
- 글 유형 (확장 가능): 템플릿 frontmatter
type로 지정하며, 없으면 템플릿 구조·이미지 성격으로 자동 추론합니다(별도 CLI 플래그 없음). 내장 기본 템플릿은 우선 how-to(따라하기형) 1종이고, narrative(서사형)·expository(설명·논설형)는 인식 가능한 유형으로 문서화하되 내장 템플릿은 추후 추가합니다.
- 출력: 본문 텍스트와 이미지 자리표시자를 교차 배치한 네이버 블로그용 초안(마크다운).
설계 원칙
- 캡션 추출 ↔ 글쓰기 분리 (맵-리듀스). 이미지는 캡션 추출 단계에서만 소비하고, 글쓰기는 추출된 텍스트 캡션만 사용합니다. 고해상도·다량 이미지에서도 컨텍스트·비용 한계를 넘지 않습니다.
- 사용자 템플릿이 진실의 원천, 내장 기본은 안전망. 분야별 프리셋(여행/맛집/리뷰)은 두지 않습니다.
--template로 준 외부 템플릿의 구조·톤·플레이스홀더를 그대로 따르고, 생략하면 내장 기본 골격으로 폴백합니다. 내장 기본 템플릿은 현재 how-to(따라하기형) 1종이며 폴백 기본값이기도 합니다(다른 유형은 외부 템플릿으로 받거나 추후 내장 추가). 내장 골격은 동시에 사용자가 자기 템플릿을 만들 때 베끼는 계약 예시 역할을 합니다.
- 환각 방지. 설명·논설형은 근거 없는 단정을 배제하고, 사실 주장은 출처로 뒷받침하며 하단에
출처 섹션을 둡니다.
- 벤더 독립. 특정 도구에 종속되지 않는 오픈 포맷(Agent Skills)으로 작성합니다.
사용법
/blog-photo-draft <images...> [--template <path|how-to>] [--dir <dir>] [--order auto|exif|name|mtime] [--max-images <N>] [--batch-size <N>] [--out <path>]
- 개별 이미지를 나열하거나
--dir로 디렉토리를 통째로 넘길 수 있고, 둘을 함께 쓰면 합쳐서 수집합니다.
--template은 선택입니다. 외부 파일을 주면 그 템플릿을 그대로 따르고(외부 SSoT), 생략하면 추론된 유형의 내장 기본 골격으로 폴백하며 어떤 기본을 썼는지 로그로 알립니다. 내장 이름(how-to)을 주면 내장 기본을 직접 지정합니다.
- 글 유형은 별도 플래그 없이 **템플릿 frontmatter
type**로 정합니다(외부 템플릿일 때). 템플릿 생략 시에는 이미지 흐름으로 유형을 추론합니다.
예시
# 외부 템플릿 사용(frontmatter에 type: narrative)
/blog-photo-draft --dir ./jeju-trip --template ./templates/travel.md
# 템플릿 생략 → 유형 자동 추론 후 내장 기본 골격으로 생성, 출력 파일 지정
/blog-photo-draft a.jpg b.heic c.png --out ./draft.md
# 내장 how-to 기본을 이름으로 직접 지정 + 대량 배치 처리
/blog-photo-draft --dir ./captures --template how-to --max-images 60 --batch-size 10
인자
| 인자 | 값 | 역할 |
|---|
<images...> | 파일 경로 나열 | 개별 이미지 입력. --dir와 함께 쓰면 합산 수집. |
--dir | 디렉토리 경로 | 디렉토리 안의 이미지(jpg/jpeg/png/heic/webp)를 일괄 수집. |
--template | 파일 경로 또는 how-to(내장 이름) | (선택) 외부 파일이면 그 구조·톤·플레이스홀더·frontmatter type를 따름. 생략 시 추론된 유형의 내장 기본 골격(templates/<type>.md, 현재 how-to 1종)으로 폴백, 내장 이름을 직접 줄 수도 있음. |
--order | auto / exif / name / mtime | 이미지 정렬 기준. 기본 auto(EXIF DateTimeOriginal → 파일명 자연정렬 → mtime 폴백). |
--max-images | 정수 | 처리 상한 가드. 초과 시 유사·연속 컷 그룹화/대표 샘플링하고 묶음·생략을 로그로 명시. |
--batch-size | 정수 | 배치 캡션 추출 시 한 묶음당 이미지 수. 기본값은 컨텍스트 여유에 맞춰 조정. |
--out | 파일 경로 | 초안 출력 경로. 미지정 시 표준 출력 또는 기본 파일명으로 저장. |
이미지 흐름 분석과 대량 이미지 배치 처리
이미지에서 **흐름(시간·장면 순서)**을 잡고, 다량·고해상도 이미지에서도 컨텍스트가 폭발하지 않도록 **캡션 추출과 글쓰기를 분리(맵-리듀스)**합니다. 순서는 다음과 같습니다: ① 포맷 정규화 → ② 정렬 → ③ 배치 캡션 추출 → ④ 상한·가드.
1. 포맷 정규화 (HEIC 처리)
- 입력은
jpg/jpeg/png/heic/webp를 받지만, HEIC(아이폰 Pro 기본 포맷)는 Claude 비전이 직접 읽지 못합니다. 캡션 추출 단계 전에 JPEG로 변환합니다.
- 변환은 macOS 기본 도구
sips를 우선 사용합니다(best-effort). 예: sips -s format jpeg <in.heic> --out <out.jpg>. sips가 없거나(다른 OS) 변환이 실패하면 해당 이미지는 건너뛰고 로그로 명시합니다(전체 실행을 중단하지 않음).
- 변환 산출물은 임시 디렉토리에 두고, 원본 파일명·순서 정보는 그대로 유지해 출력 자리표시자에 원본 이름이 남도록 합니다.
2. 정렬 (흐름 순서 결정)
--order 기본값 auto는 아래 우선순위로 폴백합니다(best-effort).
- EXIF
DateTimeOriginal — 촬영 시각. 사진(아이폰 등)에 대개 존재.
- 파일명 자연정렬(natural sort) — EXIF가 없을 때.
IMG_2.jpg < IMG_10.jpg처럼 숫자를 수치로 비교(사전식 IMG_10 < IMG_2 아님). 스크린샷(스크린샷 2026-06-27 ...)처럼 파일명에 시각이 박힌 경우에 특히 유효.
mtime(수정 시각) 폴백 — EXIF도 파일명 단서도 없을 때 최후 수단.
--order로 exif/name/mtime을 직접 지정하면 해당 기준만 사용합니다. 정렬 근거(어떤 키로 정렬했는지, 폴백이 일어났는지)는 로그로 남깁니다.
스크린샷은 EXIF DateTimeOriginal이 비어 있는 경우가 많아 파일명/mtime 폴백에 의존합니다.
3. 배치 캡션 추출 (맵 단계)
- 이미지는 이 단계에서만 소비합니다. 각 이미지를 보고 구조화된 캡션(장면·객체·이미지 내 텍스트·추정 시점/장소)을 텍스트로 추출합니다. 이후 글쓰기 단계는 이 캡션 텍스트만 입력으로 받습니다 — 원본 이미지를 다시 컨텍스트에 올리지 않으므로 고해상도·다량 이미지에서도 토큰이 폭발하지 않습니다.
--batch-size 단위로 묶어 N장씩 배치로 추출합니다. 배치는 서브에이전트로 병렬 처리할 수 있습니다(각 배치는 독립적). 기본 --batch-size는 컨텍스트 여유에 맞춰 조정합니다.
- 각 캡션은 원본 파일명·정렬 순번과 함께 기록해, 리듀스(글쓰기) 단계에서 흐름과 자리표시자 매핑이 보존되게 합니다.
4. 상한·가드 (--max-images)
- 입력 이미지 수가
--max-images를 초과하면, 유사·연속 컷을 그룹화하거나 대표 컷을 샘플링해 상한 안으로 줄입니다(흐름의 대표성 우선).
- 어떤 컷을 묶었는지/생략했는지를 로그로 명시합니다(조용한 누락 금지 — 사용자가 무엇이 빠졌는지 알 수 있어야 함).
--max-images 미지정 시에도 배치 추출로 다량 이미지를 처리할 수 있으나, 비용·시간 가드로 상한을 권장합니다.
템플릿 규약과 글 유형 분기
템플릿 규약
템플릿은 마크다운 + 선택적 frontmatter + 선택적 플레이스홀더로 구성합니다. 모든 요소가 선택이라, 최소한으로는 본문 구조만 적어도 동작합니다.
frontmatter 키 (모두 선택)
| 키 | 값 | 역할 |
|---|
type | how-to / narrative / expository 등 (확장 가능) | 글 유형 지정. 없으면 본문 구조·이미지 성격으로 추론. 내장 기본 템플릿은 현재 how-to. |
require_sources | true / false | true면 출처 섹션을 필수로 보고 근거·출처 정책의 결정적 후처리 가드(grep -q '^## 출처')를 켭니다. 내장 how-to·narrative는 생략(=false)이며, expository 유형에는 true가 적합합니다(내장 expository 템플릿은 추후 추가). |
sections | 문자열 목록 | 기대하는 본문 섹션 헤딩 순서. 글의 골격으로 사용. |
플레이스홀더
{{title}}/{{date}}/{{location}}처럼 {{...}} 토큰을 본문에 둘 수 있습니다. 캡션·메타데이터(EXIF 시각, 이미지 내 텍스트 등)에서 값을 채웁니다.
- 값을 못 구한 플레이스홀더는 비우거나 자리표시 문구로 두고, 지어내지 않습니다(환각 방지).
frontmatter 아래 본문은 구조·톤의 예시입니다. 생성 시 이 구조·말투를 따릅니다.
템플릿 해석 순서
--template 인자를 다음 우선순위로 해석합니다.
--template <경로> (외부 파일) — 그 템플릿이 진실의 원천(SSoT). frontmatter·본문 구조·플레이스홀더를 그대로 따릅니다.
--template how-to (내장 이름) — 해당 유형의 내장 기본 골격(templates/<type>.md)을 직접 지정합니다. 현재 내장은 how-to 1종입니다.
--template 생략 — 유형을 추론한 뒤, 추론된 유형의 내장 기본 골격으로 폴백합니다. 현재 내장 골격은 how-to 1종이므로, 추론된 유형의 내장 파일이 아직 없으면 how-to로 폴백하거나(또는 외부 템플릿 사용을 권합니다) 어떤 기본 골격을 썼는지 로그로 알립니다.
내장 기본 골격(현재 templates/how-to.md 1종)은 폴백 대상이자, 사용자가 자기 템플릿을 만들 때 베끼는 계약 예시입니다. narrative/expository 등 다른 유형의 내장 골격은 필요할 때 추가합니다.
글 유형 판별 (how-to / narrative / expository)
별도 CLI 플래그 없이 다음 순서로 정합니다.
- 외부 템플릿이 있으면: frontmatter
type → 없으면 템플릿 본문 구조·이미지 성격으로 추론.
- 외부 템플릿이 없으면(생략): 이미지 흐름·성격으로 추론.
- 순서가 있는 절차·단계 전개가 강하면(연속 스크린샷으로 '하는 법'을 보여주면) →
how-to(따라하기형)
- 시간순 경험·장면 전개가 강하면 →
narrative(서사형)
- 정보·비교·설명·주장이 중심이면(스크린샷·도표·자료 위주) →
expository(설명·논설형)
- 추론이 모호하면
how-to를 기본값으로 삼되(현재 내장 1종), 어떤 근거로 유형을 정했는지 로그로 남겨 사용자가 바로잡을 수 있게 합니다.
근거·출처 정책과 네이버 출력 포맷
근거·출처 정책 (설명·논설형)
설명·논설형(expository)은 정보·주장을 다루므로 환각이 가장 위험한 유형입니다. 다음을 지킵니다.
- 사실 주장은 출처로 뒷받침합니다. 수치·고유명사·인과 주장 등은 근거 출처를 명시합니다.
- 미확보 주장은 추측으로 표시하거나 제외합니다. 출처를 댈 수 없으면 단정하지 말고
~로 보입니다/추정처럼 추측임을 드러내거나 문장을 뺍니다. 근거 없는 단정은 금지입니다.
- 캡션에서 읽은 사실과 글쓴이의 해석을 구분합니다. 이미지 캡션에 실제로 있던 정보(장면·텍스트)와, 그로부터의 서사·의견을 섞지 않습니다.
- 상단
목차 + 하단 출처 섹션을 둡니다. 목차는 본문 구조를 미리 보여주고, 출처 섹션은 본문에서 인용한 근거를 모읍니다.
서사형(narrative)은 개인 경험·감상이 중심이라 출처 섹션을 강제하지 않습니다. 다만 사실로 단정하는 외부 정보가 있으면 동일하게 추측 표시/출처 원칙을 적용합니다.
결정적 출처 가드 (후처리)
출처 섹션의 존재 유무는 의미 판단이 아니라 구조적 속성이므로 결정적으로 강제합니다("AI가 알아서 확인"에 의존하지 않음).
-
초안 생성 직후, 유형이 expository이면 출력물에 목차·출처 섹션이 있는지 명령으로 검사합니다.
grep -q '^## 목차' draft.md && grep -q '^## 출처' draft.md
-
가드가 실패하면(섹션 누락) 초안을 채택하지 않고 해당 섹션을 보강해 재생성하거나, 사용자에게 누락을 명시적으로 경고합니다. 조용히 넘기지 않습니다.
-
이 가드는 섹션의 존재만 결정적으로 보장합니다. 출처가 실제로 타당한지, 근거 없는 단정이 없는지는 의미 판단이라 가드 범위 밖이며 별도 검토(사람/다른 AI)가 필요합니다.
-
expository 내장 기본 템플릿을 추후 추가할 때도 동일 규약에 따라 ## 목차/## 출처 골격을 포함합니다. 현재 내장은 how-to 1종이며 require_sources: false라 이 가드를 트리거하지 않습니다(따라하기형은 '내가 직접 한 절차' 재현이 핵심).
네이버 출력 포맷
네이버 블로그 에디터는 본문을 붙여넣고 이미지를 수동 배치하는 방식이므로, 본문 텍스트와 이미지 자리표시자를 흐름 순서대로 교차 배치합니다.
- 자리표시자는
[사진: <원본파일명> (<순번>/<총장수>)] 형식으로, 정렬 단계에서 정한 흐름 순서와 원본 파일명을 그대로 노출합니다. 사용자는 이 표시를 보고 네이버 에디터에서 해당 위치에 실제 이미지를 끼워 넣습니다.
- 자리표시자는 본문 문단 사이에 단독 줄로 둬, 어느 사진이 어느 문맥에 붙는지 한눈에 보이게 합니다.
출력 예시 — 따라하기형(how-to)
# 맥북에서 스크린샷 저장 위치 바꾸는 법
## 목차
1. 준비물
2. 따라 하기
3. 마무리
## 준비물
- macOS (Ventura 이상 기준)
- 스크린샷 도구 막대(`Command + Shift + 5`)
## Step 1 — 스크린샷 도구 막대 열기
`Command + Shift + 5`를 눌러 화면 하단에 도구 막대를 띄운다.
[사진: step1.png (1/3)]
## Step 2 — 옵션에서 저장 위치 선택
도구 막대의 `옵션`을 눌러 저장 위치를 원하는 폴더로 바꾼다.
[사진: step2.png (2/3)]
## Step 3 — 확인
스크린샷을 한 장 찍어 새 위치에 저장되는지 확인한다.
[사진: step3.png (3/3)]
## 마무리
저장 위치가 바뀌지 않으면 스크린샷 앱을 완전히 종료한 뒤 다시 시도한다.
위 how-to 예시는 순서가 있는 ## Step N마다 사진 자리표시자를 1:1로 끼워, 정렬된 이미지 흐름이 곧 단계 순서가 되게 합니다.
출력 예시 — 서사형(narrative)
# 제주 2박 3일, 바람의 기록
아침 비행기에서 내리자마자 공항 밖 공기가 달랐다.
[사진: IMG_1042.jpg (1/12)]
렌터카를 받아 첫 목적지인 협재 해변으로 향했다. 에메랄드빛이라는 말이
과장이 아니었다.
[사진: IMG_1051.jpg (2/12)]
해가 질 무렵에야 숙소에 도착했다. 첫날의 피로가 노을에 씻겨 내려갔다.
출력 예시 — 설명·논설형(expository)
# 입문자를 위한 미러리스 카메라 고르기
## 목차
1. 센서 크기가 결과물을 가른다
2. 렌즈 생태계를 먼저 본다
3. 정리
## 센서 크기가 결과물을 가른다
APS-C와 풀프레임은 같은 화각에서도 심도·노이즈 특성이 다르다.
일반적으로 풀프레임이 저조도에서 유리한 것으로 평가된다[1].
[사진: sensor_compare.png (1/4)]
## 렌즈 생태계를 먼저 본다
바디보다 렌즈 선택지가 장기 만족도를 좌우하는 경우가 많다.
[사진: lens_lineup.jpg (2/4)]
## 정리
입문 단계에서는 바디 스펙보다 렌즈·예산 균형을 우선 고려하는 편이 낫다.
## 출처
[1] 제조사 공식 사양표 및 본문에서 인용한 비교 자료 — 확인한 출처로 교체할 것.
위 expository 예시는 ## 목차로 시작해 ## 출처로 끝나, 앞의 결정적 출처 가드(grep -q '^## 목차' && grep -q '^## 출처')를 통과합니다.