SiCore TokenWorks
LLM APIAPI Gateway

token8341 ретроспектива: рахунок за чат-бота служби підтримки, що втричі перевищив бюджет — на що пішли гроші

SiCore TokenWorks Team·2026-10-03

Спочатку висновок: чат-бот служби підтримки спалює гроші переважно не через високу ціну за одиницю моделі, а через проблеми зі способом виклику. У нас всередині компанії був бот для післяпродажних запитань із кількома тисячами щоденних активних користувачів, і за перший місяць після запуску рахунок одразу сягнув потрійного розміру бюджету. Після розслідування виявилося, що ціна за одиницю моделі не змінилася ані на копійку — усе це були невидимі витрати у структурі викликів. У цій статті я описую процес ретроспективи; ті, кого цікавить оптимізація витрат на API великих моделей, можуть перевірити свій рахунок за цими пунктами.

Як виглядає аномалія в рахунку

Ознака аномалії — не "висока загальна сума", а "дивна структура". Ми вивантажили деталізацію викликів за днями й помітили три підозрілі речі: у дні з найбільшою кількістю викликів середня кількість токенів на запит зростала; частка повторних спроб наближалася до двадцяти відсотків; на одне й те саме запитання користувача витрачалося від кількох сотень токенів у короткому випадку до десятків тисяч у довгому — розкид величезний. Ці три речі разом узяті майже напевно вказують на те, що проблема не на боці моделі, а в нашому власному ланцюжку викликів.

Чотири невидимі витрати, одна прихованіша за іншу

Перше: флагманська модель виконує чорнову роботу. Спочатку ми, щоб не ускладнювати, спрямовували всі запити через флагманську модель. Але в сценарії служби підтримки понад сімдесят відсотків — це розпізнавання намірів і відповіді за фіксованими шаблонами на кшталт "де моє замовлення" чи "як оформити повернення", і для таких завдань малої моделі цілком достатньо, а різниця у вартості — на порядок. Доручати флагманській моделі відповідь на "о котрій годині ви працюєте" — це як вантажівкою доставляти їжу з доставки.

Друге: безконтрольне роздування контексту. У багатоходових діалогах ми вставляли назад усю історію повідомлень, і коли користувач доходив до десятого раунду, сама лише історія займала більшу частину токенів. Ще гірше те, що багато з цієї історії не мало жодного стосунку до поточного питання — просто баласт. Контекст не стає розумнішим із кожним зайвим токеном: після певної довжини приріст точності обмежений, а витрати зростають лінійно.

Третє: шторм повторних спроб. Ми налаштували просту повторну спробу при збої, але не зробили ні відступу, ні запобіжника. Коли вгорі траплявся випадковий тайм-аут, та сама партія запитів надсилалася знову й знову: одна невдача — одна повторна спроба, повторна спроба знову невдала — ще одна повторна спроба. Усі ці виклики в рахунку були витрачені марно, а користувач усе одно бачив помилку.

Четверте: подвійна оплата за потоковий і непотоковий режими. Це найлегше проґавити. У деяких наших ланцюжках, щоб отримати повний результат для подальшої обробки, ми робили один непотоковий виклик; а фронтенду потрібен був ефект друкарської машинки, тож ми робили ще один потоковий виклик. Одне й те саме питання — дві оплати. Згодом ми уніфікували все до потокового приймання з локальним складанням, і ця подвійна витрата зникла.

Як впровадити багаторівневу маршрутизацію

Ідея не складна: розподіляти за складністю завдання. Розпізнавання намірів, видобування слотів, фіксовані шаблони — на легку модель; справді складні діалоги, що потребують міркування, багатокрокових рішень і заспокоєння емоцій, — тільки флагманській моделі. Між ними додається шар шлюзу моделей, який ухвалює рішення: запит надходить, спершу проходить класифікатор, отримує мітку завдання, і лише потім визначається, на яку модель його маршрутизувати.

Ми використовуємо логіку автоматичного вибору оптимальної моделі за завданням і прогнали один раунд порівняння на багатомодельній маршрутизації SiCore TokenWorks: після переведення простих завдань на легку модель загальні витрати помітно знизилися, а відповіді стали швидшими. Ключове тут — не "яку модель використовувати", а те, що таблицю відповідності "яке завдання — яка модель" потрібно постійно налаштовувати. На старті ми налаштовували за досвідом, а через два тижні перекалібрували за фактичним відсотком влучань — результат виявився набагато кращим, ніж коли налаштовуєш на око. Перевага уніфікованого підключення багатьох моделей проявилася саме тут: щоб змінити стратегію маршрутизації, не потрібно чіпати бізнес-код, достатньо налаштувати на рівні шлюзу.

Порівняння рахунку до і після оптимізації

Конкретних цифр не наводжу — наводжу пропорції. Загальна кількість викликів не змінилася, бо кількість користувачів не змінилася. Загальні витрати впали приблизно на шістдесят відсотків, причому частка викликів флагманської моделі знизилася з майже ста відсотків до близько тридцяти, а решта розподілилася на легкі моделі. Виклики, пов'язані з повторними спробами, скоротилися з майже двадцяти відсотків до однозначного числа відсотків. Середня кількість токенів на запит знизилася приблизно на сорок відсотків — переважно завдяки обрізанню контексту. Подвійна оплата за потоковий режим просто обнулилася. Загалом ми повернулися з потрійного перевищення бюджету в його межі, та ще й із запасом.

Як налаштувати моніторинг і сповіщення

Заощаджені гроші потрібно втримати, і тримаються вони на моніторингу, а не на самодисципліні. Ми налаштували чотири сповіщення: спрацьовує, коли кількість токенів на один запит перевищує поріг — проти неконтрольованого роздування контексту; спрацьовує, коли частка повторних спроб перевищує заданий відсоток — проти шторму повторних спроб; спрацьовує, коли аномально зростає частка викликів флагманської моделі — це означає, що маршрутизація могла вийти з ладу; спрацьовує, коли добове зростання витрат у порівнянні з попереднім періодом перевищує поріг. Ці чотири не потрібно робити складними: достатньо агрегації за днями й сповіщення при перетині лінії. У моделі оплати за токенами витрати накопичуються в реальному часі, і якщо чекати кінця місяця, щоб глянути рахунок і лише тоді оптимізувати, гроші вже витрачені.

Одним реченням: основна частка витрат чат-бота служби підтримки — у структурі викликів, а не в ціні за одиницю моделі. Якщо ґрунтовно зробити чотири речі — багаторівневу маршрутизацію, обрізання контексту, контроль повторних спроб і уніфікацію потокового режиму, — рахунок природно знизиться. Як подальший крок: якщо у вашому сценарії ще є RAG-пошук, кількість документів, що витягуються з векторної бази, теж варто перевірити за цим самим підходом.