AMP, czyli Agents of Mass Production, to mój osobisty projekt, w którym koncentruję się na stopniowym wprowadzaniu modeli językowych do mojej codziennej pracy. Na chwilę obecną właśnie w rozwiązaniach wspierających procesy oraz biznes widzę największego możliwości dla wykorzystania generatywnej sztucznej inteligencji. Pisząc te słowa, mam już wstępne notatki na temat tego, dlaczego tak myślę, ale ten tekst pojawi się dopiero za kilka tygodni. Niemniej, powstał w wyniku dygresji, która pojawiła się w trakcie prac nad kolejnym opisem przygód związanych z pracą nad AMP.

Moi agenci potrafią coraz więcej
Obecnie AMP wspiera mnie w automatyzacji raportów z JIRY, porządkowaniu oraz opisywaniu wrażeń z ogrywek, oraz tworzeniu notatek ze spotkań. Ostatnia aktywność zaoszczędza mi dużo czasu, poza tym dodałem tutaj połączenie z bazą wektorową, dzięki czemu każda kolejne podsumowanie jest wzbogacane o informacje z poprzednich. Z racji zbliżającej się premiery „Pocket Waifu Rekindled” stanąłem przed wyczerpującym zadaniem. Muszę coraz więcej uwagi poświęcać danym ze Steama, a jest to nieprzyjemna aktywności. Dlaczego? Skąd bierze się to tarcie? Valve przecież robi wszystko, aby być przyjaznym dla swoich klientów.
Od strony gracza naprawdę mam niewiele do zarzucenia Steamowi. Zresztą nie przez przypadek stałem się posiadaczem Steam Decka i bardzo go sobie chwalę. Natomiast jako osoba zaangażowania w tworzenie gier komputerowych, muszę przyznać, że do pracy z platformą Valve podchodzę ze znacznie większą rezerwą. Dzisiaj skoncentruję się na analizie różnego rodzaju danych, bo to właśnie w tym pomagają mi modele językowe. Jednak czuję się zobligowany do tego, aby zaprezentować, skąd w ogóle wzięła się ta potrzeba. Steam prezentuje naprawdę dużo cennych zestawień na temat tego, co dzieje się w grach, którymi się opiekuję. Pierwszy problem polega na tym, że te informacje są bardzo rozproszone i trzeba się trochę naklikać, aby do nich dotrzeć. Nawet jeśli już je mam, to i tak wolę pobrać pliki CSV, aby nanieść własne komentarze oraz przejrzeć trendy. Dotyczy to takich informacji jak liczba pozyskanych list życzeń oraz DAU, bo właśnie na tych wymiarach często się skupiam.
Zupełnie inną kwestią są dane marketingowe. To jest drugi, znacznie poważniejszy, problem. Steam ma specjalne miejsce, w którym można podejrzeć wykres, zobaczyć, gdzie pojawiły się wzrosty, a gdzie spadki. Jednak dokładne zidentyfikowanie tego, skąd wziął się ten czy inny szczyt, naprawdę wymaga mnóstwo wytrwałości oraz przechodzenie przez kategorie. Doskonale zdaję sobie sprawę z tego, że wielu twórcom w zupełności wystarcza prezentacja w postaci wykresów, pewnie nie czują potrzeby, aby grzebać w tym, co jest tam pozwijane. A szkoda, bo właśnie w podkategoriach podkategorii leżą zakopane soczyste kąski informacji. Ktoś w Valve stwierdził, że ciekawscy pewnie zadowolą się plikiem i sami sobie opracują, to co ich interesuje. Ta osoba miała rację, ponieważ od dawna właśnie tak robię. Doskonale zdawałem sobie sprawę z tego, że moje metody oraz skrypty są dalekie od perfekcji i wciąż polegałem na własnej uwadze, co przekładało się na mozolne przeglądanie tych pozawijanych kategorii. Pewnego popołudnia, w ramach podwieczorku rozwoju, uznałem, że czas zaprzęgnąć do tego model językowy.
Modele decydują same
Z racji tego, że OpenAI udostępniło multimodalne GPT4-o mogłem sobie pozwolić na szybkie interpretowanie wykresów. Po prostu wrzuciłem zrzut ekranu, napisałem prompt, w którym wskazałem, że potrzebuję analizy trendów i dostałem odpowiedź. Zadowalającą, jednak to był pierwszy krok w kierunku zbudowania agenta do analizy danych z platformy Steama. Chciałem dostać znacznie, więcej dlatego postanowiłem użyć opisu wykresów jako dodatkowego kontekstu w celu wyciągnięcia dodatkowych informacji z danych zawartych w plikach CSV. Czytając te słowa, pewnie zastanawiasz się nad tym, jak wygląda prompt, który pozwala przeanalizować dane w pliku, zestawić informacje, a potem przygotować z nich raport. Ja zaczynam od rozpisania kierunku, w jakim chcę podążać oraz elementów, jakie mnie interesują, ale samo wygenerowanie promptów przerzuciłem na LLMy.
Nic mi się nie poplątało. Pracując nad tym rozwiązaniem, postanowiłem, że oddam więcej władzy w cyfrowe nibynóżki modeli językowych. Moja rola, jako użytkownika, ogranicza się do przesłania konkretnego zestawu plików. Później LLMy same decydują, jak je przeanalizować. Wprowadziłem etap, w którym model opracowuje sobie kroki pozwalające na analizę pliku, którego zawartość została wklejona. Przy każdym uruchomieniu ten proces wygląda odrobinę inaczej, ponieważ LLM reaguje na dane, jakie otrzymał. Jednak dzięki temu, że proces składa się z kilku etapów, otrzymuję znacznie ciekawsze oraz bogatsze wyniki, które następnie są streszczane oraz składane w podsumowanie, z którym mogę się zapoznać. Kluczowym aspektem tego podejścia jest zarządzanie uwagą modelu. Najpierw poprzez opracowanie kroków analizy danych, które musi wykonać, a następnie skompresowanie wyników i prezentacja ich w formie raportu. Ten ostatni krok jest dla mnie o tyle ważny, że to już są opracowane dane, które traktuję jako podstawę do oceny zaangażowania graczy oraz podejmowanych wysiłków marketingowych.

