Комментарии 1
Особенно интересен issilent_refusal - это ровно тот класс багов, который motivated мой phoenix2pytest. HTTP 200 + finish_reason=content_filter + пустой content проскакивает мимо стандартных healthcheck’ов и retry-логики, пользователь получает пустую реплику в чате.
У вас лечится одной функцией перед отдачей дальше - это локальный fix. Регрессионный угол: каждый раз когда silent refusal случается в проде, можно записать trace (input messages + model + provider headers) и автоматически генерировать pytest-кейс, который ассертит content.strip() != ‘’ плюс что fallback chain действительно отработала. Когда вы поменяете маршрутизацию или провайдер обновит модель - тест ловит регрессию до того как пользователь увидит пустоту.
Любопытный момент про prompt cache на Gemini - динамическая дата в начале промпта или ротация сессий рвёт cache hit ratio без любого алёрта. У вас в дашборде это видно (раздел про OpenRouter cached_tokens), но в коде prevention сложнее: я бы добавил инвариант в pytest-suite, который собирает финальный промпт и проверяет первые ~3800 токенов на стабильность между двумя session_id. Если меняется - это сигнал что в промпт затесалось что-то нестабильное.
Вопрос: как вы детектите cache miss на Gemini в реальном времени, а не постфактум через биллинг? Есть метрика cached_tokens / prompt_tokens < threshold на алёрте, или смотрите только daily aggregate?

AI-компаньон в проде на третьем месяце — 5 архитектурных решений и инфра-тюнинг