Wujek Bob o fundamentach tworzenia oprogramowania w czasach AI (Uncle Bob on Software Fundamentals in the Age of AI)

2026-08-19 • Matt Pocock • AI zagraniczne •wywiad •waga 4/5 •36 min czytania

Robert C. Martin („Czysty kod") opowiada, jak pracuje z agentami AI: zamiast sterować nimi promptami, ogranicza je automatycznymi sprawdzianami. Konkretne przepisy na potok agentów i to, czego w rzemiośle nie zmieniać.

Robocza publikacja redakcyjna na podstawie publicznego transkryptu YouTube. Źródło: YouTube.

O czym jest ten film

  1. Wywiad na żywo z Robertem C. Martinem — „Wujkiem Bobem”, ponad pół wieku w zawodzie — o rzemiośle programisty w czasach agentów AI.
  2. Anegdotyczne otwarcie: skąd wzięły się „poranne wywody w szlafroku” i jak dwunastolatek programujący rurkami na kołkach stał się autorem „Czystego kodu”.
  3. Zwolennik AI nie od razu: pierwszy agent (wczesny Grok) był szybki, ale niechlujny — i Martin po nim sprzątał, aż przyszło przemyślenie ról.
  4. Techniki zawsze uznawane za słuszne, lecz niepraktyczne z powodu kosztu — analiza CRAP i testowanie mutacyjne — agenty wykonują w minuty, więc wracają do codziennego użycia.
  5. Kluczowa obserwacja: bałagan w kodzie spowalnia i wywija agentów tak samo jak ludzi; agent potrafi wręcz odmówić dalszej pracy.
  6. Zasady wpisane w prompt agenty traktują po macoszemu (zjawisko „lost in the middle”), dlatego prompt startowy trzeba ciąć do minimum, a wymagania przenosić do deterministycznych narzędzi.
  7. Konkretny potok wieloagentowy: specyfikator → koder → czyściciel → hartownik → agent QA; około godziny zamiast pół dnia człowieka, przy wyższej jakości.
  8. Architektura: przesłuchiwanie agentów, własna przeglądarka zależności w stylu UML i plik reguł, którego agenty nie mogą naruszyć; głębokie moduły Johna Ousterhouta idealnie pasują do pracy modeli.
  9. Co się zmienia: progi metryk (wynik CRAP 6–8 zamiast 4) oraz rezygnacja z narzucania agentom ludzkich dyscyplin (np. rygoru TDD) przy zachowaniu ludzkich wartości.
  10. Ciężkie planowanie z góry i moda na „spec-driven development” jako powrót pokusy z lat 70.; edukacja juniorów („odgraj rolę agenta”) i teza, że fundamenty porządkują złożoność — więc wciąż obowiązują.

10 najważniejszych takeaways — z kontekstem zastosowania

1.Wymieniaj instrukcje w prompcie na automatyczne sprawdziany

Na czym polega: Reguły zapisane w plikach typu CLAUDE.md agenty traktują jak wytyczne, którymi można zlekceważyć — długie prompty „gubią się w środku” okna kontekstu. Deterministyczne narzędzia (testy, analizy złożoności, linter reguł architektury) nie znikają z pamięci i nie podlegają negocjacji.

Jak stosować: Skróć prompt startowy do kilku priorytetowych zdań. Każdy błąd, który się powtarza, zamieniaj na sprawdzenie uruchamiane po fakcie, w pętli agenta — a nie na kolejny akapit instrukcji.

Na co uważać: Nadmiar sprawdzianów spowalnia agentów. Jeśli spadną poniżej ludzkiego tempa, cały układ traci sens; pilnuj też, żeby narzędzia nie rzucały fałszywych alarmów, bo agent będzie „łatał” problemy, których nie ma.

2.Bałagan w kodzie dusi agentów tak samo jak ludzi

Na czym polega: Agent zostawia po sobie śmieci. Jeśli ich nie posprzątasz, po kilku zadaniach zaczyna się szamotać: naprawia jedno, psuje drugie, kręci się w kółko, aż w końcu poddaje się — Martin widział agenta, który wprost „odmówił dalszej pracy”.

Jak stosować: Po każdym zadaniu przepuszczaj kod przez osobny etap czyszczenia (analiza jakości, pokrycie testami, przegląd), zanim agent ruszy dalej. Sprzątanie to etap potoku, nie opcja.

Na co uważać: Agent może znosić chaos lepiej niż człowiek, ale jego próg też istnieje. Nie dowierzaj, że „agent sobie poradzi” — najpierw sprawdź, czy kod wciąż jest czytelny.

3.Prompt startowy tnij do minimum

Na czym polega: Początek okna kontekstu to „inteligentna” strefa; dalej uwaga się rozmywa — każdy token krzyczy w coraz bardziej zatłoczonej sali, a sygnał ginie w hałasie. Wszystko, co napiszesz na początku długiego promptu, z czasem i tak spada do „martwego środka”.

Jak stosować: Najważniejsze zasady dawaj na sam początek i maksymalnie zwięźle. Długie dokumenty trzymaj poza kontekstem i podawaj agentowi tylko te fragmenty, których aktualnie potrzebuje.

Na co uważać: Piękny, dziesięciostronicowy „kodeks postępowania” da agentowi złudzenie kontroli u ciebie, ale nie jemu — realną siłą jest to, co da się automatycznie sprawdzić.

4.Dziel robotę na wyspecjalizowane agenty ze świeżym kontekstem

Na czym polega: Potok Martina: specyfikator (scenariusze Gherkin i procedura QA) → koder (testy jednostkowe i implementacja) → czyściciel (analiza CRAP, przegląd) → hartownik (testowanie mutacyjne, bezlitosne) → agent QA (wykonywalny test systemowy). Zadanie, które pojedynczy agent „załatwia” w pięć minut z wątpliwym skutkiem, przechodzi przez ten tor przeszkód w godzinę — człowiek potrzebowałby pół dnia, a jakość wychodzi wyższa niż ludzka.

Jak stosować: Każdy agent dostaje jedno wąskie zadanie i „umiera” po jego wykonaniu; następny startuje z czystym kontekstem. Wyniki pośrednie przekazuj jako pliki, nie jako ciągłe ciągnienie jednej rozmowy.

Na co uważać: Narzut startu i komunikacji rośnie z liczbą węzłów. Nie buduj „stu agentów z własnymi skrzynkami mailowymi” — liczba ról ma wynikać z etapów kontroli jakości, nie z ambicji.

5.Wartości przekazuj, dyscypliny nie narzucaj

Na czym polega: TDD to dyscyplina skrojona pod ludzką pamięć krótkotrwałą: starcza jej na napisanie testu i na doprowadzenie kodu do zielonego. Agent ma pamięć ogromną i idealnie dokładną, więc wymuszanie rytmu „linijka testu — linijka kodu” mija się z celem — i tak wraca do trybu „funkcja, potem jej test”.

Jak stosować: Wymagaj rezultatów (pokrycie, przechodzące testy, metryki jakości), a nie sposobu ich osiągania. Dopuszczaj inne ścieżki prowadzące do tych samych wartości.

Na co uważać: To nie jest zgoda na odpuštěnie jakości — standardy wynikowe zostają bez kompromisów, zmienia się tylko to, którą drogą agent do nich dojdzie.

6.Przesuwaj progi metryk pod agentów

Na czym polega: Agenci mają lepszą pamięć krótkotrwałą niż ludzie, więc znoszą większą złożoność funkcji. Martin podniósł dopuszczalny wynik CRAP z 4 (norma dla człowieka) do 6 i rozważa 8.

Jak stosować: Jeśli automatyczna kontrola złożoności bezsensownie blokuje agentowi pracę, świadomie poluzuj próg i obserwuj dwie rzeczy naraz: jakość wyników i tempo. Kalibruj eksperymentalnie, jedną zmianą naraz.

Na co uważać: Nie podnoś progów „na oko”. Metryka ma chronić system przed utratą czytelności, a nie wygładzać raporty.

7.Nie planuj z góry wszystkiego — koszt zmiany runął

Na czym polega: Ciężkie planowanie z przodu to pokusa znana z lat 70., która doprowadziła do modelu kaskadowego. Agentom, które dostają „idealny plan”, i tak odbija od niego, bo nie przewidziałeś wszystkiego — a poprawianie planu w biegu kosztuje więcej niż iterowanie. Przy koszcie zmiany bliskim zera („dom za dolara”) planowanie z góry jest po prostu drogie.

Jak stosować: Krótkie iteracje: jedna–dwie historyjki, spojrzenie na architekturę, ewentualne ręczne przetasowanie, kolejne historyjki. Specyfikacje traktuj jako ulotne narzędzia rozmowy, nie jako dokument wieczysty.

Na co uważać: Ręczne porządkowanie architektury po iteracjach być może nigdy nie uda się w pełni zautomatyzować — zaplanuj na nie realny czas, zamiast udawać, że zniknie.

8.Pisz głębokie moduły — agent czyta interfejs, nie implementację

Na czym polega: Moduł o małym interfejsie i dużej ukrytej treści pozwala modelowi korzystać z funkcjonalności bez czytania kodu pod spodem. Modele zwracają uwagę na nazwy interfejsów, strukturę zależności i… testy — z nich odczytują, co system robi.

Jak stosować: Kierunek zależności między modułami zapisz w pliku reguł, którego agenci nie mogą naruszyć (a jeśli naruszą — muszą naprawić, np. odwracając zależność). Trzymaj w jednym module jedną spójną tematykę.

Na co uważać: „Nieczytanie implementacji” działa tylko dopóty, dopóki kod jest spójny z interfejsem. Moduł-wysypisko, w którym mieszają się niezwiązane tematy, zepsuje agentowi pracę tak samo jak człowiekowi.

9.Juniorzy: najpierw pisz kod, potem odgraj rolę agenta

Na czym polega: Propozycja Martina ścieżki edukacyjnej: rok samodzielnego pisania kodu, żeby wiedzieć, z czym agent ma do czynienia; potem kilka miesięcy pracy „jak agent” — te same wąskie zadania i te same automatyczne sprawdziany, pod okiem inżyniera prowadzącego rój. Dopiero po przejściu tego toru młody programista dostaje własnego agenta. Fundamenty z „starych” książek (DeMarco, Yourdon, „Pragmatyczny programista”) budują wyczucie poziomu strategicznego.

Jak stosować: Traktuj okres „bycia agentem” jako inwestycję: niby nieproduktywną, ale uczącą rozpoznawać, kiedy system się sypie. Weekend z asemblerem Martina zalega jako szczepionka przeciw złudzeniu, że wyższy poziom abstrakcji to magia.

Na co uważać: Pętla zwrotna przy decyzjach strategicznych jest długa — kto zmienia pracę co pół roku, może nigdy nie zobaczyć skutków własnych błędów. Z agentami pętla się skraca, ale tylko jeśli zostaniesz na tyle, żeby ją zamknąć.

10.Fundamenty to sposób opanowania złożoności — nie wyrzucaj ich

Na czym polega: Oprogramowanie to — za Dijkstrą — najbardziej skomplikowana rzecz, jaką ludzie kiedykolwiek próbowali robić. Fundamenty służą organizowaniu tej złożoności w formę zrozumiałą dla człowieka — a skoro modele są wzorowane na ludziach, również dla nich.

Jak stosować: Przy każdym nowym poziomie abstrakcji (binaria → asembler → kompilator → model) oddziel zasady porządkujące złożoność (zostają) od narzędzi epoki (przechodzą). Zanim coś wyrzucisz, zapytaj, czy za rok nie podniesiesz tego z podłogi i nie strzepniesz kurzu.

Na co uważać: Przekonanie, że „fundamenty już nie mają znaczenia”, kończy się uderzeniem w ścianę: najpierw agent zwalnia i zaczyna się szamotać, dopiero potem projekt pada. Ściana jest — warto o niej pamiętać, zanim się w nią wjedzie.

Redakcyjne tłumaczenie

W szlafroku, gotowy do pojedynku

Matt Pocock: Mam dziś dla was coś wyjątkowego. Gościa, z którym od dawna chciałem porozmawiać — człowieka, który siedzi w oprogramowaniu dłużej, niż ja w ogóle jestem programistą, i który teraz wyraźnie daje o sobie znać w świecie agentów. Na żywo, w szlafroku i gotowy do pojedynku: Wujek Bob. (Informacja dodatkowa: Robert C. Martin, zwany „Wujkiem Bobem” — współautor Manifestu Agile i autor „Czystego kodu”, jednej z najczęściej cytowanych książek o inżynierii oprogramowania.) Bobie, cześć, witaj.

Wujek Bob: Cześć, dziękuję. Miło tu być.

Matt Pocock: Świetnie, że jesteś. Dla widzów, którzy nie znają wątku szlafroka, trzeba go chyba wyjaśnić. Co się tam dzieje i skąd szlafrok stał się tak ważną częścią twojej postaci?

Wujek Bob: Chyba zaczęło się to dwa lata temu. Siedziałem o szóstej rano na ganku, w szlafroku, i rozmyślałem o tym, jaki okropny jest SQL — przez wszystkie te wstrzyknięcia SQL. Nie ma sensu, żeby dostęp do bazy odbywał się językiem tekstowym; pod względem bezpieczeństwa to proszenie się o kłopoty. Wyciągnąłem telefon, nagrałem tyradę — i tak narodził się „poranny wywód w szlafroku”. Podobno ludziom poszło, więc nagrałem kilka kolejnych.

Matt Pocock: Czyli w takim nastroju przychodzisz dziś na rozmowę? To jest ten Wujek Bob: „jest wcześnie, nie piłem jeszcze kawy, nie zawracajcie mi głowy”?

Wujek Bob: Tamten etap mam już za sobą — jest dziesiąta. (śmiech) Jestem dopiero przy pierwszej coli dietetycznej, więc wszystko w porządku.

Matt Pocock: O szóstej rano rozmyślać o SQL… no proszę cię. (śmiech) Widzę zresztą, że dziś zamiast szlafroka koszula polo. Ale do rzeczy: większość moich widzów to programiści, ale nie wszyscy. Jak przedstawić zjawisko zwane Wujkiem Bobem, zwłaszcza nieprogramistom?

Pół wieku w kodzie

Wujek Bob: „Zjawisko”… nie wiem, czy aż tak. Jestem programistą. Bardzo długo — ponad pół wieku. Mój pierwszy program powstał w 1964 roku, kiedy miałem dwanaście lat. Mama kupiła mi na dwunaste urodziny mały model komputera i programowało się go, nakładając białe rurki na kołki. Zasadniczo była to trójbitowa maszyna o skończonej liczbie stanów — ale dwunastolatka mogła to fascynować bez końca.

Matt Pocock: Dwanaście lat. A jak dochodzimy od tego do tego, że pół wieku później Wujek Bob robi swoje?

Wujek Bob: No, trochę więcej niż pół wieku. Po prostu uczyłem się programowania, ile się dało. Ojciec kupił mi książkę o Fortranie, o COBOL-u i o PL/I. Przeczytałem wszystkie. Nie miałem żadnej maszyny, na której dałoby się coś uruchomić, więc pisałem programy na papierze i wykonywałem je w głowie. W wieku szesnastu lat dorobiłem się dorywczo pierwszego zlecenia na kod, a w wieku osiemnastu prawdziwej pracy — i od tamtej pory jestem programistą.

Matt Pocock: Sporo czasu w okopach. I napisałeś dość ważną książkę, sądzę.

Wujek Bob: Kilka. Jedna chyba była ważna — ta jedna wyraźnie „poszła”. (pokazuje książkę) To jest drugie wydanie.

Matt Pocock: „Czysty kod”. Kiedy rozmawiam o dobrych książkach o inżynierii oprogramowania, to właśnie ją najczęściej ktoś mi zwraca jako argument. Niesamowicie popularna, niesamowicie wpływowa. I dlatego chciałem z tobą porozmawiać: wywarłeś ogromny wpływ w czasach przed AI, w erze, w której pracowałeś praktycznie od jej zarania. Jak wyglądają dla ciebie sprawy teraz, gdy AI jest i trzeba się z tym mierzyć?

Czysty kod i zderzenie z agentami

Wujek Bob: Zaskoczyło mnie to jakoś w grudniu zeszłego roku, w okresie świątecznym. Grzebałem sobie… Wcześniej bawiłem się ChatGPT, trochę Grokiem, trochę tym, trochę tamtym — i nie robiło to na mnie wrażenia. Potem przeszedł mnie etap „hmm, może te rzeczy są jednak ciekawsze, niż myślałem”. Zaopatrzyłem się w agenta. Pierwszy był, sądzę, wczesny Grok. Poprosiłem go o kod — wykonał robotę kiepsko, ale kod napisał. Akurat byłem w środku projektu, więc pomyślałem: może mi w nim pomoże. Zacząłem z nim współpracować — i non stop po nim sprzątałem. Zawsze coś nabrudził, zawsze zostawił po sobie jakieś psie kupki. I przyszło mi do głowy: to ciekawe, bo jest szybki — ale frustrujące, bo przez niego ja jestem wolny.

A potem pomyślałem: czekaj no. Skoro jest szybki, to może robić rzeczy, na które mnie nie stać.

Dwie techniki z szuflady wracają do gry

Wujek Bob: Na początku lat dwutysięcznych zdarzyły się dwie innowacje, które mnie wtedy urzekły — dobre pomysły, ale całkowicie niepraktyczne. Pierwsza nazywała się CRAP. (Informacja dodatkowa: Change Risk Analysis and Predictions — wskaźnik łączący pokrycie kodu testami z złożonością cyklomatyczną funkcji w jedną liczbę opisującą, jak słaba jest dana funkcja.) Mierzyłeś pokrycie testami, liczyłeś złożoność cyklomatyczną każdej funkcji, mieszałeś to skomplikowanym wzorem — i wychodził wynik: miara tego, jak do kitu jest funkcja. Pomyślałem: świetny pomysł. Przepuściłem przez to duży projekt, nad którym akurat pracowałem. Rzeczywiście wysypała się kupa słabych funkcji — ale poprawienie każdej z nich, przepisanie testów… pochłonęłoby mnie bez reszty. A projekt działał. Uznałem, że nie mogę sobie na to pozwolić, i odkładałem pomysł na półkę: ciekawe, ale niepraktyczne.

Drugą innowacją było testowanie mutacyjne. To mnie naprawdę zainteresowało, bo działa tak: mały program przechodzi przez kod źródłowy i zmienia znaki — minusy na plusy, „mniejsze niż” na „większe niż”, „równe” na „różne” i tak dalej. Dla każdej takiej zmiany uruchamia całą suitę testów i oczekuje, że testy się wywalą — przecież ktoś naruszył coś istotnego. Jeśli się nie wywalą, mamy mutanta, który przeżył, i trzeba go zlikwidować — czyli dobrać testy tak, by tę zmianę wykrywały.

To samo przepuściłem przez ten projekt, około roku 2000. Musiało to chodzić całą noc, bo suite testowa trwała cztery minuty, a uruchamiałem ją kilkaset razy. Wyłapałem przeżywające mutanty i naprawiłem je — ale znowu: niepraktyczne. Nie dało się tego wpuścić do normalnego procesu budowania.

I siedzę sobie w grudniu — a może już w styczniu — i myślę: czekaj no. Te chłopaki są szybkie, kompletnie nie przeszkadza im, że robota jest nudna, i zrobią, co im się każe. To może: „przepuść CRAP przez wszystko, co właśnie zrobiłeś”. I przepuszczał, a potem sprzątał kod. Patrzę na to i myślę: no, niezłe. „A teraz uruchom testowanie mutacyjne”. Uruchamiał — może zamiast całej nocy zajęło mu to trzydzieści minut — po czym łatał dziury i pilnował, żeby wszystko było pokryte testami. No proszę, pomyślałem. To może być sposób na sprzątanie tych psich kupek. One zostawiają po sobie mnóstwo śmieci i waty — a tu może mieć je sprzątać same.

Poszedłem dalej tą drogą: dokładałem kolejne narzędzia, dalej pracowałem z agentami, aż doszedłem do punktu, w którym robili całkiem niezłą robotę.

Cel: nie patrzeć w kod

Wujek Bob: Dziś moja zasada brzmi: pusczam agentów do pracy, każę im uruchamiać te narzędzia i bardzo się staram doprowadzić do sytuacji, w której w ogóle nie muszę patrzeć w kod. Mogę ufać w to, co robią. Oczywiście na inne sposoby sprawdzam, że kod wciąż trzyma poziom: zaglądam do wyników CRAP i pilnuję, żeby były niskie, od czasu do czasu robię pobieżne przeglądy, mam cały zestaw innych testów. Ale to jest cel. Jeśli te narzędzia są szybkie — a są — i jeśli potrafię je tak ograniczyć, żeby robiły dobrą robotę, to nie będę narzucał im swojej powolności. Nagroda nie polega na tym, że przeglądam kod co do linii. One są szybkie w kodzie, ja jestem wolny. Więc kod zostawiam im, a sam zajmuję się wszystkim dookoła, żeby całość się spinała. Na razie idzie nieźle.

Matt Pocock: Czyli twoim celem jest odsunięcie się od kodu, od ludzkiego przeglądu — zbudowanie wokół niego rusztowania, dzięki któremu sam prawie nie musisz go dotykać, a agent siedzi w możliwie ciasnym kaftanie bezpieczeństwa i nie może zbroić. Chcę wcześniej ruszyć jedno założenie: te „psie kupki”. Dlaczego złemu kodowi trzeba się w ogóle przyglądać? Te narzędzia są takie szybkie — po co całe to rusztowanie? Czy nie można po prostu przepychać do przodu, aż błędy same znikną?

Dlaczego brudny kod dusi również agentów

Wujek Bob: Bardzo wcześnie — właśnie mniej więcej w grudniu — zauważyłem coś takiego: kazałem temu małemu agentowi coś zrobić, zostawiał po sobie bałagan. Zamiast sprzątać, kazałem mu zrobić następne zadanie — bałaganu było jeszcze więcej. Potem następne. I widziałem, jak zwalnia, jak zaczyna mieć trudności. Wpadał w tryb: zmieni jedno, przy okazji zepsuje drugie, musi to naprawić — i przy okazji psuje trzecie. Kręcił się w kółko. Wtedy dotarło do mnie: te agenty mogą być szybkie i całkiem sprytne, ale bałagan w kodzie daje im się tak samo jak ludziom. Może nie dokładnie tak samo — może próg jest w innym miejscu — ale próg istnieje. Kod może się zrobić na tyle niechlujny, że agent przestaje dawać radę: kręci się w miejscu, pogarsza bałagan, aż w końcu odpuszcza. Miałem takie, które się po prostu poddawały. Jeden powiedział mi kiedyś — parafrazuję — „nie daję już rady tego ogarnąć”.

Matt Pocock: Twoją odpowiedzią jest więc pytanie: jak posprzątać ten bajzel. Większość ludzi w tym miejscu zaczyna faszerować agenta instrukcjami. Wlewa wiedzę do agenta implementującego: dopisuje do CLAUDE.md czy agents.md i za każdym razem, gdy zobaczy coś złego, dodaje kolejną regułę. A ty zamiast tego sięgasz po mechanizm deterministyczny — automatyczne sprawdzenia tam, gdzie inni stosują to, co nazywam „sterowaniem”: próbują agenta prowadzić. Czy ty w ogóle sterujesz? Jak to wygląda w twojej głowie?

Wytyczne z promptów kontra narzędzia, których nie da się ignorować

Wujek Bob: Na początku tak, od tego zacząłem. Pierwsze prompty: „tak robi się TDD, tak wygląda czysty kod, taki ma być twój kod, trzymaj się wszystkich reguł”. W końcu powstaje dokument na pięć, dziesięć stron o wszystkich dobrych rzeczach w kodzie. Chyba mogłem im w całości wetknąć książkę. Ale zauważyłem, że agenty — modele, jakkolwiek je nazwać — traktują te zasady jak „kodeks” z Piratów z Karaibów: to raczej wytyczne, którymi czasem się kierują.

Matt Pocock: Muszę się przyznać: dokładnie ta sama metafora przyszła mi do głowy. Cieszę się, że myślimy zgodnie. (śmiech)

Wujek Bob: Tak, i jest ku temu techniczne wytłumaczenie. Zrobiłem trochę — nie dużo, ale trochę — researchu i okazuje się, że istnieje zjawisko zwane „lost in the middle”: gdy w modelu rośnie okno kontekstu, treści z samego początku i z samego końca mają większą wagę niż to, co w środku. Wszystko, co napiszesz na początku długiego promptu, z czasem i tak zostaje zepchnięte w środek. Pierwsze trzy zdania mogą utrzymać się w strefie priorytetów, ale zdanie pięćdziesiąte i osiemdziesiąte przepadają — siedzą gdzieś w środku. A biedny agent próbuje ogarnąć narastający, wciąż narastający kontekst i wyciągnąć z niego rzeczy ważne, a środek dla niego po prostu nie istnieje. Deterministyczne narzędzia w ten sposób nie znikają.

I to jest klucz do agentów — naprawdę trudny do wykonania: zredukować początkowy prompt do absolutnego minimum, żeby jak najwięcej z niego utrzymało się w strefie priorytetów. A dopiero potem dołączyć narzędzia deterministyczne.

Matt Pocock: Zdecydowanie. Nazywam to inteligentną i głupią strefą okna kontekstu — nie mój termin, Dex Hardy’ego; ukradłem go, bo jest znakomity. Zwłaszcza na początku, w pierwszych stu pięćdziesięciu tysiącach tokenów, model jest całkiem bystry. Potem relacje uwagi w transformerze robią się coraz bardziej rozciągnięte, coraz bardziej rozmyte. To jak sala pełna krzyczących ludzi, do której wciąż wchodzą kolejni: sygnał ginie w hałasie. Mnie to w całości gra.

Skoro te sprawdzenia nie trafiają do okna kontekstu tak jak instrukcje sterujące, można je po prostu nakładać warstwami — kolejnymi i kolejnymi. Mocne typy, testy… Czy w automatycznych sprawdzianach istnieje w ogóle „za dużo”?

Czy sprawdzianów może być za dużo?

Wujek Bob: Nad tym właśnie teraz mocno pracuję. Oczywiście taki punkt musi istnieć — w końcu spowolnisz agentów poniżej ludzkiego tempa i wtedy przegrywasz. Ale dopóki utrzymujesz przewagę wydajności nad człowiekiem, jesteś na plusie. Na razie widzę, że mogę uzyskać dwu-, trzy-, czterokrotność. Wciąż idą całkiem szybko.

Sporo ich spowalniam. Gdy używasz narzędzi deterministycznych, tak naprawdę wpuszczasz agenta w pętlę — dziś wszyscy uwielbiają mówić o pętlach. Mówisz mu: „poprawiaj kod, dopóki narzędzie nie powie, że jest dobrze”. I agent kręci się w tej pętli: to poprawić, tamto dorzucić, dołożyć testy, obniżyć złożoność cyklomatyczną, rozciam teną funkcję… Chwila to zajmuje, zanim doprowadzi kod do zgodności. Płacisz więc wydajnością za wyższą jakość — i w pewnym momencie ten handel musi się wyczerpać. Ale jeszcze nie znalazłem tej granicy.

Teraz próbuję zmusić wiele agentów do współpracy i przekazywania sobie pałeczki: jeden coś robi, następny recenzuje, kolejny testuje, kolejny utwardza… Narzut na komunikację jest kosmiczny, a mimo to całość wciąż działa nieporównanie szybciej niż człowiek.

Matt Pocock: Porozmawiajmy o systemach wieloagentowych, bo to mnie fascynuje — i tu, jak sądzę, się rozjedziemy. Zawsze podchodziłem z nieufnością do ludzi, którzy mówią: „zwolniłem cały zespół, mam teraz stu agentów, każdy w innej roli, wszyscy się ze sobą komunikują, mają własne skrzynki mailowe” — i tak dalej. U mnie zawsze działała jedna rzecz, z jednym wyjątkiem: implementacja i recenzja. Zaletą nie jest tu posiadanie dwóch wąsko wyspecjalizowanych agentów, tylko podejście w duchu red-green-refactor: implementator ma napisać test — choćby brzydki — i sprawić, żeby działało; nie musi być pięknie. Potem wchodzi recenzent, który nie musi eksplorować, bo ma już diff od implementatora i dokładnie wie, co ocenia. Można mu wtedy wrzucić znacznie więcej instrukcji, bo jego zadanie jest węższe. Bardzo mnie ciekawi, jak to u ciebie: co robi implementator, co recenzent, kim są ci „hartownicy”? Nie eksperymentowałem z tym. Opowiedz.

Rój: specyfikator, koder, czyściciel, hartownik, agent QA

Wujek Bob: W takim układzie są dwie zalety. Pierwsza: równoległość. Trzech koderów naraz — a mój mały laptop uniesie sporo więcej niż trzech. Druga: gdy zawęzisz agenta do pojedynczego zadania, okno kontekstu masz pod kontrolą i problem „gubienia się w środku” traci na sile. Możesz na górze dopisać kilka reguł więcej — nie dużo, ale kilka — i będą ich raczej przestrzegać. Można też ułożyć system tak, że agent rodzi się, wykonuje zadanie i umiera, a następny startuje z czystym kontekstem. To są zalety. A wady? Czas startu jest spory: agent potrzebuje dziesięciu, piętnastu sekund, żeby w ogóle wystartować, a potem musi od nowa zbudować sobie obraz sytuacji.

Staram się zadania maksymalnie zawężać. Najpierw uruchamiam specyfikatora. Jego rola: wziąć dokument napisany przez człowieka i przerobić go na Gherkina oraz procedurę QA. Gherkin to te „given–when–then”: wysokopoziomowy test akceptacyjny. Procedura QA to w zasadzie test systemowy — przeprowadzasz system przez interfejs użytkownika. Każę mu pisać z ludzkiego punktu widzenia: „Jesteś człowiekiem. Operujesz systemem przez interfejs. Musisz udowodnić, że system działa”. Powstają dwa dokumenty — gherkinowy i QA — i one trafiają do kodera. Koder pisze testy jednostkowe i kod realizujący opisaną historyjkę, a dodatkowo doprowadza do działania scenariusze Gherkina. Kiedy to działa — a koder siedzi nad tym chwilę — pałeczka przechodzi do czyściciela. Czyściciel odpala analizę CRAP i ogólny przegląd kodu: sprząta po implementatorze, bo ten narobił do tego momentu strasznego bałaganu. Z czyściciela idzie się do hartownika. Hartownik odpala testowanie mutacyjne i jest absolutnie bezlitosny: mutuje kod, wymaga stuprocentowego pokrycia, sprawdzi każdy znak równości, każdy „mniejsze niż”… To trwa swoje. Na końcu wychodzi agent QA, który bierze napisany wcześniej dokument, zamienia go w wykonywalny skrypt sterujący systemem i zwraca deterministyczny wynik. Kto przejdzie przez całość, ma całkiem sprawny program.

Odniósłem na tym spore sukcesy. Zadanie, z którym pojedynczy agent poradzi sobie w pięć minut — z wątpliwym skutkiem — przechodzi przez ten tor przeszkód około godziny. Człowiek potrzebowałby na to około pół dnia. Czyli zyskuję cztero-, pięciokrotność produktywności, a jakość jest znacznie wyższa niż to, co człowiek w ogóle zadałby sobie trud włożyć.

Matt Pocock: A przy tym wydajność wydaje się wcześniej, żeby zyskać ją później — inwestycja we własną bazę kodu. Coś, co mnie jeszcze uderzyło: to nie tylko okno kontekstu, które modyfikujesz. Jest coś w rodzaju trajektorii sesji. Jeśli każesz agentowi coś zrobić i poprowadzisz go w określony sposób, wszystko, co nastąpi potem w tej samej sesji, będzie tę trajektorię kontynuować. Raz mu wmówisz „może przetestujmy interfejs” — i za każdym razem będzie testował interfejs, ilekroć cokolwiek zmienisz. Jedyny sposób, żeby zetrzeć trajektorię, to wyczyścić okno kontekstu. Trajektoria implementatora, który ma „po prostu sprawić, że działa”, jest dużo łagodniejsza niż ta, która wymusza stuprocentowe pokrycie. Czy to się mieści w twoim modelu głowy?

Trajektoria kontekstu: kawa i serial

Wujek Bob: Jak najbardziej. To dość znany efekt, widoczny też u ludzi, którzy nie są programistami. Rozmawiasz z modelem o tym, jaka kawa jest najlepsza i jak ją dobrze zaparzyć — miła sobie konwersacja. Obok przechodzi ktoś i gada o najnowszym serialu — i to trafia do okna kontekstu. Ty tego tam nie włożyłeś: włożył to przechodzień. I od tego momentu każda wzmianka o kawie ma coś wspólnego z serialem. Model tego nie rozróżnia. Twoje „trajektorium” jest więc trafnym określeniem: dopóki kierunek, w którym zmierza model, jest niesplątany, dopóki wszystko w kontekście jest spójne, nie dochodzi do tych szalonych halucynacji, z którymi ludzie się zmagają.

Matt Pocock: Albo do zwykłego rozjechania się z zamiarem. Halucynacja zawsze będzie zagrożeniem — to w pewnym sensie ryzyko zaakceptowane. Twoje podejście — ten bieg przez tłocznie agentów okładających się nawzajem bezlitosnymi sprawdzianami — świetnie je wybija z obiegu.

Dobra, o implementacji mówiłeś dużo; jeszcze do niej wrócimy. Interesuje mnie planowanie. Jak myślisz o wewnętrznej strukturze bazy kodu? Dobre testy są dobre, mutacje — super. Ale jeśli masz fatalnie zaprojektowane API, źle pocięte moduły, jak to się ma do automatycznych sprawdzeń? Ile nad tym pracujesz?

Architektura: przeglądarka zależności i plik, którego agent nie złamie

Wujek Bob: Do mniej więcej zeszłego miesiąca robiłem tę część ręcznie. Agenty budowały mi całość, a ja je przesłuchiwałem — ręcznie, ale jednak z ich pomocą: „Jaka tu jest struktura? Jak ten moduł współgra z tamtym? Czym w ogóle są te moduły? Jak się komunikują?”. Pytałem — a potem umierałem ze strachu, bo odpowiedzi były przerażające. Wtedy projektowałem strukturę modułów i mówiłem agentowi: powinny być podzielone tak, a komunikować się tak. Dostawały ode mnie plan implementacji, który realizowały.

To trudny kawałek. Kazałem też agentom zbudować mi przeglądarkę architektury: wyświetlam sobie na ekranie coś w rodzaju diagramu UML — strukturę modułową systemu i przebieg zależności. Klikam moduł i widzę podmoduły; klikam podmoduł i wyskakuje mi kod. Mogę schodzić w dół, jak głęboko chcę, i patrzeć na architekturę na każdym poziomie. Bardzo mi to się przydało.

Złożyłem też kolejne deterministyczne narzędzie, w którym definiuję, który moduł od którego ma zależeć, który nie ma zależeć i jak mają płynąć zależności. Wszystko trafia do małego, ciasnego pliku specyfikacji, którego agenty nie mogą naruszyć. Na końcu działa osobny sprawdzacz: jeśli złamali, muszą jakoś naprawić — zwykle odwracając zależność, wstawiając interfejs albo dzieląc moduł na pół. Dzięki temu moje reguły pozostają nietknięte.

Teraz pracuję nad tym, żeby to zautomatyzować — i, cóż, niewiele mi wychodzi. (śmiech)

Matt Pocock: Jestem w dokładnie tej samej łodzi: dobrze zaprojektowane moduły dają ogromną dźwignię. Wyjaśnij widzom tę dźwignię — dlaczego dobra struktura modułów jest ważna?

Wujek Bob: Argument jest ten sam co przy brudnym i czystym kodzie. Wszystko, co jest dobrze pocięte i ma zdyscyplinowane interfejsy, da się objąć umysłem — bo my, ludzie, dobrze porządkujemy świat na wydzielone przestrzenie. Modele też — być może z innym progiem, tego jeszcze nie wiem. Ale działają znacznie lepiej, gdy mogą skupić się na jednym module i gdy ten moduł ma własną trajektorię — twoim terminem — to znaczy gdy model nie gubi się w tematach zaszytych w środku. Dobra, używam obok siebie słów „model” i „moduł” — żeby było jasne, o czym mówię… (śmiech) …ale to jest istotne. To znowu ta kawa z serialem: jeśli wpychasz do modułu wszystko, co się da, biedny agent zastanawia się: „co ja tu w ogóle robię? jak tu cokolwiek ogarnąć?”. Dobre rozdzielenie działa całkiem nieźle — dokładnie jak u człowieka.

Głębokie moduły

Matt Pocock: Pewnie i z testów wyciągasz wtedy więcej. A skoro już przy tym jesteśmy: jestem wielkim fanem twojej pracy, ale też wielkim fanem Johna Ousterhouta…

Wujek Bob: Kto nie jest, świetny gość. Pewnie masz gdzieś jego książkę.

Matt Pocock: I jego koncepcja głębokich modułów najbardziej mnie fascynuje. Moduły złe to „płytkie”: szeroki interfejs, niewiele ukryte w środku. Głębokie: mały interfejs i dużo treści schowanej pod spodem. I nasuwa mi się, że to idealnie pasuje do modeli — mogą korzystać z interfejsu bez rozumienia implementacji. Czy to gra z twoim podejściem?

(Informacja dodatkowa: John Ousterhout, profesor Stanforda, autor „A Philosophy of Software Design”, w której wprowadza rozróżnienie na moduły płytkie i głębokie.)

Wujek Bob: Zdecydowanie. Modele zwracają uwagę na nazwy interfejsów i na strukturę. To pozwala im nie czytać kodu pod spodem — co jest i zagrożeniem, i zaletą. Dopóki kod jest spójny, wszystko gra. Zwracają też uwagę na testy: czytają je, żeby zrozumieć, co system robi. Cokolwiek poprawia strukturę kodu, pomaga modelom go zrozumieć. A tak przy okazji: w tej książce, w dodatku, jest długa debata między mną a Johnem Ousterhoutem. Była świetna — nie wiem, jak bardzo jemu się bawiło, ale ja miałem bal.

Matt Pocock: Oglądałem całość i waszą rozmowę o tym na YouTube. Świetne widowisko — zresztą dlatego cię zaprosiłem. No to pytanie: jest w twojej książce coś, co dziś byś zmienił albo dopisał? Pytam konkretnie — mówiliśmy wciąż o tym, że dobre rzeczy pozostały dobre, tylko nigdy nie było rąk do pracy, żeby je stosować. Ale czy jest coś, co po prostu trzeba wyrzucić? Nie lubię zadawać tego pytania, bo wywiera na tobie presję, (śmiech) ale masz odpowiedź?

Co bym dziś poprawił: progi tak, dyscypliny nie

Wujek Bob: Na pewno progi. Wygląda na to, że agenty znoszą inny poziom złożoności niż ludzie. Mają znacznie lepszą pamięć krótkotrwałą — ogromną i idealnie dokładną. Jednym z moich posunięć jest poluzowanie dopuszczalnej długości funkcji przez korektę wyniku CRAP. Człowiekowi trzymałem CRAP poniżej czterech; agentom ustawiłem sześć i myślę, żeby podbić do ośmiu. Szukam tego progu — a nie jest łatwy do znalezienia.

Matt Pocock: Co to znaczy w praktyce, cztery do ośmiu? Dwudziesto-, stulinijkowa funkcja?

Wujek Bob: To sprowadza się do złożoności cyklomatycznej, czyli liczby ścieżek przejścia przez funkcję. Przy stuprocentowym pokryciu CRAP równy sześciu znaczy: sześć ścieżek przez funkcję, wszystkie pokryte testami. To jest właśnie sens tej miary: pokryj wszystko testami i trzymaj złożoność na wodzy. Miałem sporo debat z agentami na ten temat — aha, każdej debacie z agentem nie wolno ufać, ale trudno, prowadzę je mimo to — i one wydają się uważać, że „sześć to chyba dobra wartość”. No tak, w to akurat nie ma co wierzyć. Ale rzeźbię w tym progu.

Jest drugi aspekt. W książkach mówię o dyscyplinach. Jedną z nich jest programowanie sterowane testami — jestem jego wielkim zwolennikiem. Ale to dyscyplina ludzka, praktykowana dlatego, że ludzka głowa działa w określony sposób. Nie mogę i nie będę narzucać jej agentom. Nie ma sensu zmuszać agenta, żeby napisał jedną linijkę testu, potem jedną linijkę kodu produkcyjnego, potem znowu linijkę testu. Dla człowieka — przynajmniej dla mnie — to ma ogromną wartość. Dla agenta nie sądzę. Pozwalam więc agentom zachowywać się bardziej à la John Ousterhout: napisać funkcję, potem test tej funkcji, potem następną funkcję i jej test. Zresztą nawet gdy każę im robić TDD z pełnym rygorem, i tak zawsze wracają do tego trybu. Skoro zawsze tak kończą, widocznie to jest w porządku. Sedno: nakładanie ludzkiej dyscypliny na agenta to prawdopodobnie błąd. Nakładanie ludzkich wartości — nie. Ale progi, granice, być może trzeba przesunąć. Same dyscypliny, same zachowania — ich narzucanie nie jest mądre.

Matt Pocock: Pięknie to ująłeś. I znowu ta pamięć krótkotrwała, prawda? TDD jest świetne, kiedy twoja pamięć krótkotrwała jest mizerna, jak u człowieka: starcza jej na napisanie testu, a potem dokładnie tyle, żeby test przepuścić. W międzyczasie możesz wyjść na kawę.

Wujek Bob: Właśnie tak. Proszę bardzo.

Matt Pocock: (śmiech) No dobrze. Mówiliśmy dużo o budowaniu — implementacji, architekturze modułów. Co robisz, zanim oddasz robotę specyfikatorowi? Ile planujesz, zanim odpalisz tę całą karuzelę? Wpuszczać złe zadanie do toru przeszkód to czyste marnotrawstwo.

Pokusa planowania z góry

Wujek Bob: Pokusa jest taka: doprecyzować. Każ człowieka specyfikować, specyfikować, specyfikować — i dopiero wtedy oddać agentom. To bardzo stara pokusa. Ulegliśmy jej w latach siedemdziesiątych i doprowadziła nas do modelu kaskadowego. Rewolucja agile była odpowiedzią. Nie wiem, jak dobrze radzimy sobie z tą rewolucją, ale chodziło o powiedzenie: „moment — całe to ciężkie planowanie z góry robi z projektów chaos, bo to, co wychodzi na końcu, nigdy nie wygląda jak plan”. I nigdy nie wyglądało.

Z agentami pokusa jest identyczna: „zaplanujemy, zaplanujemy, oddamy agentom”. Próbowałem. Jestem w środku takiej próby właśnie w tym tygodniu. I to zawsze kończy się katastrofą, zawsze tak samo: układasz plany, agenty ruszają, a ty — człowiek — orientujesz się, że planu nie da się wykonać, bo nie pomyślałeś o wszystkim, a agenty nie są tak mądre jak ty. Gnają więc na oślep w jakąś bzdurę: musisz je zatrzymać, cofnąć, przepisać plan i uruchomić wszystko od nowa. Z tym skończyłem.

Powiedziałem sobie: spróbujmy podejścia zwinngo. Nie wiem, jak to wyjdzie — może niezbyt dobrze — ale zróbmy z nimi jedną, dwie historyjki, potem spójrzmy na architekturę, może coś ręcznie poukładać, potem kolejne historyjki. To może być lepsza droga. Być może nigdy nie uciekniemy od tego ręcznego porządkowania na końcu — próbuję wymyślić sposób, ale nie wiem, czy to w ogóle możliwe.

Matt Pocock: Myślę o tym tak: był ogromny kawał pracy. Kiedyś było to budowanie rzeczy — dni, tygodnie, miesiące. Budowanie się skurczyło. Ale planowanie z przodu i przegląd z tyłu pozostały bez zmian. Oczekuje się od nas szybszych iteracji, a to, co naprawdę było trudne, wciąż jest tak samo trudne i zajmuje tyle samo. Da się nadal zbudować złą rzecz — a to najdroższy błąd. Sporo ludzi uprawia teraz „dopieszczanie planu”: biorą spec, rozkmieniają go, przepuszczają przez siedmiu różnych agentów, dostają z powrotem lepszy plan i dopiero go realizują. Brzmi nieźle?

Wujek Bob: Agenty uwielbiają pisać plany. O mój Boże, one to kochają. Będą plany zdobić: będą olśniewające, piękne, rozpisane we wszelkich szczegółach… (śmiech) A potem rozpadają się przy realizacji.

W branży widać dziś nurt „programowania sterowanego specyfikacją”. Moje wrażenie: raczej nie zadziała. Moje eksperymenty nie wypadły najlepiej. Myślę, że powinniśmy po prostu jeszcze raz sięgnąć do idei zwinnych: zrób trochę, zbierz informację zwrotną, zrób trochę więcej, znów zwrotna, przeorganizuj — i tak w kółko.

Dom za dolara

Wujek Bob: Opowiadałem kiedyś, na wykładach o agile, taką historyjkę. Gdyby każda zmiana w domu — łącznie z wylaniem fundamentów, postawieniem dachu, wszystkim — kosztowała cię jednego dolara… Jakbyś budował? Wynająłbyś architekta i zapłacił mu tysiące za idealny plan, który wykonawca potem realizuje za dolara, jednym strzałem? Czy podszedłbyś do chłopa i mówił: „fundament tutaj, w takim kształcie”… o nie, to słabe, zmieńmy. „Kuchnię tutaj, salon tam”… o rany, nie, zamieńmy. „Niech dzieci przechodzą tędy”… ten układ komunikacji jest do kitu, przenieśmy schody. (śmiech) Oczywiste, że to drugie jest lepsze — i dokładnie w tym miejscu jesteśmy. Zmiana kosztuje dolara. No dobrze: dwa, może pięć. Koszt zmiany runął w dół — najbliżej zera, jak kiedykolwiek się znajdziemy. To przepowiednia, którą pewnie przegram, ale koszty zmian spadły tak mocno, że po co to planowanie z góry? Ono jest drogie. Czemu po prostu nie pokręcić, nie poprawiać, nie majstrować — aż nie będzie dobrze?

Matt Pocock: W stu procentach się zgadzam, całkowicie. Mam ogromny problem z samą etykietą „spec-driven development”. Bo co to w ogóle jest? Można pod to podstawić dziesięć interpretacji. Za każdym razem, gdy przekazujesz agentowi informację — czy to już „prompt engineering”, czy „programowanie sterowane specyfikacją”? W sumie trochę tak. Kiedyś powiedziałbyś koledze: „popraw tylko ten błąd ładowania w nagłówku” — czy to była specyfikacja? I zauważyłem, że ilekroć mówię „zrób trochę wstępnego uzgodnienia”, ktoś od razu nazywa to spec-driven development. A moim zdaniem różnica jest gdzie indziej: czy utrwala się swoje specyfikacje, czy się do nich wraca. Trzymasz gdzieś listę specyfikacji w repozytorium?

Specyfikacje ulotne

Wujek Bob: Nie trzymam. Specyfikacje są ulotne — znikają. Często je zmieniam, majstruję przy nich i przepadają. Nie ma już odpowiednika kodu źródłowego. Kod źródłowy pisali ludzie — to była ostateczna specyfikacja. Tego już nie ma. Kod wprawdzie nadal istnieje, ale nie my, ludzie, go piszemy. Wielu osób odczuwa ten brak: „musi istnieć coś ludzkiego, co definiuje wszystko z góry”. No więc — koniec końców nawet to, co produkują agenty, powstało z udziałem ludzi.

Ostatnie robię tak: zamiast pisać specyfikację definiującą to, czego chcę albo co mam, patrzę na gotowy efekt i mówię: „to jest specyfikacja”. Mam w sieci kilka narzędzi: CRAP dla Clojure, dla Javy, dla Go — kilka napisałem, no dobra: kazałem agentom je napisać. Mam tester mutacyjny, mam uprząż do agentów. Mam to wszystko ogarnięte. I mówię ludziom: nie pobierajcie tego. Pisałem to dla siebie. Zróbcie inaczej: wskażcie swoim agentom te narzędzia, pozwólcie im się im przyjrzeć — i niech zbudują własne, dla was. (śmiech) To moim zdaniem znacznie lepszy sposób na przekazanie istoty czegoś i dopasowanie jej do własnych potrzeb.

Agenty czytają wszystko

Matt Pocock: I to jest dla mnie zawsze dziwne u agentów: jeśli im coś wyślesz, one to przeczytają. (śmiech) Co jest zupełnie inne niż u ludzi. Wyślij człowiekowi obszerną specyfikację — zdobędziesz może dwadzieścia procent skuteczności, i te dwadzieścia to jeszcze łaskawy szacunek; pięć, może. Przekaż speca agentowi — on go przeczyta.

Wujek Bob: A druga strona tego medalu: tego, co piszą agenty, ludzie nie czytają.

Matt Pocock: Dokładnie! Nie pomyślałem o tym w ten sposób. One zakładają, że przeczytamy wszystko, co napiszą. A my po prostu nie czytamy. To takie jednostronne… (śmiech) Na dłuższą metę interesuje mnie, jak zmienią się ludzkie relacje, kiedy tak przyzwyczaimy się do komunikacji z agentami. Ja dyktuję swoim agentom, jakbym gadał ze znajomym. Fascynuje mnie, jak życie z czasem naśladuje sztukę.

Taktyka dla agentów, strategia dla ludzi

Matt Pocock: No i mam może ostatnie pytanie — dość solidne. Znowu sięgam po Ousterhouta…

Wujek Bob: Czekaj, tylko wyciągnę jego książkę… gdzieś tu jest.

Matt Pocock: Ja swoją już mam. (śmiech)

Wujek Bob: Mam. Dobrze.

Matt Pocock: Programowanie taktyczne i strategiczne. Taktyczne to podoficer na ziemi, człowiek walczący w bitwie. Strategiczne to generał wyznaczający bieg wojny. Zapewne zgodzimy się, że to trafne rozróżnienie. I agenty są znakomite w tym taktycznym, a fatalne w strategicznym. Dla ludzi, którzy dopiero zaczynają — a AI zjadło już całą robotę taktyczną — jak nauczyć się programowania strategicznego? Bo widzowie chcą od ciebie dokładnie tego: „oddaj nam swój mózg, niech go sobie wszczepimy; wytłumacz, czemu testowanie mutacyjne jest takie wspaniałe”. Twoim zadaniem jest teraz rozdawać ludziom swój mózg. Jak mają się tego nauczyć?

Wujek Bob: Dostaję to pytanie często. Nie mam idealnych odpowiedzi, bo szczerze mówiąc nie wiem. Ale tak o tym myślę. Po pierwsze: programista — na studiach czy gdziekolwiek indziej — powinien uczyć się, pisząc kod. Rok pisania kodu; nie wiem dokładnie jak długo, ale na tyle, żeby wiedzieć, z czym agenty mają do czynienia. Po drugie: kiedy dostaniesz się do firmy, która intensywnie używa agentów, młody człowiek, świeżo po szkoleniu, powinien być traktowany jak agent. Inżynier prowadzący — ktoś, kto ma w locie rój agentów i pracuje strategicznie — powinien patrzeć na ciebie jak na agenta: dawać ci te same zadania co agentom i poddawać cię tym samym deterministycznym narzędziom. Powinieneś spędzić kilka miesięcy w tym stanie: okropnie nieproduktywny, ale uczący się jak diabli. A kiedy przejdziesz przez ten tor przeszkód, może będzie można ci zaufać na tyle, żebyś uruchomił własnego agenta. Będzie to wyglądać jakoś tak. Kodu nie wolno stracić z oczu całkowicie.

Mówiłem ludziom dziesięć lat temu: jeśli nigdy nie pisałeś w asemblerze, spędź weekend na pisaniu w asemblerze, żebyś wiedział, co naprawdę dzieje się za kulisami. Bo jeśli cały dzień piszesz w Javie, żyjesz w świecie fantazji — wciąż jest tam magia, której nie rozumiesz. Weekend z asemblerem — i wreszcie pojmiesz, co się naprawdę dzieje. Uważam, że to wciąż obowiązuje i jakoś mieści się w tej ścieżce edukacyjnej: od podstaw, od binariów, przez asembler, jakiś podstawowy język jak C, coś wyższego poziomu jak Python, potem praca z agentami i narzędziami deterministycznymi — a na końcu umiejętność strategicznego prowadzenia agenta, pod czyimś nadzorem. Lepiej tego nie umiem powiedzieć.

Matt Pocock: Ależ to trudne, bo dzieją się tam dwie rzeczy naraz. Agent jest warstwą abstrakcji nad kodem — a ciebie zafascynowała przeglądarka architektury, czyli kolejna taka warstwa. To znakomita droga nauki: budować sobie warstwy nad kodem, żeby przy zanurzeniu rozumieć więcej. Ale jeśli ktoś siedzi w twoich księgach rachunkowych i robi wyłącznie robotę taktyczną, firma prędzej czy później powie: po co go zatrudniamy, skoro mamy rój pięciu hartowników Wujka Boba za ułamek kosztu? (śmiech) Aha, mam jeszcze jedno pytanie, zanim wrócimy do zasobów: pętla informacji zwrotnej przy programowaniu strategicznym jest tradycyjnie bardzo długa. Ludzie, którzy zmieniają pracę co pół roku, mogą nigdy się go nie nauczyć — bo skutki ich błędów widać dopiero po dziewięciu miesiącach, więc własnych pomyłek nigdy nie oglądają. Z agentami, skoro wszystko przyspieszyło, można dostawać zwrot o własnych błędach szybciej. I mnie interesuje: skąd wiedziałeś w grudniu, że agenty popełniają błędy? Jak to rozpoznawałeś?

Jak poznać, że agent się męczy

Wujek Bob: Na początku po prostu patrzyłem w kod i widziałem te psie kupki. Ale to nie była najważniejsza część. Najważniejszy był następny krok: patrzyłem, jak się szamoczą. Widziałem, że agent się męczy — i rozpoznawałem to zmęczenie, bo sam je przeżyłem. I to jest sedno problemu: nowicjusz wszedłby i tego zmęczenia nie rozpoznał.

Skąd się tego uczysz? Uczyłem się na własnej skórze, w twardej szkole życia. A jak ma to rozpoznać młody człowiek? Jest całe bogactwo wiedzy na ten temat. Stare książki — te, których nikt nie czyta, bo są stare. Stare książki o tym temacie są znakomite. Sięgnij po Toma DeMarco, po Eda Yourdona… no, nazwiska mi uciekają…

Matt Pocock: „Pragmatyczny programista”…

Wujek Bob: Tak — mnóstwo starszych, bardzo dobrych książek. Jeśli je przestudujesz na czas, złapiesz wyczucie tego wyższego, strategicznego poziomu gry. Trzeba będzie odfiltrować archaizmy — wiele z nich pisano w latach siedemdziesiątych, osiemdziesiątych — ale właśnie wtedy wyciągnięto te lekcje. Tam bym szedł najpierw. A potem i tak trzeba się tego nauczyć na własnej skórze.

Matt Pocock: Dlatego uważam, że powinni przez kilka miesięcy odgrywać agentów — żeby poczuć, jak to jest.

Wujek Bob: No właśnie. Stań się agentem. Niech agent deleguje na ciebie.

Matt Pocock: Zostajesz subagentem agenta. Podoba mi się. (śmiech) No dobrze, mam jeszcze jedno krótkie pytanie. Z tego wszystkiego wynika, że fundamenty inżynierii oprogramowania wciąż się liczą. Czemu? I co odpowiedzieć ludziom, którzy twierdzą, że już nie?

Fundamenty wciąż obowiązują

Wujek Bob: Liczą się z tego samego powodu, z którego liczyły się zawsze. Kto to powiedział… Dijkstra, sądzę, choć pewnie przekręczę: oprogramowanie to najbardziej skomplikowana rzecz, jaką ludzie kiedykolwiek próbowali robić. Bardziej skomplikowana niż każde inne przedsięwzięcie. Dlatego fundamenty są sposobem organizowania tej złożoności w formę, którą da się objąć umysłem — nie tylko ludzkim, ale i naszych modeli. Modele przecież są wzorowane na ludziach. Fundamenty obowiązują nadal, bo to właśnie one porządkują złożoność tak, żeby dało się ją pojąć.

Są dziś ludzie przekonani, że fundamenty nie mają znaczenia. Oni się nauczą — i to na twardym gruncie — a nie zajmie im to długo. Może dłużej, niż myślę, bo agenty są całkiem niezłe. Ale widziałem, jak uderzają w ścianę. Wiem, że ta ściana tam stoi — i nie mam zamiaru znowu w nią wjeżdżać.

Matt Pocock: Bardzo ciekawe podobieństwa w tym, co się teraz dzieje. Wspominałeś o warstwie abstrakcji: kiedyś naszą warstwą był kompilator; wcześniej asembler, wcześniej binaria — a teraz wspięliśmy się na poziom modelu. Na każdym szczeblu w górę ludzie stojący szczebel niżej narzekali: „to wszystko zrujnuje, pracy nie będzie, tak się wszystko uprości, że kod pisać będą pięciolatki”. I wtedy jeszcze chodziło o binaria! (śmiech) Na każdym szczeblu to samo. Jesteśmy na następnym szczeblu i ludzie w dole krzyczą, że wszystko runie. Nie runie. Te same reguły obowiązują. Wszystkie fundamenty istnieją, ze wszystkich tych samych powodów. A reguły, które wyrzucisz, to te, które za rok podniesiesz z podłogi, strzepniesz z nich kurz i sobie przypomnisz, po co były.

Wujek Bob: Dokładnie.

Matt Pocock: Dziękuję ci bardzo, Bobie. Jest zresztą znakomity cytat — Platona, chyba: że pismo zrobi ludzi głupszymi. Ten sam argument o abstrakcji toczono już u Greków.

(Informacja dodatkowa: aluzja do dialogu Platona „Fajdros”, w którym Sokrates opowiada mit o wynalazku pisma — miało ono osłabiać pamięć zamiast ją wzmacniać.)

Pożegnanie

Matt Pocock: Widzowie — mam ich półtora tysiąca na żywo, niesamowite — zgodzimy się chyba, że to była znakomita rozmowa. Bob, dziękuję bardzo. Trzymaj jeszcze raz książkę, niech widzowie zobaczą… „Czysty kod”. Jest u ciebie jedenasta? Wracaj do szlafroka.

Wujek Bob: Tak, jest. (śmiech)

Matt Pocock: No to cudownie. Dziękuję wam wszystkim — kończę transmisję, a ja i Bob zostajemy jeszcze chwilę na osobności.