Parę słów na temat użycia AI podczas pracy (gdzie jako pracę rozumiemy nie tylko kodowanie), aczkolwiek od kodowania zaczniemy, a konkretnie od często ostatniego jego etapu - code review oraz tego, że oddelegowanie tego procesu dla AI może być już lekką przesadą.
Sprawdzanie kodu podczas procesu aktywnej pracy nad nim, jeszcze przed wrzuceniem go na GitHuba w formie PR-a, robione przez AI, w sytuacji gdy AI też ten kod napisało, jest raczej normą. Jeden agent planuje, inny pisze, jeszcze inny sprawdza. Wiele osób tak robi i jest to spoko, sprawdza się w większości przypadków. Gorzej, gdy potem po zakończeniu przez agentów pracy bierzemy to, co zrobili, robimy git push (albo kyrieleison, używamy skilla AI do pushowania, bo po co pushować nie używając tokenów?) zakładamy PR i klikamy request review, bez przejrzenia z myśleniem (swoim). Samo przejrzenie tego jest niestety bardzo problematyczne. Robienie Code Review, a raczej robienie go dobrze, nabrało na znaczeniu bardziej niż kiedykolwiek wcześniej.

Kiedyś (zamierzchłe czasy rok temu i dawniej) jednym z większych problemów programisty mógł być dług technologiczny (raczej nie był głównym, choć bywały projekty, że mogło tak być). Obok tego było dogadywanie się z klientem, rozumienie jego potrzeb, wymyślanie rozwiązań, projektowanie oprogramowania i odpowiadanie na potrzeby jego użytkowników.
Na ogół rzeczy związane z inżynierią oprogramowania najczęściej sprawiały trudności nie w samej inżynierii rozumianej jako problemy technologii, a bardziej w kwestii problemów poznawczych. Zrozumienia co jak działa, jak powinno, jak można to zrobić w najlepszy sposób.
Tego typu problemy nazywa się długiem poznawczym/kognitywnym. Czyli skupiamy się tak bardzo na znalezieniu odpowiedzi, że zapominamy jak znaleźć rzeczywisty problem, jego przyczynę. To zrozumienie, czyli brak tego długu, najczęściej prowadziło do tego, że znajdowane odpowiedzi były najlepsze, najprostsze, a oprogramowanie powstałe przy braku długu poznawczego, było łatwe do utrzymania i rozwinięcia, zmiany itp. Jeśli rozumiemy, na czym polegają problemy, to i wiemy, jak znaleźć odpowiedzi.
Dzisiaj, coraz więcej kodowania, ale i planowania, testowania możemy oddelegować do AI, w większości złożonych przypadków zrobi to szybciej niż my. Gdy robimy to w sposób nieprzemyślany, zostawiamy gdzieś z boku pozyskanie nowej wiedzy projektowej i technologicznej. Oddelegowujemy zrozumienie problemu i znalezienie odpowiedzi dla AI, tym samym tworzymy dług kognitywny, a przy okazji może i technologiczny, bo rozumiemy coraz mniej i coraz trudniej jest zrozumieć, co będzie problemem w przyszłości, a co nie.

Szczególnie narażeni na to jesteśmy, gdy od planowania do review i deploy oddaje się LLM-om i w międzyczasie skacze do kolejnego zadania, albo przeskakuje między nimi w trakcie. Już przed AI, jak ktoś skakał między zadaniami, ticketami, które nie są skończone, powinien wiedzieć, że zmiana kontekstu zbyt często, tworzy sporo problemów. Dla AI jest to trudne, dla nas może i bardziej, bo nie możemy łatwo zrobić
/clear.
Konsekwencje są oczywiste, programista coraz mniej rozumie projekt, rzadziej dostrzega potencjalne problemy, nie rozumie prawdziwych oczekiwań, nie dostrzega najlepszych rozwiązań, traci umiejętności poznawcze w zakresie inżynierii oprogramowania. Możliwości wymyślania rozwiązań, architektury na własną rękę spadają, a więc ostatecznie, napędza błędne koło, gdzie kontynuując używanie AI jako głównego narzędzia pracy, staje się coraz gorszy w obsłudze go jako narzędzia. W rezultacie AI daje coraz gorsze efekty, kosztując coraz więcej, zarówno w kosztach usługi, jak i długów, które tworzy.
Moim zdaniem AI nie zastąpi dobrego inżyniera, ale może sprawić, że będzie ich mniej.
Nawet pisząc dobry kod i dobrze rozwiązując problemy, robiąc je z LLM, możemy stworzyć nowe, nie tylko technologiczne, te stały się o wiele mniej dotkliwe, gdy zrozumienie nowych technologii jest łatwiejsze z AI.

