HiAPI
블로그

튜토리얼

hiapi에서 Nano-Banana로 캐릭터 일관성 유지하기: 스토리보드와 이커머스에 바로 쓸 수 있는 워크플로

캐릭터 바이블(character bible) 기법은 같은 얼굴, 같은 의상, 같은 분위기를 전혀 다른 장면에서도 안정적으로 유지합니다——hiapi의 비동기 /v1/tasks 엔드포인트를 통해 Nano-Banana에서 엔드투엔드로 시연하며, 현재 예상 예산은 $0.41입니다.

Jun 16, 2026
hiapi에서 Nano-Banana로 캐릭터 일관성 유지하기: 스토리보드와 이커머스에 바로 쓸 수 있는 워크플로

요약

반복 등장하는 캐릭터를 생성해 본 적이 있다면——스토리보드 마스코트, 브랜드 앰버서더, 이커머스 피팅 모델——실패 패턴을 이미 잘 알 것입니다. 매 렌더링이 "대충 비슷해 보이는 사람"이고, 두 프레임을 나란히 놓는 순간 차이가 눈에 띄게 드러납니다. hiapi의 Nano-Banana 시리즈는 바로 이 문제를 위해 튜닝되었습니다. 이 글은 제가 실제로 사용하는 워크플로입니다:

  • hiapi의 세 가지 Nano-Banana 모델 모두 캐릭터 일관성 태그를 갖고 있습니다: nano-banana(고정 $0.05), nano-banana-2(1K / 2K / 4K 각각 $0.036 / $0.057 / $0.086), 그리고 nano-banana-pro(1K와 2K는 $0.057, 4K는 $0.10). 세 가지 모두 POST /v1/tasks 뒤의 비동기 태스크입니다.
  • 핵심은 참조 이미지가 아니라 캐릭터 바이블입니다. 밀도 높고 반복 가능하며 결정적인 설명 문자열을 모든 장면별 프롬프트 앞에 접두사로 붙입니다. 이미지 투 이미지도, 파인튜닝도, LoRA도 필요 없습니다. 모델 업그레이드를 견디며 소스 컨트롤에서 버전 관리하기도 매우 쉽습니다.
  • 이 글의 두 가지 데모는 모두 hiapi를 통해 실시간 렌더링됩니다: 같은 캐릭터("Mira")가 완전히 다른 조명과 장소에 등장하는 4컷 스토리보드 시퀀스, 그리고 같은 모델("Aria")이 한 번의 의상 교체를 수행하는 3컷 이커머스 시퀀스입니다.
  • Nano-Banana 렌더링 7장의 총비용은 $0.35입니다. 품질을 나란히 비교하기 위해 Pro 등급의 Mira를 한 장 추가로 렌더링하는 비용은 $0.057입니다. 이 글의 총 예상 예산: $0.41.

"캐릭터 일관성"은 실제로 무엇을 뜻하는가

일관성은 단일 속성이 아니라, 여러 번의 렌더링에서 동시에 성립해야 같은 사람처럼 느껴지는 작은 속성들의 집합입니다:

  1. 얼굴 기하학. 눈 간격, 코 길이, 턱 너비, 볼의 부피감.
  2. 피부와 모발 표식. 피부톤, 주근깨나 점, 머리색과 머릿결.
  3. 의상과 액세서리. 그 특정 재킷, 그 특정 비니, 그 특정 공구 벨트.
  4. 분위기. 자세와 표정의 레퍼토리——이 캐릭터가 자신을 드러내는 방식.

프롬프트가 충분히 밀도 있을 때, hiapi의 Nano-Banana 모델은 1, 2, 3번을 잘 처리합니다. 4번은 저자——당신——의 몫입니다. 외형만이 아니라 자세와 표정 단서를 캐릭터 바이블에 담아야 합니다.

hiapi의 세 가지 Nano-Banana 모델

작성 시점의 실시간 /api/pricing 카탈로그에서 발췌:

