SiCore TokenWorks
LLM APIAPI GatewayAggregation

token8341retrospekcja:rachunek za bota obsługi klienta trzykrotnie przekraczający budżet — na co poszły pieniądze

SiCore TokenWorks Team·2026-10-03

Najpierw wniosek: bot obsługi klienta pali pieniądze w osiemdziesięciu procentach nie dlatego, że cena jednostkowa modelu jest wysoka, lecz dlatego, że sposób wywoływania jest błędny. Nasz wewnętrzny bot Q&A dla działu posprzedażowego, z kilkoma tysiącami dziennych aktywnych użytkowników, w pierwszym miesiącu od uruchomienia wygenerował rachunek sięgający trzykrotności budżetu. Po analizie okazało się, że cena jednostkowa modelu się nie zmieniła — całość to ukryte koszty w strukturze wywołań. W tym artykule opisuję proces analizy; jeśli zajmujecie się optymalizacją kosztów API dużych modeli, możecie skonfrontować go z własnym rachunkiem.

Jak wygląda anomalia na rachunku

Cechą anomalii nie jest „wysoka kwota całkowita", lecz „dziwna struktura". Wyciągnęliśmy szczegółowe zestawienie wywołań według dni i odkryliśmy trzy nieprawidłowości: w dniach o największej liczbie wywołań średnia liczba tokenów na pojedyncze żądanie rosła; odsetek ponownych prób zbliżał się do dwudziestu procent; to samo pytanie użytkownika zajmowało raz kilkaset tokenów, raz ponad dziesięć tysięcy — wariancja ogromna. Te trzy rzeczy razem wzięte praktycznie od razu wskazują, że problem nie leży po stronie modelu, lecz w naszym własnym łańcuchu wywołań.

Cztery ukryte koszty, jeden bardziej skryty od drugiego

Po pierwsze, model flagowy wykonuje grubą robotę. Na początku, dla wygody, wszystkie żądania kierowaliśmy jednolicie do modelu flagowego. Tymczasem w scenariuszu obsługi klienta ponad siedemdziesiąt procent to rozpoznawanie intencji i odpowiedzi ze stałym skryptem, typu „gdzie jest moje zamówienie" czy „jak zwrócić towar" — do takich zadań w pełni wystarcza mały model, a różnica w koszcie jest o rząd wielkości. Kazać modelowi flagowemu odpowiadać na „o której otwieracie" to jak wysyłać ciężarówkę po jedzenie na wynos.

Po drugie, niekontrolowane rozdęcie kontekstu. W rozmowie wieloetapowej wrzucaliśmy z powrotem całą historię wiadomości; gdy użytkownik dochodził do dziesiątej rundy, sama historia zajmowała większość tokenów. Co gorsza, wiele fragmentów historii nie miało żadnego związku z bieżącym pytaniem — czysta jazda na gapę. Kontekst nie jest tym mądrzejszy, im dłuższy; po przekroczeniu pewnej długości poprawa dokładności jest ograniczona, a koszt rośnie liniowo.

Po trzecie, burza ponownych prób. Ustawiliśmy prostą ponowną próbę przy błędzie, ale bez backoffu i bezpiecznika. Gdy po stronieupstream pojawiał się sporadyczny timeout, ta sama partia żądań była wielokrotnie dobijana: błąd — ponowna próba, ponowna próba znów błąd — znów ponowna próba. Te wywołania na rachunku to czysta strata, a użytkownik i tak widział błąd.

Po czwarte, podwójne rozliczanie streamingu i niestreamingu. To najłatwiej przeoczyć. W niektórych łańcuchach, aby uzyskać pełny wynik do dalszego przetwarzania, wywoływaliśmy w trybie niestreamingowym; frontend z kolei chciał efektu maszyny do pisania, więc wywoływał ponownie w trybie streamingowym. To samo pytanie — dwa rachunki. Dopiero po ujednoliceniu na odbiór streamingowy i lokalne składanie ten podwójny koszt zniknął.

