Перейти к содержимому

Провайдер объявил о выводе модели из эксплуатации

Провайдеры отключают старые модели регулярно, и сообщают об этом в changelog, письмом или флагом в /models. Если вы намертво прибили в коде gpt-4-0613 или claude-3-sonnet-20240229, дата отключения — это дата, когда ваш прод внезапно начнёт возвращать model_not_found. Push за несколько недель до этого превращает аварию в спокойную задачу на миграцию.

Паттерн — scheduled-функция на YC, которая раз в день сверяет список моделей провайдера с вашими «прибитыми» id.

Ключевые поля у разных провайдеров называются по-разному, но идея одна: у модели есть флаг/дата depreciation. State-файл хранит уже отправленные алёрты.

import os, json, requests
STATE = "/tmp/model-deprecation.json"
# модели, на которые вы реально ходите в проде
MODELS_IN_USE = {
"gpt-4o-2024-05-13",
"gpt-4-0613",
}
def notify(title, msg, prio):
requests.post(f"{os.environ['NOTIFLY_URL']}/message",
params={"token": os.environ["NOTIFLY_TOKEN"]},
json={"title": title, "message": msg, "priority": prio},
timeout=5)
def list_models():
r = requests.get("https://api.openai.com/v1/models",
headers={"Authorization": f"Bearer {os.environ['PROVIDER_KEY']}"},
timeout=15)
r.raise_for_status()
return {m["id"]: m for m in r.json()["data"]}
def handler(event, context):
catalog = list_models()
state = json.load(open(STATE)) if os.path.exists(STATE) else {}
changed = False
for mid in MODELS_IN_USE:
meta = catalog.get(mid)
# 1) модель совсем пропала из каталога = уже отключена
if meta is None:
if state.get(mid) != "gone":
notify("🗑️ Модель исчезла из каталога",
f"{mid} больше нет в /models — вероятно, уже отключена. "
f"Прод может отдавать model_not_found.",
prio=9)
state[mid] = "gone"; changed = True
continue
# 2) модель помечена deprecated / есть дата отключения
dep = meta.get("deprecation") or meta.get("deprecated")
if dep and state.get(mid) != "deprecated":
when = meta.get("shutdown_date") or meta.get("sunset") or "дата не указана"
notify("⚠️ Модель помечена deprecated",
f"{mid} будет отключена: {when}.\n"
f"Пора выбрать замену и прогнать eval на новой модели.",
prio=7)
state[mid] = "deprecated"; changed = True
if changed:
json.dump(state, open(STATE, "w"))
return {"statusCode": 200, "body": json.dumps({"checked": list(MODELS_IN_USE)})}

priority=7 для deprecated (у вас есть время), но priority=9, если модель уже исчезла из каталога — это уже почти инцидент.

Timer раз в сутки более чем достаточно:

Окно терминала
yc serverless trigger create timer \
--name notifly-model-deprecation \
--cron-expression '0 9 * * ? *' \
--invoke-function-name notifly-model-deprecation \
--invoke-function-service-account-id <sa-id>

Не у всех есть deprecation в /models. Тогда:

  • changelog-страница — скачиваем HTML/RSS раз в день, сравниваем хэш, при изменении шлём push (см. паттерн из integrity-check);
  • письма-анонсы — заверните адрес рассылки провайдера в Email Inbox и алёртите на слова deprecat / sunset / retire в теме;
  • runtime-детект — ловите model_not_found / invalid model прямо в проде и шлите priority=10: это последний рубеж, но лучше поздно, чем молча.
  • id модели и где вы её используете (сервис/файл);
  • дата отключения — самое важное, вокруг неё планируется миграция;
  • рекомендованная замена, если провайдер её называет;
  • ссылка на changelog/migration guide провайдера.