Бот Briefka, собирающий дайджесты телеграм-каналов, изначально использовал каскад из пяти LLM-провайдеров: два аккаунта Groq, затем Mistral, Cerebras и в конце платный DeepSeek. Идея была в том, чтобы все запросы обрабатывались бесплатно, и только при исчерпании всех лимитов подключался платный якорь. За четыре месяца число пользователей выросло с 59 до 84, и именно на этом масштабе схема начала давать сбои.
Проблема оказалась в thundering herd — одновременные запросы от рассылки дайджеста исчерпывали лимиты бесплатных провайдеров за секунды, и каскад массово падал на DeepSeek. В мае было 915 вызовов DeepSeek — по деньгам всего ~$0,10, но проблема была в линейном росте расходов при увеличении числа пользователей. Фактически разработчик сам себя DDOS-ил против собственных лимитов.
| Период | Вызовов DeepSeek | Стоимость |
|---|---|---|
| Февраль–март | 0 | $0 |
| Апрель | 88 | ~$0.02 |
| Май (до фикса) | 915 | ~$0.10 |
| Май, 26+ (после фикса) | 0 | $0 |
Решение состояло из двух частей. Во-первых, разнос пользователей по времени с паузой 10 секунд между отправками дайджестов — общее время рассылки выросло с минуты до 13 минут, но лимиты успевали восстанавливаться. Во-вторых, сериализация LLM-вызовов внутри дайджеста с помощью asyncio.Semaphore(1): теперь запросы обрабатываются последовательно, без конкуренции за лимиты. Дополнительно ввели circuit breaker: если провайдер возвращает 429, он уходит на cooldown на 10 минут. Также реализован кросс-юзерный кэш — один и тот же пост обрабатывается через LLM только один раз для всех подписчиков.
При 84 пользователях параллельные запросы создавали thundering herd — бесплатные лимиты исчерпывались, и каскад падал на платный DeepSeek.
Отдельная грабля — российский IP первого VPS: запросы к зарубежным LLM с него блокировались. После переезда на зарубежный сервер проблема исчезла. Разработчик отмечает, что для безопасности в коде реализованы fallback ошибки и cooldown, а бесплатные провайдеры могут менять условия — поэтому нужен постоянно работающий мониторинг.