모델 해상도 등급 가격(USD/장) 선택 이유
nano-banana 종횡비만, 해상도 파라미터 없음 고정 $0.05 빠른 반복. 캐릭터 초안을 잡는 모델.
nano-banana-2 1K / 2K / 4K $0.036 / $0.057 / $0.086 4K 출력, 작은 글자 렌더링 능력이 훨씬 뛰어남. 현재 정책에서 2K 등급이 1K보다 비쌈.
nano-banana-pro 1K / 2K / 4K $0.057 / $0.057 / $0.10 더 선명한 디테일, 더 깊은 미세 특징, 급격한 장면 변화에서도 정체성 유지가 가장 견고함.

세 가지 모두 input.prompt와 input.aspect_ratio를 받습니다. Pro와 -2 변형은 추가로 input.resolution(1K / 2K / 4K 중 하나)을 받습니다. 고정 가격 nano-banana는 resolution 필드를 400으로 거부합니다——등급형 모델을 선택했을 때만 설정하세요.

제 경험 규칙:

  • nano-banana-2의 1K 등급에서 바이블을 반복 개선——$0.036은 현재 세 가지 중 가장 저렴합니다.
  • 프로덕션 배치는 nano-banana-2의 1K 또는 2K 등급에서 렌더링. 2K 가격은 $0.057로 Pro와 같으므로, 어차피 2K가 필요하다면 Pro를 시도해 볼 가치가 있습니다.
  • 키 비주얼 샷——최종적으로 홈페이지, 미디어 키트, 인쇄판 룩북에 실리는 프레임——은 nano-banana-pro로.

캐릭터 바이블 기법

캐릭터 바이블은 해당 캐릭터의 모든 프롬프트 앞에 접두사로 붙이는 밀도 높은 문단입니다. 모델이 흔들릴 틈이 없을 만큼 구체적이어야 하지만, 장면을 펼칠 여지를 없앨 만큼 규정적이어서는 안 됩니다.

이 글의 스토리보드 캐릭터를 위해 제가 작성한 정확한 바이블입니다:

MIRA = (
    "Mira, a 28-year-old field engineer of mixed Filipina–Polish "
    "heritage, warm olive skin, narrow oval face, dark almond eyes "
    "with light crow's-feet, thick straight black eyebrows, a small "
    "mole on the right cheek, shoulder-length wavy black hair tied "
    "loosely behind, rust-orange beanie with a small embroidered "
    "antenna patch, dust-faded denim jacket over a graphite grey "
    "t-shirt, dark cargo trousers, scuffed brown leather work boots, "
    "a battered yellow toolbelt, friendly determined expression. "
    "Cinematic photography, 35mm lens look, natural film grain, "
    "neutral colour grade."
)

이 바이블에는 여섯 가지 의도적인 설계가 있습니다:

  1. 이름을 붙인다. "Mira"는 모델에게 안정적인 핸들을 제공합니다. 이름이 이미지에 나타나지 않더라도, 프롬프트에 이름이 있으면 정체성을 고정하는 것으로 보입니다.
  2. 혼혈 배경을 명시하고, 양쪽을 모두 지목한다. "여자"나 "아시아인"은 모호합니다. "필리핀–폴란드"는 모델을 구체적인 얼굴 융합으로 몰아갑니다.
  3. 눈, 눈썹, 머리, 피부를 각각 따로 묘사한다. "예쁘다"나 "자연스럽다"에 기대지 마세요. 기하학을 명확히 적으세요.
  4. 독특한 얼굴 표식 하나. 오른쪽 볼의 점. 가끔 움직이더라도, 이 표식이 모델을 특정 정체성 공간으로 밀어 넣습니다.
  5. 의상은 느슨한 묘사가 아니라 지목으로. "작은 자수 안테나 패치가 달린 녹슨 주황색 비니"는 반복 가능합니다. "모자"는 안 됩니다.
  6. 끝에 사진 스타일 도장 하나. "Cinematic photography, 35mm lens look, natural film grain, neutral colour grade." 이것이 원래 전혀 다른 장면들 사이의 조명 언어를 일관되게 유지합니다.

그러면 장면별 프롬프트는 단순히 바이블 + 구분자 + 짧은 장면 문단입니다. 저는 " | Scene: "를 구분자로 씁니다. 로그에서 읽기 명확하고, 모델은 뒷부분을 새 요청으로 취급합니다.

hiapi 비동기 태스크 엔드포인트 호출

