Jakub Stankowski – programowanie z AI

O autorze

Jakub Stankowski – programista .NET i Angular od 2018 roku. Pracował nad projektami frontendowymi, backendowymi i fullstackowymi, przestrzegając zasad czystego kodu, DRY i stosując CQRS. Ma również doświadczenie jako trener programowania.

Od 2023 roku intensywnie pracuje z Claude AI oraz metodą Spec-Driven Development (SDD) – produkcyjnym workflow do pracy z AI opartym na zasadzie: najpierw specyfikacja, potem implementacja. Na ProgramujZAI.pl dzieli się praktyczną wiedzą o tym, jak programować z AI bez chaosu w kodzie.

Poznaj Jakuba →

Refaktoryzacja kodu z AI jest bezpieczna tylko wtedy, gdy agent nie zgaduje, co robi stary system. Najpierw zamrażasz obecne zachowanie testami charakteryzacyjnymi. Potem spisujesz je w specyfikacji. Dopiero na końcu agent przepisuje kod małymi krokami, a Ty recenzujesz każdy diff. Ta kolejność zamienia ryzykowne przepisywanie w serię małych, sprawdzalnych zmian. Bez niej AI szybko i pewnie wprowadzi błędy, których nikt nie zauważy.

Najważniejsze informacje

  • Nie zaczynaj od przepisywania. Zacznij od testów, które opisują obecne zachowanie, łącznie z błędami.
  • Testy charakteryzacyjne mówią, co kod robi, a nie co powinien robić.
  • Specyfikacja zachowania to kontrakt, którego agent nie może złamać.
  • Jeden krok = jeden diff = jedna recenzja. Testy muszą przejść po każdej zmianie.
  • Duże systemy wymieniaj stopniowo, wzorcem strangler fig, a nie jednym wielkim przepisaniem.

AI psuje legacy, gdy nie zna obecnego zachowania

Agent AI nie wie, które dziwactwa starego kodu są błędem, a które celową logiką biznesową. Widzi funkcję na 400 linii i chce ją uporządkować. Przy okazji „naprawia” warunek, od którego zależy raport księgowy.

Legacy ma trzy cechy, które utrudniają pracę z AI:

  • Brak testów. Nie ma czym sprawdzić, czy zmiana coś zepsuła.
  • Brak dokumentacji. Wiedza siedzi w głowach osób, które dawno odeszły.
  • Ukryte zależności. Inne systemy polegają na zachowaniu, którego nikt nie spisał.

Michael Feathers w książce Working Effectively with Legacy Code definiuje legacy jako kod bez testów. To nadal najlepsza definicja. Kod bez testów to kod, którego nie możesz bezpiecznie zmienić, niezależnie od tego, kto go zmienia.

Agent przyspiesza pisanie. Nie przyspiesza zrozumienia, chyba że dasz mu twarde punkty odniesienia. Dlatego pierwszy krok nie dotyczy kodu produkcyjnego.

Testy charakteryzacyjne zamrażają to, co działa dziś

Test charakteryzacyjny zapisuje faktyczne zachowanie kodu. Nie ocenia, czy jest poprawne. Jeśli funkcja zwraca błędny wynik dla pustej listy, test też tego oczekuje.

Brzmi dziwnie, ale ma sens. Refaktoryzacja z definicji nie zmienia zachowania. Najpierw je zamrażasz, potem zmieniasz strukturę. Naprawianie błędów to osobny etap.

Tu AI pomaga najbardziej. Pisanie takich testów ręcznie jest żmudne. Agent zrobi to w kilka minut:

  1. Wskazujesz moduł i jego publiczne wejścia.
  2. Agent czyta kod i wypisuje ścieżki wykonania: warunki, pętle, przypadki brzegowe.
  3. Generuje dane wejściowe dla każdej ścieżki.
  4. Uruchamia kod i zapisuje faktyczne wyniki jako oczekiwane.
  5. Ty sprawdzasz pokrycie i dopisujesz przypadki z produkcji.

Przykładowe polecenie dla agenta:

Napisz testy charakteryzacyjne dla modułu rozliczeń.
Nie zmieniaj kodu produkcyjnego.
Testy mają opisywać obecne zachowanie, także jeśli wygląda na błąd.
Każde podejrzane zachowanie oznacz komentarzem DO WYJAŚNIENIA.
Po napisaniu uruchom testy i pokaż pokrycie gałęzi.

Ostatnia linijka promptu jest kluczowa. Komentarze „DO WYJAŚNIENIA” to Twoja lista pytań do biznesu. Agent nie decyduje, co jest błędem. Tylko to zgłasza.

Gdy wyniki są złożone, lepiej sprawdzają się testy migawkowe (approval tests). Zapisują cały wynik do pliku i porównują go przy kolejnych uruchomieniach. Więcej o weryfikacji kodu od agenta piszę w artykule o testowaniu kodu wygenerowanego przez AI.

Specyfikacja zachowania zamienia chaos w kontrakt

Testy mówią, co kod robi. Specyfikacja mówi, co ma robić po refaktorze. To serce podejścia Spec Driven Development zastosowanego do starego systemu.

Specyfikacja dla legacy różni się od specyfikacji nowej funkcji. Nie projektujesz od zera. Spisujesz istniejący kontrakt i wskazujesz, co wolno zmienić.

Dobra specyfikacja refaktoru zawiera:

  • Zachowanie do utrzymania — odwołanie do testów charakteryzacyjnych.
  • Cel strukturalny, np. podział modułu na trzy odpowiedzialności.
  • Granice — pliki i interfejsy, których agent nie dotyka.
  • Decyzje o dziwactwach — które zachować, a które naprawić później.
  • Warunek ukończenia, np. komenda testów kończy się sukcesem.

