概要
gemini-3-pro-image-preview(すなわち Nano Banana Pro)は厳格なコンテンツ安全制御を適用しており、複数の層で非準拠のリクエストを拒否します。単純な「generation failed」メッセージでは、ユーザーは問題を理解しにくいです。適切なエラーハンドリングには、次の内容が必要です。
- 拒否理由を正確に特定する — コンテンツ違反、ナレッジベースの制限、技術的なエラーを区別する
- ユーザーフレンドリーなメッセージを提供する — 技術的なエラーを理解しやすい説明に変換する
- 実行可能な提案を示す — リクエストをどう調整すれば成功しやすいかをユーザーに伝える
- 完全な技術詳細を保持する — 開発者のデバッグ用に
リクエストが HTTP 200 なのに画像が返らない 場合、これは通常、Google 側で行われた安全性判断です。APIYI の透過プロキシは結果をそのまま転送するだけです。私たちもお客様に画像を正常に生成してほしいと考えています。検出とメッセージングのロジックは、アプリケーション側で実装する必要があります。
Google コンテンツモデレーションポリシー(2026年更新)
Googleの画像生成は、二層の安全メカニズムを使用しています:- 設定可能なフィルター: ハラスメント、ヘイトスピーチ、露骨な性的コンテンツ、危険なコンテンツの4カテゴリを対象とし、
safetySettingsで調整可能です - 組み込みの保護: 児童の安全などの中核的な危害に対して常に有効で、パラメータで無効化することはできません
- 生成AI禁止使用ポリシー:
policies.google.com/terms/generative-ai/use-policy - 生成コンテンツの一般的なエラー参照:
ai.google.dev/api/generate-content
3つの主要な診断指標
優先度の高い順に次の順で確認してください。1. candidatesTokenCount(最優先)⭐
- 場所:
response.usageMetadata.candidatesTokenCount - 意味: API が生成した候補コンテンツの token 数
- ルール:
0の値は、リクエストがコンテンツモデレーション段階で完全に拒否されたことを意味します — 候補コンテンツは一切生成されていません。これは最も厳しい拒否です。
2. finishReason(第2優先)
- 場所:
response.candidates[0].finishReason - ルール:
STOP以外の値は、特別な処理が必要な異常終了を示します
finishReason 値(なお、Nano Bananaシリーズでは IMAGE_ プレフィックスの画像専用値が追加されています):
3. テキスト拒否の説明(重要)
- 場所:
response.candidates[0].content.parts[].text - ルール:
finishReasonがSTOPで、かつpartsにtextのみが含まれ、画像データがない場合、API は画像ではなく拒否説明を返しています。テキストは中国語または英語の場合があり、例えば次のようになります:
エラーシナリオのクイックリファレンス
処理フロー(判断順)
コード実装(コア)
上記のチェックを 1 つのパース関数にまとめます:Consumer-Friendly Messaging
Design principles: clear and concise, positive guidance, actionable, no blame. Recommended templates:- Consumer users: by default show only the friendly explanation + revision suggestion
- Business / tool providers: by default expand technical details (
finishReason,candidatesTokenCount, etc.) - Developers: provide an “expand/collapse” toggle to view the full JSON response
ベストプラクティス
- 優先度順に厳密に確認する:
candidatesTokenCount→finishReason→parts→ データを抽出 → キーワード検出 - thoughtSignature を確認する前にテキストを収集する: 拒否理由を失わないようにするためです
- 完全なレスポンスを保持する: 開発/テスト用ツールは、トラブルシューティングのために常に生の JSON を保存してください
- 中国語と英語の拒否テキストをサポートする: Google は中国語または英語を返すことがあるため、キーワード照合では両方をカバーする必要があります
- 段階的にフォールバックする: スマート検出が成功した場合は具体的なメッセージを表示し、それ以外は API テキストをそのまま表示し、それもできなければ親しみやすい
finishReason名を使い、最後に一般的なメッセージへフォールバックします - “unknown error” を表示しない: 常に実行可能な提案か、完全なレスポンスを含めてください
よくある質問
同じ prompt が、成功したり失敗したりするのはなぜですか?
同じ prompt が、成功したり失敗したりするのはなぜですか?
Google の安全フィルタリングにはランダム性と文脈依存があります。参照画像の内容や prompt の組み合わせ方が、いずれも判定に影響します。文言を調整するか、より間接的な表現を試してください。
それがコンテンツの問題か技術的な問題かは、どう見分ければよいですか?
それがコンテンツの問題か技術的な問題かは、どう見分ければよいですか?
candidatesTokenCount: 0 または finishReason: PROHIBITED_CONTENT → コンテンツの問題; Failed to fetch または HTTP エラー → 技術的な問題; API のテキストによる説明 → 通常はコンテンツの問題。一般ユーザーには、どの程度の技術情報を見せるべきですか?
一般ユーザーには、どの程度の技術情報を見せるべきですか?
段階的表示: デフォルトではわかりやすい説明 + 修正提案を表示し、必要に応じて技術詳細を展開し、開発モードでは完全な JSON レスポンスを表示します。
finishReason ごとに個別の処理を書き分ける必要はありますか?
finishReason ごとに個別の処理を書き分ける必要はありますか?
いいえ。マッピング表と汎用フォールバックがあれば十分です:
reasonMessages[finishReason] || のあとに生の値を表示します。