hiapi의 모든 이미지 모델은 동일한 비동기 패턴을 따릅니다: POST /v1/tasks로 생성, GET /v1/tasks/{taskId}로 폴링, 성공 시 data.output[0].url에서 렌더링 이미지를 읽습니다. 출력 URL은 짧게 유효하므로(expireAt 포함) 바이트를 즉시 스토리지로 다운로드하세요.

import os, json, subprocess, time

API = "https://api.hiapi.ai/v1/tasks"
TOKEN = os.environ["HIAPI_TOKEN"]


def submit(model: str, prompt: str, aspect_ratio: str,
           resolution: str | None = None) -> str:
    payload = {
        "model": model,
        "input": {"prompt": prompt, "aspect_ratio": aspect_ratio},
    }
    # Only nano-banana-pro and nano-banana-2 accept `resolution`.
    # The flat-priced nano-banana returns 400 on the extra field.
    if resolution and model in ("nano-banana-pro", "nano-banana-2"):
        payload["input"]["resolution"] = resolution

    r = subprocess.run(
        ["curl", "-s", "-X", "POST", API,
         "-H", f"Authorization: Bearer {TOKEN}",
         "-H", "Content-Type: application/json",
         "-d", json.dumps(payload)],
        capture_output=True, text=True, timeout=70,
    )
    data = json.loads(r.stdout)
    return data["data"]["taskId"]


def wait(task_id: str, timeout_s: int = 600) -> str:
    deadline = time.time() + timeout_s
    while time.time() < deadline:
        r = subprocess.run(
            ["curl", "-s", f"{API}/{task_id}",
             "-H", f"Authorization: Bearer {TOKEN}"],
            capture_output=True, text=True, timeout=40,
        )
        task = json.loads(r.stdout)["data"]
        if task["status"] == "success":
            return task["output"][0]["url"]
        if task["status"] == "fail":
            raise RuntimeError(task["error"])
        time.sleep(6)
    raise RuntimeError(f"timeout: {task_id}")


def render(model, scene, ratio, bible, resolution=None):
    prompt = f"{bible} | Scene: {scene}"
    return wait(submit(model, prompt, ratio, resolution))

Nano-Banana의 경우 6초 폴링 간격이 적절한 기본값입니다——상태가 좋은 날에는 단일 이미지가 약 10–60초 안에 도착합니다. 더 촘촘한 폴링은 왕복만 낭비합니다.

데모 A —— 같은 캐릭터의 4컷 스토리보드

스토리보드의 핵심은 이것입니다: 이야기는 패널 사이에서 변하는 것이고 주인공은 상수입니다. 저는 완전히 동일한 Mira 바이블로 캐릭터 시트 한 장과 장면 샷 두 장을 생성하겠습니다.

1단계 —— 바이블 시각화

바이블을 저장소에 커밋하기 전에, 그것으로 캐릭터 시트를 렌더링하세요. 바이블이 충분히 고정력이 있는지 판단하는 가장 저렴한 방법입니다.

sheet = render(
    "nano-banana", aspect_ratio="3:2", bible=MIRA, scene=(
        "a character model sheet on a clean white studio background, "
        "three views of Mira side by side — three-quarter view facing "
        "left, full profile facing right, three-quarter back view — "
        "same outfit, same hairstyle, same toolbelt, even neutral "
        "studio lighting, no shadows, no text labels."
    ),
)

여기서 주목할 만한 일이 일어났습니다: 바이블에 "Cinematic photography, 35mm lens look"이 명시되어 있는데도 모델은 3D 카툰 시트를 만들어냈습니다. "model sheet"나 "character sheet"를 요청할 때 가장 흔한 실패 모드입니다——이 토큰들이 미학을 훈련 데이터셋의 애니메이션 업계 참고 자료 쪽으로 끌어당깁니다. 두 가지 대처 방식이 있습니다:

  • 받아들인다. 시트는 바이블의 참고 문서이지 출시 결과물의 일부가 아닙니다. 의상, 액세서리, 대략적 비율이 보이는 것으로, 실제로 필요한 전부입니다.
  • 장면 조각에 "shot on Kodak Portra 400, full-frame DSLR, no illustration, no toon, no 3D render"를 넣어 밀어붙인다——보통 포토리얼리즘으로 끌어오기에 충분합니다.

