AMP. Agents of Mass Production.

Ostatnio wykorzystałem CrewAI w celu opracowania podsumowania spotkań. Efekty były bardziej niż zadowalające, ale nie zabrakło kosztownego potknięcia.

Ostatnio miałem dłuższą przerwą od pisania na temat automatyzacji z użyciem dużych modeli językowych, ponieważ brałem udział w kursie na ten temat. Tak, nareszcie, po blisko roku korzystania z tych narzędzi, usiadłem i ktoś zmusił mnie do uporządkowania wiedzy. Warto było, po recenzję pięciu tygodniu szkolenia AiDevs zapraszam tutaj, bo ten tekst będzie prezentował praktyczne zastosowanie zdobytej wiedzy. Od razu zaznaczam, że odchodzę tutaj od Make i skupiam się na kodzie napisanym w Pythonie. Dlaczego? Skąd tak decyzja? Czy porzucam tę platformę wspomagającą automatyzację?

Od kuleczek do kodu

Mam podstawową wiedzę na temat programowania. Nawet od czasu do czasu napiszę jakąś prostą grę lub skrypt do przetwarzania danych. Nie zajmuję się tym na co dzień, to taka aktywność, która pozwala mi pozmieniać kontekst w głowie i zmusić mózg do innego myślenia. Gdy rok temu, w pierwszym kwartale 2023, zabierałem się za naukę korzystania z modeli językowych, nawet przez myśl mi nie przeszło, żeby sięgnąć po API. Nie widziałem potrzeby, uważałem, że skoro mogę większość wyklikać z poziomu Make (link afiliacyjny), to po co jeszcze szarpać się z kodem? Minęło trochę czasu, w trakcie kursu AiDevs wróciłem do Pythona i uznałem, że w sumie, niektóre rzeczy wolę mieć wykonywane przez skrypt. Mam nad nim większą kontrolę.

Absolutnie nie rezygnuję z Make! Co więcej, wykorzystując webhooki, integruję tę platformę z moimi niewielkimi skryptami. Prosty kod napisany w Pythonie pozwala mi inaczej spojrzeć na to, co chcę zrobić oraz zmusza mnie do zaplanowania logiki w taki sposób, aby skupić się dokładnie na tym, co chcę osiągnąć, bez zastanawiania się, jaką kuleczkę wybrać. Python daje mi też dostęp do bezpośredniego korzystania z innych modeli językowych, które mam postawione lokalnie na komputerze. Nie muszę wysyłać zapytań do dedykowanego API, tylko odpalam sobie skrypt i dostaję odpowiedź. Ostatnią kwestią są różnego rodzaju biblioteki, z których mogę korzystać, a także połączenia z bazami danych na mojej Raspberry Pi. Dalej uważam, że Make jest super. Po prostu postanowiłem sprawdzić się z innymi narzędziami.

Jak to wyszło? Całkiem nieźle. Repozytorium projektu nazwałem „AMP. Agents of Mass Production”, ponieważ ma się skupiać na ułatwianiu mi mojej pracy w gamedevie. Jestem producentem, czyli kierownikiem projektów, więc muszę przygotowywać wiele różnych dokumentów oraz pilnować kierunku, w jakim zmierzają zespoły, którymi się opiekuję. Cyfrowy asystent w Make towarzyszy mi od początku roku, daje radę, bardzo pomaga mi w obserwowaniu tego, co dzieje się na Jirze oraz w przygotowywaniu podsumowań planów na sprint poszczególnych działów w firmie. Teraz przyszedł czas na zmierzenie się z transkrypcjami z cotygodniowych spotkań organizujących pracę zespołu.

Pętla wydatków

Zdecydowałem się, że wykorzystam do tego CrewAI. Jest to framework pozwalający na tworzenie agentów, definiowane ich ról, przydzielanie zadań oraz ich realizację. Istotne jest to, że CrewAI powala na opracowanie autonomicznego schematu działania i jego odpalanie na życzenie. Po prostu ustawiam agentów, przydzielam im zadania, a potem wykonuję skrypt i dostaję pożądane wyniki. Brzmi bardzo prosto, ale trzeba się zastanowić jak podejść do wybranego tematu. Moje pierwsze spotkanie skończyło się tym, że agenci się zapętlili i przepalili trochę tokenów. Widać to doskonale na poniższym wykresie. Jak do tego doszło?

