이미지 프롬프트 설계

원하는 얼굴이 안 나오는 문제를 36번의 버전을 거쳐 고쳤습니다. 무엇을 바꿨고, 무엇이 통하지 않았는지의 기록입니다.

대상
AI 아이돌 연습생 얼굴 생성 — 동물상 5종(고양이 · 강아지 · 늑대 · 여우 · 사슴)
모델
Gemini 2.5 Flash Image (Vertex AI) — 6개 지역 순환, 실패 시 3회 재시도
버전
v1 → v36, 결과 이미지 전부 보관
판단 기준
실존 인물을 닮지 않을 것 · 같은 얼굴로 수렴하지 않을 것 · 이미지에 글자가 없을 것 · 한 그룹처럼 보일 것

변수 설계

한 문장으로 “잘생긴 아이돌”을 요구하면 같은 얼굴만 나옵니다. 지정할 것을 축으로 쪼개고, 축마다 담당할 판단 기준을 정했습니다.

초기 변수 정의

출발점은 “무엇을 고르게 할 것인가”를 여섯 축으로 나눈 변수 정의였습니다.

분위기 / 인상VIBE얼굴 인상FACE IMPRESSION헤어스타일HAIRSTYLE헤어 컬러HAIR COLOR피부톤SKIN TONE피부 특징SKIN DETAIL
청순강아지상버즈컷자연 블랙백옥깨끗
카리스마고양이상크롭컷다크브라운내추럴베이지주근깨
시크여우상텍스처프린지애쉬그레이웜탠점
큐트모델상보울컷플래티넘올리브미세결
몽환동안소프트펌버건디딥브라운
다크울프컷밀크브라운
밝음슬릭백
롱레이어드
비대칭숏

이 정의를 그대로 프롬프트로 옮기자 얼굴이 무너졌습니다. 축이 서로를 침범했기 때문입니다. 아래는 정의가 구현으로 넘어가며 조정된 내용입니다.

초기 정의구현에서의 조정조정 이유
분위기 / 인상
청순 · 카리스마 · 시크 · 큐트 · 몽환 · 다크 · 밝음
별도 축을 없애고 얼굴상 안으로 흡수
고양이상 · 시크 / 강아지상 · 청량 / 늑대상 · 다크
분위기를 따로 지정하면 얼굴상과 충돌합니다. 시크한 강아지상을 요구하면 둘 다 흐려집니다
얼굴 인상
강아지 · 고양이 · 여우 · 모델 · 동안
동물상 5종으로 통일
모델상 · 동안 → 늑대상 · 사슴상
모델상과 동안은 기준이 다른 말입니다. 체형과 나이대를 가리키는 말이 섞이면 얼굴 축이 아니게 됩니다
헤어스타일 9종 → 20종으로 확대
얼굴 레퍼런스가 있으면 텍스트 지정을 자동으로 뺀다
같은 얼굴로 수렴하는 걸 막는 가장 싼 축입니다. 다만 양쪽에서 지정하면 서로 상쇄됩니다
헤어 컬러 · 피부톤 텍스트 축에서 제거
팔레트 고정 + 레퍼런스가 담당
색을 값으로 주면 이미지에 글자로 박히고, 한 그룹처럼 보이려면 오히려 고정해야 합니다
피부 특징
깨끗 · 주근깨 · 점 · 미세결
표식 축으로 세분화
점 12 · 주근깨 9 · 보조개 8 (위치까지 지정)
“주근깨”만 주면 얼굴 전체에 균일하게 깔립니다. 위치와 개수를 정해야 사람처럼 보입니다
(표에 없던 축) 미세 변형 7축 · 레퍼런스 대비 편차 16종 신설 고르게만 하면 같은 얼굴이 반복됩니다. 무엇을 다르게 할지도 지정해야 했습니다
표는 “무엇을 고르게 할까”의 목록이고, 프롬프트는 “그걸 어떻게 안 부딪히게 넣을까”의 문제였습니다. 축을 늘리는 것보다 겹치는 축을 합치고 빼는 일이 더 많았습니다.

얼굴 인상을 범주로 묶은 근거

