codex `/imagen`에 한글 헤드라인 시각화 맡기기 — brand-spec 락과 본문 기반 정확도

gpt-image-2 capability snapshot, brand-spec 락, 본문 기반 정확도(v1/v2 비교 3사례), anti-pattern 14개 명시 차단까지 — 134개 블로그 카드 이미지를 자동 생성하면서도 통일된 비주얼 시스템을 유지한 디자인 자동화 패턴을 정리합니다.

codex `/imagen`에 한글 헤드라인 시각화 맡기기 — brand-spec 락과 본문 기반 정확도

1. 문제 상황: AI가 만든 카드 이미지는 왜 다 비슷하게 생겼나

블로그 카드 이미지를 AI에 시킨 결과물은 한 눈에 알아볼 수 있습니다. 매트릭스 코드 비, 후드 쓴 해커, 신경망 노드, 회로기판 추상, 보라-파랑 그라데이션 — 모델이 “AI/기술” 키워드로 학습한 클리셰가 그대로 나옵니다. 그리고 한글 헤드라인은 자모가 깨지거나 아예 영문으로 대체됩니다.

134개 글에 통일된 카드를 박으려면 이걸 모두 막아야 했습니다.

  • 클리셰 차단: 글마다 다른 본문 시각화. 매트릭스 코드 비 같은 일반 모티프 금지
  • 한글 렌더 정확도: 헤드라인이 깨지지 않고 정자체로 박힘
  • 브랜드 일관성: 134개가 한 가족처럼 보이는 동일한 비주얼 시스템
  • 자동화 가능: 글 한 편에 1-3분 안에 끝나는 흐름

쉬워 보이지만 셋이 동시에 안 됩니다. “LLM에 글 본문 보내서 알아서 만들어라”라고 하면 일관성이 깨지고, 템플릿을 박아두면 클리셰가 박힙니다. 한글 텍스트는 통상의 diffusion 모델에서 자주 깨집니다.

세 가지를 한 번에 푸는 길은 두 가지 발견에서 나왔습니다.

  1. gpt-image-2(codex /imagen 백엔드)는 한글을 직접 렌더링한다 — 16pt 이상 굵은 sans-serif면 자모가 정확
  2. 본문을 읽힌 LLM이 메타데이터만 본 LLM보다 시각 디테일에 정확하다 — RAG 정확도의 일반 원리

이 둘을 합치고, 클리셰 차단 + 브랜드 일관성을 위해 brand-spec.md를 codex에 매번 주입하면 됩니다.

2. 원인 분석

2.1 왜 LLM 기본 출력은 클리셰가 되는가

이미지 생성 모델은 학습 분포에 강하게 끌립니다. “AI/tech 블로그 이미지”라는 추상 키워드를 받으면 학습 데이터에 가장 흔했던 시각 패턴 — 매트릭스 코드, 해커 후드, 신경망 노드, 회로기판 — 으로 회귀합니다.

이 회귀를 막으려면 두 가지가 필요합니다.

  1. 금지 목록을 명시 — 모델이 분포 평균으로 가는 걸 명시적으로 차단
  2. 구체적 시각 요소 명시 — 본문에서 실제로 등장하는 구체 요소(코드, 다이어그램, 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의 핵심 디테일 세 가지:

  1. Layout이 고정입니다. 좌측 한글, 우측 토픽 일러스트, 우하단 워드마크. codex가 매번 같은 골격으로 그립니다.
  2. Anti-patterns이 명시되어 있습니다. AI 클리셰 14개를 명시적으로 차단합니다.
  3. 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. 참고 자료

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만 행 데이터셋 분류 등 “결정 + 긴 콘텐츠 가공” 형태의 모든 일괄 작업에 적용됩니다.

시리즈 목차:

  1. 134개 블로그 이미지를 0 Claude 토큰으로 — Claude×Codex 멀티에이전트 분업 패턴
  2. Ghost MCP로 134개 글 일괄 메타 작업하기 — slug↔ID 매핑과 fd-3 stdin 패턴
  3. codex /imagen에 한글 헤드라인 시각화 맡기기 — brand-spec 락과 본문 기반 정확도 ← 현재 글