codex `/imagen`에 한글 헤드라인 시각화 맡기기 — brand-spec 락과 본문 기반 정확도
gpt-image-2 capability snapshot, brand-spec 락, 본문 기반 정확도(v1/v2 비교 3사례), anti-pattern 14개 명시 차단까지 — 134개 블로그 카드 이미지를 자동 생성하면서도 통일된 비주얼 시스템을 유지한 디자인 자동화 패턴을 정리합니다.
1. 문제 상황: AI가 만든 카드 이미지는 왜 다 비슷하게 생겼나
블로그 카드 이미지를 AI에 시킨 결과물은 한 눈에 알아볼 수 있습니다. 매트릭스 코드 비, 후드 쓴 해커, 신경망 노드, 회로기판 추상, 보라-파랑 그라데이션 — 모델이 “AI/기술” 키워드로 학습한 클리셰가 그대로 나옵니다. 그리고 한글 헤드라인은 자모가 깨지거나 아예 영문으로 대체됩니다.
134개 글에 통일된 카드를 박으려면 이걸 모두 막아야 했습니다.
- 클리셰 차단: 글마다 다른 본문 시각화. 매트릭스 코드 비 같은 일반 모티프 금지
- 한글 렌더 정확도: 헤드라인이 깨지지 않고 정자체로 박힘
- 브랜드 일관성: 134개가 한 가족처럼 보이는 동일한 비주얼 시스템
- 자동화 가능: 글 한 편에 1-3분 안에 끝나는 흐름
쉬워 보이지만 셋이 동시에 안 됩니다. “LLM에 글 본문 보내서 알아서 만들어라”라고 하면 일관성이 깨지고, 템플릿을 박아두면 클리셰가 박힙니다. 한글 텍스트는 통상의 diffusion 모델에서 자주 깨집니다.
세 가지를 한 번에 푸는 길은 두 가지 발견에서 나왔습니다.
- gpt-image-2(codex
/imagen백엔드)는 한글을 직접 렌더링한다 — 16pt 이상 굵은 sans-serif면 자모가 정확 - 본문을 읽힌 LLM이 메타데이터만 본 LLM보다 시각 디테일에 정확하다 — RAG 정확도의 일반 원리
이 둘을 합치고, 클리셰 차단 + 브랜드 일관성을 위해 brand-spec.md를 codex에 매번 주입하면 됩니다.
2. 원인 분석
2.1 왜 LLM 기본 출력은 클리셰가 되는가
이미지 생성 모델은 학습 분포에 강하게 끌립니다. “AI/tech 블로그 이미지”라는 추상 키워드를 받으면 학습 데이터에 가장 흔했던 시각 패턴 — 매트릭스 코드, 해커 후드, 신경망 노드, 회로기판 — 으로 회귀합니다.
이 회귀를 막으려면 두 가지가 필요합니다.
- 금지 목록을 명시 — 모델이 분포 평균으로 가는 걸 명시적으로 차단
- 구체적 시각 요소 명시 — 본문에서 실제로 등장하는 구체 요소(코드, 다이어그램, UI)를 시각화하도록 강제
두 번째가 본문 기반 정확도와 직결됩니다. “OSC8 하이퍼링크”라는 주제만 알려주면 모델은 일반적인 “터미널 + 링크”를 그립니다. 본문에 등장하는 “자격증명이 노출된 unsafe remote URL”과 “URL encoding된 safe URL” 두 케이스를 명시하면 모델은 그 두 케이스를 시각화합니다.
2.2 한글 텍스트의 함정
이미지 생성 모델에서 한글이 깨지는 건 “모델이 한글을 못 그린다”가 아니라 “토큰화 + 디퓨전 단계에서 자모 결합이 흐트러진다”에 가깝습니다.
gpt-image-2는 이 단계에서 한글 자모 결합을 비교적 안정적으로 처리합니다. 그러나 조건이 있습니다.
| 항목 | 안정적 | 깨지기 쉬움 |
|---|---|---|
| 폰트 굵기 | 16pt+ Bold/ExtraBold | 12pt 이하 |
| 폰트 종류 | sans-serif (Pretendard, Spoqa, Noto) | 손글씨·캘리그래피 |
| 블록 길이 | 헤드라인 2-3 단어 | 50자 이상 단락 |
| 한+영 혼용 | 가능 | 한 줄에 한자 추가 시 흔들림 |
brand-spec.md는 이 조건을 명시해야 합니다. “한글 헤드라인 64-72pt Pretendard ExtraBold”처럼 구체적으로.
2.3 134개 일관성 = brand-spec 한 파일
134번 호출하는데 일관된 결과가 나오려면 codex에 매번 같은 디자인 토큰을 주입해야 합니다. Brand-spec을 단일 파일로 만들고, 매 호출에 참조시키는 게 가장 단순합니다.
이 spec이 codex에게 “어떻게 그릴지”의 전체 규칙을 한 번에 전달합니다. 134번의 호출 모두 같은 락을 읽으니, 결과가 시각적으로 한 가족처럼 보입니다.
3. 해결: brand-spec 락 + 본문 기반 프롬프트
3.1 brand-spec.md 구조
실제로 운영 중인 spec의 골격입니다. 약 250줄, 7KB.
# blog.uppinote.dev — Feature Image Brand Visual System
## Format
- 16:9 widescreen, landscape
- ~1672×941 (gpt-image-2 natural 16:9 output)
- Format: PNG, raw output, no post-processing
## Background system
- Primary: deep navy #0F172A
- Secondary navy: #1E293B
- Diagonal grid lines 32px, color #1E293B, 5% opacity
## Layout (fixed)
+--------------------------+---------------------------+
| Korean headline | Topic-specific |
| (Pretendard ExtraBold, | illustration |
| 64-72pt) | (diagram / UI mockup / |
| Korean subhead | concept art) |
| English mono caption | |
+--------------------------+---------------------------+
blog.uppinote.dev
## Typography
- Korean headline: Pretendard ExtraBold 64-72pt
- Korean subhead: Pretendard Medium 26-28pt
- English caption: JetBrains Mono 14-16pt
- Color: #F8FAFC (primary), category accent for one keyword
## Category accent colors
| Tag pattern | Accent (hex) |
|----------------------------|--------------|
| AI/Claude Code, AI/도구활용 | #F97316 |
| 백엔드/API설계, /Prisma... | #14B8A6 |
| 프론트엔드/Next.js, /React... | #6366F1 |
| 인프라/Docker, /네트워크 | #10B981 |
| Ghost/... | #A855F7 |
| 자동화/n8n, /블로그 | #10B981 |
| 도구/GitHub, /Obsidian... | #F97316 |
| 개발환경/Rust, /Shell... | #F97316 |
## Right-side illustration rules
- Must depict something that actually appears in the post body
(a code snippet, a diagram, a UI mockup, a specific number)
- Use clean line-art (1.5-2px stroke, color #94A3B8)
or low-poly geometric forms
- For terminal mockups: macOS-style rounded rectangle in #1E293B
with 1px #334155 border, three traffic-light dots
(red #FF5F57, yellow #FEBC2E, green #28C840, 12px each)
- For architecture diagrams: 1px hairline boxes, rounded 8px
## Text Integration rules
- All Korean strings must render in-image
(gpt-image-2 supports Korean directly)
- Do NOT defer to HTML/CSS overlay
- Exact strings must be quoted in the prompt
- Inside code/terminal mockups, monospace text 16-18pt minimum
## Anti-patterns (ALWAYS REJECT)
- ❌ Matrix code rain / cascading green digits
- ❌ Holographic blue grid / hexagon tech background
- ❌ Hooded hacker silhouette
- ❌ Generic AI gradient purple-blue swirl
- ❌ Neural-network connected nodes motif
- ❌ Lightbulb = idea metaphor
- ❌ Gear cogs = engineering metaphor
- ❌ Hand reaching for a glowing orb
- ❌ Stock photo of person at laptop pointing at screen
- ❌ Shocked face / open mouth YouTube thumbnail trope
- ❌ Robot mascot / android face
- ❌ Sistine-Chapel hands
- ❌ Corporate Memphis flat illustration
- ❌ Placeholder text / Lorem Ipsum
- ❌ English-only rendering when Korean is required
## Specificity gate (self-check)
Before emitting the prompt, verify:
1. Named hex colors appear (≥2)
2. Lighting has direction + hardness + color-temp
3. None of the anti-pattern cliches present
4. Korean strings quoted exactly
5. Right-side illustration references a specific element
from the post body
6. Category accent matches the primary tag
이 spec의 핵심 디테일 세 가지:
- Layout이 고정입니다. 좌측 한글, 우측 토픽 일러스트, 우하단 워드마크. codex가 매번 같은 골격으로 그립니다.
- Anti-patterns이 명시되어 있습니다. AI 클리셰 14개를 명시적으로 차단합니다.
- Category accent table이 태그 → 색상 매핑을 강제합니다. 글의 첫 태그를 보고 액센트를 결정하니, 134개가 카테고리별로 자연스러운 색 그룹을 이룹니다.
3.2 codex 호출 프롬프트 구조
gen-feature-image.sh가 codex에 넘기는 프롬프트입니다.
You are designing a feature image for a Korean technical blog.
STEP 1. Read these two files in full:
- Brand visual system spec: ~/.claude/blog-feature-image/brand-spec.md
- Post content for this image: ~/blog-drafts/<slug>.md
STEP 2. From the post content, extract:
(a) A 2-3 word Korean headline that captures the core thesis
(b) A 1-line Korean subhead (around 8-12 chars)
(c) An English monospace caption with 3-5 bullet-separated keywords
(d) ONE specific concrete element from the post body
that should be visualized in the right two-thirds of the frame
(real diagram, code snippet, UI mockup, metric)
STEP 3. Determine the category accent color from the post tags
(match against the brand spec's tag→accent table).
STEP 4. Construct an English image-generation prompt (~400 words)
using the image-studio MODE_E_THUMBNAIL output template
with sections: Content Summary, Visual Hierarchy,
Attention Elements, Text Integration, Platform Optimization,
Technical Specifications, Anti-Patterns.
STEP 5. Run /imagen with that prompt and save the raw result to:
~/blog-drafts/images/<date>/<slug>-01.png
CRITICAL: Korean strings must render in-image (not post-composed).
Right-side illustration must reflect ACTUAL post content
(not generic AI motif).
codex(GPT‑5.5 기반)는 이 다단계 지시를 한 호출 안에서 따라갑니다. 즉 codex 자체가 작은 멀티 에이전트처럼 행동합니다 — 본문 분석 → 추출 → 프롬프트 구성 → 이미지 생성 → 저장.
3.3 본문 기반 정확도 — v1 vs v2 비교
첫 시도(v1)에서는 Claude가 메타데이터(제목·태그·meta_description)만 보고 프롬프트를 직접 작성했습니다. 결과는 일반적인 추상 — “API → 분기점 → 캐시 박스” 같은 — 이미지였습니다.
두 번째 시도(v2)는 codex에 본문을 직접 읽혔습니다. 같은 글의 결과가 완전히 달라졌습니다.
사례 1: “실패도 캐싱하라 — API 클라이언트 회복력”
| 버전 | 우측 일러스트 |
|---|---|
| v1 (메타만) | API 박스 → 다이아몬드 분기 → Ok<T>(teal) / Err<E>(red) 두 캐시 박스. 일반적이고 본문과 약하게 연결됨 |
| v2 (본문 직접) | fetchUsageLimits(ttl=300) 터미널 + 6단계 흐름 (1.token → 2.memory cache → 3.fileCache → 4.pendingRequests → 5.API 429 → 6.set negative cache 30s) + 상수 NEGATIVE_CACHE_SECONDS = 30, STALE_FALLBACK_SECONDS = 3600 |
v2가 본문에 실제로 적힌 알고리즘과 상수를 시각화했습니다. v1은 “negative caching”이라는 주제어를 보고 추측한 일반적 도식이었습니다.
사례 2: “OSC8 하이퍼링크 — 두 가지 보안 함정”
| 버전 | 우측 일러스트 |
|---|---|
| v1 | 터미널 미니어처에 클릭 가능한 underlined link 한 줄 + 마우스 커서 |
| v2 | 본문의 두 함정을 시각화 — unsafe remote (자격증명 노출된 OAuth token이 URL에 박힌 케이스) vs safe remote (URL encoding된 안전한 GitHub URL), 그리고 regex (userinfo 제거) 코드 한 줄, fix-issue-#42 → fix-issue-%2342 URL encoding 예시 |
v2는 본문이 다루는 두 함정을 직접 보여줍니다. v1은 “OSC8 = 클릭 가능한 링크”라는 추상을 보여줄 뿐 함정은 시각화하지 못합니다.
사례 3: “claude-dashboard v1.25~v1.26 — 위젯을 쪼개고”
| 버전 | 우측 일러스트 |
|---|---|
| v1 | 3개 위젯 타일이 떠 있는 일반적 도식 |
| v2 | BEFORE (단일 context 위젯) → getContextData() → AFTER (3개 서브위젯 카드: contextBar / contextPercentage 80% / contextUsage 160K/200K) + 커뮤니티 기여 4개 배지(tagStatus, peakHours, Pro 7-day, Catppuccin Latte) |
v2는 “위젯을 쪼개고 커뮤니티가 보탰다”는 본문 thesis를 BEFORE/AFTER + 커뮤니티 배지로 정확히 시각화합니다.
세 사례의 공통 패턴: 메타데이터만 본 v1은 추상으로 회귀하고, 본문을 직접 읽은 v2는 본문이 실제로 다루는 구체 요소를 시각화합니다. RAG 정확도의 일반 원리가 이미지 생성에도 그대로 적용됩니다.
4. gpt-image-2 capability snapshot
prompt를 잘 만들어도 백엔드의 capability를 모르면 헛수고입니다. gpt-image-2(2026-05 기준)에서 검증된 능력과 한계입니다.
CAN (자신 있게 시도)
- 한글/영문 헤드라인 텍스트 — 16pt+ 굵은 sans-serif/serif, 자모 정확
- 다국어 혼용 — 한+영 동시 (예: “OSC8 보안 함정 / Best Practices”)
- 로고 타이포그래피 — 워드마크, 한자/한글 디자인 타이포
- 숫자/날짜 단순 표기 — “2026”, “BEST 5”, “Vol.3”
- 복잡한 레이아웃 — 헤드라인 + 서브카피 + 가격 + CTA 한 컷
- 표·UI 목업·차트 — 행/열 정렬, 라벨, 범례
- 손/얼굴/포즈 디테일 — 손가락 개수, 표정, 시선 방향
- 사진 사실성 — DSLR 룩, 조명 일관성
WEAK (조심해서 시도)
- 매우 작은 글씨 — 8pt 이하 본문은 깨질 확률 높음 → 헤드라인 위주 설계
- 긴 본문 단락 — 한 블록 50자 이상은 중간에 자모 흔들림
- 정확성이 중요한 숫자 — 가격/날짜/전화번호는 1-2글자 변형 위험 (생성 후 검수 필수)
- 손글씨/캘리그래피 한글 — 자모 결합 흔들림 잦음, 정자체 폰트가 안전
CAN'T 가정 금지 (구세대 diffusion 직감 차단)
- ❌ “한글은 어차피 깨지니까 영문으로만 만들자” — gpt-image-2는 한글 OK
- ❌ “텍스트는 빼고 만든 후 HTML/CSS로 합성하자” — 1차 직접 렌더 금지 사유 아님
- ❌ “썸네일이니까 텍스트 부분만 따로 디자인하자” — 한 컷에 통합 렌더가 정석
- ❌ “로고에 한자/한글 들어가면 안 됨” — 워드마크 직접 렌더 가능
이 capability snapshot이 brand-spec과 함께 codex의 prompt에 녹아 있어야 합니다. 안 그러면 codex가 “안전하게 영문으로 갈까?” 같은 회피를 하기 쉽습니다.
5. 결과: 134개의 통일된 카드
134개 모든 이미지가:
- 해상도 1672×941 — gpt-image-2 자연 16:9 출력
- 다크 네이비 + 카테고리 액센트 — brand-spec 락 100% 준수
- 좌측 한글 헤드라인 + 우측 본문 시각화 — 동일 레이아웃
- 우하단
blog.uppinote.dev워드마크 — 동일 위치, 미세한 30% opacity - 실패율 0건 — 134/134 정상 생성
특히 “본문 시각화”가 글마다 다르면서도 비주얼 시스템이 한 가족처럼 보이는 게 신기한 결과였습니다. brand-spec 락의 효과입니다.
6. 핵심 개념 정리
| 개념 | 한 줄 정의 |
|---|---|
| brand-spec.md | 비주얼 시스템·typography·color·anti-pattern을 한 파일에 모은 LLM-injection 디자인 토큰 |
| Category accent table | 태그 → 액센트 색상 매핑. 글 첫 태그로 결정, 카테고리별 시각 그룹 형성 |
| gpt-image-2 capability snapshot | 모델이 안정적으로 그릴 수 있는 것 / 못 그리는 것을 명시한 prompt 보조 자료 |
| Specificity gate | 프롬프트 emit 전 self-check 항목 (hex 색·조명·텍스트·반-클리셰) |
| 본문 기반 정확도 | 메타만 본 LLM보다 본문 직접 읽은 LLM이 시각 디테일에 정확하다는 RAG 원리 |
| Anti-pattern 14개 | AI 이미지 생성 클리셰를 명시 차단 (매트릭스, 후드 해커, 신경망 노드 등) |
7. 베스트 프랙티스 체크리스트
brand-spec 작성:
- [ ] Format (해상도·비율·포맷) 명시
- [ ] Layout 고정 (좌측/우측 분할, 워드마크 위치)
- [ ] Typography (폰트 종류·크기·색상)
- [ ] Category accent table (모든 태그를 색에 매핑)
- [ ] Anti-pattern 목록 (최소 10개의 명시적 차단)
- [ ] Specificity gate (self-check 5-7개 항목)
- [ ] Backend capability snapshot 인용 (gpt-image-2의 CAN/WEAK/CAN'T)
프롬프트 구성:
- [ ] 본문 파일 경로를 codex에 직접 전달 (Claude 컨텍스트 우회)
- [ ] 다단계 지시 (read → extract → construct → /imagen → save)
- [ ] 한글 string은 따옴표로 정확히 quote
- [ ] Right-side illustration은 본문의 구체 요소를 명시
- [ ] Anti-pattern을 프롬프트 끝에 “REJECT” 섹션으로 박기
검증:
- [ ] 결과 이미지 Read해서 한글 자모 확인
- [ ] 본문 핵심 요소가 우측에 시각화됐는지 확인
- [ ] 카테고리 액센트 색이 spec 표와 일치
- [ ] Anti-pattern이 새어 들어오지 않았는지 확인
8. FAQ
Q. brand-spec을 한 파일이 아니라 디렉토리로 쪼개면?
A. 단일 파일이 codex에 한 번 read로 끝나는 장점이 큽니다. 디렉토리로 쪼개면 codex가 어떤 파일을 우선 읽을지 결정해야 하고, 락이 분산됩니다. 250줄 정도라면 한 파일이 가장 단순합니다.
Q. 첫 결과가 마음에 안 들면 어떻게 재시도하나요?
A. 보통 두 길입니다. (1) 단순 재호출 — codex는 비결정적이라 두 번째가 다른 시각으로 나옵니다. (2) brand-spec에 새 anti-pattern 추가 — 같은 클리셰가 두 번 나오면 명시 차단. v2 작업에서 처음엔 “generic AI gradient purple-blue swirl”이 자주 나와 spec에 anti-pattern으로 추가했습니다.
Q. gpt-image-2가 한글을 진짜 안정적으로 그리나요?
A. 헤드라인급(16pt+ 굵은 sans-serif, 6글자 이하)은 매우 안정적입니다. 134개 중 한글 깨짐 없었습니다. 다만 본문급 작은 글씨는 위험합니다. brand-spec에서 “Korean headline 64-72pt”로 크기를 강제하는 게 이유입니다.
Q. 다른 이미지 모델(Imagen, Midjourney, Stable Diffusion)에도 적용되나요?
A. brand-spec 락은 그대로 적용됩니다. 다만 backend capability snapshot은 모델별로 다시 작성해야 합니다. Stable Diffusion은 한글 자모 결합이 약하니 “Korean rendered in-image” 가정을 빼고 “text overlay in post-processing” 흐름으로 바꿔야 합니다.
Q. v1/v2 차이가 단순히 codex가 GPT‑5.5라 똑똑해서 그런 거 아닌가요?
A. 모델 성능 차이도 일부 있지만 본질은 “본문을 직접 읽었느냐”입니다. v1에서도 Claude는 충분히 똑똑한 모델이었지만 본문이 컨텍스트에 없었습니다. v2가 더 정확한 이유는 RAG 정확도의 원리이고, codex 자리에 Claude를 두고 본문을 읽혔어도 비슷한 결과가 나왔을 겁니다.
Q. brand-spec은 어떻게 진화시키나요?
A. 새 글 카테고리가 생기면 category accent table에 한 줄, 새 클리셰가 발견되면 anti-pattern 목록에 한 줄 추가. Specificity gate는 새 self-check 항목 발견 시. 134개 작업 동안 spec은 7번 정도 업데이트됐습니다. Git 버전 관리 권장.
9. 참고 자료
- OpenAI Codex CLI GitHub
- gpt-image-2 API 가이드 (OpenAI Platform)
- Pretendard 한글 폰트
- Image Studio 프롬프트 패턴 (커뮤니티)
10. 시리즈 마무리
이 시리즈는 134개 블로그 이미지 자동화를 세 각도에서 다뤘습니다.
- 1편은 ‘왜’ — Claude는 오케스트레이션, Codex는 실행. 책임 분리로 토큰을 거의 0으로
- 2편은 ‘어떻게 매핑하나’ — slug↔ID 캐시, 페이지네이션, fd-3 stdin, parallel tool_use 한도
- 3편은 ‘어떻게 시각화하나’ — brand-spec 락, gpt-image-2 capability, 본문 기반 정확도
세 편을 함께 읽으면 “긴 콘텐츠를 다루는 일은 보조 에이전트에게 위임하고, 결정은 메인 LLM이 짧은 식별자로 지휘한다”는 멀티에이전트 분업 패턴의 완성된 그림이 됩니다. 같은 패턴은 100개 PR 리뷰, 200개 문서 마이그레이션, 1만 행 데이터셋 분류 등 “결정 + 긴 콘텐츠 가공” 형태의 모든 일괄 작업에 적용됩니다.
시리즈 목차:
- 134개 블로그 이미지를 0 Claude 토큰으로 — Claude×Codex 멀티에이전트 분업 패턴
- Ghost MCP로 134개 글 일괄 메타 작업하기 — slug↔ID 매핑과 fd-3 stdin 패턴
- codex
/imagen에 한글 헤드라인 시각화 맡기기 — brand-spec 락과 본문 기반 정확도 ← 현재 글