Разделяйте retry и fallback
Повторная попытка отправляет запрос снова по тому же маршруту, потому что сбой может быть временным. Fallback меняет провайдера или модель, потому что исходный маршрут недоступен или не подходит.
Если объединить оба действия в один общий цикл retry, инциденты становится сложнее диагностировать, а стоимость может расти без повышения вероятности успеха.
- Retry: таймаут, сброс соединения, 429 или временный ответ 5xx.
- Fallback: повторяющийся сбой провайдера, ограничение емкости модели или ограничение политикой.
- Stop: некорректный запрос, неподдерживаемый параметр или неудачная валидация вывода.
Стройте таблицу маршрутов с совместимостью по возможностям
Модели fallback следует группировать по возможностям, а не по бренду. Запрос с изображением не может перейти на текстовую модель, а строгий JSON-процесс не должен маршрутизироваться к модели, которая регулярно нарушает схему.
- Требуемые модальности входа и выхода.
- Минимальный контекст и длина вывода.
- Поддержка вызова инструментов и структурированного вывода.
- Максимально допустимые стоимость и задержка.
Применяйте единый бюджет на уровне запроса
Бюджет запроса должен покрывать все попытки retry и fallback. Перед запуском следующей попытки проверьте, достаточно ли оставшихся лимитов по задержке и стоимости.
const routePolicy = {
maxAttempts: 3,
maxLatencyMs: 18_000,
maxEstimatedCost: 0.12,
retryOn: [408, 429, 500, 502, 503, 504],
fallbackModels: ['primary-model', 'quality-fallback', 'fast-fallback'],
};Измеряйте качество fallback, а не только доступность
Запрос, который завершился успешно, все равно может быть продуктовой неудачей. Отслеживайте валидацию вывода, долю пользовательских исправлений и завершение задачи после события fallback.
Рекомендуемая панель: успешность маршрута, частота fallback, p95 задержки, оценочная стоимость, доля успешной валидации и оценка качества по модели.