처음에는 눈·코·턱을 하나씩 묘사했습니다. 결과는 과장되고 어색한 얼굴이었습니다. 부위별 지시가 서로 충돌하면서 한 사람으로 모이지 않았기 때문입니다. 그래서 부위가 아니라 인상을 한 덩어리로 지정하기로 했습니다.

동물상을 고른 데에는 세 가지 이유가 있습니다.

이유내용
눈매·표정·얼굴 크기가
한 묶음으로 움직인다
“올라간 눈매”만 지정하면 나머지가 따라오지 않습니다. 고양이상이라고 하면 눈매·얼굴 크기·표정·시선이 함께 정해집니다
팬덤이 이미 쓰는 말이다 고양이상·강아지상·늑대상은 K-pop 팬들이 아이돌을 분류할 때 쓰는 용어입니다. 사용자가 설명 없이 고를 수 있어, 제작 화면에서 그대로 선택 항목이 됩니다
인상과 개인차를 나눌 수 있다 프리셋이 인상을 정하고, 미세 변형 7축이 개인차를 만듭니다. 역할이 겹치지 않아 서로를 망가뜨리지 않습니다
// 프리셋과 미세 변형의 역할을 프롬프트에 명시해 둔다
The selected face type defines the overall impression and eye expression,
while the Individual details create subtle personal variation
without changing the fundamental face type.
부위별 묘사로 돌아가면 다시 얼굴이 무너집니다. “무엇을 고르게 할까”를 정하는 일이 곧 프롬프트 설계였습니다. 제작 화면의 선택 항목(인종 · 분위기 · 인상 · 헤어)도 이 축에서 그대로 나왔습니다.

확정한 변수 축

축무엇을 지정하나가짓수담당하는 기준
얼굴상 프리셋 눈매 · 얼굴 크기 · 표정 · 시선으로 묶은 인상 한 덩어리 5인상이 겹치지 않을 것
헤어 길이 · 컷 · 질감 · 가르마 — 얼굴과 분리해 따로 지정 20같은 얼굴로 수렴하지 않을 것
얼굴 미세 변형 눈 간격 · 쌍꺼풀 · 눈 크기 · 눈썹 · 코 · 입 · 분위기
7축 중 매번 4개를 뽑아 조합
3~4씩같은 얼굴로 수렴하지 않을 것
표식 점 · 주근깨 · 보조개 — 위치와 개수까지 지정 12 · 9 · 8개인 식별감 (과장은 금지)
의상 단색 일상복. 패턴 · 프린트 · 글자 금지 10한 그룹처럼 보일 것
액세서리 13칸 중 10칸이 “없음” — 대부분 비워 둔다 13얼굴을 가리지 않을 것
카메라 · 조명 모드(profile 4:3 / editorial 3:4) · 배경 5 · 포즈 10 · 앵글 5
팔레트는 고정
2 · 5 · 10 · 5한 그룹처럼 보일 것
레퍼런스 face는 얼굴형·헤어, pose는 상체 각도, outfit은 옷만
한 사진이 한 축만 맡는다
3종트렌드에 맞는 얼굴
레퍼런스 대비 편차 16종 중 매번 3개를 필수로 적용 16 중 3실존 인물을 닮지 않을 것

적용한 프롬프팅 기법

따로 배우고 시작한 게 아니라 결과를 보며 고치다 보니 자리를 잡았는데, 나중에 프롬프트 엔지니어링 글을 읽고 나서 각각이 이미 이름이 있는 기법이라는 걸 알았습니다.

한 일해당하는 기법
레퍼런스 사진을 붙여 얼굴형·포즈·의상을 따르게 함 Few-Shot — 말로 설명하지 않고 예시를 준다
사진마다 “face는 얼굴형만, pose는 각도만” 역할 지정 Role Prompting — 입력마다 맡을 일을 정한다
모자 · 전신 · 글자 · 실존 인물 금지 Negative Constraint — 하지 말 것을 명시한다
축을 슬롯으로 쪼개 매번 값을 뽑아 조립 Structured Prompting — 틀을 고정하고 값만 바꾼다
뒤에 올수록 강한 걸 이용해 규칙 순서를 재배치 Instruction Ordering — 위치로 우선순위를 준다

