> ## Documentation Index
> Fetch the complete documentation index at: https://docs.apiyi.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Nano Banana 시리즈 개발자 가이드

> Nano Banana 시리즈(Pro / 2 / 2 Lite / Gen 1)의 모델 선택, 과금, 엔드포인트, 개발 형식, FAQ를 한곳에서 확인할 수 있는 가이드입니다. 개발자가 Gemini 이미지 생성 API를 빠르게 시작할 수 있도록 돕습니다.

## 모델 카드

| 모델                      | 공식 모델 ID                         | 과금                                                                    | 비고                    |
| ----------------------- | -------------------------------- | --------------------------------------------------------------------- | --------------------- |
| **Nano Banana Pro**     | `gemini-3-pro-image-preview`     | 요청당 고정 **\$0.09/req** (약 ¥0.63; 충전 프로모션 후 약 ¥0.55)                    | 최고 품질                 |
| **Nano Banana 2**       | `gemini-3.1-flash-image-preview` | 요청당 **\$0.055/req** (4K 출력에 권장됨); 또는 동적 token 기반 과금, 2K는 약 **\$0.04** | 최고의 가성비               |
| **Nano Banana 2 Lite**  | `gemini-3.1-flash-lite-image`    | 요청당 고정 **\$0.025/req**; 또는 token 기반 과금 약 **\$0.018/req** (공식 가격의 40%) | 가장 빠르고 가장 저렴함, 1K만 지원 |
| **Nano Banana** (Gen 1) | `gemini-2.5-flash-image`         | 요청당 고정 **\$0.02/req**                                                 | 가장 저렴함                |

<Info>
  전체 가격 비교, 요청당 과금과 token 기반 과금의 차이, token 선택 조언은 [Nano Banana Series Pricing](/ko/api-capabilities/nano-banana-pricing)를 참고하십시오.
</Info>

### 크기 제어

* **원본 이미지 비율을 따르려면**: `aspectRatio`를 단순히 생략하십시오. 여러 이미지 편집 시나리오에서는 **마지막 이미지의 크기**가 우선합니다
* **해상도 `imageSize`**: `1K` / `2K` / `4K`를 지원합니다
  * Nano Banana (Gen 1)은 **1K만 지원합니다**
  * Nano Banana 2는 **512px를 추가합니다**
  * Nano Banana 2 Lite는 **1K만 지원합니다** (2K/4K/512px 미지원)

<Warning>
  동일한 코드를 사용해 1세대 `gemini-2.5-flash-image`를 호출할 때는 **반드시 `imageSize` 파라미터를 제거해야 합니다**(`2K` / `4K`를 지원하지 않기 때문입니다), 그렇지 않으면 호출이 실패합니다.
</Warning>

## 통합 방법

### 공식 문서

* Google 공식 문서: `ai.google.dev/gemini-api/docs/image-generation`
* APIYI와 통합하려면 **request URL + KEY를 APIYI의 것으로만** 바꾸면 됩니다. 나머지 모든 파라미터는 공식 문서와 동일합니다.

### 공식 상태 확인(업스트림 문제 진단)

Nano Banana 시리즈는 Google의 AIStudio / Gemini API 위에서 동작합니다. 드물게 **흐릿한 2K / 4K 출력 실패**는 통합 계층이 아니라 **Google 측** 문제일 수 있습니다. Google의 공식 상태 페이지를 직접 복사해서 방문해 보세요: `aistudio.google.com/status`.

예를 들어 2026년 6월 19일에 해당 페이지에는 "Issues with Nano Banana"가 표시되었습니다. Gemini API 및 AI Studio의 Nano Banana 2 / Pro에서 2K 또는 4K 해상도에서 문제가 있었습니다. 비슷한 증상이 보이면 먼저 공식 상태 페이지와 비교해서 업스트림 장애인지 빠르게 확인하십시오.

<Info>
  APIYI는 안정성을 위해 Nano Banana 시리즈를 **이중 AIStudio + Vertex 채널**로 운영합니다. 한쪽 공식 채널에 문제가 생기면 다른 쪽이 대신 서비스를 계속 제공할 수 있습니다.
