Optymalne doborowanie modeli LLM: routing, odzyskiwanie danych i ocena w zależności od rzeczywistej wielkości modelu
Naucz się, jak wybierać między małymi a dużymi modelami językowymi w zależności od obciążenia, mierzyć koszt za udaną zadanie oraz najpierw korzystać z routingu, RAG, buforowania i walidacji.
Liczby parametrów ułatwiają tworzenie nagłówków, więc łatwo jest traktować je jako wskaźnik jakości produktu: model o pojemności 70 miliardów musi być lepszy od modelu o pojemności 7 miliardów, więc największy model, jaki możesz sobie pozwolić, musi być bezpiecznym wyborem. W warunkach produkcyjnych ten skrót szybko przestaje być skuteczny. Większe modele zazwyczaj kosztują więcej za każdą próbę wywołania, reagują wolniej, zwiększają obciążenie infrastruktury i często rozwiązują problemy, których twoja aplikacja nigdy nie miała. Ten przewodnik pokazuje, jak wybierać model w oparciu o obciążenie pracy, a nie tylko o jego rozmiar, jak analizować koszty, opóźnienia i awarie łącznie, oraz jakie elementy architektury (routing, pobieranie danych, walidacja, cache i sam kod) zazwyczaj przynoszą większe korzyści niż prosta aktualizacja.
Dlaczego zasada „im większe, tym lepsze” przestaje działać w warunkach produkcyjnych
Intuicja jest zrozumiała. Inżynierowie oprogramowania od dziesięcioleci obserwują, jak ulepszenia sprzętowe przynoszą korzyści: szybszy procesor, więcej pamięci RAM, większe dyski oraz nowsza karta graficzna to niemal zawsze ulepszenia. Gdy modele językowe stawały się większe i bardziej zaawansowane, naturalne wydawało się przeniesienie tego modelu myślowego. Jeśli jeden model rozumuje lepiej niż inny, dlaczego ktoś miałby celowo wybrać ten słabszy?
Odpowiedź pojawia się w momencie, gdy model jest wykorzystywany do realizacji konkretnej funkcji. Pytanie, które zadajemy, zmienia się z „Który model jest najmądrzejszy?” na „Który model daje najlepszy wynik w tym konkretnym zastosowaniu?”. To zupełnie różne pytania. Największy model może dostarczyć nieco lepszą odpowiedź, ale przy tym działa znacznie wolniej. Jego użycie może kosztować kilka razy więcej. Może być bezużyteczny przy prostym kroku klasyfikacji, generować zbyt długie odpowiedzi, których nie da się wyświetlić w interfejsie użytkownika, szybko wyczerpywać dostępny budżet kontekstowy oraz komplikować proces wdrożenia. Co najważniejsze, może rozwiązywać problem, którego tak naprawdę nie mamy.
Zacznij od obciążenia pracy, a nie od liczby parametrów
Bardziej wiarygodny sposób wyboru modelu polega na najpierw opisaniu samej pracy. Zanim porównasz jakiekolwiek modele, odpowiedz na następujące pytania:
- Jak wygląda dane wejściowe?
- Jaki wynik jest oczekiwany?
Ostatnie pytanie to prawdziwe pytanie inżynieryjne, a reszta tego przewodnika dotyczy jego odpowiedzi: dlaczego największy model nie jest automatycznie najlepszy, jak decydować między małymi a dużymi modelami, kiedy duży model rzeczywiście uzasadnia swój koszt oraz jak wygląda rozsądny projekt produkcyjny.
Jeden produkt wsparcia, dwa zupełnie różne obciążenia
Rozważmy aplikację wsparcia dla przedsiębiorstw. Użytkownik wpisuje „Szyfruj moje hasło”. Co powinien zrobić tutaj warstwa AI? Najprawdopodobniej powinna jedynie rozpoznać intencję i przypisać ją do odpowiedniej etykiety, takiej jak ta poniżej, aby aplikacja mogła przekazać zapytanie do ustalonego, deterministycznego procesu pracy.
PASSWORD_RESET
Do przypisania tej etykiety nie jest potrzebny żaden złożony model analityczny. Kierowanie takiego zapytania przez taki model byłoby wątpliwym wyborem projektowym, ponieważ lekki model lub nawet dopasowywanie słów kluczowych i reguł mogą to prawdopodobnie obsłużyć.
A teraz wyobraźmy sobie inne zapytanie: klienci w Europie od wczorajszego wdrożenia napotykają przerywane problemy z płatnościami, a użytkownik chce, aby system porównał różnice po wdrożeniu z logami usługi płatności, znalazł prawdopodobne wzorce awarii, ocenił, czy za problemem stoi nowy mechanizm ponawiania prób, oraz zaproponował plan odwrócenia zmian. To zapytanie wymaga znacznie więcej.
- pobieranie odpowiednich zmian wdrożeniowych oraz logów
- wielka ilość kontekstu
- umiejętność czytania i rozumienia kodu
- analiza wyników logów
- rozumowanie obejmujące kilka kroków
- korelacja zdarzeń pomiędzy systemami
- jasne wyjaśnienie techniczne
- uczciwe radzenie sobie z niepewnościami
Tutaj silniejszy model może rzeczywiście dodać wartość. Błędem nie jest użycie dużego modelu, lecz traktowanie tych dwóch zadań tak, jakby stanowiły ten sam obciążenie.
Funkcjonalna definicja wartości modelu
Praktycznym sposobem na sformułowanie tego wyboru jest przybliżona heurystyka:
Wartość modelu = możliwości × niezawodność × użyteczność ÷ koszt
To nie jest formuła, którą można obliczyć. To sposób myślenia. Model, który jest o 10% bardziej wydajny, ale pięć razy droższy i trzy razy wolniejszy, niekoniecznie jest lepszą opcją produkcyjną. Podobnie model, który jest niezwykle tani, ale niewiarygodny w realizacji danego zadania, również jest złym wyborem. To, co należy optymalizować, to nie maksymalna inteligencja, lecz najbardziej przydatna inteligencja na jednostkę kosztu, opóźnienia i złożoności.
Dlaczego duże modele są kuszące i gdzie pojawiają się ograniczenia
Preferowanie dużych modeli nie jest irracjonalne, ponieważ oferują one rzeczywiste zalety. Często lepiej radzą sobie z złożonym rozumowaniem, wykazują bardziej równomierną wydajność przy różnorodnych zadaniach, skuteczniej interpretują niejasne instrukcje, efektywniej poruszają się w złożonych bazach kodu, wymagają mniej specyficznych wskazówek i mogą być znacznie bardziej skuteczne przy naprawdę trudnych zadaniami.
Dlaczego więc nie używać najsilniejszego modelu wszędzie? Ponieważ produkcja wprowadza ograniczenia, których rzadko widać w liczbach z tabel rankingowych. Wyobraźmy sobie punkt końcowy obsługujący 100 000 żądań dziennie. Jeśli większy model kosztuje znacznie więcej za każdą próbę wywołania, ta różnica przestaje być abstrakcyjna – odbija się na budżecie infrastruktury. Jeśli większy model jest także wolniejszy, użytkownicy to zauważają. Jeśli ma tendencję do dawania rozwlekłych odpowiedzi, wzrasta koszt tokenów. A jeśli aplikacja wykonywa tysiące małych zadań, wysyłanie każdego z nich do zaawansowanego modelu rozumowania to po prostu marnotrawstwo.
Wybór modelu to problem optymalizacyjny, a nie konkurs popularności.
Model na szczycie tabeli benchmarków niekoniecznie jest tym, który tworzy najlepszą aplikację.
Liczba parametrów to tylko jeden z wymiarów
Porównania modeli zazwyczaj koncentrują się na rozmiarze: 7B, 13B, 34B, 70B, setki miliardów. Sam rozmiar niewiele mówi o odpowiedniości modelu do konkretnego zastosowania. Praktyczne porównanie uwzględnia jednocześnie kilka wymiarów, na przykład:
- zdolność modelu do wykonywania konkretnej zadania
- opóźnienie, zarówno czas do wygenerowania pierwszego tokena, jak i całkowity czas generowania
- koszt za zapytanie i za ukończone zadanie
- przepustowość przy oczekiwanej obciążeniu
- rozmiar kontekstu faktycznie potrzebny do wykonania zadania
- niezawodność i spójność przy powtarzanych próbach
- możliwości wdrożenia, w tym lokalne lub prywatne hostowanie
- możliwość kontrolowania modelu
Możliwość kontrolowania zasługuje na szczególną uwagę, ponieważ łatwo ją przeoczyć. Model może być bardzo wydajny, ale trudny do kontrolowania. W procesach biznesowych przewidywalne zachowanie często jest cenniejsze niż kreatywność.
Strukturalna ekstrakcja to inny cel
Weźmy na przykład ekstrakcję faktur. Ta funkcja wymaga określonego formatu, takiego jak poniżej, a nie dogłębnego opisu dokumentu.
{
"invoiceNumber": "...",
"invoiceDate": "...",
"vendor": "...",
"total": 0
}
Ważne jest tutaj niezawodny, dobrze sformatowany wynik, który kod używany dalej może zawsze przetworzyć. To odrębny cel optymalizacji w porównaniu z ogólną zdolnością rozumowania, a mniejsze lub bardziej ograniczone modele często dobrze go realizują, szczególnie w połączeniu z walidacją schematu.
Latenca: pierwsza pułapka w produkcji
W demonstracji sześciosekundowe oczekiwanie wydaje się w porządku. Wynik jest imponujący, dzielisz go z zespołem i wszyscy są zadowoleni. Gdy w rzeczywistej aplikacji umieścisz tę samą operację za przyciskiem, doświadczenie się zmienia: użytkownik kliknie, pojawi się spinner i minie trzy, pięć lub osiem sekund. W tym momencie nikt już nie podziwia inteligencji modelu – zastanawiają się, dlaczego aplikacja działa tak wolno.
Latencja jest cechą produktu i w oprogramowaniu interaktywnym ma ogromne znaczenie.
Dlaczego większe modele zazwyczaj reagują wolniej
Dokładna zależność zależy od wielu czynników: architektury modelu, sprzętu, stosu serwowania, kwantyzacji, grupowania zapytań, liczby generowanych tokenów, rozmiaru promptu oraz projektu modelu. Jako ogólna tendencja można jednak stwierdzić, że modele wymagające większych zasobów obliczeniowych potrzebują więcej zasobów na jeden token i mogą zwracać wyniki wolniej. Jest to szczególnie istotne w:
- interfejsy czatu
- asystenci do kodowania i funkcja autodopisywania
- asystenci głosowi
- narzędzia wsparcia klienta
- interaktywne panele kontrolne
- przepływy pracy oparte na agentach, w których czekanie narasta na kolejnych etapach
Funkcja autodopisywania wyraźnie ilustruje ten problem. Sugestia kodu, która wymaga pięciu sekund, nie jest już autodopisywaniem – to zakłócenie. Mniejszy model, który odpowiada niemal natychmiast, jest często znacznie bardziej przydatny niż silniejszy model, który zmusza programistę do czekania.
Strumieniowanie poprawia percepcję, a nie moc obliczeniową
Strumieniowanie to standardowy sposób na sprawienie, by czekanie wydawało się krótsze. Bez niego użytkownik nic nie widzi, dopóki cała odpowiedź nie będzie gotowa:
[wait...]
Hello! Here is the answer...
Za pomocą strumieniowania tekst pojawia się na ekranie w miarę przychodzenia tokenów:
Hello
Hello, here
Hello, here is
Hello, here is the
Hello, here is the answer...
Należy zachować jasne rozróżnienie. Strumieniowanie zmniejsza odczuwaną opóźnioność, ponieważ pierwsze słowa pojawiają się szybko, ale nie zmniejsza zużytej mocy obliczeniowej ani całkowitego czasu do uzyskania pełnej odpowiedzi. Jest to ulepszenie doświadczenia użytkownika, a nie optymalizacja wydajności, i nie ma żadnego wpływu na kroki ni interaktywne, takie jak klasyfikator w ramach pipeline’u.
Koszt: mierz go dla każdego pomyślnego zadań
Właśnie w tym momencie wiele prototypów przekształca się w drogie systemy. Podczas rozwoju koszty wydają się znikome: jeden inżynier wysyła kilka zapytań i nikt nie myśli o rachunku. Następnie pojawia się rzeczywisty ruch, a każde żądanie może zawierać znacznie więcej niż tylko wiadomość użytkownika:
- wielu jednoczesnych użytkowników
- kilka żądań na sesję
- długie zapytania
- pobrane dokumenty
- wyniki narzędzi
- historia rozmów
- wygenerowane odpowiedzi
Ilość tokenów rośnie szybko, a wybór modelu zaczyna mieć ogromne znaczenie.
Bardziej trafną miarą niż cena za połączenie jest koszt prawidłowego wykonania zadania. Porównajmy dwa hipotetyczne modele (liczby są ilustracyjne, a nie wynikami testów):
- Model A: 0,01 dolara za zapytanie, dokładność 90%, potrzeba około 1,11 zapytań na jeden sukces, co daje około 0,011 dolara za ukończone zadanie.
- Model B: 0,05 dolara za zapytanie, dokładność 96%, potrzeba około 1,04 zapytań na jeden sukces, co daje około 0,052 dolara za ukończone zadanie.
Liczba prób, jakiej należy oczekiwać, to po prostu jeden podzielony przez wskaźnik skuteczności, więc koszt za jeden sukces to cena żądania podzielona przez dokładność. Jeśli model B kosztuje pięć razy tyle, a poprawia wyniki jedynie nieznacznie, firma może uzasadnienie wolać model A. Sytuacja zmienia się, gdy błędna odpowiedź jest kosztowna – na przykład gdy powoduje zwrot pieniędzy, problemy z przestrzeganiem regulacji lub przerwę w działaniu. Dlatego koszt zawsze musi być rozważany razem z konsekwencjami niepowodzenia, a nie sam w sobie.
Zbyt duże modele do zbyt małych problemów
Powszechnym antypatronem jest następujący scenariusz: każda przychodząca wiadomość jest klasyfikowana jako skarga, pytanie lub wniosek o zwrot pieniędzy, a każda z nich trafia do najbardziej zaawansowanego dostępnego modelu. Powodem jest wygoda – jedna API, jeden prompt, jeden model i koniec. Jednak architektura nie polega na tym, by jedna komponenta była w stanie robić wszystko; chodzi o dopasowanie każdego zadań do odpowiedniej komponenty. W przypadku prostej klasyfikacji dostępne są następujące opcje:
- reguły deterministyczne
- embeddingi
- niewielki model językowy
- dedykowany klasyfikator
- większy model przeznaczony dla przypadków o niskim poziomie pewności
Ostatnia opcja prowadzi do jednego z najskuteczniejszych wzorców stosowanych w produkcji.
Eskalacja: drogi model jako mechanizm obsługi wyjątków
Naiwny projekt wysyła wszystko bezpośrednio do dużego modelu:
Every request
↓
Large model
Projekt z eskalacją pozwala taniemu modelowi spróbować najpierw i sprawdzić, na jakim poziomie jest pewny swojej odpowiedzi:
Every request
↓
Small/cheap model
↓
Confidence check
↓
┌───────────────┐
│ │
High confidence Low confidence
│ │
Fast answer Large model
Odpowiedzi o wysokim poziomie pewności są zwracane natychmiast; tylko przypadki niepewne trafiają do większego modelu. Droższy model przestaje być standardowym rozwiązaniem i staje się obsługą wyjątków. Ten wzorzec wymaga istnienia wiarygodnego sygnału pewności, takiego jak skalibrowany wynik klasyfikatora, zgodność między metodami lub narzędzie walidujące, które może odrzucić błędnie sformatowane wyniki – dlatego należy sprawdzić, jak często niskiej jakości odpowiedzi przechodzą przez gałąź „wysokiej pewności”, zanim się na nią polegnie.
Kierowanie żądaniami między różnymi poziomami modeli
Gdy tak to postrzegasz, modele przestają wyglądać jak konkurenci i zaczynają przypominać wyspecjalizowanych pracowników. Router żądań może znajdować się przed kilkoma warstwami i wybierać odpowiednią dla każdego żądania, z wspólnym krokiem walidacji przed tym, jak cokolwiek dotrze do użytkownika:
User Request
|
v
Request Router
|
+-----------+-----------+
| | |
v v v
Simple Medium Complex
| | |
v v v
Small LLM Mid Model Large Model
| | |
+-----------+-----------+
|
v
Validation Layer
|
v
Response
Router potrzebuje jakiegoś pojęcia związанego z złożonością. Najprostszą wersją jest mały zestaw kategorii:
SIMPLE
MEDIUM
COMPLEX
Logika rozdzielania żądań może wtedy być tak prosta, jak przełącznik oparty na werdykcie klasyfikatora. Poniższy przykład jest napisany w C#, ale język ma tu drugorzędne znaczenie; ta sama struktura doskonale pasuje również do usługi w TypeScript.
public async Task<string> ProcessAsync(Request request)
{
var complexity = await classifier.ClassifyAsync(request);
return complexity switch
{
Complexity.Simple =>
await smallModel.GenerateAsync(request),
Complexity.Medium =>
await mediumModel.GenerateAsync(request),
Complexity.Complex =>
await largeModel.GenerateAsync(request),
_ => throw new InvalidOperationException()
};
}
Ważne jest to, co kod komunikuje pod względem architektury: nie każda prośba wymaga maksymalnego poziomu inteligencji. Jeśli ta decyzja będzie stosowana konsekwentnie, może ona drastycznie zmienić efektywność ekonomiczną systemu AI. Należy pamiętać, że sam klasyfikator dodaje każdej prośbie jeden wywołanie i pewien opóźnienie, więc powinien być znacznie tańszy od modeli, do których kieruje żądania, a nieznana kategoria powinna wywoływać wyraźny sygnał błędu, tak jak to robi tutaj domyślna ścieżka.
Gdy luka polega na braku wiedzy, a nie inteligencji
Kolejnym częstym odruchem jest stwierdzenie: „Model nie zna naszej wewnętrznej dokumentacji, więc przejdźmy na większy model”. Rozmiar nie rozwiązuje problemu braku wiedzy. Gdy informacje są własnością intelektualną, świeże lub wysoce specyficzne dla danej dziedziny, problemem jest dostęp do wiedzy, a nie moc rozumowania. Właśnie to ma na celu rozwiązanie Retrieval-Augmented Generation (RAG). Podstawowy schemat działania wygląda następująco:
User Question
|
v
Embedding / Retrieval
|
v
Relevant Documents
|
v
Prompt + Retrieved Context
|
v
Language Model
|
v
Answer
Jeśli użytkownik pyta o wewnętrzną politykę zwrotów pieniędzy twojej firmy dla klientów korporacyjnych, żaden model o ogólnej przeznaczeniu, bez względu na jego rozmiar, nie zna odpowiedzi. Musisz dostarczyć odpowiedni tekst w instrukcji. Aby lepiej zrozumieć, jak działa ten krok pozyskiwania informacji, zapoznaj się z naszym przewodnikiem na temat sposobu, w jaki systemy RAG pozyskują aktualną wiedzę na żądanie.
Napraw pipeline informacji przed modelem
To prowadzi do zasady, którą warto przyjąć jako regułę:
Ulepsz to, co podajesz modelowi, zanim go ulepszasz.
Zespoły regularnie próbują naprawić słabe odpowiedzi, przechodząc na większy model, podczas gdy prawdziwa przyczyna leży gdzie indziej:
- słabe pozyskiwanie informacji
- nierelacyjne dokumenty
- brak metadanych
- słabe dzielenie na fragmenty
- niewystarczający kontekst
W takich przypadkach wąskim gardłem nie jest model, lecz pipeline przetwarzania informacji.
Jakość kontekstu jest ważniejsza niż jego ilość
Duże okna kontekstowe są imponujące, ale większa ilość kontekstu nie oznacza automatycznie lepszych wyników. Przekazanie modelowi 200 stron dokumentacji, gdy odpowiedź znajduje się w zaledwie dwóch akapitach, technicznie dostarcza mu informacji, ale w praktyce utrudnia zadanie, ponieważ musi teraz znaleźć istotne informacje pośród zbędnego hałasu. Nadmiernie duży kontekst może powodować:
- wyższe zużycie tokenów
- dłuższy czas reakcji
- wyższe koszty
- rozpraszanie uwagi
- większe ryzyko sprzecznych informacji
Lepszym celem jest jak najmniejsza ilość wysokiej jakości kontekstu, która nadal pozwala modelowi udzielić poprawnej odpowiedzi. Dlatego zaawansowane systemy RAG inwestują tak wiele w warstwę wyszukiwania, wykorzystując takie techniki jak:
- poszukiwanie semantyczne i hybrydowe
- filtrowanie według metadanych
- przepisywanie zapytania użytkownika
- ponowna klasyfikacja pasujących fragmentów
- utrzymywanie dokumentów w aktualnym stanie
- wytwarzanie dobrze ustrukturyzowanych fragmentów tekstu
Halucynacje wymagają weryfikacji, a nie większego modelu
Nieprzyjemna prawda: użycie wystarczająco potężnego modelu nie sprawia, że halucynacje znikną. Silniejsze modele rzeczywiście lepiej radzą sobie z identyfikacją faktów i rozumowaniem w różnych zadaniach, ale model językowy pozostaje generatorem tekstu, a nie źródłem prawdy, które można badać jak bazę danych. Dlatego rozwiązanie leży w projekcie: należy dodać do procesu wyraźną weryfikację, na przykład:
User Request
↓
Retrieve Evidence
↓
Generate Answer
↓
Validate Claims
↓
Return Response
Dla procesów o wysokiej wartości można to wzmocnić poprzez:
- cytaty wskazujące na dowody
- wyjścia strukturyzowane sprawdzane pod kątem schematu
- weryfikację zgodności z regułami biznesowymi
Pozwól modelowi rozumować, a oprogramowaniu egzekwować zasady
To tworzy ważną granicę w architekturze. Jeśli od modelu wymaga się obliczenia łącznej kwoty faktury, nie ma powodu, by ufać jego arytmetyce, skoro aplikacja może wykonać te obliczenia dokładnie. Lepiej podzielić odpowiedzialności:
Model:
Extract line items
Application:
Calculate subtotal
Application:
Calculate tax
Application:
Calculate total
Model:
Explain the result
Model wyodrębnia poszczególne pozycje i wyjaśnia wynik; aplikacja oblicza podsumowanie, podatek oraz łączną kwotę. Każda część robi to, w czym jest niezawodna, a liczby widoczne dla użytkownika są z natury zawsze poprawne.
Gdzie małe modele się sprawdzają, a gdzie zawodzą
Mniejsze modele językowe są często uznawane za „mniej inteligentne”, co technicznie jest prawdą w wielu sytuacjach. Jednak inżynieria nie dotyczy wyłącznie inteligencji, a małe modele oferują konkretne zalety:
- niskie koszty przetwarzania
- niska latencja
- prostsze wdrożenie lokalne
- lżejsze wymagania infrastrukturalne
- potencjalnie wyższa przepustowość
- łatwiejsze skalowanie
- dobre dopasowanie do zadań specyficznych
- przydatność w scenariuszach typu edge
- potencjalnie lepsza ochrona prywatności przy działaniu lokalnym
Są szczególnie przydatne do klasyfikacji, wydobywania informacji, streszczania, routingu, autodopisywania, prostych transformacji oraz zadań w specyficznych domenach. Jeśli chcesz zgłębić ten temat, naszy przegląd małych, specjalistycznych modeli przewyższających gigantyczne LLM-y omawia go bardziej szczegółowo.
Jednak małe rozmiary nie oznaczają automatycznie lepszej jakości. Niektóre zadania wykraczają poza możliwości małego modelu: złożone rozumowanie na podstawie wielu źródeł, analiza kodu, trudne problemy planistyczne lub subtelna interpretacja. W takich przypadkach silniejszy model może usprawiedliwić swoją cenę. Obie skrajności są złym doradztwem – „zawsze używaj największego” marnuje pieniądze, a „zawsze używaj najmniejszego” skutkuje produktem niskiej jakości. Lepsza zasada brzmi:
Niech będzie to najmniejszy model, który spełnia wymagania jakościowe Twojej aplikacji.
Zadania wymagające dużych modeli
Żaden z tych punktów nie jest argumentem przeciwko dużym modelom. Są one niezwykle przydatne, a określone zadania wyraźnie uzasadniają dodatkową moc obliczeniową.
Złożone, wieloetapowe rozumowanie
Gdy funkcjonalność wymaga łańcuchowego rozumowania, silniejszy model może dostarczyć znacznie lepszych wyników.
Ręczne programowanie
Duże modele sprawdzają się w przypadku złożonych wymagań, nieznanych baz kodu, decyzji architektonicznych oraz trudnych sesji debugowania.
Ambiwalentny język naturalny
Część zapytań nie pasuje do z góry określonych kategorii. Silniejszy model zazwyczaj lepiej radzi sobie z rozpoznawaniem niuansów i intencji.
Synteza z wielu dokumentów
Gdy odpowiedź wymaga połączenia informacji z wielu źródeł, ważniejsza staje się zdolność modelu.
Przepływy pracy oparte na agentach
Agent zazwyczaj musi:
- Zrozumieć cel
- Sporządzić plan działań
- Wybrać narzędzia
- Zbadać wyniki
- Odzyskać się po niepowodzeniach
- Zmodyfikować plan
- Zakończyć zadanie
To jest o wiele trudniejsze niż klasyfikacja, więc silniejszy model może być w pełni uzasadniony. W każdym przypadku test jest taki sam: używaj dużych modeli, gdy ich dodatkowe możliwości przynoszą mierzalną wartość.
Koszt operacyjny sprytnej architektury
Istnieje koszt, którego benchmarki nigdy nie pokazują: złożoność architektury. Najprostszym możliwym rozwiązaniem jest jedna aplikacja, jeden duży model, jedna odpowiedź:
Application
↓
Large Model
↓
Response
A teraz wyobraź sobie optymalizację wszystkiego naraz:
Application
↓
Router
↓
Classifier
↓
Small Model
↓
Confidence Evaluator
↓
RAG
↓
Reranker
↓
Large Model
↓
Validator
↓
Fallback Model
↓
Human Review
Ten proces może faktycznie doprowadzić do lepszego systemu, ale wprowadza również znacznie więcej komponentów, a każdy z nich niesie ze sobą:
- dodatkowy monitoring i logi
- nowe sposoby awarii
- większą powierzchnię testową
- dodatkową infrastrukturę do uruchomienia
- trudniejsze procesy wdrażania
- więcej wiedzy, której zespół musi posiadać, aby go obsługiwać
Dlatego optymalizacja powinna być celowa. Budowanie architektury składającej się z siedmiu modeli w celu zaoszczędzenia kilku centów na zapytanie rzadko jest dobrą decyzją; dodawaj kolejne warstwy tylko wtedy, gdy pomiary pokazują, że opłaca się utrzymywać je w działaniu.
Oceniaj na podstawie własnego obciążenia, a nie rankingu
Publiczne punkty odniesienia są punktem wyjścia, a nie decyzją. Twoja aplikacja ma swój własny punkt odniesienia, i to jedyny, który ma znaczenie. W przypadku asystenta do przeglądania kodu w AI zestaw oceny może obejmować:
- Urazliwości typu SQL injection
- Sytuacje wyścigowe
- Błędy null-reference
- Uchybienia w autoryzacji
- Nieprawidłowe radzenie sobie z wyjątkami
- Problemy wydajnościowe
- Naruszenia zasad architektury
Dla asystenta obsługi klienta należy mierzyć różne kryteria:
- Zgodność z polityką
- Dokładność faktograficzna
- Ton komunikacji
- Dokładność eskalacji problemów
- Zachowanie przy odmowie
- Walidność strukturyzowanego wyniku
Zbiór danych do oceny powinien jak najbardziej przypominać rzeczywisty ruch użytkowników.
Stworzenie narzędzia do porównań
Bazowa procedura jest prosta: zbiera się zapytania przypominające te z produkcji wraz z oczekiwanymi wynikami, testuje się każdy model kandydujący na ich podstawie i porównuje wyniki.
Production-like prompts
↓
Expected outcomes
↓
Run Model A
↓
Run Model B
↓
Compare
↓
Measure
Przydatne wskaźniki do rejestrowania przy każdym uruchomieniu:
- Sprawność i ukończenie zadania
Gdy to jest już ustalone, wybór modelu staje się decyzją inżynieryjną, a nie domysłem, i można ponownie uruchomić ten sam interfejs za każdym razem, gdy dostawca wypuszcza nową wersję modelu.
Czterostopniowy proces wyboru modelu
Dla nowej funkcji AI dobrze sprawdza się prosty, powtarzalny proces.
Krok 1: Dokładne zdefiniowanie zadania
Nie zaczynaj od pytania „który model powinniśmy użyć?”. Zacznij od pytania „co dokładnie musi osiągnąć model?” i zapisz odpowiedź w konkretnych terminach:
Input:
Customer email
Output:
Intent + urgency + recommended workflow
Taka specyfikacja, z jasnym wejściem i jasnym wyjściem, jest o wiele bardziej przydatna niż niejasny cel.
Krok 2: Zdefiniowanie, co oznacza „dostatecznie dobre”
Ustal jasne kryteria akceptacji przed przeprowadzeniem jakichkolwiek testów. Na przykład:
Intent accuracy >= target threshold
Structured output must always validate
Response should normally arrive within target latency
Rzeczywiste progi zależą od aplikacji; ważne jest, aby istniały przed porównaniem modeli, dzięki czemu wyniki nie mogą być później usprawiedliwiane.
Krok 3: Najpierw wypróbuj najprostszy możliwy model
To krok, który zespoły najczęściej pomijają. Zaczynaj od prostych rozwiązań, mierz efekty i zatrzymaj się, jeśli model zadziała poprawnie. Przejdź do następnego poziomu tylko wtedy, gdy model zawiedzie:
Small Model
↓
Evaluation
↓
Pass? ── Yes → Ship
|
No
↓
Larger Model
↓
Evaluation
↓
Pass? ── Yes → Ship
|
No
↓
Stronger architecture/model
W praktyce wspinasz się po drabinie możliwości, krok po kroku, a każdy kolejny poziom musi zostać zdobyty dzięki nieudanej ocenie.
Krok 4: Optymalizuj otaczający system
Zanim przejdziesz na kolejny poziom, sprawdź resztę systemu:
- Czy proces wyszukiwania zwraca właściwy materiał?
- Czy instrukcja jest jednoznaczna?
- Czy każdy element kontekstu jest rzeczywiście istotny?
- Czy wynik jest weryfikowany przed użyciem?
Lepsze rozwiązania w tym obszarze czasami całkowicie eliminują potrzebę użycia większego modelu.
Inne elementy, które warto sprawdzić przed aktualizacją
Prompty jako umowy
Inżynieria promptów to nie magia, ale słabo sformułowane zadanie może sprawić, że nawet zdolny model będzie zachowywać się źle. Porównajmy niejasną instrukcję:
Analyze this customer message.
z taką, która określa oczekiwany wynik oraz zasady radzenia sobie z niepewnościami:
Analyze the customer message.
Return JSON with:
- intent
- urgency
- sentiment
- recommended_action
Do not invent information that isn't present.
If the intent is unclear, return "unknown".
Druga wersja zapewnia modelowi jasny kontrakt: nazwane pola, wyraźna zаборона na wymyślone fakty oraz określoną wartość awaryjną. Dodanie kilku przykładów często dalej poprawia wyniki. Istnieje jednak pewien limit – żadne sformułowanie instrukcji nie może dać modelowi umiejętności, których zasadniczo brakuje, a gdy ta zdolność jest nieobecna, modyfikacje instrukcji przynoszą coraz mniejsze efekty. Traktuj instrukcje jako jeden z elementów procesu optymalizacji, a nie całe rozwiązanie.
Doprecyzowanie, RAG czy weryfikacja?
Kolejną częstą reakcją na słabe wyniki jest stwierdzenie „zróbmy doprecyzowanie”. Czasami to rzeczywiście rozwiązanie właściwe, ale najpierw należy zdiagnozować problem:
- Jeśli model nie posiada aktualnej lub specyficznej dla firmy wiedzy, np. dzisiejszej polityki, wykorzystanie mechanizmów wyszukiwania jest zazwyczaj lepsze niż doprecyzowanie, ponieważ wiedza się zmienia, a ponowne szkolenie jest powolne.
Dostosowanie środka naprawczego do rzeczywistego problemu oszczędza zarówno czas, jak i pieniądze.
Caching: nudna optymalizacja, która działa
Caching nie jest efektowny wizualnie, ale bardzo skuteczny. Jeśli użytkownicy ciągle pytają „jaka jest wasza polityka zwrotów?“, nie ma powodu, by za każdym razem wywoływać model. Gdy odpowiedź jest stabilna, należy ją zapisać w cache’u. Poniższy przykład w C# najpierw sprawdza cache, wywołuje model tylko w przypadku braku odpowiedzi i przechowuje wynik na 30 minut:
public async Task<string> GetAnswerAsync(string question)
{
var key = CreateCacheKey(question);
var cached = await cache.GetStringAsync(key);
if (cached is not null)
return cached;
var answer = await model.GenerateAsync(question);
await cache.SetStringAsync(
key,
answer,
TimeSpan.FromMinutes(30));
return answer;
}
Prawdziwe cacheowanie semantyczne jest bardziej złożone niż dokładne dopasowywanie ciągów znaków, ponieważ dwa różnie sformułowane pytania mogą wymagać tej samej odpowiedzi, a konieczna jest polityka unieważniania odpowiedzi w przypadku zmian podstawowych faktów. Idea architektoniczna pozostaje niezmienna:
Naj szybszą prośbą do AI jest ta, której nigdy nie wysyłasz.
To samo zasada dotyczy eliminacji duplikatów, przedsobierania danych, deterministycznych odpowiedzi, ponownego wykorzystania wyników wyszukiwania, cacheowania prefiksów zapytań tam, gdzie dostawca to obsługuje, oraz prostego ponownego wykorzystania odpowiedzi. Zanim zaczniesz płacić za większą moc obliczeniową, usuń tę, której nie potrzebujesz.
Traktuj tokeny jako budżet zasobów
Gdy potraktujesz system AI jako system rozproszony, tokeny stają się kolejnym zasobem do zarządzania. Tradycyjne usługi obsługują procesor, pamięć, sieć i przechowywanie danych. Aplikacje AI dodają tokeny wejściowe, tokeny wyjściowe, rozmiar kontekstu oraz czas przetwarzania, co sprawia, że projektowanie zapytań staje się kwestią wydajności.
Rozważ przesyłanie pełnej historii rozmowy z każdym żądaniem. Zapytania stale się powiększają, a do tego dochodzą pobrane dokumenty, wyniki narzędzi, instrukcje systemu oraz wcześniejsze działania agenta. Proste pytanie może ostatecznie zawierać ogromną ilość danych. Lepszy projekt wybiera tylko istotne informacje przed ich pobraniem i tworzy zwięzły kontekst:
Conversation
↓
Relevant history selection
↓
Retrieval
↓
Compact context
↓
Model
Zamiast przesyłać wszystko, co system kiedykolwiek widział:
Everything we've ever seen
↓
Model
Więcej kontekstu nigdy nie jest bezkosztowe: płacisz za niego pieniędzmi, opóźnieniami oraz, często, jakością odpowiedzi.
Agenci mnożą skutki każdej z tych decyzji
Systemy oparte na agentach sprawiają, że wybór modelu ma jeszcze większe znaczenie. Jedna prośba użytkownika może przerodzić się w wiele kroków:
User Request
↓
Planning
↓
Tool Selection
↓
Search
↓
Database Query
↓
Code Execution
↓
Analysis
↓
Final Response
Jeśli każdy krok jest wykonywany przy użyciu najdroższego modelu, koszty mogą gwałtownie wzrosnąć. Jednak kroki te rzadko wymagają tych samych możliwości. Taka mieszana alokacja może wyglądać w ten sposób:
Intent classification → Small model
Simple tool selection → Small model
Complex planning → Large model
Data extraction → Small model
Final explanation → Medium model
To jest heterogeniczna architektura sztucznej inteligencji, i to właśnie w tym kierunku zmierzają wiele systemów produkcyjnych: nie jeden ogromny model, który robi wszystko, lecz kilka modeli, narzędzi, komponentów deterministycznych, pipeline’ów do wyszukiwania i mechanizmów weryfikacji pracujących razem. Nasz artykuł o tym, dlaczego koszty sztucznej inteligencji opartej na agentach rosną szczegółowo omawia aspekt kosztowy tego zjawiska.
Rozważaj modele jako członków zespołu
Pomocna analogia: wyobraźmy sobie trzech inżynierów. Jeden jest bardzo doświadczony, drogi i przepracowany. Drugi ma dużą praktykę i jest wydajny. Trzeci jest początkujący, ale bardzo szybki w wykonywaniu prac powtarzalnych. Nie powierzylibyśmy każdego zadania najdoświadczeniwszemu inżynierowi – przydzielilibyśmy prace według stopnia trudności:
Simple repetitive task
→ Engineer C
Normal feature
→ Engineer B
Complex architecture problem
→ Engineer A
Modele można traktować w ten sam sposób. Mniejszy model nie jest „zły” – może po prostu być odpowiedni do węższych zadań. Kluczową umiejętnością jest dzielenie pracy na mniejsze części. Zamiast szukać jednego modelu, który poradzi sobie ze wszystkim, podzielmy proces pracy tak, aby każdy komponent zajmował się tym, w czym jest najlepszy. Taki sposób myślenia pozwala na lepszą skalowalność.
Podsumowanie: architektura referencyjna
Łącząc te koncepcje, asystent AI dla przedsiębiorstwa mógłby być zorganizowany w ten sposób:
User
|
v
API / Gateway
|
v
Request Router
|
+-------------+-------------+
| |
v v
Simple Request Complex Request
| |
v v
Small Model Planner
|
+------------+------------+
| | |
v v v
Search Database Tools
| | |
+------------+-------------+
|
v
Context
|
v
Strong Model
|
v
Validator
|
+------+------+
| |
Valid Invalid
| |
v v
Response Retry/Fallback
Zwróć uwagę na to, czego nie dzieje się: od największego modelu nie wymaga się wykonywania wszystkiego. Proste żądania trafiają do małego modelu, natomiast złożone przechodzą przez planer, który zbiera dane z wyszukiwarek, baz danych i narzędzi, a dopiero wtedy silny model przetwarza przygotowany kontekst. Walidator sprawdza wynik, a nieważne rezultaty powodują ponowną próbę lub użycie alternatywy. Projekt opiera się na:
- routerze, który wybiera odpowiednią ścieżkę
- narzędziach do pozyskiwania danych i dowodów
- systemach deterministycznych służących do dokładnej pracy
- modelach specjalizowanych pod kątem określonej roli
- strategiach walidacji oraz ponownych prób i alternatyw
Tutaj model jest jedną częścią systemu, a nie całym systemem.
Dziesięć błędów, które ciągle się powtarzają
- Najpierw wybór modelu, a dopiero później opis problemu. Ten porządek jest odwrotny; najpierw należy określić zakres pracy, zanim cokolwiek innego.
Lista kontrolna przy wyborze modelu
Gdy pojawia się decyzja dotycząca modelu, przeanalizuj kolejno te pytania:
- Czy deterministyczny kod może to rozwiązać? Jeśli tak, napisz kod. Nie używaj AI tylko dlatego, że jest dostępna.
- Czy zadanie jest proste i powtarzalne? Spróbuj małego modelu.
Ta lista kontrolna jest o wiele bardziej przydatna niż pytanie, który model jest największy i dostępny.
Pytanie, które warto zadać doświadczonym inżynierom AI
Ciekawe pytanie w rozmowie rekrutacyjnej na stanowisko związane z architekturą AI brzmi: „Dlaczego po prostu nie wybrać najskuteczniejszego modelu na rynku do wszystkiego?”
Słaba odpowiedź kończy się stwierdzeniem „mniejsze modele są tańsze”. To prawda, ale niepełna. Dobra odpowiedź uwzględnia możliwości modelu do realizacji konkretnego zadania, niezawodność, opóźnienia i przepustowość, koszt, ilość potrzebnego kontekstu, routowanie między modelami, proces wydobywania informacji, zadania, które powinien wykonywać kod, metody oceny, koszty awarii oraz obciążenie operacyjne.
Prawidłowym dalszym pytaniem jest: „Jak udowodnisz, że wybrany model jest wystarczająco dobry?”. Odpowiedź powinna dotyczyć oceny, a nie opinii, tematów na mediach społecznościowych, zrzutów ekranu z listą liderów czy slajdów od dostawców. Decydujące są twoje obciążenia pracy, dane oraz metryki.
Optymalizacja istniejącej aplikacji krok po kroku
Gdy funkcja oparta na AI jest zbyt wolna lub zbyt droga, powstrzymaj się od natychmiastowej zamiany modeli. Zamiast tego przeprowadź systematyczne badania:
- Pomiar. Zbieraj dane dotyczące liczby żądań, tokenów wejściowych i wyjściowych, opóźnienia, wskaźnika błędów, skuteczności zadań oraz kosztu modelu.
- Znajdź drogie obciążenia. Określ, jakie typy żądań zużywają najwięcej zasobów.
- Usuń niepotrzebne wywołania. Wykorzystuj cache, logikę deterministyczną, usuwanie duplikatów oraz przedobliczenia.
- Zmniejsz zakres kontekstu. Pomiń nieistotną historię i dokumenty.
- Popraw wyszukiwanie. Zwracaj lepsze dowody zamiast większej ich ilości.
- Próbuj mniejszego modelu. Sprawdź, czy jakość pozostaje akceptowalna.
- wprowadź routowanie. Przesyłaj tylko trudne przypadki do silniejszych modeli.
- Waliduj to, co jest ważne. Zastosuj schematy, reguły, narzędzia oraz ludzką weryfikację tam, gdzie to konieczne.
Jeśli wydaje ci się to znajome, powinno. To w zasadzie ta sama dyscyplina stosowana do optymalizacji tradycyjnego oprogramowania.
Najlepsza architektura AI jest zazwyczaj hybrydowa
Obraz aplikacji AI jako interfejsu użytkownika wywołującego API LLM i zwracającego odpowiedź staje się coraz mniej aktualny:
Frontend
↓
LLM API
↓
Response
Prawdziwe aplikacje coraz częściej przypominają bramkę koordynującą reguły, procesy wyszukiwania, modele, narzędzia oraz mechanizmy weryfikacji:
Application
|
v
AI Gateway
|
+-----------+-----------+
| | |
v v v
Rules Retrieval Models
| | |
+-----------+-----------+
|
v
Tools
|
v
Validation
|
v
Application
Taki projekt łączy klasyczną inżynierię oprogramowania z uczeniem maszynowym, modelami językowymi i mechanizmami wyszukiwania, a także bazami danych, API, zabezpieczeniami, możliwościami obserwacji oraz logiką biznesową napisaną w formie kodu. To dobra wiadomość dla inżynierów oprogramowania: inżynieria AI nie zastępuje inżynierii oprogramowania, lecz dodaje do niej potężny nowy element.
Pomaga również zmiana perspektywy: przestańmy pytać, który model jest najmądrzejszy, a zacznijmy pytać, który system jest najmądrzejszy. Genialny model w słabo zaprojektowanym systemie może dać okropne wyniki, podczas gdy model o umiarkowanych możliwościach w dobrze zaprojektowanej architekturze może służyć do tworzenia doskonałych produktów. Dobre systemy kompensują słabości modelu dzięki mechanizmom wyszukiwania i narzędziom, routingu i buforowaniu, uporządkowanym wynikom i weryfikacji, kodowi zapewniającemu dokładną pracę oraz ciągłej ocenie. W tym sensie możliwości sztucznej inteligencji są właściwością architektury, a nie tylko modelu.
Zacznij od małego i rozwijaj na podstawie dowodów
Rozsądna domyślna strategia dla każdej nowej funkcji opartej na sztucznej inteligencji jest przedstawiona w tym schemacie:
Start
|
v
Define the workload
|
v
Can code solve the problem?
/ \
Yes No
| |
Use code v
Try small model
|
v
Evaluate
|
+----------+----------+
| |
Pass Fail
| |
Ship v
Improve architecture
|
v
Evaluate
|
v
Try stronger model
|
v
Evaluate
Zapobiega to bardzo powszechnemu błędowi: wydawaniu pieniędzy na problem, który lepsza inżynieria mogłaby rozwiązać.
Czasami odpowiedni model to wcale nie model
Lekcja nie polega na tym, że małe modele są lepsze; to byłoby równie błędne jak przeciwne twierdzenie. Prawidłowy model to taki, który spełnia wymagania zadania, równoważąc jednocześnie możliwości i niezawodność z opóźnieniem, kosztem oraz złożonością. Czasami jest to mały model, czasami duży, czasami połączenie obu, a czasami w ogóle nie model AI. Jeśli jakiś typ żądania można obsłużyć za pomocą prostego rozwiązania, takiego jak to, nie ma powodu do używania LLM:
if (request.Type == "PasswordReset")
{
return StartPasswordResetWorkflow();
}
To nie jest anty-AI; to dobra inżynieria. Nie kupiłbyś serwera z nieograniczoną ilością procesorów dla usługi, która potrzebuje dwóch rdzeni, ani nie przydzieliłbyś terabajta pamięci procesowi, który używa 4 GB. Ten sam rozsądek odnosi się do modeli: możliwości, których nie potrzebujesz, to koszt, którego też nie potrzebujesz.
Główne wnioski
- Zamień „Jaki jest największy model, który możemy sobie pozwolić?” na „Jaka jest najprostsza architektura, która niezawodnie rozwiązuje ten problem?”. To pytanie naturalnie prowadzi do kwestii routingu, wyszukiwania, cache’owania, kodu deterministycznego, oceny, opóźnień oraz radzenia sobie z awariami.
- Oceniaj modele pod kątem kosztu za udaną zadanie, uwzględniając konsekwencje błędnej odpowiedzi, a nie cenę za połączenie lub liczbę parametrów.
- Traktuj brak wiedzy jako problem wyszukiwania, a arytmetykę lub reguły jako problem oprogramowania; żaden z nich nie zostanie rozwiązany dzięki większemu modelowi.
- Wybieraj najmniejszy model, który przechodzi ocenę przeprowadzoną na podstawie własnych danych w warunkach produkcyjnych, i ulepszaj go tylko na podstawie konkretnych dowodów.
- Zachowuj architekturę tak prostą, jak to uzasadniają oszczędności, i kontynuuj pomiary po wdrożeniu, ponieważ modele, prompty i użytkownicy ciągle się zmieniają.
Najpierw zaprojektuj rozwiązanie wokół problemu, a dopiero potem wybierz model pasujący do tego projektu. Czasami taki model będzie ogromny, czasami zaskakująco mały, a czasami najmądrzejszą decyzją będzie w ogóle nie używanie modelu.
Literatura pokrewna
- Retrieval-Augmented Generation Explained: Fixing LLM Knowledge Gaps — Dowiedz się, dlaczego modele językowe generują błędne informacje i tracą aktualność, a następnie zobacz krok po kroku, jak technika RAG pobiera dane, dzieli je na fragmenty, embeduje i uzupełnia prompty, aby to naprawić.
- RAG vs Agentic RAG vs Graph RAG: Choosing the Right Retrieval Architecture — Przeczytaj, dlaczego prosta technika RAG zawodzi przy zadaniach wymagających wielu kroków i danych strukturalnych, oraz jak pętle agentywne i techniki wyszukiwania oparte na grafach rozwiązują różne słabości.