저는 여기서 1번 방식을 택했는데, 다음 두 장면 샷이 프로덕션 프레임이기 때문입니다.

2단계 —— 같은 Mira를 완전히 다른 두 환경에 배치

workshop = render("nano-banana", "3:2", MIRA, scene=(
    "Mira in a cluttered repair workshop, leaning over a wooden "
    "workbench under a single warm hanging bulb, reading a circuit "
    "schematic on tablet, soldering iron beside her, walls lined "
    "with scavenged parts, late evening, focused expression."
))

rooftop = render("nano-banana", "3:2", MIRA, scene=(
    "Mira on a city rooftop in cold overcast morning light, kneeling "
    "to bolt a small antenna mast to a ledge, wind moving her hair, "
    "distant grey buildings, breath barely visible, concentrated "
    "working expression."
))

두 장면은 환경적으로 공통점이 전혀 없습니다——좁은 실내 공간의 따뜻한 텅스텐 조명 대 넓은 옥상의 차가운 일광. 하지만 안테나 패치가 달린 녹슨 비니는 같고, 데님 재킷은 같고, 공구 벨트는 같으며, 얼굴은 두 이미지 모두에서 같은 젊은 여성으로 읽힙니다. 이것이 바이블이 작동하는 모습입니다.

장면 사이에 무엇이 변했는가 (그리고 변하지 않은 것)

속성 작업장 옥상
광온 따뜻한 텅스텐 차가운 흐림
자세 앉아서 몸을 숙임 무릎 꿇음
배경 어수선한 실내 탁 트인 도시 옥상
하루 중 시간 늦은 밤 이른 아침
비니 ✅ 같은 녹슨 주황색 + 패치 ✅ 동일
데님 재킷 ✅ 같은 워시 ✅ 동일
공구 벨트 ✅ 같은 노란색 가죽 ✅ 동일
얼굴 기하학 ✅ 동일 ✅ 동일
점 오른쪽 볼에 위치 존재(약간 흐림)

마지막 줄이 가장 중요합니다. 완전히 다른 두 조명 상황에서 그 작은 점이 오른쪽 볼에 남아 있습니다. 이것이 바로 원하는 신호입니다.

데모 B —— 같은 모델의 3컷 이커머스 시퀀스

이커머스는 이 글의 두 데모 중 더 어려운 쪽입니다. 모델은 여러 각도와 의상 교체 사이에서 문자 그대로 완전히 동일하게 보여야 합니다. 브랜드 고객이 제품 상세 페이지에서 이 사진들을 머릿속으로 A/B 하기 때문입니다. 아주 작은 흔들림도 환상을 깨뜨립니다.

다음은 Aria의 바이블입니다:

ARIA = (
    "Aria, a 26-year-old fashion catalogue model of Korean descent, "
    "soft warm undertone skin, oval face with slightly defined "
    "cheekbones, thin straight black eyebrows, dark brown almond "
    "eyes, small natural lips with a faint warm pink, a single "
    "beauty mark just below the left eye, centre-parted glossy "
    "black hair falling straight to mid-back, ears pierced with a "
    "single small gold stud each side, no other jewellery, calm "
    "neutral expression, even soft studio lighting from front-left, "
    "clean light grey seamless paper backdrop, full-body framing, "
    "50mm portrait lens look, neutral colour balance, slight matte "
    "film finish."
)

이 바이블은 Mira 바이블이 하지 않은 세 가지를 합니다:

  • 조명과 배경을 고정합니다. 카탈로그 모델은 깔끔한 회색 배경과 평평한 좌전방 스튜디오 조명에 살아야 합니다. 둘 다 바이블에 적으면 매 렌더링이 여기서 시작합니다.
  • 구도를 지정합니다. "Full-body framing, 50mm portrait lens look"은 세 이미지 모두에서 일관되게 재현됩니다.
  • 여백을 못 박습니다. "No other jewellery"는 Nano-Banana가 렌더링 절반에서 체인이나 시계를 즉흥적으로 추가하는 것을 막는 작은 문구입니다.

1단계 —— 정면 메인 이미지

