Projekt harnesa związanego z event stormingiem, został zakończony.
Uznałem, że nie ma sensu go kontynuować, nie panuje nad zmianą, rozrósł się do niebotycznych rozmiarów. Doświadczenia przy nim zebrane pchnęły mnie w objęcia nowego projektu, tym razem harness do refaktoryzacji.
Bogatszy o poprzednie doświadczenia, i potrzebę chwili rozpocząłem generowanie nowego projektu. Tym razem postanowiłem wziąć na warsztat temat pracy z legacy kodem, który intensywnie eksploatuje od jakiegoś czasu. Potrzebowałem ustrukturyzować i zautomatyzować kroki, które są potrzebne do bezpiecznej zmiany.
Wersje
Aktualnie mam wersje trzecią tego projektu.
- Ta wersja to był po prostu skill, w którym zaczołem opisywać zasady w jaki sposób będę podchodził do refaktoru.
- W tej wersji wprowadziłem orkiestratora, bo się skill rozrósł i naturalnie poszedłem w kierunku harnessa.
- Tutaj aktualnie jestem, wprowadziłem opcje testowania - jeszcze nie przetestowana.
Oczywiście to nie koniec, pomysły mam kolejne ale muszę się powstrzymywać bo te pomysły w poprzednim projekcie spowodowały jego niepokojący rozrost.
Krótki opis tego co mam.
Całość to jest pięć plików:
- orkiestrator - zarządca niewolników,
- etap 0 - ten etap jest od sprawdzenia czy harness był już uruchamiany,
- etap 1 - etap analizy i wprowadzania testów
- etap 2 - etap właściwej zmiany
- etap 3 - niegotowy/niezaimplementowany
Szczegółowy opis
Ten mój mały harness opisuje podejście do refaktoru, na początek kierowałem się bardziej Feathrsem i to jego podejście było główną przyczyną do tego żeby to powstało, ale później uznałem, że LLM ma też kierować się innymi "wielkimi", także są tam jakby cztery konteksty w których się ma poruszać.
Uznałem, że ten harness w pierwszym etapie swojego istnienia będzie działał w oparciu o decyzje użytkownika. Dlaczego tak a nie automatycznie jak we wcześniejszym projekcie? To ze względu na to że nie ufam LLM-om, nadmiar zmian jest nie doogranięcia (przeze mnie) więc uznałem że na razie nie będzie automatu póki nie napiszę jakieś sensownej weryfikacji zmian to weryfikował to będzie człowiek.
Twarda zasada jest taka, że nie ma komitowania, uruchamiania przez AI to człowiek musi robić.
Etap 0
Podstawą działania tego harnesa jest wznowienie pracy po np wyczyszczeniu kontekstu co jest też kolejną podstawą w tym projekcie, tych podstaw to będzie kilka, może filar to lepsze słowo.
No to podstawowe założenie, to jedno z nich właśnie takie, że harness ma działać po tym jak z jakiegoś powodu zakończy, przerwie działanie ma wznowić w tym samym miejscu. Od tego jest etap 0 żeby to zweryfikować. W wersji 3 weszły jeszcze testy wiec etap 0 oprócz normalnego odpalania bada czy był też test uruchamiany.
Ten etap wykonuje agent, żeby nie marnować cennego kontekstu. Wynikiem jest json i tylko tyle. Orkiestrator otrzymuje wiadomość czy kontynuować sesje czy robić od nowa całą konfigurację. Etap 0 sprawdza też plik refactor-session.md który zapisuje start poprzedniej sesji jeżeli jest więcej niż godzina różnicy orkiestrator nie kontynuuje sesji, zaczyna nową. Ten warunek nie jest jeszcze definitywny, na razie taki czas jest ustawiony na podstawie testów będzie go można zmienić. Mam też taki pomysł żeby dodać plik konfiguracji do harnesa z opcjami, które wpłyną na zmianę zachowania, bez potrzeby ingerencji w defincje samego projektu. Ale to w późniejszych wersjach.
Orkiestrator
Nim przejdę do etapu pierwszego słów kilka o orkiestratorze, tym razem zarządca niewolników pełni inna rolę, tylko zarządza, a przynajmniej na razie tak mu się wydaje. We wcześniejszym projekcie orkiestrator miał znacznie szersze kompetencje, on sterował procesem i był pośrednikiem między różnymi etapami, przygotowywał informacje i przekazywał różnym etapom. Tym razem jest inaczej z powodu specyfiki tematu nie potrzebuje poprzez orkiestratora przekazywać informacji, etapy z definicji działają w izolacji, wyniki jest dostępny w kodzie, bo na kodzie poszczególne etapy bazują, żerują.
Wracając do miszcza ceremoni, orkiestrator bardziej skupia się na zarządzaniu, czyli po odpowiedzi z etapu 0 następuje konfiguracja czyli użytkownik musi odpowiedzieć na kilka pytań, co orkiestrator skrzętnie zapisuje i pamięta, oraz przesyła do poszczególnych etapów.
Dlaczego tak, ponieważ zauważyłem, że czasami mi się konfiguracja traciła i co jakiś czas muszę przypominać ją jak pracuje z LLM-em. Teraz konfiguracja jest w pliku i jest przekazywana do etapu, po za tym orkiestrator ma ją zapamiętać w swoim kontekście i po zakończeniu każdego etapu sprawdzić czy to co zapamiętał zgadza się ze stanem zapisanym w pliku, to takie zabezpieczenie na wypadek wystąpienia "piątek kolumny". Jeżeli coś takiego wystąpi to jest to sygnał na natychmiastowe przerwanie działania harnessa, dla mnie to kritikal error.
Orkiestrator ma jeszcze kilka dodatkowych funkcji, może np przełączyć etap drugi na pierwszy jeżeli dostanie takiego requesta, np zaistniał refaktor albo zmiana w kodzie i trzeba zmienić testy, a testami zajmuje się etap 1 nie 2, więc idzie request do orkiestratora który go przepycha do etapu 1.
Ogólne funkcje orkiestratora:
- inicjuje cały proces - co sobie omówiliśmy,
- ustala tryb uruchomienia - normalny czy test, - o tym później, bo się tworzy dopiero,
- przekazuje plik konfiguracji - o tym wspominałem
- czuwa w trakcie trwania - o tym wspominałem przy okazji requestów z etapów,
- pilnuje integralności - sprawdzanie konfiga,
- pilnuje poprawnego wykonania etapów, o tym potem,
- prowadzi log - tu za bardzo nie ma co omawiać
Co też istotne, wspominałem o tym to, że ja chcę bazować na częstym resetowaniu kontekstu, czyli jeżeli chodzi o clude code, to funkcja /clear. Z tego co wiem to nie da się jej wywołać automatycznie więc na razie jest prośba o ręczne wykonanie tej metody i póki co monit o to nie będzie powiązany ze zużyciem. Na tę chwilę pomysł jest taki żeby po każdej iteracji (o tym przy omawianu etapu 1) wysłać monit o reset. Dlatego tak istotne żeby pamiętać stan i decyzje, po takim resecie wykona się etap 0.
Poprzedni projekt też miał takie zabezpieczenia, znaczy takie które pozwalały wrócić, do kontekstu.
Teraz jednak chciałbym to bardziej rozbudować, pomysł jest taki żeby nad orkiestratorem wprowadzić jeszcze jednego zarządce, a sam orkiestrator pracował by jako agent, czyli wykonał by zadanie i zwolnił zasoby, ale to będzie wymagało doprecyzowania i jakiegoś planu, to w kolejnych wersjach.
Przy okazji wspomnę że zmiany w projekcie też powstają inaczej niż w poprzedniej wersji, są dwa pliki changes.md i changes-test.md. Pliki te służą za wprowadzenie moich pomysłów i realizacje ich przez Klaudiusza, są też swoistą historią, tego jak to powstawało, oprócz gita.
Na razie tyle o orkiestratorze, nadmienię że jest on dość obszerny już, jak w poprzedniej wersji.
Etap 1.
Etap tworzenia testów, przygotowania kodu, na przyjęcie testów. Z tym kodem z którym ja mam styczność bywa różnie ale znacząca większość nie pozwala uruchomić testów, więc trzeba zadbać żeby się dało. Od tego jest ten etap, przygotowanie kodu do utworzenia testów, ale bez jego modyfikacji, czyli minimalna zmiana. Coś takiego właśnie pokazywał Michael Feathers w swojej książce.
Szczegóły
Komunikacja odbywa się za pomocą json, czyli na wejściu i wyjściu generowany jest odpowiedni komunikat, nie przekazuje stanu etapu, tylko polecenie lub info o zakończeniu.
Ten etap pracuje w pętli analiza - implementacja, ale każda faza zaczyna się od wczytania pliku z konfiguracją. Tak jak wspominałem to jest zabezpieczenie, przed tym, że LLM zapomni co zostało we wstępnej fazie ustalone.
Cykl analiza - implementacja może powtarzać się wielokrotnie ale może też być tylko raz, analizę zatwierdza człowiek. W późniejszych wersjach chcę to zrobić też w pełni automatycznie ale nim to będzie tak działać potrzebuje testów i czegoś co pozwoli mi zweryfikować poprawność wyniku, teraz jeszcze nie mam tego, na razie jest człowiek. Implementacja będzie mogła być robiona przez słabsze modele jeżeli będzie ona dobrze zrobiona, na razie też jeszcze tego nie ma.
Ogólnie etap dzieli się na kroki:
- ocena testowalności,
- identyfikacja zależności blokujących testy,
- propozycja minimalnego odsprzęgnięcia,
- gdy odprzęgnięcie nie jest możliwe:
- zakończenie działania,
- zakończenie z decyzją użytkownika,
- opakowanie dodatkową abstrakcja,
- pytanie o kierunek zmian
- napisanie testu - obecnego kodu,
- wydzielenie dużych metod - w zależności od ilości kodu którego obejmuje refaktor,
- sprawdzenie wyniku przez użytkownika
W tym etapie znajduje się również opis tego co wspominałem wcześniej czyli przykładu że etap drugi potrzebuje zmiany testu. Ja przyjąłem warunek że tylko etap 1 zmienia piszę, zmienia testy, etap kolejny będzie puszczał requesta z monitem zmiany, szczegóły są opisane właśnie w etapie 1 w sekcji Tryb zadaniowy.
Etap pierwszy ma również opis loga, co jest istotne gdyż dzięki temu można stwierdzić co zastało zrobione, liczę też że dzięki temu będzie możliwe wznowienie po przerwaniu procesu.
Ogólnie pracę nad etapami wciąż trwają, coś poprawiam coś dodaje więc ta wersja nie jest ostateczna, a testy mogą przynieść weryfikacje w poszczególnych punktach.
Etap 2
Ten etap jest uruchamiany przez orkiestratora, użytkownik akceptuje etap pierwszy. Ten etap to konkretne zmiany, mamy testy jesteśmy bezpieczni.
Ten etap docelowo będzie miał dwie funkcje zmiana funkcjonalności i refaktor, oraz sam refaktor. Na razie zaimplementowana jest opcja druga tylko refaktor, ale nie przetestowana.
Wariant refaktor składa się z kilku kroków, opisałem je według moich wytycznych, w późniejszych wersjach będzie można je zmienić i wpisać swoje.
- czytelność (nazewnictwo),
- magic numbery,
- przerwanie zależności
kolejne kroki są jeszcze w budowie, czyli jeszcze nie są zdefiniowane. Cały harnes nie jest skończony, w miarę przechodzenia przez kolejne etapy testów części harnessa będą uzupełniane.
Podsumowanie
Tak jak wspominałem, część etapów jest w budowie, nie wszystko jest zaimplementowane. Aktualnie skupiłem się nad zaimplementowaniem orkiestratora głównych etapów oraz testów narzędzia z możliwością mockowania, tę opcje muszę przetestować i stworzyć system ocenny, scenariusze testowe.
Jak będzie to gotowe to można znowu przejść do rozbudowy poszczególnych etapów.
A w ramach testów samego narzędzia mogę uruchomić etap pierwszy i częściowo drugi, co pozwoli na weryfikacje działania poza trybem testowym.
Na koniec link do repo projektu :
Brak komentarzy:
Prześlij komentarz