</Info>

### 엔드포인트 지원

* **권장 엔드포인트**(Gemini 네이티브): `https://api.apiyi.com/v1beta/models/gemini-3-pro-image-preview:generateContent`
* **OpenAI 호환 모드**를 통한 호출을 지원합니다(참고: **URL 업로드는 지원되지 않으며**, 대신 Base64를 사용하십시오)
* **지원하지 않습니다** `/v1/image/generations`

### 개발 형식(기본 권장)

* **\[권장] Google 네이티브 엔드포인트 형식을 사용하십시오**
* 이미지: **Base64로 업로드하고, 다운로드 후 재호스팅**
* 호출 방식: **동기식 멀티스레드 호출**; 비동기 호출은 아직 지원되지 않습니다

## 입력 이미지 요구사항

* **단일 이미지는 7MB를 초과할 수 없습니다**(Google 규칙입니다). Google Cloud Storage를 통해 가져오는 경우 파일당 제한은 30MB입니다
* **프롬프트당 최대 14개 이미지**
* **지원되는 MIME 유형**: `image/png`, `image/jpeg`, `image/webp`, `image/heic`, `image/heif` (`jpg` 형식은 이미 APIYI에서 지원됩니다)
* **Base64 크기 증가**: 이미지를 Base64로 변환하면 크기가 약 **33.3%** 증가합니다(7MB 이미지는 약 9.3MB가 됩니다)
* **APIYI 제한**: 단일 요청에 업로드되는 이미지의 총 용량은 **100MB 미만**이어야 합니다. 모든 호출은 동기식이며, 과도하게 큰 페이로드는 메모리 급증을 유발할 수 있습니다

<Frame caption="Google official technical specs: inline / console upload per-file limit is 7MB, supporting png/jpeg/webp/heic/heif">
  <img src="https://mintcdn.com/apiyillc/gZdh_-LS6bvRJGUL/images/nano-banana-image-size-limit.png?fit=max&auto=format&n=gZdh_-LS6bvRJGUL&q=85&s=fc422e34e493a907363115118f715690" alt="Google Gemini 3 Pro Image 공식 기술 사양 표: 단일 이미지 제한 7MB, 프롬프트당 최대 14개 이미지, 지원되는 가로세로 비율 및 MIME 유형" width="1400" height="701" data-path="images/nano-banana-image-size-limit.png" />
</Frame>

<Frame caption="Base64 encoding increases size by about 33.3%: a 7MB image is roughly equal to 9.3MB">
  <img src="https://mintcdn.com/apiyillc/gZdh_-LS6bvRJGUL/images/nano-banana-base64-size.png?fit=max&auto=format&n=gZdh_-LS6bvRJGUL&q=85&s=dffe216ee6e97c2661ce816eb5408a22" alt="Base64 크기 계산: 7MB 원본 이미지는 4/3 비율로 인코딩하면 약 9.33MB입니다" width="1448" height="984" data-path="images/nano-banana-base64-size.png" />
</Frame>

**모범 사례**: API로 보내기 전에 이미지에 **무손실 압축**을 적용하여, 과도한 해상도로 인해 요청이 느려지는 것을 방지합니다.

Google 공식 사양 참고 자료(직접 복사하여 방문하시기 바랍니다): `docs.cloud.google.com/vertex-ai/generative-ai/docs/models/gemini/3-pro-image`

## URL 이미지 입력

Base64 외에도 **Gemini 네이티브 엔드포인트**는 이미지 URL(이미지 호스트 / OSS 주소)을 `fileData.fileUri`를 통해 직접 전달하는 것을 지원하므로, 로컬 인코딩이 필요하지 않습니다.

<Warning>
  **URL 업로드는 이미지 호스트와 OSS 주소에 대한 요구 사항이 엄격합니다**: 주소가 글로벌 CDN에 있지 않으면(예: Tencent Cloud Object Storage는 기본적으로 중국 전용 CDN을 사용합니다), Google의 서버가 이미지에 접근하지 못할 가능성이 매우 높아 요청이 실패합니다(일반적인 증상: **출력에 이미지가 참조되지 않습니다**).

  **가능하면 더 안정적인 Base64 업로드를 우선 사용하십시오** — 플랫폼 관점에서 이는 가장 운영 투자가 많이 이루어진, 가장 신뢰할 수 있는 경로입니다.