frontal = render("nano-banana", "3:4", ARIA, scene=(
    "full-body straight-on frontal e-commerce shot, Aria standing "
    "relaxed with arms at sides, wearing a structured rust-olive "
    "wool blazer (single-breasted, two buttons, notch lapel, no "
    "pattern) over a plain ivory crew-neck t-shirt and straight-leg "
    "dark indigo denim jeans, simple white leather sneakers, clean "
    "look-book composition."
))

재킷 렌더링에 대한 솔직한 설명 하나: 프롬프트는 녹슨 올리브색을 요구했지만 Nano-Banana는 따뜻한 담배 갈색으로 해석했습니다. Pantone 스타일의 특정 색상명("rust-olive", "burnt sienna", "ultramarine")은 생성에서 안정적으로 재현되지 않습니다. 브랜드 정확한 색상이 필요하다면 기본 이미지를 렌더링한 뒤 색상 전문화 모델에서 이미지 투 이미지를 한 번 실행하거나, 메인 이미지 순간에만 nano-banana-pro로 색상이 정확한 샘플 이미지를 한 장 구매하고 가격을 받아들이세요.

2단계 —— 같은 의상의 4분의 3 각도

side = render("nano-banana", "3:4", ARIA, scene=(
    "full-body three-quarter angle from her right, Aria standing "
    "relaxed, wearing the same structured rust-olive wool blazer "
    "(single-breasted, two buttons, notch lapel, no pattern) over "
    "a plain ivory crew-neck t-shirt and straight-leg dark indigo "
    "denim jeans, simple white leather sneakers, hands by her "
    "sides, look-book lighting."
))

이 부분이 캐릭터 일관성 데모에서 항상 무너지는 지점입니다: 같은 사람, 회전. 얼굴이 일관되어야 하고, 헤어스타일이 일관되어야 하며, 의상이 그녀 몸에 걸리는 방식도 일관되어야 합니다. 나란히 보면 두 사진은 같은 촬영처럼 읽힙니다——같은 모델, 같은 콜시트, 같은 메이크업 의자. 이것이 필요한 결과입니다.

3단계 —— 같은 모델, 완전히 다른 의상

swap = render("nano-banana", "3:4", ARIA, scene=(
    "full-body straight-on frontal e-commerce shot, Aria standing "
    "relaxed with arms at sides, now wearing an oversized "
    "camel-coloured double-breasted wool overcoat (mid-thigh length, "
    "wide lapels, large mother-of-pearl buttons) over a black "
    "turtleneck and straight-leg charcoal trousers, black ankle "
    "boots, look-book lighting."
))

이것이 Nano-Banana에 캐릭터 일관성 태그를 안겨준 데모입니다. 같은 얼굴, 왼쪽 눈 아래 같은 점, 같은 머리 길이와 가르마, 같은 금색 귀걸이, 같은 자세 어휘——의상과 실루엣만 바뀝니다. 가상 피팅 플로우, 자동 룩북 생성기, 대량 생산 PDP 촬영을 구축하고 있다면, 바로 이 변환을 수천 번 실행하게 될 것입니다.

언제 Nano-Banana-Pro를 써야 하는가

비용과 품질의 트레이드오프를 확인하기 위해, nano-banana-pro의 1K 등급에서 Mira를 한 장 추가로 렌더링했습니다. 현재 추정: $0.057:

같은 Mira 바이블. 같은 " | Scene: " 구분자. 모델 이름만 바꿨습니다. 이미지당 $0.007을 더 지불하면(Pro의 $0.057 대 고정 Nano-Banana의 $0.05) 실제로 얻는 것은:

  • 더 선명한 미세 디테일——한 올의 머리카락, 데님 직조, 비니의 자수 패치.
  • 덜 눈에 띄는 정체성 표식을 더 잘 유지——눈 모양과 눈썹 기울기가 Mira 시리즈의 나머지와 더 비슷하게 읽힙니다.
  • 더 나은 작은 글자 렌더링. 장면에 간판, 라벨, 로고가 썸네일 크기에서 읽혀야 한다면 Pro가 원하는 것입니다.

