개요
gemini-3-pro-image-preview (즉, Nano Banana Pro)는 엄격한 콘텐츠 안전성 제어를 적용하며, 여러 계층에서 규정에 맞지 않는 요청을 거부합니다. 단순한 “생성 실패” 메시지는 사용자가 문제를 이해하는 데 도움이 되지 않습니다. 적절한 오류 처리는 다음을 충족해야 합니다.
- 거부 사유를 정확히 식별해야 합니다 — 콘텐츠 위반, 지식 베이스 제한, 기술 오류를 구분해야 합니다
- 친절한 사용자 메시지를 제공해야 합니다 — 기술적 오류를 이해하기 쉬운 설명으로 바꿔야 합니다
- 실행 가능한 제안을 제공해야 합니다 — 성공할 수 있도록 요청을 어떻게 조정해야 하는지 알려야 합니다
- 완전한 기술 세부 정보를 유지해야 합니다 — 개발자 디버깅용입니다
요청이 HTTP 200이지만 이미지가 없는 경우라면, 이는 보통 Google 쪽에서 내린 안전성 판단입니다. APIYI의 투명한 프록시는 결과를 있는 그대로 전달할 뿐입니다 — 저희도 고객이 이미지를 성공적으로 생성하길 바랍니다. 감지 및 메시징 로직은 애플리케이션 측에서 구현해야 합니다.
Google 콘텐츠 검토 정책 (2026 업데이트)
Google의 이미지 생성은 2단계 안전 메커니즘을 사용합니다.- 구성 가능한 필터: 괴롭힘, 혐오 발언, 성적으로 노골적인 콘텐츠, 위험한 콘텐츠의 네 가지 범위를 다루며,
safetySettings을 통해 조정할 수 있습니다 - 내장 보호 조치: 아동 안전과 같은 핵심 유해 행위에 대해서는 항상 활성화되어 있으며, 매개변수를 통해 비활성화할 수 없습니다
- 생성형 AI 금지 사용 정책:
policies.google.com/terms/generative-ai/use-policy - 생성형 콘텐츠 일반 오류 참고 자료:
ai.google.dev/api/generate-content
세 가지 핵심 진단 지표
다음 순서로 우선순위, 높은 것부터 낮은 것까지 확인하십시오:1. candidatesTokenCount (최우선) ⭐
- 위치:
response.usageMetadata.candidatesTokenCount - 의미: API가 생성한 후보 콘텐츠의 token 수입니다
- 규칙: 값이
0이면 요청이 콘텐츠 검열 단계에서 즉시 거부되었으며 후보 콘텐츠가 아예 생성되지 않았다는 뜻입니다. 이는 가장 엄격한 거부입니다.
2. finishReason (두 번째 우선순위)
- 위치:
response.candidates[0].finishReason - 규칙:
STOP이외의 값은 특수 처리가 필요한 비정상 종료를 의미합니다
finishReason 값입니다(참고로 Nano Banana 시리즈는 IMAGE_ 접두사가 붙은 이미지 전용 값을 추가했습니다):
3. 텍스트 거부 설명 (중요)
- 위치:
response.candidates[0].content.parts[].text - 규칙:
finishReason가STOP이지만parts에text만 있고 이미지 데이터가 없을 때, API는 이미지 대신 거부 설명을 반환합니다. 텍스트는 중국어 또는 영어일 수 있으며, 예를 들면:
오류 시나리오 빠른 참고
처리 흐름(결정 순서)
핵심 코드 구현
위의 검사들을 하나의 파싱 함수로 결합합니다:소비자 친화적 메시지
설계 원칙: 명확하고 간결함, 긍정적인 안내, 실행 가능함, 비난 없음. 권장 템플릿:- 소비자 사용자: 기본적으로 친절한 설명 + 수정 제안만 표시합니다
- 비즈니스 / 도구 제공자: 기본적으로 기술 세부 정보(
finishReason,candidatesTokenCount등)를 펼쳐서 표시합니다 - 개발자: 전체 JSON 응답을 볼 수 있도록 “펼치기/접기” 토글을 제공합니다
모범 사례
- 우선순위에 따라 엄격하게 확인합니다:
candidatesTokenCount→finishReason→parts→ 데이터 추출 → 키워드 감지 - thoughtSignature를 확인하기 전에 텍스트를 먼저 수집합니다: 거부 설명을 잃지 않기 위함입니다
- 전체 응답을 유지합니다: 개발/테스트 도구는 문제 해결을 위해 항상 원시 JSON을 저장해야 합니다
- 중국어와 영어 거부 텍스트를 지원합니다: Google은 중국어나 영어를 반환할 수 있으므로 키워드 매칭은 둘 다를 포괄해야 합니다
- 점진적 폴백을 적용합니다: 스마트 감지가 성공하면 구체적인 메시지를 표시하고, 그렇지 않으면 API 텍스트를 직접 표시하며, 그다음에는 친숙한
finishReason이름을 사용하고, 마지막에만 일반 메시지로 폴백합니다 - “알 수 없는 오류”는 절대 표시하지 않습니다: 항상 실행 가능한 제안이나 전체 응답을 포함해야 합니다
자주 묻는 질문
왜 같은 prompt가 때로는 성공하고 때로는 실패합니까?
왜 같은 prompt가 때로는 성공하고 때로는 실패합니까?
Google의 안전 필터링은 무작위성과 문맥 의존성이 있습니다. 참조 이미지의 내용과 prompt를 결합하는 방식이 모두 판단에 영향을 미칩니다. 문구를 조정하거나 더 간접적인 표현을 사용해 보십시오.
어떻게 콘텐츠 문제인지 기술 문제인지 구분합니까?
어떻게 콘텐츠 문제인지 기술 문제인지 구분합니까?
candidatesTokenCount: 0 또는 finishReason: PROHIBITED_CONTENT → 콘텐츠 문제; Failed to fetch 또는 HTTP 오류 → 기술 문제; API 텍스트 설명 → 보통 콘텐츠 문제입니다.일반 사용자는 기술 정보를 얼마나 보아야 합니까?
일반 사용자는 기술 정보를 얼마나 보아야 합니까?
단계적 표시: 기본적으로는 친절한 설명 + 수정 제안을 보여주고, 필요하면 기술 세부 정보를 펼쳐 보이며, 개발 모드에서는 전체 JSON 응답을 표시합니다.
모든 finishReason마다 별도 처리를 작성해야 합니까?
모든 finishReason마다 별도 처리를 작성해야 합니까?
아닙니다. 매핑 테이블과 일반적인 폴백이면 충분합니다:
reasonMessages[finishReason] || 그런 다음 원시 값을 표시합니다.