Провайдер объявил о выводе модели из эксплуатации
Провайдеры отключают старые модели регулярно, и сообщают об этом в
changelog, письмом или флагом в /models. Если вы намертво прибили в коде
gpt-4-0613 или claude-3-sonnet-20240229, дата отключения — это дата, когда
ваш прод внезапно начнёт возвращать model_not_found. Push за несколько
недель до этого превращает аварию в спокойную задачу на миграцию.
Паттерн — scheduled-функция на YC, которая раз в день сверяет список моделей провайдера с вашими «прибитыми» id.
Скелет: опрос /models и сверка с вашими id
Заголовок раздела «Скелет: опрос /models и сверка с вашими 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>Провайдеры без флага в API
Заголовок раздела «Провайдеры без флага в API»Не у всех есть 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 провайдера.