</Warning>

<Info>
  URL 업로드는 **Gemini 네이티브 엔드포인트**에서만 작동합니다; **OpenAI 호환 모드에서는 URL 업로드를 지원하지 않으며** Base64가 필요합니다.
</Info>

### Curl 예시 (파일 URI)

```bash theme={null}
curl --location 'https://api.apiyi.com/v1beta/models/gemini-3-pro-image-preview:generateContent' \
  --header 'Authorization: Bearer sk-' \
  --header 'Content-Type: application/json' \
  --data '{
      "contents": [
          {
              "parts": [
                  {
                      "fileData": {
                          "fileUri": "https://raw.githubusercontent.com/apiyi-api/ai-api-code-samples/refs/heads/main/Vision-API-OpenAI/otter.png",
                          "mimeType": "image/png"
                      }
                  },
                  {
                      "text": "add five dogs"
                  }
              ],
              "role": "user"
          }
      ],
      "generationConfig": {"responseModalities": ["IMAGE"],
      "imageConfig": {
        "aspectRatio": "16:9",
        "imageSize": "2K"
      }},
      "safetySettings": []
  }'   > output.json
```

### Python 예제 (fileUri)

```python theme={null}
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Gemini 3 Pro Image - Image editing (minimal file_uri version)
Purpose: only for a quick check that the endpoint works
"""

import requests
import base64
import json
from pathlib import Path
from datetime import datetime

# ============================================================================
# Configuration
# ============================================================================

API_KEY = "sk-"
API_URL = "https://api.apiyi.com/v1beta/models/gemini-3-pro-image-preview:generateContent"

# Image URL
IMAGE_URL = "https://raw.githubusercontent.com/apiyi-api/ai-pics/refs/heads/main/1762260696217_dd0352c1f9604540.png"
IMAGE_MIME_TYPE = "image/png"

# Edit instructions
EDIT_PROMPT = "Change the person's clothes to a blue jacket and hair to a purple gradient; keep pose, gaze direction, and other structural features unchanged."
SYSTEM_PROMPT = "You are a professional expert in image description and generation. Your task is to produce high-quality image prompts with rich detail and a clear artistic style, or to make accurate, creative edits to existing images, based on the user's request."

# Output parameters
ASPECT_RATIO = "9:16"
RESOLUTION = "4K"
MAX_OUTPUT_TOKENS = 8000
OUTPUT_FILE = f"minimal_{datetime.now().strftime('%Y%m%d_%H%M%S')}.png"

# ============================================================================
# Core
# ============================================================================

def main():
    print("=" * 60)
    print("Testing file_uri endpoint")
    print("=" * 60)
    print(f"Image URL: {IMAGE_URL[:80]}...")
    print(f"Edit prompt: {EDIT_PROMPT}")
    print(f"Output params: {RESOLUTION}, {ASPECT_RATIO}")
    print("-" * 60)

    # Build the request body
    # Note: fileData, mimeType, fileUri must be in camelCase
    payload = {
        "generationConfig": {
            "responseModalities": ["IMAGE", "TEXT"],
            "imageConfig": {
                "imageSize": RESOLUTION,
                "aspectRatio": ASPECT_RATIO
            },
            "maxOutputTokens": MAX_OUTPUT_TOKENS
        },
        "contents": [
            {
                "role": "model",
                "parts": [{"text": SYSTEM_PROMPT}]
            },
            {
                "role": "user",
                "parts": [
                    {
                        "fileData": {           # camelCase: fileData (not file_data)
                            "mimeType": IMAGE_MIME_TYPE,  # camelCase: mimeType
                            "fileUri": IMAGE_URL          # camelCase: fileUri
                        }
                    },
                    {"text": EDIT_PROMPT}
                ]
            }
        ]
    }

    # Send the request
    print("\nSending request...")
    try:
        response = requests.post(
            API_URL,
            json=payload,
            headers={
                "Content-Type": "application/json",
                "Authorization": f"Bearer {API_KEY}"
            },
            timeout=300
        )

        print(f"Response status: {response.status_code}")

        if response.status_code != 200:
            print(f"❌ Error: {response.text}")
            return

        # Parse the response
        data = response.json()
        print("✅ Response received")

        # Save full response for debugging
        with open(OUTPUT_FILE + ".response.json", "w", encoding="utf-8") as f:
            json.dump(data, f, indent=2, ensure_ascii=False)
        print(f"📄 Response saved: {OUTPUT_FILE}.response.json")

        # Extract and print text
        parts = data["candidates"][0]["content"]["parts"]
        for part in parts:
            if "text" in part:
                print(f"\n💬 Text response: {part['text']}")

        # Save image
        for part in parts:
            if "inlineData" in part or "inline_data" in part:
                image_data = part.get("inlineData", part.get("inline_data", {})).get("data")
                if image_data:
                    image_bytes = base64.b64decode(image_data)
                    with open(OUTPUT_FILE, "wb") as f:
                        f.write(image_bytes)
                    print(f"\n✅ Image saved: {OUTPUT_FILE}")
                    print(f"📦 File size: {len(image_bytes) / 1024:.1f} KB")
                    print(f"🔗 File path: {Path(OUTPUT_FILE).resolve()}")
                    return

        print("⚠️  No image data found in the response")

    except requests.Timeout:
        print("❌ Request timed out")
    except Exception as e:
        print(f"❌ Error: {e}")

if __name__ == "__main__":
    main()
    print("\n" + "=" * 60)
    print("Test finished")
    print("=" * 60)
```

