규모 있게 이미지 생성을 자동화하면서 여러 다른 API를 관리하지 않으려면, 워크플로우를 모델 제공자와 분리하는 것이 가장 쉽습니다. 모든 이미지 요청을 하나의 큐에 넣고, 각 작업을 현재 모델 ID로 라우팅하며, 호환되는 요청을 하나의 CometAPI 키와 OpenAI 호환 기본 URL https://api.cometapi.com/v1. 를 통해 전송하세요.
이 튜토리얼은 Python으로 그 파이프라인을 구축합니다. JSON Lines 큐에서 제품, 광고, 콘텐츠 작업을 받아들이고; 모델을 선택하며; 동시성을 제한하고; 일시적 실패를 재시도하며; URL 기반 또는 base64 기반 결과를 저장하고; 작업별 사용량과 예상 비용을 기록합니다. 예제는 이러한 프로덕션 필수 요소를 하나의 간결한 블록에 담아, 기사를 코드 레퍼런스로 바꾸지 않고도 워크플로우를 테스트할 수 있게 합니다.
통합 이미지 API가 배치 생성을 단순화하는 방법
마지막에는 워크플로우가 다음과 같은 형태가 됩니다:
jobs.jsonl → bounded worker pool → CometAPI /v1/images/generations → object storage → manifest.jsonl
큐와 스토리지 계층은 그대로 여러분의 소유입니다. 이미지 모델을 바꾸더라도 인증 시스템이나 주 요청 경로가 아니라 model 값만 변경됩니다. 이것이 통합 이미지 API의 실질적 이점입니다. 모델 선택이 별도의 공급자 통합이 아니라 하나의 파이프라인 내부의 라우팅 결정이 되기 때문입니다.
이미지 생성 자동화를 위해 무엇이 필요한가요?
Python 3.10 이상, requests 패키지, CometAPI 키, 쓰기 가능한 출력 위치, 그리고 최소 하나의 최신 이미지 모델 ID가 필요합니다.
유일한 의존성을 설치하세요:
pip install requests
키는 서버에서 설정하고, 브라우저 코드나 저장소에는 절대 넣지 마세요:
export COMETAPI_KEY="your-key"
기본 URL은 https://api.cometapi.com/v1이며, 호환되는 텍스트-투-이미지 작업은 POST /images/generations 를 사용합니다. 배포 전에는 라이브 모델 카탈로그에서 각 모델을 검증하세요. 카탈로그는 권한 헤더 없이도 현재 ID, 지원 엔드포인트, 기능, 가격 메타데이터를 반환합니다.
2026년 8월 20일 기준, 라이브 카탈로그에는 다음과 같은 유용한 두 경로가 나열되어 있었습니다:
| 작업 부하 | 모델 ID | 적합한 이유 |
|---|---|---|
| 출력 설정 제어가 필요한 제품 이미지 | gpt-image-2 | 문서화된 OpenAI 호환 경로에서 사용량 데이터와 base64 이미지 콘텐츠를 반환 |
| 대량 광고 및 콘텐츠 컨셉 | doubao-seedream-4-5-251128 | 동일한 생성 경로를 사용하며 요청당 가격으로 제공됨 |
이 표는 시작점일 뿐이며, 두 모델이 동일한 기능을 가진다는 주장은 아닙니다. 크기, 품질, 포맷, 참조 이미지 지원, 응답 동작은 모델별로 다릅니다. 선택적 파라미터를 전달하기 전에 모델 레코드와 연결된 문서를 확인하세요.
Python으로 배치 이미지 생성 워크플로우 구축 방법
1. 모든 작업에 내구성 있는 ID 부여
하나의 JSON 객체를 줄마다 사용하면 큐, 데이터베이스 내보내기, 스프레드시트 작업이 동일한 워커에 공급될 수 있습니다:
{"id":"sku-1001","kind":"product","prompt":"Studio product photo of a ceramic coffee dripper on a warm neutral background"}
{"id":"campaign-204","kind":"ad","prompt":"Editorial summer travel image, vivid natural light, wide composition, no text"}
{"id":"blog-088","kind":"content","prompt":"Minimal illustration of a developer automating a creative workflow, no text"}
ID는 출력 파일명과 매니페스트 키가 됩니다. 프로덕션에서는 이 값을 멱등성 키로 사용하고, 재처리 전에 이미 성공으로 표시된 ID는 건너뛰세요.
2. 작업 유형별 라우팅 후 라이브 카탈로그 검증
예제는 제품 작업을 gpt-image-2 에, 광고 또는 콘텐츠 작업을 doubao-seedream-4-5-251128 에 매핑합니다. 작업은 자신의 model 필드로 선택을 재정의할 수 있습니다. 시작 시 워커는 공개 카탈로그를 다운로드하고 더 이상 나열되지 않은 ID는 거부합니다.
이는 애플리케이션 전반에 공급자별 SDK를 하드 코딩하는 것보다 안전합니다. 자체 프롬프트에 대해 품질, 지연 시간, 가격을 평가한 뒤 하나의 매핑에서 라우트를 변경할 수 있습니다.
3. 전체 배치를 한꺼번에 실행하는 대신 동시성을 제한
워커는 4개의 동시 요청으로 시작합니다. 이 숫자는 보수적인 애플리케이션 설정일 뿐, 보편적인 서비스 한도는 아닙니다. 계정의 지연 시간과 429 응답을 측정한 다음, 근거에 따라 MAX_WORKERS 를 올리거나 내리세요.
408, 429, 5xx 응답만 지수 백오프와 지터로 재시도합니다. 인증 오류, 잘못된 모델 ID, 지원되지 않는 파라미터는 즉시 실패로 처리합니다. 같은 잘못된 요청을 재시도해 봐야 지연만 늘어납니다.
4. 저장 전에 결과를 정규화
이미지 모델은 항상 동일한 컨테이너를 반환하지는 않습니다. 문서화된 GPT Image 응답은 data[0].b64_json 을 포함하지만, 다른 호환 모델은 data[0].url 을 반환할 수 있습니다. 워커는 둘 다 처리하고, 이미지를 임시 파일에 쓴 뒤 다운로드 또는 디코드가 성공한 후에만 이름을 바꿉니다.
프로덕션에서는 로컬 output/ 디렉터리를 S3, R2, GCS 또는 다른 오브젝트 스토어로 대체하세요. 제공자 호스팅 URL을 보존 스토리지로 취급하지 마세요. 보존 정책에 명시되어 있지 않다면 URL은 영구적이지 않을 수 있습니다.
5. 사용량, 시도 횟수, 예상 비용 기록
모든 결과는 작업 ID, 모델, 저장 경로, 상태, 그리고 라이브 카탈로그가 충분한 가격 데이터를 제공할 때의 예상 USD 비용을 담은 간결한 매니페스트 행이 됩니다. 실패한 작업은 배치에서 사라지지 않고 오류를 유지합니다.
배치 이미지 생성용 전체 Python 스크립트
다음을 batch_image_pipeline.py로 저장하고, jobs.jsonl을 같은 위치에 두고, python3 batch_image_pipeline.py를 실행하세요.
import base64, json, os, random, time
from concurrent.futures import ThreadPoolExecutor
from pathlib import Path
import requests
BASE_URL = "https://api.cometapi.com/v1"
KEY = os.environ["COMETAPI_KEY"]
WORKERS = int(os.getenv("MAX_WORKERS", "4"))
OUT = Path("output")
ROUTES = {
"product": "gpt-image-2",
"ad": "doubao-seedream-4-5-251128",
"content": "doubao-seedream-4-5-251128",
}
catalog = requests.get("https://api.cometapi.com/api/models", timeout=30)
catalog.raise_for_status()
CATALOG = {model["id"]: model for model in catalog.json()["data"]}
def generate(job):
model = job.get("model", ROUTES[job["kind"]])
if model not in CATALOG:
raise ValueError(f"Unknown model: {model}")
payload = {"model": model, "prompt": job["prompt"], "n": 1}
if model == "gpt-image-2":
payload.update(quality="low", size="1024x1024", output_format="jpeg")
for attempt in range(4):
response = requests.post(
f"{BASE_URL}/images/generations",
headers={"Authorization": f"Bearer {KEY}"},
json=payload,
timeout=180,
)
if response.status_code not in {408, 429} and response.status_code < 500:
break
time.sleep(2**attempt + random.random())
response.raise_for_status()
body = response.json()
item = body["data"][0]
if item.get("b64_json"):
data = base64.b64decode(item["b64_json"])
extension = body.get("output_format", "png")
else:
download = requests.get(item["url"], timeout=120)
download.raise_for_status()
data = download.content
extension = {"image/png": "png", "image/webp": "webp"}.get(
download.headers.get("content-type"), "jpg"
)
path = OUT / f"{job['id']}.{extension}"
path.write_bytes(data)
price, usage = CATALOG[model].get("pricing") or {}, body.get("usage", {})
cost = price.get("per_request")
if cost is None and price.get("input") is not None:
cost = (usage.get("input_tokens", 0) * price["input"] +
usage.get("output_tokens", 0) * price["output"]) / 1_000_000
return {"id": job["id"], "model": model, "path": str(path),
"estimated_usd": cost * price.get("ratio", 1) if cost is not None else None}
def safe_generate(job):
try:
return {"status": "success", **generate(job)}
except Exception as error:
return {"id": job["id"], "status": "failed", "error": str(error)}
OUT.mkdir(exist_ok=True)
jobs = [json.loads(line) for line in Path("jobs.jsonl").read_text().splitlines() if line]
with ThreadPoolExecutor(max_workers=WORKERS) as pool:
results = list(pool.map(safe_generate, jobs))
with (OUT / "manifest.jsonl").open("w") as manifest:
manifest.writelines(json.dumps(result) + "\n" for result in results)
이 스크립트는 런타임에 최신 카탈로그를 사용하며, 두 개의 폴백 매핑은 2026년 8월 20일에 검증된 예시입니다. 다른 날짜에 코드를 게시하거나 배포하기 전에 다시 확인하세요.
배치 이미지 생성 워크플로우 테스트 방법
하나의 작업과 하나의 워커로 시작하세요:
MAX_WORKERS=1 python3 batch_image_pipeline.py
성공적인 GPT Image 응답은 다음 구조를 따릅니다:
{
"created": 1776841943,
"output_format": "jpeg",
"quality": "low",
"size": "1024x1024",
"usage": {
"input_tokens": 16,
"output_tokens": 208,
"total_tokens": 224
},
"data": [{"b64_json": "<base64-image-data>"}]
}
워커는 이미지를 디코드하여 output/<job-id>.jpeg 에 기록하고, output/manifest.jsonl 에 성공 행을 추가합니다. 모델이 URL을 반환하는 경우, 워커는 이를 다운로드하여 동일한 매니페스트 형식으로 로컬 경로를 저장합니다.
코드는 로컬에서 문법 점검을 완료했습니다. 실제 생성 호출에는 CometAPI 키가 필요하므로 동시성을 늘리기 전에 한 작업으로 스모크 테스트를 실행하세요.
배치 이미지 생성 비용은 얼마인가요?
모델 요금은 변동되므로 가격은 타임스탬프를 포함해야 합니다. 2026년 8월 20일 기준, 라이브 CometAPI 모델 카탈로그 는 다음과 같은 기본 가격 필드와 0.8 청구 비율을 반환했습니다:
gpt-image-2: 입력 토큰 100만 개당 $5, 출력 토큰 100만 개당 $30; 기재된 비율을 적용하면 각각 $4와 $24가 됩니다.doubao-seedream-4-5-251128: 요청당 $0.04; 기재된 비율을 적용하면 요청당 $0.032가 됩니다.
CometAPI 가격 가이드 는 공식 가격이 있는 모델의 토큰 기반 청구와 요청당 가격 모델의 호출 기반 청구를 설명합니다. 스크립트는 실행 시 카탈로그를 읽고 동일한 규칙을 사용합니다:
token cost = ratio × (input tokens × input rate + output tokens × output rate) / 1,000,000
request cost = ratio × per-request price
예를 들어, 위의 문서화된 GPT Image 응답은 입력 토큰 16개와 출력 토큰 208개를 보고합니다. 8월 20일 카탈로그 값을 사용하면, 그 예시 결과의 추정치는 약 $0.005056입니다. 실제 합계는 모델, 품질, 크기, 프롬프트, 재시도, 응답 사용량에 따라 달라집니다. 고정된 이미지당 비용 가정보다는 API 응답과 계정 사용 대시보드를 청구 기록으로 간주하세요.
실패 작업에 대한 예산도 책정하세요. 확인되지 않은 타임아웃 이후의 재시도는 두 번째 과금 가능한 결과를 생성할 수 있으며, 기술적으로 성공했지만 검수에서 실패한 이미지도 예산을 소비합니다. API 비용과 승인율을 모두 추적하세요:
effective cost per accepted image = total batch spend / approved images
일반적인 이미지 생성 API 오류 및 해결 방법
| 증상 | 가능한 원인 | 해결 |
|---|---|---|
| 401 | 키 누락 또는 잘못된 키 | 서버 측 COMETAPI_KEY를 확인 |
| 400 | 잘못된 모델 또는 미지원 옵션 | 라이브 카탈로그를 재확인하고 모델별 필드를 제거 |
| 429 | 동시성이 과도함 | MAX_WORKERS를 낮추고 지수 백오프 유지 |
| 반복되는 5xx | 일시적인 업스트림 장애 | 상한을 두고 재시도한 다음, 작업을 데드 레터 큐로 이동 |
| 이미지 미저장 | 응답이 다른 컨테이너를 사용함 | data[0]를 확인하고 b64_json 또는 url을 모두 지원 |
| 중복 과금 | 부분 실패 후 작업이 재생됨 | 내구성 있는 ID를 사용하고 저장이 성공한 후에만 승인 |
모든 오류를 재시도하지 마세요. 영구적인 400 요청은 유효하지 않은 상태로 남을 것이며, 제한 없는 429 재시도 루프는 트래픽 급증을 적체로 바꿀 수 있습니다.
대규모 프로덕션 이미지 생성 모범 사례
다수의 워커가 관여하면 JSON Lines에서 내구성 있는 큐로 전환하세요. 가시성 타임아웃을 최대 생성 시간보다 길게 설정하고, 이미지와 매니페스트 저장이 완료된 후에만 작업을 승인하며, 소진된 작업은 검토를 위해 데드 레터 큐로 보냅니다.
선택적 제어는 모델별 구성에 유지하세요. 공유 페이로드에는 model, prompt, n: 1 같은 공통 필드만 포함하고, 선택한 모델 문서가 확인한 경우에만 quality, size, output_format 을 추가하세요. 폴백 라우팅을 추가한다면 동일 작업을 지원하는 모델을 선택하고, 제공자별 옵션을 무작정 재생하지 말고 해당 모델에 맞게 페이로드를 재구성하세요.
API 키를 시크릿 매니저에 저장하고, 프롬프트 입력을 제한하며, 정책에 따라 생성된 자산을 스캔하고, 제공자 URL을 장기 제품 기록에서 제외하세요. 작업 ID, 모델 ID, 지연 시간, 시도 횟수, 사용량, 저장 경로, 검수 결과, 카탈로그 스냅샷 날짜를 기록하세요. 이 필드들은 단순 가격이 아닌 승인된 이미지당 비용으로 모델을 비교할 수 있게 해 줍니다.
마지막으로 예산 가드레일을 설정하세요. 최대 배치 크기, 작업별 재시도 한도, 일일 지출 알림, 승인율 하락 시 중단 조건 등입니다. 나쁜 프롬프트를 더 빨리 확장하는 것은 최적화가 아닙니다.
대규모 이미지 생성 자동화에 대한 FAQ
여러 API를 관리하지 않고 이미지 생성을 대규모로 자동화하는 가장 쉬운 방법은 무엇인가요?
하나의 큐와 스토리지 워크플로우를 사용하고, 호환되는 이미지 요청을 하나의 CometAPI 키와 https://api.cometapi.com/v1/images/generations. 를 통해 전송하세요. 별도의 인증과 공급자 SDK를 유지하는 대신, 라우팅 계층에서 모델 ID를 변경하세요.
한 요청으로 여러 이미지 모델에 동시에 생성하도록 요청할 수 있나요?
예제는 작업당 한 모델을 전송합니다. 팬아웃은 애플리케이션 워크플로우입니다. 서로 다른 ID와 모델 값을 갖는 작업을 복제한 다음, 저장된 출력을 비교하세요. 이렇게 하면 각 모델에 비용과 검수 상태를 귀속할 수 있습니다.
동시성은 어느 정도가 적절한가요?
모든 계정과 모델에 공통인 숫자는 없습니다. 4개 워커 같은 작은 제한된 풀로 시작하고, 지연 시간과 429 응답을 모니터링하여 증거에 기반해 튜닝하세요.
반환된 URL을 저장해야 하나요, 아니면 이미지 자체를 저장해야 하나요?
이미지 자체를 여러분의 오브젝트 스토리지에 저장하세요. 반환된 URL은 일시적일 수 있으며, GPT Image 모델은 URL 대신 base64 콘텐츠를 반환할 수 있습니다.
가장 저렴한 모델은 어떻게 선택하나요?
호출당 가격이 아니라 승인된 이미지당 비용을 계산하세요. 토큰 또는 요청 요금, 재시도, 실패한 다운로드, 반려된 자산, 후처리, 인간 검토를 포함하세요. 게시 또는 배포하는 날 라이브 모델 카탈로그 를 다시 확인하세요.
엔드포인트와 응답 형식은 어디에서 확인해야 하나요?
CometAPI 빠른 시작, 모델 카탈로그 문서, 이미지 생성 레퍼런스, 가격 가이드 를 사용하세요.