고사용량 장면(예: 매일 수백 프레임의 스토리보드나 절차적 카탈로그 생성)에는 nano-banana-2의 1K 등급 $0.036이 적절한 기본값입니다. Pro는 1K와 2K 모두 $0.057로 nano-banana-2의 2K와 같으므로, 2K나 메인 이미지 프레임이 필요한 곳——커버 이미지, 룩북 메인 이미지, 마케팅 원페이지——에 사용하세요.

이 글의 현재 예상 예산

렌더링 모델 등급 현재 추정
커버(Mira 태양광 발전소) Nano-Banana 16:9 고정 $0.05
캐릭터 시트 Nano-Banana 3:2 고정 $0.05
스토리보드 1 —— 작업장 Nano-Banana 3:2 고정 $0.05
스토리보드 2 —— 옥상 Nano-Banana 3:2 고정 $0.05
이커머스 —— 정면 Nano-Banana 3:4 고정 $0.05
이커머스 —— 측면 Nano-Banana 3:4 고정 $0.05
이커머스 —— 의상 교체 Nano-Banana 3:4 고정 $0.05
Pro 비교 이미지 Nano-Banana-Pro 3:2, 1K $0.057
총계 $0.41

이미지 여덟 장, Bearer 토큰 하나, HTTP 엔드포인트 하나, SDK 조립 불필요, 업스트림 계정 관리 불필요——이것이 hiapi의 용도입니다.

제가 계속 되돌아오는 실용 규칙

  1. 바이블은 한 번만 작성하고, 소스 컨트롤에, 상수 모듈에 둔다. 다른 설정 문자열처럼 대하세요. 버전 관리하세요.
  2. 바이블마다 이름 하나. "Mira", "Aria". 모델이 이름을 표시하지 않더라도, 프롬프트에 있으면 안정적인 핸들입니다.
  3. 정체성 표식 세 개를 골라 강하게 의존한다. Mira는 안테나 패치가 달린 비니, 노란색 공구 벨트, 그 점입니다. Aria는 점, 중분할 머리, 금색 귀걸이입니다. 이 셋이 한 번의 렌더링에서 살아남으면 캐릭터도 살아남습니다.
  4. Pantone 스타일 색상명을 신뢰하지 않는다. "Rust-olive"는 담배 갈색으로 흔들렸습니다. 색상이 중요하면 먼저 렌더링 후 다운스트림 보정하거나, Pro를 쓰고 의도적으로 브랜드 샘플 이미지를 촬영하세요.
  5. 사진 스타일 도장을 바이블의 끝에 둔다. "Cinematic 35mm"나 "50mm portrait lens, slight matte film finish"——맨 끝에 두면 긴 프롬프트 잘림에서 살아남습니다.
  6. 캐릭터 시트를 먼저 렌더링하고, 카툰으로 흔들릴 것을 예상한다. 정상입니다. 시트는 당신을 위한 것이지 출시용이 아닙니다. 프로덕션 샷은 같은 바이블에 장면 내 프롬프트 조각을 더해 포토리얼리즘을 유지하세요.
  7. 초안과 양산에는 nano-banana-2의 1K($0.036), 메인 이미지 샷과 2K가 필요한 모든 것에는 nano-banana-pro(1K 또는 2K 모두 $0.057). 클라이언트에 작은 스케줄러를 만들어 quality 파라미터로 모델을 선택하고 올바른 해상도를 전달하세요.
  8. 고정 가격 nano-banana는 resolution을 거부한다. 클라이언트에서 모델명으로 해당 필드를 게이트하세요. 피와 눈물로 배운 400입니다.

이것이 워크플로입니다. 바이블 하나를 가져와, 정체성 표식 세 개를 고르고, 장면 조각을 만들고, POST /v1/tasks로 트리거하면, 같은 사람이 매 렌더링의 반대편에서 걸어 나옵니다.

텍스트 바이블보다 참조 이미지 경로를 선호하나요? Ideogram 3.0 Character는 대신 업로드한 참조 이미지에서 캐릭터를 고정하며, 프롬프트 가이드는 마스코트, 동화책 페이지, 마스크 편집에서 같은 기법을 보여줍니다.

영구 AI 아티팩트로 빌드 시작하기

API 키를 받아 태스크 기반의 하나의 API로 이미지, 비디오, 오디오 모델을 호출하세요.

API 문서 보기