Czy łatwo było mi oddać władze nad przepływem informacji w nibynóżki modelu? Nie, ale jednocześnie zdawałem sobie sprawę z tego, że pisanie promptów, ich testowanie oraz modyfikowanie pochłania sporo czasu. Dlatego stwierdziłem, że przecież nic nie stoi na przeszkodzie, aby LLM sam je sobie tworzył, a następnie wykonywał. Ja, jako osoba pracująca nad procesem, określam jedynie kierunek, a także dostarczam dane. Reszta dzieje się już poza moją wiedzą, widzę jedynie informacje w konsoli o zrealizowaniu kolejnych kroków. Na koniec, we wskazanym folderze, ląduje potrzebny mi raport. Czas wykonywania? Około 10 minut, przy 5 plikach zawierających dane z ostatniego miesiąca. Koszt? 1 dolar, 80 centów. Efekty? Zadowalające, bardzo, bardzo zadowalające. Mam nawet pewien niewielki i bezpieczny przykład!
Najnowsza gra JNT Games, „Pocket Waifu Rekindled” brała udział w czerwcowym Steam Next Fest. Co oznacza, że w danych marketingowych był wyraźnie widoczny zwiększony ruch związany z tym wydarzeniem. Jednak z jakich miejsc pochodził? Jak tego szukać, w tych wszystkich pozawijanych kategoriach, porozrzucanych okruszkach informacji, jakie dostarcza Valve? Świetnie poradziły sobie z tym modele językowe! Znalazły informację na temat kluczowego wydarzenia, same określiły miejsce, w którym się rozpoczęło oraz zakończyło, a następnie wskazały, skąd pochodził ruch oraz podzieliły się uwagami na temat konwersji i zaproponowały kilka kierunków, które warto uwzględnić w strategii marketingowej. Być może teraz zastanawiasz się, dlaczego raz piszę model językowy, a innym razem modele językowe. To nie jest błąd, to nie jest moja nieuwaga.
Więcej, niż jeden
Po pierwszych eksperymentach z modelami językowymi, prowadziłem je często na niewielkich zestawach danych, szybko zauważyłem, że różnie odpowiadają. Inaczej reaguje GPT, inaczej Calude, inaczej Llama. Dostrzegłem duże korzyści z wykorzystywania tańszych modeli w celu zrealizowania celów wymagających mało skomplikowanego rozumowania oraz używania otwartoźródłowych LLMów do mniejszych eksperymentów. Jak chociażby generowanie pytań do raportów lub proponowanie kierunku, w jakim należy je rozwinąć. Nawet niewielkie modele, 3B oraz 8B, potrafiły wskazać jakąś ciekawą ścieżkę, jeśli otrzymały dobrze przygotowane dane i odpowiednie instrukcje. O to pierwsze jestem w stanie zadbać ja, a o drugie zadba inny model językowy.
Jednak taka strategia ma swoją cenę. Jednakowo w formie niematerialnej, czyli czasu, jak i materialnej, czyli pieniędzy. Istotne stało się dla mnie wprowadzenie do procesu etapu weryfikacji uzyskiwanych odpowiedzi, dokonywanego przez duży model (tutaj rewelacyjnie sprawdza się Claude 3.5 Sonnet), a następnie ich syntezy przy pomocy innego LLMa. Pracując nad tym rozwiązaniem, przepaliłem sporo tokenów w różnych usługach oraz zużyłem niemało prądu. Wnioski z tych eksperymentów są takie, że nie warto zamykać się na modele otwartoźródłowe. Uruchomienie lokalnie niewielkiego LLMa, takiego Phi3, wymaga przynajmniej 8 GB RAM. Ja tego korzystam na Raspberry Pi 5! Jasne, wygenerowanie odpowiedzi trwa, nie dostanę jej od razu, tak jak jest to w przypadku korzystania z usługi Anthropic lub OpenAI. Tylko że jeśli potrzebuję jedynie opracować metadane dla dokumentu, który jest po angielsku, bo wiele LLMów z otwartym źródłem kiepsko radzi sobie z innymi językami, to po co mam korzystać z dużych modeli? Model na Raspberry Pi otrzymuje treść, zestaw informacji, mieli to i zapisuje w bazie danych.
Inną sprawą jest skuteczność rozwiązań, z których korzystam. Zauważyłem, że znacznie lepsze wyniki otrzymuję, jeśli informacje przerzucam pomiędzy modelami, a potem kompresuję oraz weryfikuję ich odpowiedzi. Wymaga to więcej czasu, wymaga to też kroku, w którym konieczne jest odpowiednie opracowanie danych. Tutaj znowu z pomocą mogą przyjść modele językowe, jednak ja wolę się trzymać sprawdzonych skryptów czyszczących opracowanych w Pythonie. Mam gwarancję, że w pierwszym kroku procesu analizy, dane zawsze będą wyglądały tak samo. Kolejną kwestią jest to, czy zadanie, które chcesz wykonać, w ogóle wymaga tak rozbudowanego procesu. W moim przypadku jest to generowanie raportów na temat gier wydanych na Steamie, więc muszę pogodzić wiele różnych aspektów tego zadania i tutaj faktycznie jestem w stanie wykorzystać odpowiedzi z różnych modeli językowych. Natomiast jeśli chcesz wygenerować odpowiedź na maile od klienta, to w zupełności wystarczy użyć jednego LLMa, a potem zweryfikować odpowiedź.

