Спочатку висновок: модельний шлюз — це не просто "підключити кілька API". Це рівень інфраструктури, який повинен самостійно витримувати збої. Два роки тому ми займалися AI-інтеграцією для однієї платформи онлайн-консультацій, і інтелектуальна служба підтримки працювала на єдиному модельному API. Якогось вівторка близько другої години ночіверхів'я почав повертати 504, SDK за замовчуванням повторював спробу тричі з експоненційним відступом, але бізнес-сторона одночасно мала кілька тисяч паралельних сесій, і кількість повторів миттєво зросла до кількох разів більше за нормальні запити. Пул потоків був заповнений, навіть перевірка стану вичерпала тайм-аут, і весь ланцюжок викликів завалився, як доміно. Під час розбору після інциденту проблема була не в самій моделі, а в тому, що ми поклали всі яйця в один кошик і не мали жодного рівня шлюзу для підстраховки.
Що насправді повинен вирішувати модельний шлюз
Якщо розібрати, рівень шлюзу має витримувати чотири речі. Маршрутизація між моделями — це база: одне й те саме завдання "запитання-відповідь служби підтримки" можна за наміром розподіляти до дешевших вітчизняних моделей, а для складних міркувань звертатися до просунутих моделей. Обмеження швидкості та запобіжники — це порятунок: до того, як єдиний Key буде перевантажений, потрібно активно обірвати трафік. Трансляція протоколів — найбільш недооцінена частина: тіла запитів, тіла відповідей і структури помилок у SDK різних постачальників відрізняються. Атрибуція витрат — це питання того, чи можна взагалі порахувати рахунок: скільки токенів спалила кожна бізнес-лінія та кожен орендар, потрібно вміти розкласти до конкретної людини.
У нашому проєкті ми використовували модельний шлюз token8341, щоб на практиці автоматично обирати оптимальну модель за завданням; він сумісний з OpenAI SDK, достатньо змінити один рядок base_url, щоб перемкнутися. Ця властивість особливо дружня до наявних систем — не потрібно переписувати десятки місць виклику в коді. Те, що робить на цьому рівні SiCore TokenWorks, по суті, зводить складність агрегації AI API всередину шлюзу.
Протокольні пастки потокового виведення SSE
Потокове виведення — зона, де найбільше наступають на граблі. Зовні здається, що всі використовують SSE, але насправді відмінності чималі. У стратегії поділу на блоки одні постачальники ріжуть за токенами, інші — за реченнями, а ще інші можуть вкладати кілька блоків даних в один сегмент. З ознакою завершення ще більший безлад: стиль OpenAI використовує data: [DONE], інші постачальники просто розривають потік без ознаки. Коди помилок також не уніфіковані: тайм-аут може бути 429, може бути 503, а може бути відповідь 200 з об'єктом помилки всередині.
Рівень шлюзу повинен виконувати нормалізацію: уніфіковано перетворювати на стандартний формат SSE, доповнювати ознаку завершення, відображати коди помилок різних постачальників на один набір внутрішніх переліків помилок. Так верхній бізнес має обробляти лише один тип потоку. Звучить як брудна робота, але без цього рівня кожна бізнес-команда повторно наступатиме на ті самі граблі.
Як налаштувати обмеження швидкості, щоб не завдати шкоди
Кошик токенів підходить для контролю згладженої швидкості: місткість кошика визначає толерантність до сплесків, швидкість поповнення визначає довгострокове середнє. Ковзне вікно підходить для статистичного обмеження швидкості, наприклад "не більше N разів на хвилину". У реальному продакшені ми використовуємо обидва: на вході ковзне вікно для грубого захисту, на рівні окремого Key кошик токенів для точного контролю.
Ротація кількох Key — ще один ключовий момент. Для одного постачальника замовляють кілька Key, шлюз опитує їх за вагою; якщо якийсь Key запускає обмеження швидкості, його тимчасово вилучають, а після періоду охолодження повертають. Так обмеження квоти одного Key не перетворюється напряму на стелю для бізнесу. Слід зауважити: ротація повинна поєднуватися із запобіжниками, інакше один поганий Key вибиратиметься знову і знову.
Деградація та мультиактивність: як визначити RPO і RTO
Після тайм-ауту основної моделі автоматично перемикатися на резервну — ця дія має бути швидкою. Усередині ми визначаємо RTO як "час від виявлення збою до переведення трафіку" і ставимо ціль на рівні секунд; RPO стосується стану сесії, в ідеалі — нульові втрати, але в потоковому сценарії вже виведений вміст не можна відкотити, можна лише гарантувати, що подальші запити не перервуться. При виборі резервної моделі слід враховувати відповідність можливостей: не можна, щоб основна модель робила довгі міркування над текстом, а резервна вміла лише короткі запитання-відповіді — перемикання на неї означає деградацію до каліцтва.
Попередження про пастку: не пишіть логіку повторів у бізнес-коді. Вбудовані в SDK повтори знаходяться поза рівнем шлюзу і під час збою конфліктуватимуть зі стратегією запобіжників шлюзу. Повтори слід уніфіковано зводити до шлюзу, а бізнес-сторона отримує лише успіх або остаточну невдачу.
Одним реченням: цінність модельного шлюзу в тому, що він централізовано обробляє цю брудну роботу — уніфіковане підключення кількох моделей, обмеження швидкості, нормалізацію протоколів, деградацію — дозволяючи бізнес-коду залишатися чистим. Якщо дивитися ширше, якщо ви зараз обираєте AI API шлюз, звертайте увагу на те, чи можна його підключити зміною одного рядка base_url, і чи можна налаштувати стратегію перемикання під час збою.
Автор: Чень Цзінсін
Дата публікації: 4 жовтня 2026 року