<Tip>
  `fileData`, `mimeType`, 및 `fileUri`는 **camelCase**여야 합니다(`file_data` / `file_uri` 아님); 그렇지 않으면 매개변수가 무시되고 이미지가 참조되지 않습니다.
</Tip>

## 과금 기본 사항 (중요)

* **동기식 호출 지속 시간**: Pro / 2 at 4K는 합리적인 생성 시간으로 약 **30–150초**가 소요됩니다
* **타임아웃으로 연결이 끊겨도 과금됩니다**: 예를 들어 생성에 120초가 걸리지만 클라이언트가 타임아웃을 100초로 설정하고 연결을 끊어도 여전히 과금됩니다
* **429 / 503은 과금되지 않습니다**: 실패한 요청은 과금되지 않습니다(저희는 고객이 너무 오래 기다리거나 이미지 없이 막혀 있지 않도록 하려고 합니다)
* **콘텐츠 안전성 거부도 과금됩니다**: 고객 입력에 콘텐츠 안전성 문제가 있어 Google이 이미지 생성을 거부하는 경우에도 **status code 200은 여전히 과금됩니다** — 아래의 오류 처리와 보장 플랜을 참고하십시오

## 타임아웃 설정(중요)

4K 이미지 생성은 **이미지 업로드, API 처리, Base64 이미지 다운로드**와 같은 단계를 거치므로 전체적으로 더 오래 걸립니다(백엔드는 **API 처리 시간** 기준으로 과금합니다). 정상 조건에서는 4K에 약 **50초**(폴링 제외)가 걸리지만, 클라이언트가 타임아웃을 너무 짧게 설정하면 생성이 완료되기 전에 **연결이 조기에 끊기며** 오류를 보고합니다:

```text theme={null}
API Connection Error: HTTPSConnectionPool(host='api.apiyi.com', port=443): Read timed out. (read timeout=120)
```

<Frame caption="Call logs: time-to-first-byte for 4K generation is about 43–61s, so the default 120s timeout is too tight">
  <img src="https://mintcdn.com/apiyillc/gZdh_-LS6bvRJGUL/images/nano-banana-timeout-error.png?fit=max&auto=format&n=gZdh_-LS6bvRJGUL&q=85&s=79eb88c65cd4ff91caa57e1402658b81" alt="호출 로그: gemini-3-pro 4K 생성의 첫 바이트까지의 시간은 43초에서 61초입니다" width="1400" height="837" data-path="images/nano-banana-timeout-error.png" />