Rozgryzanie recenzji
Podobnie ma się sprawa z analizowaniem opinii graczy. Steam udostępnia API dzięki, któremu każdy może zebrać recenzje pod danym produktem. Chciałbym napisać, że dzieje się to bez najmniejszego problemu, jednak już kilka razy spotkałem się z sytuacją, w której zwrotka przychodziła pusta, a recenzje na stronie produktu były. Zauważyłem, że na StackOverflow jest kilka postów na ten temat, problem pozostaje nierozwiązany. Problemem nie jest to, że gra jest oznaczona jako tylko dla dorosłych. Pusta zwrotka dotyczy różnych produktów, ale wiadomo, że przecież są inne metody pobierania danych ze stron internetowych. Zawsze można poudawać przeglądarkę.
Niezależnie od wybranego sposobu pobrania recenzji, zostaniesz z zestawem tekstów. Pozostaje tylko połączyć się z modelem językowym, i wyciągać informacje z opinii, a potem opracować ładne podsumowanie, które będzie można zaprezentować na spotkaniu z zespołem. Też tak pomyślałem na początku. Jednak szybko zauważyłem, że model nie wyciąga dobrych wniosków, tak jakby brakowało mu jakiejś kluczowej informacji. Co nią było? Banalna sprawa, przecież LLM nie ma pojęcia, jaką grę ocenili klienci, nie wie, czego dotyczą recenzje. Dlatego postanowiłem wzbogacić kontekst o podsumowanie tego, jaka to jest gra, co ma w opisie, co twórcy uznali za ważne, jak otagowali swój produkt. Te wszystkie dane są dostępne na stronie Steama, wystarczy je pobrać, a potem spakować w ładne podsumowanie, które potem będzie wykorzystywane do weryfikowania recenzji.

