한 줄 요약 — "제품 사진을 넣으면 사람이 나와서 그 제품을 말로 리뷰해 주는 15초 세로영상"을 만드는 기능입니다.
지금 기능은 돌아갑니다(dev·alpha 서빙 확인). 막혀 있는 건 만드는 게 아니라 "우리가 정한 숫자가 진짜 맞는지 확인하는 일" 입니다.
인스타·틱톡에 올라오는 그 영상들 있죠. 일반인처럼 생긴 사람이 카메라 보고
"저 이거 진짜 써봤는데요, 아침마다 이거 하나면 끝나요."
하면서 제품을 들어 보이는 광고. 그걸 사람·촬영·편집 없이 제품 사진 한 장에서 뽑는 게 이 라인입니다.
[제품 사진] + [사람 레퍼런스]
│
▼
┌──────────────────┐
│ UGC 라인 (6단계) │
└──────────────────┘
│
▼
15초 세로영상 (9:16)
· 사람이 실제로 말을 함 (입모양 맞춤 = 립싱크)
· 그 제품이 화면에 그대로 나옴
채팅창에서 "제품 리뷰 영상 만들어줘" 하면 이 순서로 갑니다.
① 제품 담기 ──▶ ② 방향 고르기 ──▶ ③ 사람 캐스팅
│
▼
⑥ 마무리 ◀── ⑤ 영상 생성 ◀── ④ 대본 확인 ★
| 단계 | 무슨 일이 |
|---|---|
| ① 제품 담기 | 저장해 둔 제품을 고르거나, 제품 페이지 URL을 붙이거나, 새로 등록합니다. 실제 제품 사진은 반드시 있어야 합니다 |
| ② 방향 고르기 | "어떤 영상으로 갈지"를 우리가 미리 만들어 둔 카탈로그에서 고릅니다 (아래 3절) |
| ③ 사람 캐스팅 | 우리가 준비한 모델 목록에서 고르거나, 사용자가 자기 사진을 올립니다. 여러 각도 사진이 있어야 얼굴이 안 흔들립니다 |
| ④ 대본 확인 | 여기가 이 라인의 심장입니다. 대본을 먼저 쓰고 사용자에게 실제 문장을 보여준 뒤 승인을 받습니다 — 크레딧을 쓰기 전에 |
| ⑤ 영상 생성 | 승인받은 그 프롬프트를 손대지 않고 그대로 seedance 모델에 넣습니다 |
| ⑥ 마무리 | 인스타 피드처럼 생긴 목업 안에 넣어 "올리면 이렇게 보인다"를 보여줍니다 |
영상 1편이 곧 돈(크레딧)입니다. 만들고 나서 "대사가 이상한데요" 하면 그 돈은 이미 날아갔습니다.
그래서 글자는 공짜, 영상은 유료라는 순서를 강제합니다.
⛔ 그리고 ⑤에서 대본을 다시 쓰지 못하게 막아뒀습니다. 글 쓰는 모델은 같은 입력에도 매번 다른 문장을 씁니다 — 다시 부르면 사용자가 본 대본과 영상이 말하는 대본이 갈라집니다.
가장 중요한 설계 판단입니다. 모델에게 자유롭게 만들라고 하지 않습니다.
우리가 미리 검증해서 박아둔 메뉴판(카탈로그)이 있습니다.
연출 26종 × 훅 15종 × 상황 26종 × 앵글(무엇을 주장할지)
format hook setting angle
[코드가 결정] [AI가 결정]
· 이 제품 카테고리에 맞는가 · 좁혀진 후보 중 사용자 요구에 맞는 것
· 훅 끝 상태 → 연출 시작 상태가 이어지나 · 대사 본문
· 후보 좁히기
왜 나눴냐면 — 67개를 통째로 AI에 주면 요약해 버리고, 좁히기만 하고 AI를 빼면 사용자 요구가 반영되지 않습니다. 둘 다 실측으로 확인된 실패입니다.
"남들이 다 좋대요" 같은 앵글은 사용자가 그 사실을 실제로 말해줬을 때만 씁니다.
사실 없이 앵글만 주면 모델이 없는 타인 반응·없는 가격을 지어냅니다. 그래서 근거 없으면 앵글을 떨어뜨리고 경고를 답니다 — 지어낸 광고보다 밋밋한 광고가 낫습니다.
여기가 지난 한 달 작업의 대부분입니다.
AI가 대본을 씀
│
├─ 0차 · 깨진 한글 검사 ────── (코드) 재작성 2회까지
├─ 1차 · 글자 수 세기 ──────── (코드) 재작성 6회까지
├─ 2차 · 빈칸 안 채운 곳 ───── (코드) 재작성 3회까지
└─ 3차 · 뜻이 통하는가 ─────── (AI 심사역)
│
▼
사용자에게 보여주고 승인
네 검문소 모두 "작업을 죽이지 않습니다." 재시도를 다 써도 통과시키되 경고를 붙입니다.
막아서 아무것도 안 나오는 것보다, 나오되 "이건 이런 문제가 남았습니다"를 말해주는 쪽을 택했습니다.
모델이 존재하지 않는 글자를 만듭니다. 쯤 → 쯴, 졌 → 졠, 쟁 → 잱.
카드 문구에 오타처럼 그대로 나갑니다. 제공사를 바꿔 실험해도 손상률이 같아서 전송 문제가 아니라 모델이 글자를 만드는 층의 결함으로 확정했습니다. 그래서 라우팅이 아니라 검출 → 재작성으로 막습니다.
AI는 자기가 쓴 글자 수를 못 셉니다. 169자를 써놓고 "범위 안입니다"라고 자기보고한 실측이 있습니다.
그런데 이게 영상 품질을 직접 망칩니다.
대본이 짧으면 → 남는 시간을 영상 모델이 [지어낸 말]로 채웁니다
대본이 길면 → 발화가 밀려 [입모양이 어긋납니다] (립싱크 드리프트)
그래서 글자 수만큼은 코드가 셉니다. 15초 한국어 기준으로 층이 셋입니다.
48자 ─────────────────────────────── 87자 ← 판정(hard). 여기 벗어나야 다시 씀
54 ──────────────────── 78 ← 권고(soft). 벗어나면 경고만
58 ──────── 74 ← 지시. AI에게 주는 목표
왜 세 겹이냐 — 초당 3.57자와 3.60자 사이에 결과물의 차이가 없는데, 예전엔 그 경계에서 재작성을 시켰습니다. 15초 기준 재시도 소진율 50% 였습니다. 그래서 "지시는 보수적으로, 판정은 너그럽게"로 갈랐습니다.
문장 수도 코드가 정해서 알려줍니다. AI에게 "2~6문장"만 주면 길이와 무관하게 항상 5문장 × 15자를 씁니다(30판 실측). 15초에서 75자가 나와 상한에 딱 붙습니다. 4문장이면 60자로 한가운데인데 말이죠.
카탈로그 조각에는 제품 무관 문구가 들어 있습니다 — 그녀가 방금 말한 그 디테일을 톡 친다 같은.
이건 실제 제품 동작으로 바꿔 써야 하는 자리인데, 안 바꾸면 영상 모델이 그 대목을 자기 마음대로 연출합니다. 8편 중 3편이 그대로 새어 나간 실측이 있어 코드 검산을 붙였습니다.
글자 수로는 절대 못 잡는 게 있습니다.
"스티치가 촘촘히 박혀 있어서 쉽게 안 풀려요. 못 벗겠어요." ← 뜻이 이상함
"저 이거 그냥 장식장에 놔둘래요." ← 사겠다는 건지 처박겠다는 건지
이건 읽어야 잡힙니다. 그래서 이 자리만 AI가 판정합니다 (7개 기준: 뜻이 통하나 · 사고 싶어지나 · 준 사실을 넘지 않았나 · 화면과 안 부딪히나 · 마지막이 제품으로 착지하나 · 광고 문어체 아닌가 · 시청자에게 말을 거나).
같은 30조합을 두 방식으로 만들어 적대 감사를 붙였습니다.
| 방식 | 화면이 틀리게 나옴 |
|---|---|
| 매번 AI가 통째로 조립 | 13/30 (43%) |
| 사람이 미리 쓴 골격 + AI는 빈칸만 | 1/30 (3%) |
조합에서 어려운 부분 — 훅과 연출의 이음새, 카메라·손의 해소, 초 단위 타임라인 — 은 제품과 아무 상관이 없습니다. 그래서 그 부분은 오프라인에서 쓰고 감사받아 박제해 두고, 실행 시점 AI는 대사 N줄 + 제품 물성 설명만 채웁니다. 빈칸 채우기는 코드가 하므로 대사 누락·헤더 붕괴가 구조적으로 불가능합니다.
| 언제 | 사고 | 어떻게 막았나 |
|---|---|---|
| — | 카탈로그를 못 읽어 AI가 멋대로 창작 (#115) | 축 조회·조합 도구를 이식 |
| — | 심사역 출력이 한 겹 더 감싸져 아무 심사 없이 통과 (#224) | 언랩 + 회귀 테스트 |
| — | 훅과 연출 첫 장면이 둘 다 0초를 차지해 충돌 (#228) | 훅이 첫 비트 안에서 해소되도록 지시 |
| 8/11 | 원두 봉지에서 액체 커피가 쏟아짐 (#289~#291) | 제품 물성(PHYSICS) 블록 + 빈칸 검산(#295·#297) |
| — | 카드 한글이 간헐적으로 깨짐 (#257·#327) | 모델 생성층 결함으로 확정 → 검출·재작성 |
| — | 대사 말투가 반말/존대 뒤죽박죽, 마지막 문장이 전부 똑같음 (#306) | 존댓말 기본 고정 + 획일 마무리 제거 |
| 8/16 | 작문 규칙(4문장) ↔ 코드 게이트(2~6문장) 어긋남 — 준수율 14% (#339) | 문장 수를 코드가 계산해 지시에 실음 |
| 8/16 | 심사 기준 하나가 17판 중 0건도 못 잡음 (#338) | 기준 재작성 |
| 8/18 | 재작성 소진율 50% — 취향 문제로 예산을 태움 | 게이트 3층 분리 (지시/권고/판정) |
8/18 에 리뷰 8건 반영 → main 머지 → dev·alpha 재동기까지 끝났습니다. (PR pion-bot#5174·#5180, 배포 #5205·#5206 — 전부 머지·success 확인)
8/18 에 게이트를 넓히면서 74~87자(초당 5.0~5.82자) 구간이 새로 열렸습니다.
그런데 이 구간이 실제 seedance 출력에서 립싱크가 버티는지 확인을 못 했습니다. 세 가지가 동시에 막혔습니다.
⑴ 립싱크는 [영상을 눈으로 봐야] 판정됩니다 — 코드가 셀 수 있는 값이 아닙니다
⑵ 이 작업 머신에 aws CLI 가 없어 [dev DB 를 못 봅니다]
⑶ 우리 원장(DB)에 [영상 길이·밀도가 안 실려 있어] 그 구간만 골라낼 수가 없습니다
8/21 에 (a) dev 조회 결과 공유 / (b) 원장에 계측 추가 중 택1을 물어뒀고, 8/24 현재 응답 없음입니다.
※ 사용자 지시로 (b) 글자수 계측은 손대지 않고 대기 중입니다 — seedance 레퍼런스 프롬프트를 먼저 검토한 뒤 방향을 잡기로 했습니다.
CI 전체 이력 스캔에서 지금도 인증에 성공하는 옛 자격증명이 나왔습니다(로컬 재스캔 전수 44건: Postgres 25 · GCP 5 · Gemini 4 · Slack 5 · 기타 5).
현재 소스에는 0건인데 지운 옛 커밋의 값이 오늘도 살아 있습니다. 남은 일은 누가 언제 폐기할지 — 서비스 영향 판단이라 사람 몫입니다. UGC 기능 자체는 아니지만 같은 레포 CI를 붉게 만듭니다.
검출 기준(KS X 1001 2350자) 밖의 정상 글자(똠·펲·샾 등)를 손상으로 오판할 수 있습니다.
안 고친 이유: 통과는 시키므로 경로를 안 막고, 현재 기준은 421판 전수 대조에서 오검 0건으로 세운 것이라 재측정 없이 좁히면 진짜 손상을 놓치게 됩니다. 실제 오탐이 관측되면 그때 엽니다.
density_tol 12%(판정 여유)와 target_inset 0.7(지시를 얼마나 안쪽으로 당길지) — 둘 다 튜닝값입니다. 코드 주석에 그렇게 명기돼 있습니다. "여기부터 결과물이 망가진다"는 측정치가 아니라 "이 정도는 봐주자"는 판단입니다. ①번이 풀려야 이게 근거를 얻습니다.
문장 길이 기준은 한국어 15자만 30판 실측이고, 영어 60·일본어 16은 밀도 비율에서 역산한 값입니다. 실측 코퍼스가 쌓이면 갱신 대상으로 주석에 적어뒀습니다.
조합은 26 × 15 × 26 인데 검증된 골격은 10개입니다. 나머지는 전부 "매번 조립"(오류율 43%) 경로로 폴백합니다. 골격 하나 추가는 저작 → 적대 감사 → PASS 후 등록이라 손이 많이 듭니다. 품질 개선 효과가 가장 확실한데 가장 안 늘어난 자산입니다.
게이트를 조정해도 그래서 좋아졌는지를 사후에 볼 수 없습니다. 심사 판정은 원장에 쌓고 있는데(#315) 영상 길이·밀도가 payload 에 안 실려서 튜닝의 효과를 되짚을 수가 없습니다. ①의 ⑶번과 같은 뿌리입니다.
UGC 전용 인물 자료(바디시트 818MB·얼굴 크롭 113MB, 약 534파일)를 올리려 했는데 업로드 창구·권한이 정의되지 않아 요청이 무산됐습니다(#54, NOT_PLANNED). 지금 캐스팅은 의류 룩북용 프리셋을 빌려 쓰고 있습니다 — 돌아가긴 하지만 UGC 화자로 고른 인물들이 아닙니다.
잘 된 것 제품 사진 → 15초 말하는 영상. 6단계 여정 + 4겹 검문소로 서빙 중(dev·alpha 확인)
"매번 창작"을 버리고 검증된 메뉴판 + 미리 만든 골격으로 오류율 43% → 3%
크레딧 쓰기 전에 대본을 반드시 승인받는 순서
막힌 것 새로 연 글자수 구간이 실제 영상에서 버티는지 = 사람 눈 + dev 접근 필요 (무응답 3일)
옛 자격증명 52건 폐기 결정 (사람 몫)
아쉬운 것 게이트 핵심 상수 2개가 감이다 · 영·일 기준은 추정 · 골격 10종뿐 ·
튜닝 효과를 사후에 볼 계측이 없다 · 전용 인물 자료는 못 올렸다
근거: pion-bot apps/agent/src/mastra/tools/creagen/ugc-director/ (gate.ts · judge.ts · slots.ts · hangul-integrity.ts · ugc-skeletons.ts · review-ledger.ts) 코드·주석 실측 / creagen-space 이슈 #54·#115·#224·#228·#257·#289·#295·#306·#315·#338·#339·#362·#368 / pion-bot PR #5174·#5180·#5205·#5206 머지 상태 gh 확인.