Jak wdrożyć routing warstwowy

Pomysł nie jest skomplikowany: rozdzielać ruch według trudności zadania. Rozpoznawanie intencji, ekstrakcja slotów, stałe skrypty — idą do lekkiego modelu; dopiero złożone sesje wymagające rozumowania, wieloetapowych decyzji i łagodzenia emocji trafiają do modelu flagowego. Pomiędzy dodajemy warstwę bramy modelowej, która najpierw przepuszcza żądanie przez klasyfikator, nadaje etykietę zadania, a następnie decyduje o routingu do konkretnego modelu.

My korzystamy z logiki automatycznego wyboru optymalnego modelu według zadania; na routingu wielu modeli SiCore TokenWorks przeprowadziliśmy rundę porównań — po przełączeniu prostych zadań na lekki model całkowity koszt wyraźnie spadł, a odpowiedzi stały się szybsze. Kluczem nie jest tu „którego modelu użyć", lecz to, że tabela mapowania „jakie zadanie — jaki model" musi być stale dostrajana. Na początku konfigurowaliśmy na wyczucie; po dwóch tygodniach skalibrowaliśmy ponownie na podstawie rzeczywistego współczynnika trafień i efekt był znacznie lepszy niż przy zgadywaniu. Właśnie wtedy ujawniła się też zaleta jednolitego dostępu do wielu modeli: zmiana strategii routingu nie wymaga modyfikacji kodu biznesowego, wystarczy korekta na poziomie bramy.

Porównanie rachunku przed i po optymalizacji

Nie podaję konkretnych liczb, podaję proporcje. Całkowita liczba wywołań się nie zmieniła, bo liczba użytkowników się nie zmieniła. Całkowity koszt spadł o około sześćdziesiąt procent, przy czym udział wywołań modelu flagowego spadł z blisko stu procent do około trzydziestu procent, a reszta została rozdzielona do lekkich modeli. Wywołania związane z ponownymi próbami spadły z blisko dwudziestu procent do jednocyfrowego odsetka. Średnia liczba tokenów na pojedyncze żądanie spadła o około czterdzieści procent, głównie dzięki przycinaniu kontekstu. Podwójne rozliczanie streamingu spadło bezpośrednio do zera. W sumie: z trzykrotnego przekroczenia budżetu wróciliśmy do jego wnętrza, z jeszcze pewnym zapasem.

Jak skonfigurować monitoring i alerty

Zaoszczędzonych pieniędzy trzeba pilnować — monitoringiem, nie samodyscypliną. Skonfigurowaliśmy cztery alerty: przekroczenie progu liczby tokenów na pojedyncze żądanie — zabezpieczenie przed utratą kontroli nad kontekstem; przekroczenie ustalonego odsetka ponownych prób — zabezpieczenie przed burzą retry; anomalny wzrost udziału wywołań modelu flagowego — sygnał, że routing może zawodzić; wzrost dziennego kosztu dzień do dnia powyżej progu. Nie trzeba tego robić bardzo skomplikowanie — agregacja dzienna i alert po przekroczeniu linii w zupełności wystarczą. W modelu rozliczania za tokeny koszt narasta w czasie rzeczywistym; jeśli poczekacie do końca miesiąca, żeby zajrzeć na rachunek i wtedy optymalizować, pieniądze już zostały wydane.

Podsumowując jednym zdaniem: główny koszt bota obsługi klienta tkwi w strukturze wywołań, nie w cenie jednostkowej modelu. Jeśli solidnie zrobicie te cztery rzeczy — routing warstwowy, przycinanie kontekstu, kontrolę ponownych prób i ujednolicenie streamingu — rachunek sam spadnie. Rozszerzając temat: jeśli w waszym scenariuszu jest jeszcze wyszukiwanie RAG, liczbę rekordów zwracanych z bazy wektorowej również warto sprawdzić według tego samego podejścia.