Tak, uznałem, że przecież część opinii nie będzie przydatna. Ludzie piszą naprawdę dziwne, czasem dość niepokojące, rzeczy w recenzjach na Steamie. Paradoksalnie dzieje się to także pod produktami, które należą do grupy innej, niż tylko dla dorosłych. Dlatego tak ważne jest odsianie ziarna od plew. Aby to zrobić, model otrzymywał skompresowany opis gry, a także recenzję i decydował, czy jej treść będzie przydatna w ocenie produktu. To sprawiło, że zaoszczędziłem zarówno czas, jak i tokeny w dalszej części procesu. Jednocześnie ignorowałem kwestię, czy recenzja była oznaczona na Steamie jako negatywna lub pozytywna. Już wcześniej opracowałem prosty automat zajmujący się oceną sentymentu i zauważyłem, że modele językowe dobrze sobie z tym radzą.
Na tym etapie mam już zebranie tylko i wyłącznie te opinie, które są wartościowe w kontekście analizowanej gry. To jest piekielnie kluczowa informacja! Inaczej model reaguje, jeśli ma po prostu szukać pomocnej recenzji, w ogólnym znaczeniu, a inaczej jeśli mu się zawęża kontekst. Jednak samo zebranie recenzji to zdecydowanie za mało, aby przygotować zestawienie dobrych i złych doświadczeń użytkowników. Aby to zrobić, zdecydowałem się na wykorzystanie bazy wektorowej, do której wrzuciłem przesiane recenzje. Co otrzymałem? Zestawienie treści pełnych różnych opinii, zamienionych na wektory znaczeń. Nic nie stoi na przeszkodzie, aby tę bazę odpytać, a następnie skompresować odpowiedzi do oddzielnego tekstu, który będę mógł wykorzystać jako podstawę do dalszej dyskusji z zespołem oraz oceny tego, jak funkcjonuje gra. Nie zależy mi na tym, aby dodatkowo prezentować, ile było recenzji dobrych, a ile negatywnych. Problem polega na tym, że nawet jeśli ktoś napisze, że dużo elementów gry go odrzuciło, to i tak zdarza się, że coś pochwali. Mimo to recenzja na Steamie będzie oznaczona jako negatywna. Właśnie dlatego zdecydowałem się przesianie recenzji, zapakowanie ich w bazę wektorową i dopiero z niej zacząłem wyciągać informacje potrzebne do raportu.
Jak to zrobiłem? Ponownie wykorzystałem samodzielność modelu językowego. Nic nie stoi na przeszkodzie, aby to LLM opracował zestaw pytań do bazy wektorowej, który pozwoli zebrać pozytywne oraz negatywne doświadczenia. Chciałem uniknąć sytuacji, w której model zaproponuje ogóle problemy dotyczące gier i na ich podstawie stworzy zestawienie tego, co było dobre, a co złe. Dlatego, ponownie, wykorzystałem skompresowany opis gry ze strony produktu na Steam oraz tagi. To pozwoliło mi naprowadzić LLM na bardzo konkretne właściwości gry, którymi chwalili się sami twórcy. Skoro pewne elementy były dla nich ważne, klienci widzą opis, to też na niego reagują grając oraz pisząc recenzje. W ten sposób otrzymałem pytania dotyczące konkretnej gry, co dało możliwość opracowania listy dobrych złych doświadczeń. Z racji tego, że te dane są ogólnodostępne, to przykładowy wynik działania agenta zajmującego się opracowywaniem recenzji, znajdziesz tutaj.
Co dalej?
AMP ewoluuje. Tym razem zająłem się bardzo konkretną kwestią, czyli pracą z danymi od Steama. Postawiłem też na wcześniej wykorzystywane przeze mnie metody — generowanie pytań oraz opracowywanie odpowiedzi na podstawie informacji pozyskanych z bazy wektorowej. Pracując nad asystentem pomagający mi w przeglądanych danych gier, postanowiłem dać mu większą swobodę. Nie szukałem idealnego promptu pozwalające na analizę informacji zawartych w plikach, raczej uznałem, że model sam opracuje listę kroków, które następnie wykona. Opisów tego, czego może spodziewać się w danych, również nie otrzymuje, wie tylko, że będzie pracował z informacjami dotyczącymi gry komputerowej, że będą one pochodziły ze Steama, a końcowy raport ma zostać zaprezentowany w firmie, której głównym zajęciem jest gamedev. Reszta dzieje się sama.
Myślę, że spędzę trochę czasu, szlifując tego asystenta. W końcu jest jeszcze trochę danych, które mogę wykorzystać dla dostarczenia lepszego kontekstu.
You must be logged in to post a comment.