기법 이름은 박송이, 「프롬프트 엔지니어링 가이드 A to Z (기초편)」, 퓨처드릴 참고

레퍼런스가 맡은 축은 텍스트 지정이 자동으로 빠집니다. 둘 다 넣으면 서로 상쇄돼 레퍼런스가 무력해집니다. 헤어를 양쪽에서 지정했다가 겪은 일입니다.

A/B 비교 — 초기안과 현행안

같은 얼굴상 프리셋으로 생성한 초기안(v1)과 현행안(v36)을 나란히 둡니다. 조건을 하나만 바꾼 통제 실험이 아니라, 36회의 수정이 누적된 두 지점의 비교입니다.

v1 고양이상 결과
V1 — 고양이상
v36 고양이상 결과
V36 — 고양이상
v1 강아지상 결과
V1 — 강아지상
v36 강아지상 결과
V36 — 강아지상
v1 늑대상 결과
V1 — 늑대상
v36 늑대상 결과
V36 — 늑대상
v1 여우상 결과
V1 — 여우상
v36 여우상 결과
V36 — 여우상
v1 사슴상 결과
V1 — 사슴상
v36 사슴상 결과
V36 — 사슴상
v1은 배경과 구도가 프리셋마다 거의 같습니다. v36은 포즈·의상·배경이 흩어지면서도 다섯 명이 한 그룹으로 보이도록 조명과 렌즈를 고정했습니다.

레퍼런스 대비 동일인 유사도 측정

“얼굴상은 따르되 같은 사람으로 보이면 안 된다”가 가장 지키기 어려운 조건입니다. 눈으로만 보던 걸 숫자로 재봤습니다.

측정 방법

얼굴 검출YuNet — 이미지에서 가장 큰 얼굴 하나를 잡아 정렬
특징 추출SFace — 얼굴을 128차원 벡터로
유사도생성 결과와 같은 얼굴상 레퍼런스의 코사인 유사도. 레퍼런스가 2장이면 높은 쪽
판정선0.363 — OpenCV가 “같은 사람”으로 보는 기준값
표본버전당 얼굴상 5종 · 총 24개 버전 · 119장

실험 비용

총 생성량약 2,000장 이상 — 버려서 남지 않은 컷 포함
남아 있는 결과252장 (버전 35개 + 최신 + 채택본)
이미지당 출력 토큰1,290 tokens
출력 단가$30 / 1M tokens
이미지 1장약 $0.039 — 한 장에 55원꼴
입력(프롬프트 + 레퍼런스 3장)약 $0.0014 — 전체의 3% 남짓
합계약 $80 (환율 1,400원 기준 약 11만 원)
2,000장은 대략적인 추정치입니다. 실패한 컷은 그때그때 지워서 남아 있는 것은 252장뿐이고, 버전별 보관본과 작업 기억을 근거로 잡은 수치입니다.

버전별 결과

판정선 이하 — 다른 사람 판정선 초과 — 같은 사람으로 판정될 수 있음
버전레퍼
런스
평균 유사도최고 유사도 프리셋 간
수렴도
룩 편차
v1전
0.349
0.418
+0.20856.6
v2전
0.324
0.401
+0.29561.3
v3전
0.339
0.410
+0.3178.7
v5전
0.352
0.439
+0.40710.0
v7전
0.278
0.414
+0.48817.2
v8전
0.305
0.373
-0.00215.7
v9전
0.289
0.342
+0.05027.0
v10전
0.342
0.466
+0.17413.9
v11전
0.364
0.426
+0.10317.8
v12전
0.321
0.407
+0.2065.9
v13전
0.291
0.334
+0.13613.4
v14전
0.301
0.334
+0.05525.8
v15전
0.315
0.388
——
v16전
0.350
0.407
+0.10015.5
v17전
0.281
0.340
+0.04819.8
v18전
0.361
0.412
-0.0579.1
v29후
0.377
0.567
+0.20456.3
v30후
0.416
0.542
+0.3479.3
v31후
0.366
0.428
+0.13114.1
v32후
0.422
0.596
+0.48124.6
v33후
0.445
0.586
+0.53010.6
v34후
0.466
0.645
-0.01215.7
v35후
0.378
0.521
+0.21215.7
v36후
0.402
0.471
+0.25114.1

