Get Shit Done, praca z asystentami AI bez chaosu
Get Shit Done to sposób pracy oparty na prostym spostrzeżeniu: skoro koszt napisania kodu spadł, wąskim gardłem przestało być pisanie, a stało się decydowanie, co napisać, i sprawdzanie, czy powstało to, o co chodziło.
Nazwa sugeruje pośpiech i to jest największe nieporozumienie wokół tego podejścia. Nie chodzi o robienie rzeczy szybciej byle jak, tylko o usunięcie kroków, które przy asystentach przestały mieć sens, i wzmocnienie tych, które nabrały znaczenia.
Co się faktycznie zmieniło
Warto nazwać różnicę konkretnie, bo od tego zależy, które nawyki warto zmienić, a które zostawić.
Napisanie funkcji zajmowało kiedyś dwadzieścia minut, a dziś dwie. Napisanie klasy z testami zajmowało pół dnia, a dziś godzinę. To jest zmiana rzeczywista i mierzalna.
Nie zmieniło się natomiast nic w tym, ile trwa zrozumienie cudzego kodu, ile trwa znalezienie błędu w kodzie, którego nikt nie czytał, i ile kosztuje decyzja architektoniczna podjęta źle.
Wniosek jest przewidywalny: skoro tanieje pisanie, a nie tanieje rozumienie, to proporcja się przesuwa. Kod powstający szybciej niż da się go przejrzeć jest długiem, a nie postępem, i to jest główna pułapka tego okresu.
Właściwe podejście polega więc nie na przyspieszaniu wszystkiego, tylko na przyspieszaniu pisania przy jednoczesnym utrzymaniu tempa przeglądania. Zadanie ma taki rozmiar, żeby dało się przeczytać wynik, a nie taki, na jaki pozwala narzędzie.
Zadanie jako jednostka pracy
Pierwsza zasada dotyczy podziału i jest najważniejsza z całej listy.
Zadanie dobre dla asystenta ma trzy cechy. Da się je opisać w dwóch zdaniach razem z kryterium ukończenia. Dotyka najwyżej kilku plików. Wynik da się przejrzeć w kwadrans.
Zadanie złe wygląda tak: „przepisz moduł płatności na nową architekturę". Asystent coś zrobi, zmiana obejmie trzydzieści plików, a przejrzenie jej zajmie dłużej niż napisanie samodzielnie. Praktycznie nikt tego nie przegląda i wynik trafia do repozytorium na zaufanie.
Podział takiego zadania na siedem mniejszych zajmuje kwadrans i zwraca się natychmiast. Każdy krok da się sprawdzić, każdy da się cofnąć osobno, a gdy trzeci pójdzie źle, nie trzeba wycofywać wszystkiego.
Warto też zauważyć, że mniejsze zadania dają lepsze wyniki same w sobie. Model dostaje węższy kontekst, więc rzadziej trafia obok, a Ty formułujesz polecenie precyzyjniej, bo obejmuje jedną rzecz.
Formułowanie polecenia
Druga zasada dotyczy tego, co piszesz, i jest miejscem, gdzie różnica w skuteczności jest największa.
Opisuj rezultat i ograniczenia, nie kroki. Kolejność ustali narzędzie, a Twoim zadaniem jest ustalić granice.
Anuluj zamowienie.
Rezultat: uzytkownik moze anulowac zamowienie w statusie nowe lub
oplacone. Anulowane zamowienie zwraca srodki i wysyla powiadomienie.
Ograniczenia:
- interfejs OrderService zostaje bez zmian
- testy dopisz w src/orders/orderService.test.ts
- nie ruszaj migracji bazy, kolumna status juz istniejeLista ograniczeń jest tu ważniejsza od opisu rezultatu. Rezultat narzędzie zwykle odgadnie, a granice, których nie wolno przekroczyć, nie wynikają z niczego, co widać w kodzie.
Podawaj kontekst zamiast liczyć, że zostanie odnaleziony. Nazwa pliku, nazwa katalogu albo wklejony kształt obiektu zawężają obszar poszukiwań skuteczniej niż dokładniejszy opis samego zadania.
Zaczynaj od pytania przy nieznanym kodzie. Zapytanie, jak działa fragment, przed zmienianiem go kosztuje grosze i oszczędza cofania zmian opartych na złym założeniu.
Zapisuj polecenia, które zadziałały. Sformułowanie, po którym narzędzie trafiło za pierwszym razem, jest w tym samym repozytorium wielokrotnie użyteczne, a odtwarzanie go z pamięci po dwóch tygodniach zwykle się nie udaje.
## Dodanie pola do zamowienia
Dodaj pole <nazwa> typu <typ> do zamowienia.
Przejdz przez wszystkie warstwy: schemat Prisma, migracja, typ w
src/orders/types.ts, walidacja w src/orders/schema.ts, formularz w
src/app/orders/[id]/edit.tsx. Testy dopisz do istniejacych plikow.
Nie dodawaj nowych zaleznosci.Plik z takimi zapisami obok wytycznych projektu przyspiesza pracę całego zespołu bardziej niż jakiekolwiek ustawienie. Nawiasy ostre w miejscach zmiennych wystarczą, żeby polecenie dało się użyć ponownie bez czytania go w całości.
Weryfikacja, czyli to, co nabrało znaczenia
Trzecia zasada dotyczy sprawdzania i jest tą, którą najczęściej się pomija, bo nie wygląda na postęp.
Testy zmieniają całą dynamikę pracy z asystentem. Narzędzie, które po zmianie uruchamia testy i widzi czerwony wynik, poprawia się samo. Narzędzie bez testów zgłasza gotowość i zostawia Ci sprawdzanie. To jest najtańsza inwestycja w skuteczność, jaka przy tym sposobie pracy istnieje.
Sprawdzanie typów i analiza statyczna działają tak samo: dają natychmiastową informację zwrotną, której model może użyć bez Twojego udziału.
{
"scripts": {
"verify": "pnpm lint && tsc --noEmit && vitest run --reporter=dot"
}
}Jedno polecenie zamiast trzech ma znaczenie praktyczne. Zdanie w wytycznych mówiące „zadanie jest skończone, gdy przechodzi pnpm verify" jest jednoznaczne, a lista trzech osobnych poleceń kończy się uruchomieniem pierwszego z nich. Projekt bez tej warstwy nie jest gotowy na pracę zadaniową, niezależnie od tego, jak dobre jest narzędzie.
Przegląd czytany, a nie przeglądany, to trzeci element. Kod wygenerowany wygląda na dopracowany i to jest jego najbardziej mylące działanie. Obsługa błędów, przypadki brzegowe i zachowanie przy pustych danych to miejsca, w których wygląd rozjeżdża się z zawartością najczęściej.
Praktyczna zasada: jeśli nie masz czasu przeczytać zmiany, nie masz czasu jej wprowadzić. To brzmi surowo i jest jedyną regułą, która chroni przed zamianą tempa w dług.
Sam rozmiar zmiany mówi, czy ta zasada da się jeszcze zastosować.
git diff --stat
git diff -- '*.test.ts' '*.spec.ts'Drugie polecenie warto uruchomić osobno, bo zmiany w testach czyta się inaczej niż zmiany w kodzie. Test dopasowany do implementacji zamiast do wymagania wygląda dokładnie tak samo jak test poprawny i przechodzi tak samo zielono.
Co zostawić z dawnych nawyków
Nie wszystko, co działało wcześniej, straciło sens, i warto to rozróżnić.
Zostaje myślenie o architekturze przed rozpoczęciem. Decyzja, gdzie leży logika biznesowa i jak dzielą się warstwy, kosztuje tyle samo co dawniej, a błąd w niej kosztuje jeszcze więcej, bo kodu opartego na złym założeniu powstaje teraz więcej i szybciej.
Zostają testy, przegląd kodu i kontrola wersji. Zmienia się natomiast ich waga: przy wolnym pisaniu były ubezpieczeniem, przy szybkim są warunkiem koniecznym.
Odchodzi natomiast planowanie szczegółów przed pierwszą linijką. Skoro napisanie wersji roboczej zajmuje kwadrans, dyskusja o kształcie interfejsu w oderwaniu od działającego kodu jest droższa niż zobaczenie go. To jest ta część, w której dawne zasady faktycznie przestały pasować.
Odchodzi też przywiązanie do pierwszej wersji. Przepisanie czegoś, co powstało w godzinę, jest tanie, więc trzymanie się rozwiązania, o którym wiadomo, że jest złe, ma mniej sensu niż kiedyś.
Plik z wytycznymi projektu
Najtańsza rzecz, jaką można zrobić dla jakości wyników, i najczęściej pomijana, bo nie wygląda na pracę.
Asystent widzi kod i wyciąga z niego wnioski, co działa przy projekcie spójnym i zawodzi przy takim, który ma historię. Konwencja, od której odstępowano przez dwa lata, zostanie odczytana jako obie wersje naraz i wynik będzie zależał od tego, na który plik akurat trafi.
Co warto tam zapisać. Używane biblioteki oraz te, których zespół świadomie unika, bo model domyślnie sięgnie po najpopularniejszą, a nie po Waszą. Sposób nazywania plików i funkcji. Gdzie leżą testy i jakim poleceniem się je uruchamia, bo bez tego narzędzie ich nie odpali. Wersję języka i ustawienia kompilatora. Oraz reguły niewynikające z kodu, na przykład że warstwa usług nie sięga bezpośrednio do bazy.
Efekt widać od pierwszego zadania, bo znika najczęstsza kategoria poprawek: kod poprawny technicznie i niepasujący do reszty projektu. Zamiast poprawiać to samo przy każdej zmianie, zapisujesz regułę raz.
Warto ten plik traktować jak kod: trzymać w repozytorium, przeglądać przy zmianach i uzupełniać za każdym razem, gdy poprawiasz coś po raz drugi. Reguła dopisana po drugim wystąpieniu problemu oszczędza trzecie i wszystkie następne.
Praca zespołowa
Kilka rzeczy zmienia się, gdy tego sposobu pracy używa nie jedna osoba, tylko zespół.
Przegląd kodu zyskuje na znaczeniu i traci na oczywistości. Zmiana wygenerowana wygląda na bardziej dopracowaną niż zmiana napisana ręcznie, więc osoba przeglądająca łatwiej ją przepuszcza. Warto to nazwać wprost w zespole, bo świadomość tego zjawiska wystarcza, żeby czytać uważniej.
Ustalcie, co wchodzi do repozytorium. Kod wygenerowany trafia do przeglądu tak samo jak napisany ręcznie, a nie obok niego. Bez tej zasady w projekcie pojawia się warstwa, której nikt nie czytał, i nikt nie wie która.
Wspólny plik z wytycznymi jest tu ważniejszy niż przy pracy w pojedynkę, bo bez niego każda osoba dostaje kod w swoim stylu i projekt rozjeżdża się szybciej, niż ktokolwiek zauważy.
Ostatnia rzecz to oczekiwania. Zespół, który przyjmie, że narzędzie skraca drogę do pierwszej wersji, a nie do wersji gotowej, pracuje spokojniej niż zespół liczący na to, że zadanie zlecone rano będzie wieczorem na produkcji. Ta druga postawa prowadzi do wypuszczania rzeczy nieprzejrzanych, bo termin był ustalony przy założeniu, którego nikt nie sprawdził.
Narzędzia i ich rola w tym układzie
| Narzędzie | Postać | Mocna strona | Rola w tym podejściu |
|---|---|---|---|
| Cursor | Osobny edytor | Kontekst projektu, podpowiadanie | Praca ciągła nad istniejącym kodem |
| Aider | Wiersz poleceń | Niezależność, dowolny model | Zadania zamknięte, commit po każdym |
| Windsurf | Osobny edytor | Agent pracujący zadaniami | Zmiany obejmujące wiele plików |
| Claude | Rozmowa albo terminal | Rozumowanie, długie odpowiedzi | Decyzje projektowe i przegląd |
Wybór narzędzia jest tu najmniej istotną decyzją i warto to powiedzieć wprost, bo pochłania najwięcej rozmów. Wszystkie z powyższych obsługują pracę zadaniową, a różnice w skuteczności są mniejsze niż różnice wynikające z tego, jak formułujesz polecenia i czy masz testy.
Sensowny układ to jedno narzędzie do pracy ciągłej i jedno do zadań zamkniętych, a nie pięć uruchomionych naraz. Zmienianie narzędzia co miesiąc kosztuje więcej niż daje, bo za każdym razem odbudowujesz nawyki.
Warto natomiast rozdzielić role. Rozmowa o tym, jak coś zaprojektować, i wykonanie tego to dwa różne zadania, i przeprowadzenie pierwszego przed drugim zwykle poprawia wynik obu.
Pułapki tempa
Cztery rzeczy, które w tym sposobie pracy psują się najczęściej.
Pierwsza to kod, którego nikt nie przeczytał. Objawia się dopiero przy pierwszym błędzie, gdy okazuje się, że nikt w zespole nie wie, jak ten moduł działa, bo powstał w piętnaście minut i nikt nie miał powodu w niego zaglądać.
Druga to rozjazd konwencji. Każde zadanie wykonane osobno daje kod poprawny i nieco inny, a po trzydziestu zadaniach projekt ma cztery style nazywania i trzy sposoby obsługi błędów. Plik z wytycznymi projektu rozwiązuje to najtaniej.
Trzecia to złudzenie postępu. Liczba zmian rośnie, a produkt stoi w miejscu, bo praca idzie na rzeczy łatwe do zlecenia, a nie na te ważne. Warto raz w tygodniu spojrzeć, co faktycznie posunęło się do przodu, zamiast liczyć wprowadzone zmiany.
Czwarta to długie sesje. Rozmowa prowadzona nad jednym zadaniem przez godzinę niesie ze sobą cały dotychczasowy kontekst, więc rośnie koszt, a skuteczność poprawek spada, bo narzędzie gubi się we własnych wcześniejszych decyzjach. Domknięcie zadania i rozpoczęcie nowego bywa tańsze niż dalsze poprawianie.
Typowe błędy
Pierwszy to zadania obejmujące zbyt wiele plików naraz. Zmiana, której nie da się przejrzeć, trafia do repozytorium bez przeglądu.
Drugi to praca bez testów. Asystent bez informacji zwrotnej z uruchomienia nie ma jak sam się poprawić i przerzuca całe sprawdzanie na Ciebie.
Trzeci to brak pliku z wytycznymi projektu. Bez niego każde zadanie daje kod niezgodny z konwencjami, a Ty poprawiasz to samo w kółko.
Czwarty to uruchamianie narzędzia na brudnym drzewie pracy. Zmiany wprowadzone automatycznie mieszają się z Twoimi i rozdzielenie ich staje się osobnym zadaniem.
Piąty to zlecanie zadań, które szybciej zrobić samemu. Poprawka jednej linijki, którą wiesz jak zrobić, zajmie mniej czasu niż jej opisanie.
Szósty to mylenie tempa z postępem. Trzydzieści zmian w tygodniu przy produkcie stojącym w miejscu to koszt, a nie wynik.
FAQ
Czy to podejście nadaje się do dużych projektów?
Tak, pod warunkiem zachowania rozmiaru zadań. Duży projekt oznacza więcej kontekstu do przekazania, więc wskazywanie plików i utrzymywanie pliku z wytycznymi ma tam większe znaczenie niż w małym. Sama zasada, że zadanie ma być przejrzalne, nie zależy od skali.
Czy AI zastąpi programistę w tym układzie?
Nie w tym, do czego to podejście się sprowadza. Pisanie kodu stanieje, a decydowanie co napisać, ocenianie czy powstało to, o co chodziło, i ponoszenie odpowiedzialności za wynik pozostają po Twojej stronie i to one stały się wąskim gardłem.
Jak pogodzić tempo z jakością?
Przez rozmiar zadania. Zadanie na tyle małe, żeby dało się je przejrzeć w kwadrans, daje jedno i drugie. Zadanie większe daje tempo kosztem jakości, a to jest wymiana, która zwraca się przeciwko Tobie przy pierwszym błędzie w produkcji.
Od czego zacząć, jeśli projekt nie ma testów?
Od dopisania testów do fragmentu, nad którym akurat pracujesz, a nie od pokrycia całości. Narzędzie potrafi je napisać, a Ty zyskujesz natychmiast pętlę zwrotną w tym jednym miejscu i możesz ją rozszerzać przy kolejnych zadaniach.
Które narzędzie wybrać?
Najmniej istotna decyzja z całego zestawu. Cursor, Aider i Windsurf obsługują pracę zadaniową, a różnice między nimi są mniejsze niż różnice wynikające z formułowania poleceń i obecności testów.
Szersze omówienie pracy z modelami znajdziesz w dokumentacji Anthropic, a opis pracy w terminalu na stronie Aidera.