</Frame>

더 안전하게 사용하려면 해상도별로 타임아웃을 설정하는 것을 권장합니다:

```python theme={null}
timeout = {
    "1K": 300,  # 5 minutes - quick preview
    "2K": 300,  # 5 minutes - recommended
    "4K": 600,  # 10 minutes - ultra HD
}
```

## 멀티턴 대화형 편집(네이티브는 지원하지만 역방향 모델은 지원하지 않습니다)

Nano Banana 시리즈는 **Gemini 네이티브 형식**을 사용하며 **진정한 대화형 멀티턴 편집**을 지원합니다: 각 턴에서 생성된 이미지를 `contents`에 다시 추가하여 \*\*`role: "model"` `inlineData`\*\*로 만든 뒤, 다음 사용자 지시를 보냅니다. 모델은 **전체 대화 기록**을 바탕으로 편집하고 **변경 사항을 누적**합니다(예: 먼저 소파 색을 바꾸고, 그다음 액세서리를 추가하면 — 앞선 변경은 유지됩니다).

이는 "역방향" 이미지 모델과 근본적으로 다릅니다 — 통합하기 전에 이 점을 분명히 이해해야 합니다:

| 항목              | Nano Banana (Gemini 네이티브)                                             | 역방향 모델(예: `gpt-image-2-all`)                  |
| --------------- | --------------------------------------------------------------------- | --------------------------------------------- |
| 엔드포인트           | `/v1beta/...:generateContent`                                         | `/v1/chat/completions`(chat 형식)               |
| 멀티턴 메커니즘        | ✅ **진정한 대화형**: `role:model` 이미지를 `contents`에 다시 채워 넣습니다; 모델은 기록을 읽습니다 | ❌ 대화 상태가 없습니다: `assistant` 기록의 이미지는 **무시됩니다** |
| 턴 간 누적          | ✅ 지원됨(빨간 소파 → 모자 추가, 소파는 빨간색으로 유지됨)                                   | ⚠️ 재입력만 지원, 한 번에 한 단계 편집                      |
| 이전 이미지를 편집하는 방법 | 마지막 출력물을 대화 기록의 `model` 이미지로 다시 채워 넣습니다                               | 이전 이미지 URL을 **새 사용자 메시지**의 참조로 전달합니다          |

<Info>
  테스트 결과: 이전 이미지를 `model` 역할의 턴으로 다시 채워 넣으면 Nano Banana 2(`gemini-3.1-flash-image-preview`)가 편집을 계속 이어가고 변경 사항을 정확히 누적합니다. 반면 역방향 모델은 **마지막 사용자 메시지**의 참조 이미지만 읽으므로, 대화 기록을 유지해도 멀티턴에는 동작하지 않습니다.
</Info>

최소 예제(각 출력을 동일한 `contents`에 다시 채워 넣기):

```python theme={null}
import requests, base64

API_KEY = "sk-your-api-key"
URL = "https://api.apiyi.com/v1beta/models/gemini-3.1-flash-image-preview:generateContent"
H = {"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"}
CFG = {"responseModalities": ["IMAGE"], "imageConfig": {"imageSize": "2K"}}

contents = []  # keep one running conversation history

def turn(instruction, save_to):
    contents.append({"role": "user", "parts": [{"text": instruction}]})
    data = requests.post(URL, headers=H,
                         json={"contents": contents, "generationConfig": CFG}, timeout=300).json()
    part = next(p for p in data["candidates"][0]["content"]["parts"] if "inlineData" in p)
    contents.append({"role": "model", "parts": [part]})   # key: backfill the output image
    with open(save_to, "wb") as f:
        f.write(base64.b64decode(part["inlineData"]["data"]))

turn("Generate an orange cat sitting on a blue sofa, simple line-art style", "step1.png")
turn("Make the sofa red; keep the cat and composition unchanged", "step2.png")   # edits the previous image
turn("Put a small yellow hat on the cat; keep everything else the same", "step3.png")  # accumulates; red sofa kept
```