Żeby nie było, że to puste słowa, za takimi zjawiskami są i badania i przykłady. Nie jest to też coś nowego, na co potwierdzenia znajdujemy dopiero dzisiaj i dopiero z AI. Najpopularniejszy jest z GPS-em.
Jak wyszły GPS dostępne w kieszeni, a i nawet przed tym, jak każdy telefon to miał, mieliśmy bardzo podobne zjawisko, które do dziś można łatwo zaobserwować.
Ktoś regularnie korzystający z Google Maps itp. ma wyraźnie gorszą pamięć przestrzenną i zdolności poznawcze związane z mapowaniem zależne od hipokampu w porównaniu z osobami, które nawigują przy użyciu map lub po prostu doświadczenia, rozglądania się itp. Ktoś, kto często używa GPS-u, ma o wiele gorszą orientację w terenie od kogoś, kto tego nie robi.

Inuici, którzy w młodszych pokoleniach zamienili tradycyjne, trudne, ale pewne umiejętności orientacji w terenie na GPS, mieli z tym masę problemów. Nie potrafili użyć technologii w taki sposób, który nie prowadził do atrofii ich własnych umiejętności, uzależnieni od niej, umierali, gdy znaleźli się w trudnej sytuacji, a technologia była nagle albo niedostępna, albo niewystarczająca.
Nie jest to nic nowego, że technologia coś daje, a coś zabiera, problem zauważalny już od ponad 40 lat, polecam bardzo pracę Borgmanna na ten temat z 1984.

Główna lekcja z tej lektury (dla mnie) to:
Nie przestać zastanawiać się nad szczegółami tego, w jaki sposób osiągamy cel za pomocą środków (technologia, AI w obecnym kontekście), i nigdy po prostu ślepo nie korzystać z urządzeń (używać Linuxa). Wielu ludzi postrzega funkcję nowoczesnej technologii wyłącznie jako środek do osiągnięcia celu. Bardzo złe podejście.
Technology and the Character of Contemporary Life

To samo grozi z AI, jeśli włączasz je do absolutnie każdego elementu pracy, bo możesz, a nie temu, że to akurat w danym momencie dobry pomysł, dobre narzędzie do wykonania pracy przez Ciebie. Pracy, którą rozumiesz i potrafisz SAM uzasadnić.
Nie jest to żaden nowy problem, ale coraz bardziej się nasilający i dostrzegalny. Tutaj pierwszy artykuł z brzegu jak się googluje "AI cognitive debt". Nawet dobry.
How Generative and Agentic AI Shift Concern from Technical Debt to Cognitive Debt
Przykład z projektu gdzie pracuję i jestem jako tech lead swojego zespołu: dostaję powiadomienie na GH "Józio (anonim) has requested your review". Nic nowego, bo wszystko, co mergowane musi mieć approve. Wchodzę w PR, czytam ticket. Brzmi prościutko, 1h może 2 (bez AI) i tak też wycenione (1 story point). Trzeba dodać jeden event handler, jedną komendą, jeden command handler. Do tego są dwa testy. Bardzo proste rzeczy, bo wszystkie te wspomniane to absolutna baza projektu (CQRS, Rails Event Store). Mamy takich rzeczy setki i dev, który to wystawił, robił to już dziesiątki, może i setki razy, bo w projekcie jest dłużej ode mnie.
Patrzę a tam:
- Wszystkie testy czerwone (6500) - znalezienie przyczyny zajmuje mniej niż 1s bo jest ta sama dla każdego testu, zły import command busa, czyli tego, czym odpalamy komendy. To samo jest robione w projekcie setki razy w setkach innych plików.
- Nie ma komendy ani jej handlera. Event handler robi rzeczy, które w CQRS robią komendy. Pierwsza taka instancja w projekcie (jak się okazało druga, bo jak byłem chory ten sam developer przepchnął to samo jak mnie nie było, ale to już oddzielna rozmowa).
- Test mockuje WSZYSTKO.
- Każdy commit co-authored albo authored by Claude.
- Opis PR-a na 30 linijek, informacji tłumaczących cokolwiek co zostało zepsute brak, tłumaczących łamanie konwencji brak. Tylko bezsensowne objaśnienia tego co widać gołym okiem klikając zakładkę "files changed".
Nie jest to pierwszy taki przypadek i nie jest to jedyny developer który wycina mi takie numery. Jako lead muszę się z tym męczyć i X razy tłumaczyć te same rzeczy. Jest to męczące i smutne, bo staram się ich czegoś uczyć, a widzę tylko jak ich poziom jako programistów i inżynierów spada.


