deprecations の表を開いたのは、火曜の昼前でした。Veo 3.1 の preview が3種、10月22日で提供終了と書かれています。移行先の欄には gemini-omni-1.1-flash。
この日付を見て、私が最初に思ったのは「置換すれば終わる」ではなかった——と気づいたのは、画面を閉じたあとでした。どこで Veo を呼んでいるのかを、私自身がもう覚えていない——そのことのほうが気がかりだったのです。
個人開発では、素材を動画にして試すスクリプトが、どうしても何本か残ります。動いているものもあれば、一度だけ回して放置したものもあります。
先に決めたのは「何を直すか」ではなく「何が呼んでいるか」
最初のうち、私は検索窓に veo-3.1 と打ち込んで、出てきた行を片端から書き換えようとしました。結果は芳しくありませんでした。ノートブックの出力セルに残った古いモデル名まで拾ってしまい、一方で、環境変数から名前を読み込むスクリプトは一件も見つからなかったのです。
いまは次の順で進めています。
- モデル名の文字列を探します(コード・設定ファイル・ノートブック)
- 文字列に出てこない間接参照を探します(環境変数、設定ファイルのキー)
- 見つかった箇所を「期日までに直す」「止めてよい」「そもそも使っていない」の3つに振り分けます
書き換える前に、まず数えます。 この線引きだけは、期日が近いほど守るようにしています。
呼び出し箇所を洗い出すスクリプト
停止対象は preview の3種です。正確なモデル ID は deprecations の表で確かめ、下の PATTERNS に貼り込んでください。ここでは veo-3.1 で始まり preview で終わる名前を広めに拾う形にしています。
import re
import sys
from pathlib import Path
# 何を解決するか: 停止対象のモデル名が、どのファイルの何行目に残っているかを一覧にする
PATTERNS = [
re.compile(r"veo-3\.1[\w.\-]*preview"), # 文字列としての直書き
re.compile(r"VEO_MODEL|VIDEO_MODEL"), # 間接参照の目印(自分の命名に合わせて変更)
]
SKIP_DIRS = {".git", "node_modules", ".venv", "__pycache__"}
EXTS = {".py", ".js", ".ts", ".json", ".yaml", ".yml", ".env", ".ipynb", ".md", ".sh"}
def scan(root: Path):
for path in root.rglob("*"):
if any(part in SKIP_DIRS for part in path.parts):
continue
if not path.is_file() or (path.suffix not in EXTS and path.name != ".env"):
continue
try:
lines = path.read_text(encoding="utf-8", errors="ignore").splitlines()
except OSError:
continue
for no, line in enumerate(lines, 1):
for pat in PATTERNS:
if pat.search(line):
yield path, no, line.strip()[:120]
if __name__ == "__main__":
root = Path(sys.argv[1] if len(sys.argv) > 1 else ".")
hits = list(scan(root))
for path, no, text in hits:
print(f"{path}:{no}: {text}")
print(f"\n合計 {len(hits)} 件")なぜ .ipynb と .md まで含めているのか。ノートブックは出力セルにモデル名が残りますし、メモ代わりの Markdown に書いた手順は、あとで誰かがコピーして動かしてしまうからです。
出てきた行は、そのまま次の表計算に貼って「直す/止める/不要」を一つずつ振っていきます。数十行なら、10分もかかりません。
棚卸しで見落としやすい三つの場所
スクリプトで拾えるのは、リポジトリの中にあるものだけです。拾いきれない場所が、少なくとも三つあります。
一つ目は、定期実行の設定です。cron やクラウド側のスケジューラに、コマンドライン引数でモデル名を渡している場合があります。コードを何度検索しても出てきません。
二つ目は、別のマシンに置いたままの .env です。普段使いのパソコンでは直したのに、古い環境変数がもう一台に残っている、という形で期日を迎えるのが、いちばん手が止まります。
三つ目は、ノートブックの共有コピーです。自分のリポジトリは直しても、人に渡した写しは直りません。
この三つは、検索ではなく思い出す作業です。私は紙に「動画を回している場所」を書き出し、スクリプトの結果と突き合わせるようにしています。
差し替え先は、コードではなく設定に一か所だけ置く
棚卸しが済んだら、モデル名を設定ファイルに寄せます。ここで一つ、正直に書き残しておきたいことがあります。
移行先の gemini-omni-1.1-flash を、Veo と同じ generate_videos で呼ぶのか、別の呼び出し形になるのか。私はこの記事を書いた時点で、自分の手元で動かして確かめておりません。 呼び出し形は公式の移行ガイドで確認し、下のコードは「モデル名の解決」と「期日の扱い」だけを担当させています。
import os
from datetime import date
# 何を解決するか: モデル名を一か所に集め、期日を過ぎたら黙って流れずに止まる
SHUTDOWN = date(2026, 10, 22)
def resolve_video_model() -> str:
model = os.environ.get("VIDEO_MODEL")
if not model:
raise RuntimeError("VIDEO_MODEL が未設定です。.env か実行環境に指定してください")
is_veo_preview = model.startswith("veo-3.1") and model.endswith("preview")
if is_veo_preview and date.today() >= SHUTDOWN:
# 期日後に旧モデルを指していたら、代替へ自動で切り替えず止める
raise RuntimeError(f"{model} は {SHUTDOWN} に提供終了しています。設定を差し替えてください")
if is_veo_preview:
remaining = (SHUTDOWN - date.today()).days
print(f"⚠️ {model} は残り {remaining} 日で停止します")
return modelなぜ自動で代替モデルに切り替えないのか。出力の傾向も、料金も、対応する尺や解像度も、モデルごとに違うからです。気づかないうちに別のモデルへ流れると、請求と出来上がりが静かにずれていきます。止まって知らせてくれるほうが、後始末は軽く済みます。
Before / After にすると、直す場所はこれだけです。
# Before: 呼び出しのたびにモデル名が直書きされている
operation = client.models.generate_videos(model="veo-3.1-...-preview", prompt=prompt)
# After: 解決は一か所。名前を変えたいときは環境変数だけ触る
model_id = resolve_video_model()... の部分には、棚卸しで見つかった実際の名前が入ります。After に書き換えたら、最初の1本は短い尺で回し、動画が出来上がるところまで見届けてください。呼び出し形が変わる場合は、ここで初めて分かります。
期日までの進め方
残りの16日は、次のように割るつもりです。
- 今週は、棚卸しを実行して「直す/止める/不要」を振ります
- 来週前半は、「直す」だけを設定に寄せて、短い尺で1本ずつ試します
- 10/22 の3日前に、旧モデル名が残っていないことをもう一度スクリプトで確かめます
使っていないスクリプトは、直さずに止めます。直す範囲を広げないことも、期日前の大事な線引きです。
最初の一手
まず、上の検索スクリプトを、動画を触ったことのあるフォルダに一度かけてみていただければと思います。件数を見れば、今週やることの大きさが分かります。数が少なければ肩の荷が下りますし、多ければ、今日のうちに分かってよかったと思えるはずです。
Veo 3.1 Lite の基本的な呼び出し方はVeo 3.1 Lite API で低コスト動画生成を始めるにまとめています。差し替え後の呼び出し形を確かめるときの足場になれば幸いです。