Agent może przygotować pierwszą wersję. Daj mu kod i testy, a poproś o opis zachowania prostym językiem. Potem poprawiasz go Ty. Ostatnie słowo w specyfikacji zawsze należy do człowieka.

Gotowy szablon znajdziesz w poradniku jak napisać dobrą specyfikację dla AI. Typowe pułapki opisuję w tekście o najczęstszych błędach w Spec Driven Development.

Agent refaktoryzuje małymi krokami, Ty recenzujesz każdy diff

Duży refaktor w jednym podejściu to proszenie się o kłopoty. Diff na dwa tysiące linii nikt nie przejrzy uczciwie. Mały diff przejrzysz w pięć minut i naprawdę go zrozumiesz.

Pętla pracy wygląda tak:

  1. Agent proponuje plan refaktoru jako listę małych kroków.
  2. Zatwierdzasz plan lub go skracasz.
  3. Agent wykonuje jeden krok, np. wydzielenie funkcji.
  4. Agent uruchamia testy charakteryzacyjne.
  5. Recenzujesz diff i robisz commit.
  6. Wracasz do punktu 3.

Każdy commit to punkt bezpieczeństwa. Gdy coś pójdzie źle, cofasz jeden krok zamiast całego dnia pracy. W Claude Code ten rytm wymusisz instrukcją w CLAUDE.md i hookiem uruchamiającym testy po każdej edycji. Opisuje to dokumentacja hooków Claude Code.

Dla całych systemów sprawdza się wzorzec strangler fig opisany przez Martina Fowlera. Nowy kod stopniowo przejmuje kolejne funkcje starego. Stary system obumiera kawałek po kawałku, a produkcja działa cały czas.

Przy recenzji patrz na trzy rzeczy: czy diff robi tylko to, co mówi plan, czy agent nie zmienił testów i czy nie pojawiły się nowe zależności. Więcej technik znajdziesz w artykule o code review z AI.

Pięć błędów, które kończą refaktor katastrofą

  • Refaktor i naprawa błędów naraz. Gdy test nie przechodzi, nie wiesz, czy to zamierzona poprawka, czy regresja.
  • Pozwolenie agentowi edytować testy. Agent, który „naprawia” test, żeby przeszedł, unieważnia całą siatkę bezpieczeństwa.
  • Zbyt duży kontekst. Wrzucenie całego monolitu do jednej sesji kończy się zgadywaniem. Pracuj moduł po module.
  • Brak granic w specyfikacji. Agent zmieni publiczne API, bo „tak będzie czyściej”.
  • Ślepe zaufanie zielonym testom. Testy pokrywają tylko znane ścieżki. Logi z produkcji pokażą resztę.

Pierwszy błąd jest najczęstszy. Refaktoryzacja i zmiana zachowania to dwa osobne zadania, nawet jeśli oba robi ten sam agent.

Jak wdrożyć to w praktyce

  1. Wybierz jeden moduł o dużej wartości i umiarkowanym rozmiarze. Nie zaczynaj od najstraszniejszego.
  2. Wygeneruj testy charakteryzacyjne z agentem i dopisz przypadki z produkcji.
  3. Zbierz listę „DO WYJAŚNIENIA” i ustal z biznesem, co jest błędem.
  4. Napisz specyfikację refaktoru z granicami i warunkiem ukończenia.
  5. Dodaj do pliku instrukcji zasadę: agent nie edytuje testów i robi jeden krok naraz.
  6. Refaktoryzuj w pętli: krok, testy, recenzja, commit.
  7. Dopiero potem napraw błędy z listy, każdy jako osobne zadanie z nowym testem.

FAQ

Czy AI może samo zrefaktoryzować stary kod?

Technicznie tak, ale bez testów i specyfikacji to ryzykowne. Agent nie odróżni błędu od celowej logiki biznesowej. Bezpieczny refaktor wymaga człowieka, który zatwierdza plan i recenzuje każdy diff.

Czym są testy charakteryzacyjne?

To testy, które zapisują obecne zachowanie kodu, nawet jeśli jest błędne. Służą jako siatka bezpieczeństwa podczas refaktoryzacji. Pojęcie spopularyzował Michael Feathers.

Jak refaktoryzować legacy code bez testów?

Nie refaktoryzuj kodu bez testów. Najpierw dodaj testy charakteryzacyjne, nawet zgrubne. AI generuje je szybko, więc brak testów nie jest już wymówką.

Czy lepiej przepisać system od zera, czy refaktoryzować?

Zwykle lepiej refaktoryzować stopniowo. Przepisanie od zera gubi wiedzę zaszytą w starym kodzie. Wzorzec strangler fig pozwala wymieniać system kawałek po kawałku bez przestoju.

Który agent AI jest najlepszy do refaktoryzacji?

Przy refaktorze liczy się kontrola nad każdym krokiem, więc dobrze sprawdzają się agenty pracujące interaktywnie, jak Claude Code. Porównanie znajdziesz w artykule Codex vs Claude Code.

Podsumowanie

Refaktoryzacja kodu z AI działa, gdy odwrócisz intuicyjną kolejność. Najpierw testy charakteryzacyjne, potem specyfikacja, na końcu małe kroki z recenzją. AI przyspiesza każdy z tych etapów, ale żadnego nie zastępuje. Dzięki temu nawet kod, którego nikt nie rozumie, da się zmienić bez strachu przed wdrożeniem. Tę samą metodę stosuję przy nowych projektach, co opisuję w artykule o Claude Code i Spec Driven Development.

Chcesz zobaczyć cały proces na prawdziwym kodzie? Subskrybuj mój kanał na YouTube i pobierz darmowy workflow ze strony standev.it/ai-workflow-bonus.


Dodaj komentarz

Twój adres email nie zostanie opublikowany. Wymagane pola są oznaczone *