비동기 이미지 생성 API를 사용하면 생성 요청을 제출하고 즉시 작업 식별자를 받은 다음, HTTP 연결을 계속 열어두지 않고도 나중에 완성된 이미지를 가져올 수 있습니다. 이 튜토리얼에서는 작업 수명 주기, 폴링과 웹훅을 선택해야 하는 시점, 그리고 느리거나 실패한 작업이 제품 경험을 저해하지 않도록 재시도 로직을 설계하는 방법을 다룹니다.
핵심 요약
- 이미지 생성은 요청-응답 방식이 아닌 작업(job) 기반으로 이루어집니다. 생성 지연 시간(수 초에서 수십 초)이 발생하여 동기식 연결을 유지하는 것이 불안정하기 때문입니다.
- 폴링은 구축과 디버깅이 더 간단합니다. 웹훅은 지연 시간과 요청 수를 줄여주지만, 공개 엔드포인트, 서명 검증, 중복 전달에 대한 멱등성(idempotent) 처리가 필요합니다.
- 재시도 로직은 제출 실패, 작업 중단, 웹훅 전달 누락을 구분해야 하며, 각각 다른 복구 경로가 필요합니다.
- 정확한 엔드포인트 이름, 필드 이름, 웹훅 페이로드 형태는 제공업체 및 TokenLab의 자체 API 인터페이스에 따라 다릅니다. 배포 전 항상 docs.tokenlab.sh에서 최신 사양을 확인하십시오.
이미지 생성 API가 비동기식인 이유
텍스트 완성 API는 토큰 생성이 스트리밍할 수 있을 만큼 빠르기 때문에 종종 동일한 연결에서 응답을 반환할 수 있습니다. 반면, 확산 모델(diffusion-based)이든 자기회귀 모델(autoregressive)이든 이미지 생성 모델은 일반적으로 시간이 더 오래 걸리며 해상도, 모델 선택, 대기열 깊이에 따라 지연 시간이 가변적입니다. 수십 초 동안 동기식 HTTP 요청을 열어두는 것은 불안정합니다. 클라이언트 타임아웃, 로드 밸런서 유휴 제한, 모바일 네트워크 끊김 등으로 인해 이미 비용을 지불하고 생성한 결과물을 잃어버릴 가능성이 커지기 때문입니다.
이미지 생성 제공업체 전반에서 사용되는 표준 패턴은 작업 모델입니다. 요청을 제출하고 작업 식별자와 초기 상태(일반적으로 queued 또는 processing 등)를 받습니다. 이후 작업이 종료 상태에 도달하면 상태 엔드포인트를 폴링하거나 웹훅 알림을 받고, 별도의 호출을 통해 최종 이미지 URL이나 바이너리 데이터를 가져옵니다.
TokenLab은 Nano Banana 2, Nano Banana Pro, Nano Banana 2 Lite 제품군, GPT Image 2, Reve 2.0, MAI-Image-2.5를 포함한 여러 이미지 모델에 대한 액세스를 단일 API 인터페이스를 통해 제공합니다. 현재 목록은 이미지 모델 디렉토리를, TokenLab 전용 작업 엔드포인트 동작은 비동기 이미지 생성 작업 가이드를 참조하십시오. 아래의 일반적인 패턴은 호출하는 기본 모델과 관계없이 적용되지만, 정확한 필드 이름과 상태 값은 docs.tokenlab.sh에 문서화되어 있으므로 이 문서의 내용을 추측하기보다 해당 문서를 확인해야 합니다.
작업 수명 주기: 제출, 폴링, 검색
개념적으로 비동기 이미지 작업은 세 단계로 구성됩니다.
- 제출(Submit): 프롬프트와 매개변수를 POST하고 작업 ID와 초기 상태를 받습니다.
- 상태 확인(Check status): 작업 ID를 사용하여 GET 엔드포인트를 폴링하거나 웹훅 이벤트를 기다립니다.
- 결과 검색(Retrieve output): 상태가 종료(성공 또는 실패)되면 이미지 URL이나 오류 세부 정보를 가져옵니다.
다음은 Python을 사용한 예시 폴링 패턴입니다. 엔드포인트 경로와 필드 이름은 자리 표시자로 취급하십시오. 프로덕션 환경에서 사용하기 전에 API 문서에서 현재 TokenLab 작업 엔드포인트 형태를 확인하십시오.
import time
import requests
API_BASE = "https://api.tokenlab.sh/v1" # docs.tokenlab.sh에서 현재 기본 URL 확인
HEADERS = {"Authorization": f"Bearer {API_KEY}"}
def submit_image_job(prompt, model="nano-banana-2"):
resp = requests.post(
f"{API_BASE}/images/jobs",
headers=HEADERS,
json={"prompt": prompt, "model": model, "idempotency_key": generate_key()},
)
resp.raise_for_status()
return resp.json()["job_id"]
def poll_job(job_id, max_wait_seconds=120, interval=2, backoff=1.5):
waited = 0
while waited < max_wait_seconds:
resp = requests.get(f"{API_BASE}/images/jobs/{job_id}", headers=HEADERS)
resp.raise_for_status()
data = resp.json()
if data["status"] in ("succeeded", "failed"):
return data
time.sleep(interval)
waited += interval
interval = min(interval * backoff, 15)
raise TimeoutError(f"Job {job_id} did not complete within {max_wait_seconds}s")
job_id = submit_image_job("a studio product shot on white background")
result = poll_job(job_id)
if result["status"] == "succeeded":
image_url = result["output"]["url"]
else:
print("job failed:", result.get("error"))
제출 호출 시 idempotency_key는 중요합니다. 작업이 생성된 후 클라이언트가 작업 ID를 받기 전에 네트워크 오류가 발생하면, 동일한 키로 제출 호출을 재시도하여 중복 생성을 방지하고 기존 작업을 반환받아야 합니다. 제공업체 전반에서 공통적이지만 보편적이지는 않은 패턴이므로, TokenLab의 작업 엔드포인트가 현재 문서에서 멱등성 키를 어떻게 지원하는지 확인하십시오.
폴링 vs 웹훅: 장단점
두 접근 방식 모두 유효하며, 올바른 선택은 트래픽 패턴과 인프라에 따라 달라집니다.
폴링은 구현 및 로컬 테스트가 더 간단하고 공개 엔드포인트가 필요 없으며, 몇 초의 지연 시간이 중요하지 않은 저용량 또는 배치 작업에 적합합니다. 단점은 폴링 간격만큼의 최소 지연 시간이 발생하며, 장기 실행 작업에 너무 자주 폴링할 경우 불필요한 요청이 발생한다는 점입니다.
웹훅은 작업 상태가 변경될 때 서버로 알림을 푸시하므로 지연 시간을 낮추고 낭비되는 상태 확인 호출을 줄입니다. 운영 비용은 발생합니다. 공개적으로 접근 가능한 HTTPS 엔드포인트가 필요하고, 페이로드가 제공업체로부터 왔음을 확인하기 위한 서명 검증이 필요하며, 중복되거나 순서가 뒤바뀐 전달을 처리해야 합니다.
OpenAI의 웹훅 이벤트 참조 문서는 비동기 작업을 위한 이 패턴의 일반적인 형태를 설명합니다. 엔드포인트는 유형과 객체 식별자가 포함된 이벤트를 수신하며, 권장되는 관행은 웹훅 본문을 최종 진실의 원천으로 신뢰하는 대신 API를 통해 리소스의 현재 상태를 가져오라는 알림으로 처리하는 것입니다. 이 '푸시 후 풀(pull-after-push)' 패턴은 웹훅 페이로드가 잘리거나 지연되거나 여러 번 전달되는 경우를 대비해 보호해주므로 어떤 이미지 제공업체를 통합하든 채택할 가치가 있습니다.
웹훅 안전하게 구현하기
이미지 작업 완료를 위해 웹훅을 선택하는 경우, 다음 관행을 통해 조용한 실패 가능성을 줄일 수 있습니다.
- 서명 검증: 들어오는 모든 웹훅 요청을 처리하기 전에 서명을 검증하십시오. 일치하지 않는 것은 거부하고, 일반 트래픽과 별도로 기록하여 잘못 구성된 시크릿을 빠르게 파악하십시오.
- 빠른 응답, 나중 처리: 검증이 완료되는 즉시 200 상태 코드로 웹훅을 승인하고, 실제 작업(이미지 가져오기, 저장소에 쓰기, 사용자에게 알림)은 백그라운드 작업이나 대기열로 넘기십시오. 제공업체는 일반적으로 적시에 2xx 응답을 받지 못하면 웹훅 전달을 재시도하는데, 핸들러가 느리고 동기식이라면 중복 처리가 발생할 수 있습니다.
- 작업 ID로 중복 제거: 처리된 작업 ID(또는 이벤트 해시)를 저장하여 재시도된 전달이 알림을 다시 생성하거나 파일 쓰기를 다시 처리하지 않도록 하십시오.
- 리소스 재요청: 위에서 설명한 '푸시 후 풀' 패턴에 따라, 포함된 출력 URL을 반드시 최종적인 것으로 신뢰하기보다 웹훅 페이로드의 작업 ID를 사용하여 리소스를 다시 가져오십시오.
최소한의 핸들러 예시:
from flask import Flask, request, abort
app = Flask(__name__)
processed_job_ids = set() # 프로덕션 환경에서는 실제 저장소 사용
@app.route("/webhooks/image-jobs", methods=["POST"])
def handle_webhook():
if not verify_signature(request):
abort(401)
event = request.get_json()
job_id = event.get("job_id") or event.get("data", {}).get("id")
if job_id in processed_job_ids:
return "", 200 # 이미 처리됨, 승인 후 건너뜀
enqueue_background_task("fetch_and_store_image", job_id)
processed_job_ids.add(job_id)
return "", 200
이미지 작업 완료에 사용되는 정확한 웹훅 이벤트 이름, 페이로드 구조, 서명 헤더를 현재 제공업체 문서와 대조하고, docs.tokenlab.sh에 설명된 TokenLab 자체 웹훅 지원과 별도로 확인하십시오. 이러한 세부 정보는 제공업체마다 다르며 변경될 수 있습니다.
재시도 설계: 세 가지 실패 유형
비동기 이미지 작업은 세 가지 방식으로 실패하며, 각각 고유한 처리가 필요합니다.
- 제출 실패: 작업 생성을 위한 POST가 4xx 또는 5xx를 반환합니다. 5xx 및 네트워크 오류의 경우 지수 백오프와 지터(jitter)를 사용하여 재시도하되, 동일한 멱등성 키를 재사용하여 중복 작업을 생성하지 않도록 합니다. 4xx 오류(잘못된 프롬프트, 유효하지 않은 모델, 할당량 초과)의 경우 요청을 변경하지 않고 재시도하면 다시 실패하므로 호출자에게 오류를 노출하십시오.
- 작업 중단(Stuck jobs): 작업이 예상 생성 시간을 훨씬 넘어서도 종료되지 않은 상태로 유지됩니다. 모델별로 최대 대기 임계값을 설정하고(생성 시간은 모델과 해상도에 따라 다름), 제공업체가 공식적으로 실패 처리를 하지 않았더라도 애플리케이션 목적상 실패한 것으로 처리하십시오. 작업 중단 비율이 증가하는 것은 종종 제공업체 측의 장애를 의미하므로 이를 별도로 기록하십시오.
- 웹훅 전달 누락: 엔드포인트가 다운되었거나 전달이 누락되어 이벤트가 전혀 도착하지 않는 경우입니다. 이것이 웹훅 우선 설계에서도 폴링 폴백을 유지해야 하는 이유입니다. 종료 상태가 아닌 몇 분 이상 된 작업의 상태를 주기적으로 확인하는 스캔을 통해 웹훅이 조용히 도착하지 않은 작업을 잡아낼 수 있습니다.
결정 체크리스트
이미지 생성 기능에 대한 작업 완료 방식을 결정할 때 이 체크리스트를 사용하십시오.
| 시나리오 | 권장 접근 방식 | 이유 |
|---|---|---|
| 저용량, 내부 도구 또는 배치 스크립트 | 폴링 | 구축이 가장 간단함; 공개 엔드포인트 불필요 |
| 지연 시간이 중요한 사용자 대면 기능 | 웹훅, 폴링 폴백 스캔 병행 | 지연 시간 감소; 폴백이 누락된 전달을 포착 |
| 높은 작업량(일일 수천 건) | 웹훅 | 과도한 상태 확인 요청량 방지 |
| 공개 HTTPS 엔드포인트를 노출할 수 없는 경우 | 폴링 | 웹훅은 접근 가능한 수신자가 필요함 |
| 엄격한 중복 방지 필요 | 제출 시 멱등성 키 사용, 수신 시 작업 ID로 중복 제거 | 재시도된 제출 및 중복 웹훅 전달로부터 보호 |
| 하나의 파이프라인에 여러 이미지 모델 사용 | 자체 계층에서 작업 상태 및 오류 처리 정규화 | 기본 제공업체들은 동일한 상태 분류 체계를 공유하지 않음 |
제한 사항
이 문서는 비동기 이미지 작업 API에 대한 일반적인 패턴을 설명하며, 위에서 언급된 것 외에 TokenLab이나 특정 기본 모델 제공업체에 대한 정확한 엔드포인트 경로, 필드 이름, 타임아웃 값 또는 웹훅 이벤트 이름을 보장하지 않습니다. 작업 상태 어휘, retry-after 헤더, 웹훅 서명 체계는 제공업체마다 다르며 시간이 지남에 따라 변경될 수 있습니다. 이 문서의 코드를 복사해서 붙여넣는 프로덕션 코드가 아닌 예시로 취급하고, 배포 전에 docs.tokenlab.sh에서 현재 요청 및 응답 형태를 확인하십시오. 이 문서는 특정 모델에 대한 가격 책정, 속도 제한 또는 처리량 보장을 다루지 않습니다.
FAQ
항상 폴링 대신 웹훅을 사용해야 하나요? 아닙니다. 웹훅은 운영 비용이 더 높은 대신 지연 시간과 요청 수를 줄여줍니다. 저용량 또는 내부 사용 사례의 경우 폴링이 종종 더 간단하고 동일하게 안정적인 선택입니다. 많은 프로덕션 시스템이 웹훅을 기본 경로로 사용하고 주기적인 폴링 스캔을 폴백으로 사용합니다.
재시도 시 중복 이미지 생성을 어떻게 방지하나요? 작업 제출 요청에 멱등성 키를 사용하여 네트워크 오류 후 재시도된 POST가 새 작업을 생성하는 대신 기존 작업을 반환하도록 하십시오. 이를 의존하기 전에 제공업체의 작업 생성 엔드포인트가 이를 지원하는지 확인하십시오.
작업이 완료될 때 웹훅 엔드포인트가 다운되면 어떻게 되나요? 동작은 제공업체에 따라 다릅니다. 일부는 일정 기간 동안 전달을 재시도하지만, 다른 일부는 재전달을 보장하지 않습니다. 제공업체의 재시도 정책과 관계없이 종료 상태가 아닌 몇 분 이상 된 작업에 대해 주기적인 폴링 스캔을 수행하는 것이 실용적인 안전장치입니다.
이미지 생성 기능을 구축 중이며 하나의 API에서 여러 모델에 걸친 작업 기반 액세스를 비교하고 싶다면, 이미지 모델 디렉토리와 비동기 이미지 생성 작업 가이드를 검토한 후, Get Started를 통해 TokenLab의 API 문서를 확인하여 빌드에 필요한 현재 엔드포인트 및 웹훅 세부 정보를 확인하십시오.
출처
2026-07-14 기준 가격
- OpenAI webhook events2026-07-14 기준 확인
- TokenLab API documentation2026-07-14 기준 확인
- TokenLab model directory2026-07-14 기준 확인