Zamiast użyć podsumowania transkrypcji, uznałem, że ominę ten krok i zdefiniuję agenta, który będzie je robił. Pomysł wydaje się niezły, ale wymaga dobrego opracowania sekwencji wydarzeń, jaką ma się posługiwać mój cyfrowy zespół. Moim błędem było to, że jeden agent zaczął pytać drugiego o konkretne zadania ze spotkań, a że nie znajdował ich w przygotowanym podsumowaniu, to zaczynał przeglądać pliki z transkrypcjami. Tak to trwało przez dłuższą chwilę, a tokeny spokojnie były przepalane. Dlaczego czekałem? Chciałem zobaczyć, co z tego wyniknie. Poza kosztami nauczyłem się tego, aby dokładnie definiować role oraz zadania. Kompresowanie informacji wejściowych, na przykład za pomocą przygotowania podsumowania, też nie zaszkodzi.

Właśnie dlatego należy ustawić w OpenAI limit wydatków oraz wiadomość, która przechodzi, gdy przekroczy się określony próg. Okazjonalne przepalanie tokenów, to, niestety, element nauki pracy z dużymi modelami językowymi. Trzeba zaakceptować, to, że od czasu do czasu, jakaś struktura zacznie skręcać w zupełnie innym kierunku, niż się zaplanowało. Ja, po tej nauczce, postanowiłem stworzyć oddzielny skrypt, który będzie zajmował się przygotowywaniem transkrypcji, a następnie opracowywał podsumowanie na podstawie dostępnego zapisu spotkania. To znacznie ułatwiło mi dalszą pracę. Przypominam, że to jak przygotowane są dane, ma kluczowe znaczenie dla efektów działania modelu językowego. Co to znaczy? Jak wrzucasz źle opracowane śmieci, to na koniec dostaniesz więcej śmieci.

Cyfrowy zespół do spraw spotkań

Zanim usiadłem ponownie do pracy, postanowiłem rozpisać jakie akcje mnie interesują, co dokładnie chcę osiągnąć. Chcę tworzyć podsumowania spotkania na podstawie skompresowanej treści transkrypcji, zestawienia podjętych decyzji oraz spis akcji, które należy podjąć w kolejnym sprincie. Są to czynności, które wykonuję pod każdym, cotygodniowym, spotkaniu, aby wiedzieć, w jakim kierunku zmierzają projekty, jakimi się opiekuję. Czy to zadanie jest zbyt trudne dla modelu językowego? W końcu one halucynują, mylą się, to niebezpieczne, aby je wykorzystywać do czegoś tak ważnego. Jeśli właśnie nawiedziły cię takie myśli, to czytaj dalej.

Agenci

Zacząłem od zdefiniowania agentów, którzy mają brać udział w opracowywaniu wcześniej wymienionych akcji. Tak wygląda przykładowa persona:

  • Zadaniem pól dotyczących roli, celu oraz historii osoby, jest utworzenie agenta, który będzie skupiony na określonych czynnościach w ramach uruchomionego procesu. Modele językowe rewelacyjnie radzą sobie z wchodzenie w zdefiniowane role.
  • W agencie należy wybrać model, z jakiego będzie korzystał. To jest bardzo istotne z perspektywy kosztów oraz zadań, jakie ma realizować. Czasem warto wykorzystać GPT 3.5 Turbo, które jest znacznie tańsze od GPT 4, a, w określonym przypadku, może dawać podobne wyniki. To trzeba przetestować i lepiej zrobić to w ramach izolowanych akcji niż z użyciem procesu opracowanego w CrewAI.
  • Narzędzia to jedna z niezwykle interesujących cech agentów. Ten z przykładu ma dostęp do konkretnego katalogu, potrafi czytać pliki w nim zawarte, a także wykorzystywać similarity search w bazie wektorowej. Dzisiaj zostawiam ten termin wytłumaczony tylko za pomocą linku, myślę, że wrócę do niego z bardziej rozbudowanym przykładem.
  • Ustawiam verbose na True, aby widzieć kroki, jakie wykonuje agent. Dzięki temu wiem, jak wyglądała jego droga do zakończenia konkretnego zadania.
  • Pola memory oraz cache nie oznaczają tego samego! CrewAI oferuje możliwość automatycznego tworzenia bazy danych, która przyjmuje formę pamięci, z jakiej korzystają agenci. Co oznacza, że mój cyfrowy zespół, wraz z przygotowywaniem kolejnych podsumowań, będzie wiedział coraz więcej na temat moich projektów. Baza jest przechowywana lokalnie na dysku. Cache to wyniki działań wykorzystanych narzędzi, ale w obrębie odpalonego procesu.
  • Pola allow_delegationoraz max_iter sprawiły, że przyszło mi słono zapłacić za pierwsze testy CrewAI. Agent może delegować zadania do innych agentów, co, w moim przypadku, sprawiło, że zaczęli się przerzucać obowiązkiem stworzenia podsumowania. Ciągle potrzebowali od siebie jakieś nowych wiadomości, w efekcie, zamiast skoncentrować się na zadaniu, zaczęli zmierzać donikąd. Pole max_iter określa maksymalną liczbę interakcji, po jakich agent zostanie zmuszony do udzielenia odpowiedzi. Domyślnie jest ustawione na 25, co też wpłynęło na koszty mojego testu w momencie, gdy agenci zaczęli się przerzucać odpowiedzialnością.

