壁紙アプリ向けに画像アセットをまとめて作ろうとすると、最初の関門はいつも「何枚生成するか」ではなく「何枚捨てるか」でした。100枚欲しいなら、実際には300枚から400枚を生成して、構図や色が破綻したものをふるい落とします。この捨てる前提の枚数がそのまま課金額に乗ってくるのが、個人開発でのつらいところでした。
2026年7月に提供が始まった Nano Banana 2 Lite は、Gemini の画像モデルのなかで最も高速かつ低コストという位置づけです。単純に「安いモデルへ全部寄せればよい」と考えたくなりますが、私が実際に試して落ち着いたのは、Lite を一次生成に、標準の Nano Banana 2 を採用後の本番レンダに使い分ける二段構成でした。その分け方の判断基準と、実際に動く最小のルーターを、以下に残しておきます。
「捨てる画像」に最上位モデルの品質は要らない
大量生成の一次パスで生まれる画像の大半は、そもそも採用されません。構図が破綻していたり、狙った雰囲気から外れていたりするものを、人か機械が弾いていきます。ここに標準モデルの解像度や描き込みを使うのは、捨てるものに一番高い単価を払っている状態でした。
一次パスに求められるのは「採用/不採用を判断できる程度の完成度」であって、配信品質ではありません。Lite の速度と単価は、まさにこの用途に噛み合います。個人開発で壁紙アプリを運用してきた身として、私の一次パスで見たいのは色の方向性と大まかな構図だけなので、Lite の出力で判断に困った場面はほとんどありませんでした。数百枚単位で回す私の運用では、この一次パスの単価差がひと月の請求にそのまま効いてきます。
逆に、採用が決まった一枚は配信されて長く使われます。ここだけは標準モデルで作り直す価値があります。二段に分ける発想の核心は、「捨てる前提の枚数」と「残す一枚」で、支払うべき単価が違うという点にあります。
一次生成・採用判定・本番レンダの三工程に切る
二段構成は、工程を三つに分けると素直に組めます。
まず一次生成では、Lite で候補を必要枚数の3〜4倍だけ作ります。次の採用判定では、機械的なふるい落とし(解像度・アスペクト比・明るさの偏り・重複)を先に通し、残ったものだけ人の目、あるいは Vision モデルの評価に回します。最後の本番レンダで、採用された候補と同じ指示(プロンプトとシード)を標準モデルに渡し、配信品質の一枚を作り直します。
この三工程で効いてくるのは、一次生成と本番レンダで指示を共有できるかどうかです。採用した候補のプロンプトとシードを控えておけば、本番レンダは「同じ狙いを高品質で再現する」だけの作業になります。ここが切れていると、採用したはずの雰囲気が本番で再現できず、二度手間になります。
二段ルーターの最小実装
工程を関数として切り出すと、全体の見通しがよくなります。以下は Gemini API の Python SDK を使った最小構成です。モデルIDは環境によって変わるため、定数として外に出しています。
import os
from google import genai
client = genai.Client(api_key=os.environ["GEMINI_API_KEY"])
# モデルIDは提供状況に合わせて設定する
MODEL_DRAFT = os.environ.get("MODEL_DRAFT", "nano-banana-2-lite")
MODEL_FINAL = os.environ.get("MODEL_FINAL", "nano-banana-2")
def generate_draft(prompt: str, seed: int) -> bytes:
"""一次生成: Lite で採用判定用の候補を1枚作る。"""
res = client.models.generate_images(
model=MODEL_DRAFT,
prompt=prompt,
config={"number_of_images": 1, "seed": seed},
)
return res.generated_images[0].image.image_bytes
def machine_screen(image: bytes) -> bool:
"""機械的なふるい落とし。ここで大半を弾く。"""
from PIL import Image
import io
img = Image.open(io.BytesIO(image)).convert("RGB")
w, h = img.size
if w < 512 or h < 512:
return False
# 明るさが極端に偏った出力を弾く
grayscale = img.convert("L")
mean = sum(grayscale.getdata()) / (w * h)
if mean < 20 or mean > 235:
return False
return True
def render_final(prompt: str, seed: int) -> bytes:
"""本番レンダ: 採用候補と同じ指示を標準モデルで再現する。"""
res = client.models.generate_images(
model=MODEL_FINAL,
prompt=prompt,
config={"number_of_images": 1, "seed": seed},
)
return res.generated_images[0].image.image_bytes
def run_batch(prompt: str, want: int, oversample: float = 3.0) -> list[bytes]:
"""一次生成→機械ふるい落とし→採用分だけ本番レンダ。"""
finals: list[bytes] = []
tried = 0
target_drafts = int(want * oversample)
for seed in range(target_drafts):
tried += 1
draft = generate_draft(prompt, seed)
if not machine_screen(draft):
continue
# ここに人 or Vision 評価を挟む。通ったら本番レンダ。
finals.append(render_final(prompt, seed))
if len(finals) >= want:
break
print(f"drafts={tried} finals={len(finals)}")
return finalsポイントは seed を一次生成と本番レンダで共有していることです。同じシードとプロンプトを渡すことで、Lite で見た構図の方向性を標準モデルでも近い形で再現できます。machine_screen はあえて安価な判定に留め、本当に見たい候補だけを人や Vision 評価に送る前段のフィルタとして置いています。
コストがどう変わるか
二段構成の効き目は、単価差と採用率で決まります。仮に一次生成の単価を標準モデルの4分の1、必要枚数100枚、一次生成を3倍の300枚、採用率をそのうち約35%とすると、支払いの内訳は次のようになります。
| 方式 | 標準モデル呼び出し | Lite 呼び出し | 相対コスト(標準単価=1として) |
|---|---|---|---|
| 全部を標準モデルで生成 | 300回 | 0回 | 300 |
| 二段構成(Lite一次+標準100本番) | 100回 | 300回 | 100 + 300×0.25 = 175 |
この試算だと、二段にするだけで相対コストは300から175へ、およそ42%の削減になります。採用率が下がって捨てる枚数が増えるほど、一次生成を安く回せる二段構成の利点は大きくなります。逆に、ほぼ全部を採用するようなワークフローでは差が縮むため、二段にする意味は薄れます。
数字はあくまで単価比を仮定した相対値です。実際の単価は提供状況で変わりますので、counttokens 相当の見積りと実請求を突き合わせて、自分のワークロードで計算し直すことをおすすめします。コストの上限管理そのものについては、Gemini API を組み込んだ個人プロダクトのコスト暴走を防ぐ — 請求書を見てから慌てないためのガードレール設計に別途まとめています。
Lite に寄せすぎないための線引き
安いからといって本番レンダまで Lite に任せると、配信品質で後悔します。私はこの判断を単純に保っていて、「そのまま出力がユーザーの端末に届くか」で分けています。届くものは標準モデル、届く前に捨てられるものは Lite、という線引きです。
もう一つ気をつけているのは、一次生成と本番レンダの再現性です。シードとプロンプトを控えていないと、採用した雰囲気を本番で作り直せず、Lite で見た良さが消えてしまいます。二段構成を導入する前に、生成指示をログとして残す仕組みを先に用意しておくと、後の作り直しがはるかに楽になります。動画から一枚を起こす場合の指示設計は、Nano Banana 2 に動画を渡してサムネイルを1枚生成する — gemini-3.1-flash-image の動画→画像を実装したメモも参考になるかもしれません。
まとめ
大量画像生成のコストは、生成する枚数ではなく「捨てる枚数にどの単価を払っているか」で決まります。Nano Banana 2 Lite を一次生成に、標準の Nano Banana 2 を採用後の本番レンダに置く二段構成は、この単価の払い分けを素直に実装する方法でした。
次の一歩として、まずは手元のワークフローの採用率を測ってみてください。採用率が低いほど、一次生成を安いモデルに寄せる効果は大きく出ます。そのうえで、シードとプロンプトを控える仕組みを先に入れておけば、二段構成はそのまま既存のパイプラインに載せられます。
私自身もまだ単価比の見極めを調整している途中ですが、捨てる前提の一次パスを安く回すという考え方は、個人開発のコスト設計で長く使えそうだと感じています。お読みいただきありがとうございました。