프리셋 간 수렴도 = 5명의 얼굴 영역 상관계수 평균 (낮을수록 서로 다름) · 룩 편차 = 5장의 LAB 평균색 표준편차 (낮을수록 한 그룹)

최신 버전(v36) 프리셋별

얼굴상레퍼런스 대비 유사도판정
고양이상
0.415
임계값 초과
강아지상
0.471
임계값 초과
늑대상
0.326
이하
여우상
0.347
이하
사슴상
0.449
임계값 초과

측정 결과 해석

기대와 다른 결과가 나온 항목이 있습니다.

확인한 것숫자
룩 일관성은 확실히 좋아졌다 룩 편차 56.6 → 14.1. 배경·조명·팔레트를 고정한 효과가 그대로 나타납니다
레퍼런스를 넣자 유사도가 올라갔다 평균 0.323 → 0.409. 얼굴상을 잘 따라온 대가로 원본에 가까워졌습니다
판정선을 넘는 컷이 늘었다 레퍼런스 전 27%(21/79) → 후 55%(22/40)
최신 버전도 안전하지 않다 v36은 5명 중 3명이 판정선을 넘습니다 (강아지상 0.471 · 사슴상 0.449 · 고양이상 0.415)
수렴도는 단조롭게 좋아지지 않았다 v18 -0.057로 가장 좋았다가 v33 0.530으로 되돌아갑니다. 버전당 5장이라 흔들립니다
이 측정의 한계 — 버전당 5장뿐이라 값이 크게 흔들립니다. 판단 기준 넷 중 실존 연예인 닮음과 이미지 내 글자는 자동으로 재지 못해 눈으로 확인했습니다. 버전 간 비교도 조건을 하나만 바꾼 통제된 실험이 아닙니다.

반복 실험에서 도출한 설계 원칙

모두 결과를 확인한 뒤 되돌아가 수정하며 얻은 것입니다.

배운 것무슨 일이 있었나
위치가 곧 우선순위 뒤에 올수록 강하게 먹힙니다. 표정·피부·카메라 규칙을 뒤로 뺀 뒤에야
앞의 지시를 이겼습니다
한 축은 한 곳에서만 헤어를 텍스트와 레퍼런스 양쪽에서 지정하면 서로 상쇄돼
둘 다 무력해집니다
금지만으로는 안 된다 레퍼런스에 “무시하라”만 잔뜩 걸면 기여할 자리가 없어집니다
역할을 줘야 작동합니다
AI 티의 정체는 완벽함 비대칭·잔머리·초점 이탈·삐뚠 소품 배치를
명시적으로 요구해야 사진이 됩니다
헥스코드는 글자로 박힌다 색을 #9BB3C4로 쓰면 이미지 안에 그대로 인쇄됩니다
색은 반드시 서술어로
모드가 결과를 좌우한다 profile과 editorial은 사실상 다른 사진입니다
“예전 같지 않다”의 원인이 프롬프트가 아니라 모드였던 적이 있습니다

현행 프롬프트 구조

실제 운영 중인 코드에서 그대로 인용했습니다.

기본 블록 — 인물과 얼굴 하한선

// 성별에 따라 주어가 갈리고, 얼굴 레퍼런스가 있으면 골격 문장이 바뀐다
Photorealistic photo of an extremely handsome Korean male K-pop idol,
exactly 20 years old, boyish and youthful — never looks older than 22,
no mature or manly features. Bare face, no makeup, no contouring,
no nose highlight, smooth clear skin.

Large clear eyes, high nose bridge, short narrow chin,
slim short V-line jaw — never wide, square or long.

High detail. Must NOT resemble any real celebrity.
He wears no hat, no cap, no beanie and no headwear of any kind —
his hair is fully visible. ...
Absolutely no text, no letters, no numbers, no watermark,
no logo anywhere in the image.

동물상 프리셋 — 인상을 정하는 축

// 눈·코·턱을 하나씩 묘사하면 과장된 얼굴이 나온다. 다섯 덩어리로 묶었다
고양이상 · 시크   Cat-like face type: rounded eyes with a slight upward outer tilt,
                small delicate face, cool and aloof expression,
                lips softly closed, calm distant gaze.

