明日で止まる画像モデルの棚卸しをしていて、手が止まった行がありました。
止まるモデルの名前には -preview が付いていません。付いていないのに止まります。
一方で、いま一番深く考えてくれる推論モデルには -preview が付いています。付いているのに、私は本番のパイプラインで使っています。
モデル名の末尾を安全の目印にしていたつもりが、実際には何も守っていなかった、ということでした。
GA と preview の違いは、新しさではなく予告の出方です
GA(一般提供)と preview を「完成度の高さ」で読んでいると、選び方を間違えます。
私が実務で意味があると感じているのは、次の一点だけです。
そのモデルの停止が、日付つきで非推奨表に載るかどうか。
GA のモデルも止まります。明日8月17日に止まる imagen-4.0-generate-001 は、名前の形の上では preview ではありません。GA のモデルが、日付を提示されたうえで停止します。
preview のモデルは、その表に載る前に静かに置き換わることがあります。実際、6月に画像のプレビューモデルが停止したときは、気づいたのが朝のバッチが落ちた後でした。
つまり両者の差は「止まるかどうか」ではありません。止まる前に、こちらが準備できる時間をもらえるかどうかです。
この読み替えをしてから、モデルを選ぶときの質問が変わりました。「どれが一番賢いか」ではなく、「このモデルが消えると知らされるのはいつか」を先に見るようになりました。
いまの Gemini は、強い順と GA 順が入れ替わっています
2026年8月時点のラインナップを、性能ではなく提供段階で並べ直すと、少し落ち着かない表になります。
| モデル | 提供段階 | 主な用途 |
|---|---|---|
| Gemini 3.1 Pro | preview | 最上位の推論。深く考えさせたい処理 |
| Gemini 3.7 Flash | GA(8月13日) | コード生成・Web開発・エージェント的な処理 |
| Gemini 3.6 Flash | GA | トークン効率重視の汎用。3.5 Flash より低価格帯 |
| Gemini 3.5 Flash-Lite | GA | 低遅延・低コスト。大量処理のサブエージェント |
| Gemini 3.1 Flash TTS | preview | 音声合成。話し方の制御ができる |
上から下へ、強い順にはなっていません。一番強い層が preview で、日々の処理を回す層が GA という順序です。
個人開発でこの表を見ると、判断が一つに絞られます。深く考えさせたい処理ほど、予告なく変わりうるモデルに預けることになる、ということです。
私の場合、記事の下書き整形や、App Store と Google Play に出す説明文の下ごしらえといった「毎日回るもの」は GA の Flash 系に置いています。逆に、月に数回しか動かさない設計相談のような処理は preview の Pro に投げています。
理由は品質ではなく復旧のしやすさです。月に数回の処理なら、動かなくなった日に手で直せます。毎朝5時に動くものは、そうはいきません。
自分のコードが preview を何箇所踏んでいるか、先に数えます
「preview は避けよう」と決めても、いま何箇所使っているかを知らなければ動けません。
そこで、モデル ID を書いている場所を集めて3つに仕分けるだけのスクリプトを用意しました。難しいことはしていません。文字列を拾って、末尾の形で分けているだけです。
#!/usr/bin/env python3
"""check_preview_models.py
コードベースの中で Gemini のモデル ID を書いている場所を集め、
GA / preview / エイリアス の3つに分けて表示します。
使い方: python3 check_preview_models.py <ディレクトリ>
"""
import re
import sys
from pathlib import Path
MODEL_RE = re.compile(r"[\"']((?:gemini|imagen|gemma)[a-z0-9._-]*)[\"']")
TEXT_SUFFIX = {".py", ".ts", ".tsx", ".js", ".mjs", ".json", ".yaml", ".yml", ".toml"}
def classify(model_id: str) -> str:
if model_id.endswith("-latest"):
return "alias" # 指す先が黙って入れ替わる
if "-preview" in model_id or "-exp" in model_id:
return "preview" # 予告が短い可能性がある
return "ga?" # GA と思われる。ただし後述の落とし穴あり
def scan(root: Path):
found = []
for path in sorted(root.rglob("*")):
if not path.is_file() or path.suffix not in TEXT_SUFFIX:
continue
lines = path.read_text(encoding="utf-8", errors="ignore").splitlines()
for lineno, line in enumerate(lines, 1):
for m in MODEL_RE.finditer(line):
found.append((classify(m.group(1)), m.group(1), f"{path}:{lineno}"))
return found
def main() -> int:
root = Path(sys.argv[1] if len(sys.argv) > 1 else ".")
found = scan(root)
if not found:
print("モデル ID の記述は見つかりませんでした。環境変数も確認してください。")
return 0
for bucket, label in (("preview", "preview(予告が短い可能性)"),
("alias", "エイリアス(指す先が黙って入れ替わる)"),
("ga?", "GA と思われるもの(非推奨表で要確認)")):
rows = [r for r in found if r[0] == bucket]
print(f"\n[{label}] {len(rows)} 箇所")
for _, model_id, where in rows:
print(f" {model_id:38s} {where}")
risky = sum(1 for r in found if r[0] in ("preview", "alias"))
print(f"\n合計 {len(found)} 箇所。うち先に確認すべきものが {risky} 箇所あります。")
return 1 if risky else 0
if __name__ == "__main__":
sys.exit(main())なぜ .json や .yaml まで見に行くかというと、モデル名はコードよりも設定ファイルに隠れていることが多いためです。Python だけを grep して安心してしまうと、設定に書いた一行を取りこぼします。
エイリアスを preview と別枠にしているのにも理由があります。gemini-flash-latest のような書き方は、停止のお知らせが来なくても、ある日から別のモデルに変わります。これは preview とは違う種類の不確かさなので、混ぜて数えると対処を間違えます。
スクリプトが「GA」と答えた行こそ、明日止まります
サンプルのプロジェクトを作って走らせた結果が、この記事で一番お伝えしたい部分です。
[preview(予告が短い可能性)] 2 箇所
gemini-3.1-pro-preview sample/app/draft.py:1
gemini-3.1-flash-tts-preview sample/app/tts.ts:1
[エイリアス(指す先が黙って入れ替わる)] 1 箇所
gemini-flash-latest sample/conf/models.json:1
[GA と思われるもの(非推奨表で要確認)] 3 箇所
gemini-3.6-flash sample/app/draft.py:2
gemini-3.5-flash-lite sample/app/tts.ts:2
imagen-4.0-generate-001 sample/conf/models.json:1
合計 6 箇所。うち先に確認すべきものが 3 箇所あります。一番下の「GA と思われるもの」の中に、imagen-4.0-generate-001 が入っています。明日止まるモデルです。
スクリプトは間違っていません。名前の形だけを見れば、確かに preview ではないからです。名前の形からは、そのモデルが止まるかどうかは分かりません。
ですから、この仕分けは「危険なものを見つける道具」ではなく、「非推奨表と突き合わせる順番を決める道具」として使っています。preview とエイリアスから先に確認し、GA の列は非推奨表と一件ずつ照らし合わせる、という順序です。
関数名の廃止とモデルの停止が別の話であることは、generate_images は2027年まで残ります。それでも8月17日に画像生成は止まりますに書きました。この記事の仕分けは、その2つを混同しないための前段になります。
preview に乗ってよい場所を、自分の言葉で決めておきます
preview を全部避ける、という判断は現実的ではありません。いま一番深く考えてくれるモデルが preview にいるからです。
私は次の3つで線を引いています。
- 人が結果を見てから次に進む処理であれば preview を使う(止まっていればその場で気づけます)
- 決まった時刻に無人で動く処理には GA だけを置く(気づくのが翌朝になります)
- 出力を保存して後から再現する必要がある処理には preview を使わない(同じ出力を二度と作れなくなります)
3番目は6月の停止で学んだことです。preview のモデルで作った壁紙アプリ用の下絵を、あとから同じ条件で作り直そうとして、できませんでした。生成物を資産として抱えるなら、作った側のモデルが消えることまで含めて考える必要があります。
この線引きは、書き出して置いておくことに意味があります。頭の中にあるうちは、締切が近い日に「今回だけ」と崩れるからです。
なお、GA の中でどれを選ぶかという話は、性能よりも請求書の形で決まる場面が多くあります。8月13日に一般提供に入った 3.7 Flash の価格をどう吸収するかは、Gemini 3.7 Flash の値上げ分は、バッチ層へ移すとちょうど相殺されますで扱っています。
明日までに一度だけやること
手元のプロジェクトで上のスクリプトを一度走らせて、出てきた「preview」と「エイリアス」の行だけをメモに残してください。
直す必要はまだありません。数が分かっていれば、次に停止のお知らせが届いた日に、慌てる時間がそのまま減ります。
私自身、6月は数を知らないまま朝を迎えました。同じ形で二度困らないように、いまは月初にこのスクリプトを走らせるようにしています。お読みいただきありがとうございました。