Jak więc redukować ten dług poznawczy? Jak nie pozwolić by technologia przejęła nasze umiejętności, tak jak potworasy ukradły talenty zawodnikom NBA?
Wyżej wymieniona książka (Technology and the Character of Contemporary Life) ma niezłe rady na poziomie filozoficznym, także polecam, ja się podzielę tym co stosuję wobec siebie, może komuś pomoże to samo.
Do tego wszystkiego oczywiście dochodzi po prostu nie robienie tego co wyżej opisałem jako złe.
Wraz z przyspieszeniem procesu rozwoju i produkcji kodu staram się zwolnić tempo w innych obszarach, które wcześniej często wymagały pośpiechu (a może po prostu musiały być szybkie), aby nadrobić czasochłonne kodowanie. Oznacza to, że poświęcam więcej czasu na planowanie, przeglądanie i testowanie. Dzięki temu zapoznaję się z tym, co tworzymy ja i inni.
Kod jest tani w pisaniu, ale nie w zrozumieniu.
Wcześniej programowanie polegało w 80% na czytaniu, a w 20% na pisaniu kodu. Teraz jest to raczej 90-10 (dla niektórych może to inaczej wyglądać, jeśli chodzi pisanie samemu, ale właśnie o te 10% jest walka). Kiedy zarówno czytanie, jak i pisanie schodzą na dalszy plan na rzecz AI, moim zdaniem jest to złe i powoduje wzrost długu poznawczego.
Na razie uważam, że większość pracy pozostaje taka sama, ale można skupić się na innych rzeczach, aby osiągnąć te same wyniki – zazwyczaj szybciej, ale szybkość rozwoju nigdy nie była głównym czynnikiem/miernikiem dobrego oprogramowania. Ilość linijek kodu wypluwanych dziennie nie równa się zwiększonej wartości biznesowej, tak jak 100% pokrycia testami nie oznacza, że wszystko mamy przetestowane (nawet nie przetestowane dobrze, po prostu przetestowane, mutant się kłania).
Spędzam więcej czasu na czytaniu kodu niż wcześniej, więcej czasu na ręcznym testowaniu.
Kwestionowanie wstępnych rozwiązań też jest przydatne. Jeśli kod jest tani i szybki w produkcji, warto nie zgadzać się z pierwszym rozwiązaniem zaproponowanym przez AI, nawet po planowaniu i tym wszystkim, żeby sprawdzić niektóre pomysły i upewnić się, że rozumiemy, co tworzymy (żeby krytykować, trzeba rozumieć, co się krytykuje).
Więc w skrócie:
- Zwolnij tempo przeglądu architektury, zrób to dwa razy.
- Nigdy nie oddawaj czegoś do Code Review bez pełnego zrozumienia kodu samemu.
- Więcej testów, w tym ręcznych (myślę, że obecnie QA jest też bardziej wartościową rolą, bo to osoba która procesy i problemy musi rozumieć bardzo dobrze i mieć na nie krytyczne spojrzenie).
- Poświęć więcej czasu na przegląd kodu (własnego i innych PR).
- Nie zgadzaj się i kwestionuj AI częściej, często tylko dla samej zasady. Mając dobre guardy przeciw temu, żeby Twój AI nie był "Yes-man" może to mieć bardzo dobre efekty. Zapytaj siebie: jak byś to zrobił? Dlaczego Claude wybrał takie podejście? Jakie są wady? Przedstaw to mu i zobacz (tylko, no trzeba mieć dobrze zsetupowanego Claude’a/AI żeby też nie zgadzał się z każdą krytyką).
- Uważam również, że ważne jest, aby nadal ćwiczyć kodowanie samodzielnie, bez AI. Mam własne pet-projekty, w których to robię, i staram się, aby były one jak najbardziej odmienne od tego, czym zajmuję się w pracy. AI tam używam tylko do lepszego zrozumienia, np. nowego dla mnie języka.
I to tyle. Mam nadzieję, że da to komuś coś do myślenia, pomoże wam nie tyle co pozostać na poziomie, ale i się rozwijać. To trudny temat, ale i bardzo ciekawy, w zasadzie wchodzimy tu na grunty niegdyś dostępne tylko w science-fiction, więc jeśli ktoś się nie zgadza, ma coś do dodania, zapraszam do dyskusji.