<Tip>
  전체 자세한 내용(history-backfill 방식과 re-feed 방식, 기존 이미지에서 멀티턴을 시작하는 방법)은 [이미지 편집 API · 멀티턴 대화형 편집](/ko/api-capabilities/nano-banana-2-image/image-edit#multi-turn-conversational-editing)에 있습니다.
</Tip>

## 응답에 가끔 여러 이미지가 포함되는 이유

`gemini-3-pro-image`를 호출하면, 로그에 간헐적으로 6000개 이상의 출력 token 항목(심지어 5자리 수도 관찰됨)과 일치하는 \*\*단일 응답 내 여러 이미지 파트(테스트에서 2–10개 관찰)\*\*를 볼 수 있습니다. 이는 이상 현상이 아닙니다. Google의 공식 문서에 따르면 Gemini 3 이미지 모델은 기본적으로 “추론”이 활성화되어 있으며(API에서 비활성화할 수 없음), 모델은 구도와 논리를 시험하기 위해 중간 이미지를 생성하고, 이러한 초안은 최종 버전과 함께 `parts`에 나타나며, “추론 안의 마지막 이미지가 최종 렌더링 이미지이기도 하다”고 명시합니다(공식 문서: `ai.google.dev/gemini-api/docs/image-generation`). 2026년 7월에 수행한 테스트를 기준으로 하면(Google 기본 `generateContent` 형식):

| 시나리오                                                 | 반환된 이미지                               |
| ---------------------------------------------------- | ------------------------------------- |
| 순수 텍스트-투-이미지                                         | 항상 1개(프롬프트에서 명시적으로 “여러 이미지”를 요청해도 동일) |
| 단순 이미지 편집(액세서리 추가 / 배경 변경 / 스타일 변경)                  | 항상 1개                                 |
| 복잡한 작업형 편집(예: 여러 제약이 있는 “4면 캐릭터 시트 + 의상 변경 + 흰색 배경”) | 2–10개, 일관되게 재현 가능                     |

트리거는 **image editing** 자체가 아니라 **prompt의 작업 복잡도**입니다. 여러 이미지는 여전히 **단일 candidate** 안에 있으며(여러 candidate가 아님), 각 이미지는 완전한 이미지입니다. 이는 동일한 디자인의 연속 초안(같은 구도, 약간 다른 세부 사항)이며, **마지막 파트가 최종 버전**입니다. 이러한 초안은 일반 이미지 파트로 반환되며(`thoughtSignature` 필드가 있고, `thought: true` 플래그는 없음), Google 문서는 Thinking이 최대 두 개의 중간 이미지만 생성한다고 설명하지만, 우리는 복잡한 작업에서 최대 10개까지 관찰했습니다.

**과금 영향**: 각 이미지는 고정 token 수로 과금됩니다(1K/2K 해상도에서는 이미지당 1120 token, 4K에서는 2000 token). 따라서 출력 token은 이미지 수에 정확히 비례하여 증가합니다. 로그에 간헐적으로 나타나는 6000개 이상의(극단적 경우 약 13.5k까지) output-token 항목은 단순히 4–10개 이미지 응답일 뿐이며, **과금 이상 현상이 아닙니다**.

**권장되는 후속 코드**:

```python theme={null}
parts = response["candidates"][0]["content"]["parts"] or []   # parts is null on safety refusals
images = [p["inlineData"]["data"] for p in parts if "inlineData" in p]

if images:
    final_image = images[-1]   # last one = final version
```

* **항상 parts를 순회하십시오** — 응답당 이미지가 1개라고 가정하지 마십시오. 이미지별 카운팅 또는 저장 로직은 실제 part 수를 기준으로 해야 합니다
* **하나만 필요할 때는 마지막 이미지를 사용하십시오**: 앞선 초안은 세부 사항이 덜 완성되어 있고 품질이 약간 낮으므로 첫 번째 이미지를 선택하지 마십시오
* **prompt로 이미지 수를 제어하는 것은 대체로 효과가 없습니다**(테스트에서 “이미지 1개만 출력” 지시가 무시됨) — 코드에서 처리하십시오
* 여러 이미지 응답은 35–142초(1K 해상도 기준이며 이미지가 많을수록 더 길어짐)가 걸리며, 단일 이미지 응답보다 눈에 띄게 더 오래 걸립니다 — 위의 timeout 권장값(5분 이상)을 유지하십시오

<Tip>
  usageMetadata 필드의 전체 분석(세부 정보와 합계의 차이, 거부 응답에서의 계산 특이점 등)과 더 많은 내용은 [Usage Fields & Output Explained](/ko/api-capabilities/nano-banana-usage-metadata)을 참조하십시오.
</Tip>

## 자주 묻는 질문

<CardGroup cols={2}>
  <Card title="오류 처리 가이드" icon="triangle-alert" href="/ko/api-capabilities/gemini-image-error-handling">
    실패한 생성, 콘텐츠 검열 정책, 친화적인 프롬프트 전략을 진단하는 세 가지 핵심 지표
  </Card>

  <Card title="반드시 읽어야 할 일반 개발 질문" icon="circle-question" href="/ko/faq/nano-banana-image-failure">
    실패한 생성 문제 해결과 자주 묻는 질문
  </Card>

  <Card title="실패한 생성 보장 플랜" icon="shield-check" href="/ko/api-capabilities/nano-banana-pro-guarantee">
    입력으로 인해 발생하지 않은 실패에 대해서는 실패한 요청 수에 따라 크레딧이 환급됩니다
  </Card>
</CardGroup>

<AccordionGroup>
  <Accordion title="왜 connection reset by peer / write_response_body_failed (500)가 발생합니까?">
    전체 오류는 다음과 같습니다:

    ```text theme={null}
    [&{{write tcp ip:port->ip:port: write: connection reset by peer Unknown error shell_api_error  write_response_body_failed} 500 }]
    ```

    이는 **대개 대용량 이미지 업로드로 인해 발생합니다 — 요청 본문이 너무 커져 연결이 끊어집니다**. 다음 모범 사례를 따르십시오:

    * **이미지 수를 제한하십시오**: 공식 규칙 내에서 유지하십시오(프롬프트당 최대 14장 이미지 — 위의 공식 사양을 참조하십시오).
    * **이미지당 크기를 제한하십시오**: 각 이미지를 5MB 미만으로 유지하십시오 — 공식 이미지당 상한은 7MB이며, base64 인코딩은 크기를 대략 1/3 늘리므로 여유를 두십시오.
    * **업로드 전에 프런트엔드에서 압축하십시오**: API로 보내기 전에 프런트엔드(또는 서버 측 릴레이)에서 이미지를 압축하십시오 — 일반적인 방식은 긴 변의 길이를 제한하고, JPEG/WebP로 변환하며, quality 파라미터를 조정하는 것입니다.
    * **URL 입력으로 전환하십시오**: Gemini 기본 형식은 `fileData.fileUri`을 통해 이미지 URL 전달을 지원하므로, 지나치게 큰 base64 요청 본문을 완전히 피할 수 있습니다 — 위의 [URL 이미지 입력](#url-image-input)을 참조하십시오.
  </Accordion>
</AccordionGroup>

## 사용 사례

* **AI 채팅 클라이언트**: [Cherry Studio](/ko/scenarios/chat/cherry-studio)와 같은 클라이언트는 APIYI를 통해 직접 이미지를 생성하도록 구성할 수 있습니다
* **생성 테스트**: 채팅 클라이언트나 콘솔에서 모델 성능을 빠르게 확인할 수 있습니다

## 고급 요구사항

* **URL을 통해 이미지를 업로드하고 싶으십니까?** Gemini 네이티브 엔드포인트는 `fileData.fileUri`를 통해 이미지 URL을 전달할 수 있습니다. 그러나 OpenAI 호환 모드는 URL 업로드를 지원하지 않으므로, 대신 Base64를 사용하십시오. 위의 [URL 이미지 입력](#url-image-input)에서 코드 예제와 주의 사항을 확인하십시오.
* **직접 다운로드 URL을 받고 싶으십니까(대신 Base64가 아니라)?** NB-OSS 그룹을 사용하십시오 — [Nano Banana OSS 그룹](/ko/api-capabilities/nano-banana-oss-group)을 참조하십시오.