강아지상 · 청량   Puppy-like face type: big round friendly eyes,
                soft rounded features, bright open smile with teeth slightly showing,
                warm approachable energy.

늑대상 · 다크     Wolf-like face type: sharp upward-tilted eyes, defined brow ridge,
                high cheekbones, intense direct stare,
                mouth firmly closed, dangerous charisma.

닮았지만 다른 사람 — 편차를 강제하기

“다른 사람으로 만들라”는 추상적인 지시는 먹히지 않습니다. 편차 16종에서 매번 3개를 뽑아 레퍼런스 대비 구체적인 차이를 강제합니다. 같은 레퍼런스에서 매번 다른 얼굴이 나오게 하는 역할도 겸합니다.

Compared to the person in the attached reference photos,
this person differs as follows:
  set the eyes a little further apart;
  give noticeably fuller lips;
  make the face noticeably longer and narrower.
These differences are mandatory.

레퍼런스에 역할 주기

무시 목록만 주면 레퍼런스가 할 일이 없어집니다. 사진마다 맡을 축을 하나씩 지정했습니다.

face    얼굴형·인상·눈의 성격·헤어(길이·색·컷·질감)를 따른다
        동일인이 아니며 알아볼 수 있어서는 안 된다
        점·흉터 같은 고유 표식은 복사하지 않는다
        배경·의상·포즈·앵글·조명·색감·글자는 무시한다

pose    상체와 어깨 각도, 팔과 손의 위치, 고개 기울기, 시선 방향만 가져온다
        인물·얼굴·헤어·의상·배경·조명은 완전히 무시한다

outfit  옷만 가져온다 — 아이템·핏·레이어링·넥라인·실루엣·원단·색
        최종 크롭 안에 들어오는 부분만 재현한다
레퍼런스가 담당하는 축은 텍스트 지정을 자동으로 생략합니다. 둘 다 넣으면 서로 상쇄돼 레퍼런스가 무력해집니다.

기각한 접근

시도했다가 접은 방법과, 대신 택한 방법입니다.

시도한 것결과와 대안
워터마크를 프롬프트로 막기 여섯 번 시도해 전부 실패
→ 레퍼런스 하단 10%를 잘라내는 전처리로만 해결
배경색을 헥스코드로 지정 이미지에 글자로 인쇄됨
→ 색은 전부 서술어로
눈·코·턱을 하나씩 묘사 과장되고 어색한 얼굴
→ 동물상 5종으로 묶고, 미세 변형은 따로 분리
“아이돌 메이크업” 분필을 바른 듯한 코
→ 화장기 없는 맨얼굴로 명시
인종 키워드 고정관념에 가까운 얼굴
→ 키워드 제거
레퍼런스 사진을 그대로 참고 배경·각도·옷까지 따라옴
→ 얼굴형과 헤어만 참고하도록 역할 제한
아직 남은 문제 — 의상 레퍼런스가 크롭·노출 규칙을 이깁니다. 전신 룩북 사진이 “가슴 위로 자르라”는 지시를 누르고, 코스프레 오프숄더가 노출 금지를 이깁니다.

변수 조합 설계

한 축만 무작위로 두면 결과가 빠르게 한 얼굴로 수렴합니다. 축을 여러 겹으로 중첩했습니다.

축가짓수
동물상 프리셋5종 — 고양이 · 강아지 · 늑대 · 여우 · 사슴
헤어20종 (여자는 밥·보울컷 등 4종 제외)
얼굴 미세 변형7축 중 매번 4개 — 턱 · 턱끝 · 중안부 · 광대 · 눈 · 코 · 입
표식점 12 · 주근깨 9 · 보조개 8 (매번 전부 추첨)
의상10종 가중 추첨
액세서리13칸 중 10칸이 “없음”
레퍼런스 대비 편차16종 중 매번 3개, 필수 적용
표식은 작고 흐릿하게, 대칭이 아니게 — 과장되면 그린 것처럼 보입니다. “고유하게 만들라”와 “자연스럽게 두라”가 부딪히는 자리라 양쪽에 가드 문장을 따로 붙였습니다.