Zadania

Agenci muszą coś robić. Tak prezentuje się przykładowe zadanie:

  • Każde zadanie musi posiadać opis oraz przypisanego agenta. Na przykładzie za opracowanie decyzji odpowiedzialny jest project manager.
  • Zadanie musi być zrealizowane w określony sposób. Lista, podsumowanie mające maksymalnie 300 słów — to jest pole, w którym to definiujesz.
  • Chcesz, aby agent ukończył zadanie i jego efekt zapisał do pliku? Musisz uzupełnić pole output_file. Nie zawsze możesz tego potrzebować. Efekty zadań i tak trafiają do cache’u w trakcie wykonywanego procesu, a sam agent może postanowić, aby realizacja trafiła też do pamięci.

Realizacja

Przed wyruszeniem w drogę, należy zebrać drużynę:

  • W przykładzie celowo wyciągnąłem pole share_crew. Jeśli ustawisz je na True, to wynik pracy agentów oraz to jak zostali skonfigurowani, zostanie przesłani do zespołu odpowiedzialnego za CrewAI. To pole jest opcjonalne, ja je pomijam, a jak mam bardziej paranoiczny moment, to ustawiam je na False.
  • Proces, w jakim działa cyfrowy zespół, możesz zdefiniować. Ja używam Process. hierarchical, co oznacza, że agenci działają w hierarchii, a ich wyniki analizuje manager. W moim przykładzie jest nim ChatOpenAI(model="gpt-4-turbo"), ten element obsługuje pole manager_llm. Jest to agent weryfikujący wyniki, nie zawsze warto z niego korzystać. Czasem wystarcza sekwencyjny proces, czyli wykonanie akcji w zdefiniowanej kolejności. Ja zdecydowałem się na hierarchię, ponieważ zależało mi na ekstrakcji celów na sprint na podstawie podsumowania oraz decyzji. Potrzebny był agent, który zweryfikuje wyniki, aby nie doszło do sytuacji, w której otrzymam śmieci, bo punktem wyjścia był stos źle poukładanych informacji.

Efekty pracy agentów

Po przeanalizowanie tego, co przygotował mój cyfrowy zespół, stwierdzam, że materiał wyjściowy jest na tyle dobry, aby trafić do dokumentacji firmy. Trzymali się tematu, korzystali z udostępnionych informacji, nawet poprawnie przypisali osoby, o których mówiłem w trakcie spotkania. Podobnie jest z decyzjami. Czy halucynacje były problemem? Nie, agenci bardzo dobrze trzymali się dostarczonego im kontekstu i nie wymyślali. Musiałem wprowadzić pewne poprawki, dookreślić dosłownie kilka elementów. Agenci nie posiadali pełnej wiedzy na temat projektów, dysponowali tylko i wyłącznie informacji z jednego spotkania, stąd wzięło się parę nieścisłości.

Jednak nie było to nic krytycznego. Wśród opisanych decyzji, była także ładnie podsumowania strategia dotycząca wydania naszej gry „Pocket Waifu: Rekindled”. Zgodna z tym, o czym mówiliśmy na spotkaniu, miała nawet przypisany poprawny priorytet. Tak samo było z tematami związanymi z zarządzaniem społecznością. Po pierwszym uruchomieniu widzę, że ten zestaw agentów znacznie ułatwi mi pracę. Szczególe tę związaną z przygotowywaniem podsumowań po spotkaniach oraz kontrolą podjętych decyzji. Umożliwia mi to skupienie się na innych aspektach opieki nad projektami, bo nie muszę przesłuchiwać nagrań i porównywać ich z moimi notatkami.

Czy da się to zbudować w Make? Pewnie tak, po prostu będzie wymagała wiele pracy, ale sądzę, że jest możliwe osiągnięcie podobnych wyników. Trzeba się tylko liczyć z tym, że konieczne może być powiązane ze sobą kilku scenariuszy i przekazywanie danych pomiędzy nimi.

##Na koniec udostępniam link do przykładowego kodu, który realizuje to, co opisałem w tekście. Nie musisz korzystać z LangChaina, można go spokojnie zastąpić bezpośrednim zapytaniem do API OpenAI.