日曜の朝、deprecations のページを開き直して、表の下のほうで目が止まりました。10月22日更新の表に、11月17日の欄がまとまって並んでいたのです。TTS が 3 つと Live 系が 2 つで、どれも名前に preview が付いていました。
停止日は同ページの説明どおり「最も早い日」で、これより前に止まることはなくても、後ろにずれる保証はありません。今日から数えて 23 日。個人開発で音声読み上げを足したことがある方は、自分のフォルダのどこにその名前が書いてあるか、すぐには言えないのではないでしょうか。私自身もそうでした。個人開発で試しに足した音声機能ほど、設定がいろいろな場所に散っているものなのだと、数えようとして初めて気づきました。
最初にお伝えしたいのは、名前の置き換えより先に、名前の数え上げを終わらせるほうがよい、ということです。数が分かれば、直す順番も、今週中に終わるかどうかも見えてきます。
対象になっている名前
deprecations の表(2026年10月22日更新)で、停止日が 11月17日になっているのは次の 5 つです。
gemini-3.1-flash-tts-previewはgemini-3.8-flash-ttsまたはgemini-3.8-flash-lite-ttsへgemini-2.5-flash-preview-ttsも同じくgemini-3.8-flash-ttsまたはgemini-3.8-flash-lite-ttsへgemini-2.5-pro-preview-ttsも同じ移行先ですgemini-3.1-flash-live-previewはgemini-3.8-liveへgemini-2.5-flash-native-audio-preview-12-2025もgemini-3.8-liveへ
同じ表には、10月22日に止まった Omni 系や、10月23日に止まった Deep Research の旧名も載っています。こちらは過ぎた話なので、ここでは扱いません。前回の期限を棚卸しした手順は 9月30日に止まる Omni プレビューの棚卸し に書いています。
名前を数えるスクリプト
手で検索すると、.env.local や YAML の設定ファイルを開き忘れます。そこで、フォルダを丸ごと走査して「ファイル名:行番号」を並べるだけの小さなスクリプトを使います。
#!/usr/bin/env python3
"""止まる予定のモデル名が、どのファイルの何行目に書かれているかを数える。"""
import re
import sys
from pathlib import Path
# 2026-10-22 更新の deprecations ページから転記(停止日は「最も早い日」)
RETIRING = {
"gemini-3.1-flash-tts-preview": ("2026-11-17", "gemini-3.8-flash-tts / gemini-3.8-flash-lite-tts"),
"gemini-2.5-flash-preview-tts": ("2026-11-17", "gemini-3.8-flash-tts / gemini-3.8-flash-lite-tts"),
"gemini-2.5-pro-preview-tts": ("2026-11-17", "gemini-3.8-flash-tts / gemini-3.8-flash-lite-tts"),
"gemini-3.1-flash-live-preview": ("2026-11-17", "gemini-3.8-live"),
"gemini-2.5-flash-native-audio-preview-12-2025": ("2026-11-17", "gemini-3.8-live"),
}
SKIP_DIRS = {".git", "node_modules", ".next", "dist", "build", "__pycache__", ".venv"}
TEXT_EXT = {".py", ".js", ".ts", ".tsx", ".json", ".yaml", ".yml", ".toml",
".env", ".md", ".txt", ".sh", ".swift", ".kt", ".dart", ".cfg", ".ini"}
def candidates(root: Path):
for p in root.rglob("*"):
if any(part in SKIP_DIRS for part in p.parts) or not p.is_file():
continue
# .env.local のように拡張子が複数ある名前も拾う
if p.suffix in TEXT_EXT or p.name.startswith(".env"):
yield p
def main(root_arg: str) -> int:
root = Path(root_arg)
# 長い名前を先に当てる(-preview-12-2025 を取りこぼさないため)
pattern = re.compile("|".join(re.escape(k) for k in sorted(RETIRING, key=len, reverse=True)))
hits = 0
for path in candidates(root):
try:
lines = path.read_text(encoding="utf-8").splitlines()
except (UnicodeDecodeError, OSError):
continue # バイナリや読めないファイルは飛ばす
for no, line in enumerate(lines, 1):
for m in pattern.finditer(line):
date, to = RETIRING[m.group(0)]
print(f"{path.relative_to(root)}:{no}\t{m.group(0)}\t{date}\t-> {to}")
hits += 1
print(f"-- {hits} 件", file=sys.stderr)
return 1 if hits else 0
if __name__ == "__main__":
sys.exit(main(sys.argv[1] if len(sys.argv) > 1 else "."))見つかれば終了コードが 1 になるので、後からシェルスクリプトや CI に組み込めます。
手元で動かして確かめたこと
3 つのファイルだけの使い捨てフォルダ(.env.local、Python の 1 ファイル、YAML の 1 ファイル)に、止まる名前を意図的に 4 か所埋めて走らせました。結果は次の 4 行で、4 件すべてを拾えています。
.env.local:1 gemini-2.5-flash-preview-tts 2026-11-17 -> gemini-3.8-flash-tts / gemini-3.8-flash-lite-tts
src/voice.py:1 gemini-2.5-flash-native-audio-preview-12-2025 2026-11-17 -> gemini-3.8-live
config/app.yaml:1 gemini-3.1-flash-tts-preview 2026-11-17 -> gemini-3.8-flash-tts / gemini-3.8-flash-lite-tts
config/app.yaml:2 gemini-2.5-pro-preview-tts 2026-11-17 -> gemini-3.8-flash-tts / gemini-3.8-flash-lite-ttsYAML の 2 行目はコメント文の中の名前です。これも拾うのは意図どおりで、説明文に古い名前が残っていると、あとで誰かが写して使ってしまうからです。
作りながら気をつけた 3 点
拡張子だけで絞ると .env.local を落とします。 Path.suffix は最後の .local を返すため、.env の一覧に引っかかりません。名前が .env で始まるかどうかを別に見ています。
名前の長さの順に当てます。 gemini-2.5-flash-native-audio-preview-12-2025 のように、ほかの名前の一部と重なりうる長いものは、長い順に並べないと途中で切れた形で一致します。
このスクリプトが拾えないものもあります。 文字列を "gemini-" + version + "-flash-tts" のように組み立てている箇所、データベースやクラウドの管理画面に保存した設定、ノーコードツールの内部設定です。ここは検索では見つかりません。見つからなかった件数は、いま思えば「ゼロ」ではなく「このフォルダの中ではゼロ」と読みます。
見つかった行の直し方
直す順番は、置き換えやすさではなく、止まったときの被害の大きさで決めています。
- 本番のサーバーが読む設定(環境変数・設定ファイル)
- アプリに同梱している定数
- テスト・サンプル・README
TTS から TTS へ、Live から Live へ、という置き換えの方向は表のとおりです。ただし、名前を変えるだけで声の質や応答の間が同じになる保証はありません。移行先の gemini-3.8-live については、Live API のセッションを設計した記事 Live API で同時通訳アプリを作る際のセッション設計 の考え方がそのまま使えます。実際の声を聞き比べるのは、名前を差し替えたあとの別の作業にしておくと、切り分けが楽になります。
もう一つ、置き換えたあとに「返ってきたモデル名」を記録しておくと、自動で振り替えられた場合にも気づけます。方法は Flash の返事の調子が変わった朝の確認手順 にまとめています。
今日やること
数えるのは今日、直すのは数えた後。 この線引きを守るだけで、23 日という残りが「長いのか短いのか」を、自分のフォルダの件数で判断できるようになります。
まずは、いちばん大きいプロジェクトのフォルダでスクリプトを一度走らせて、件数をメモに残してください。ゼロだった場合も、管理画面に保存した設定を一つ開いて、同じ名前がないかだけ見ておくと安心です。