Jakość jest jedyną zmienną
Zadaniem kierownika projektu jest równoważenie czterech zmiennych: zakresu, czasu, kosztu i jakości. Klasyczny trójkąt ograniczeń mówi, że można optymalizować pod kątem dwóch, ale nie wszystkich czterech. Chcesz szybko i tanio? Ucierpi jakość. Chcesz dobrze i szybko? Wzrośnie koszt. Trójkąt jest użytecznym modelem mentalnym dla środowisk z ograniczonymi zasobami.
Nie działam w środowisku z ograniczonymi zasobami. Pracuję z agentem AI, który potrafi generować kod z szybkością inferencji, oknem kontekstowym mieszczącym cały codebase i kosztem sesji liczonej w dolarach, nie w pensjach. Trójkąt ograniczeń się załamuje.
Kiedy agent może zaimplementować funkcję w ciągu minut, pytanie nie brzmi „czy stać nas, żeby zrobić to dobrze?”. Pytanie brzmi „dlaczego mielibyśmy robić to źle?”
Eliminacja
Należy usunąć czas z decyzji. Nie „jak długo to zajmie?”, lecz „jak powinno to wyglądać, gdy będzie ukończone?”. Pierwsze pytanie optymalizuje pod kątem szybkości dostarczenia. Drugie optymalizuje pod kątem artefaktu.
Należy usunąć koszt z decyzji. Sesja, która produkuje poprawny, czysty, dobrze przetestowany kod, kosztuje tyle samo co sesja, która produkuje doraźny, chaotyczny, nieprzetestowany kod. API nalicza tę samą stawkę za token niezależnie od jakości. Marginalny koszt zrobienia tego dobrze wynosi zero.
Należy usunąć wysiłek z decyzji. Agent się nie męczy. Setna funkcja jest pisana z taką samą sprawnością jak pierwsza. Nie istnieje ludzka krzywa zmęczenia, która uzasadniałaby skróty pod koniec sesji. Jakość wyników jest ograniczona jakością instrukcji i jakością otaczającego kontekstu, a nie liczbą upłyniętych godzin.
Co pozostaje po wyeliminowaniu czasu, kosztu i wysiłku? Jakość. Jakość jest jedyną zmienną, która pozostała.
Co to oznacza w praktyce
Gdy jakość jest jedyną zmienną, wiele typowych decyzji inżynierskich staje się oczywistych:
Napisz test. Debata o tym, czy pisać test dla konkretnej funkcji, znika. Agent pisze test w sekundy. Koszt marginalny wynosi zero. Marginalny zysk to trwała weryfikacja. Niepisanie testu to świadomy wybór akceptacji niższej jakości bez żadnych oszczędności.
Napraw sąsiedni kod. Przy naprawianiu błędu otaczający kod często zawiera powiązane problemy: niespójne nazewnictwo, brak obsługi błędów, nieaktualne wzorce. W środowisku ograniczonym czasowo naprawia się błąd i zostawia resztę „na później”. Gdy jakość jest jedyną zmienną, naprawia się wszystko, czego się dotyka. „Później” nigdy nie nadchodzi. „Teraz” jest bezkosztowe.
Użyj właściwej abstrakcji. Szybki hack rozwiązuje doraźny problem. Właściwa abstrakcja rozwiązuje kategorię problemów. W środowisku ograniczonym czasowo hack trafia na produkcję dziś, a abstrakcja nigdy. Gdy agent może zaimplementować jedno i drugie w tej samej sesji, hack nie ma przewagi. Warto wybrać abstrakcję.
Przeczytaj przed pisaniem. W środowisku ograniczonym czasowo inżynierowie czasem modyfikują kod, którego nie przeczytali w całości, polegając na lokalnym zrozumieniu. Gdy agent może przeczytać cały plik, zrozumieć wzorce i modyfikować z pełnym kontekstem, nie ma powodu, by działać z częściowym zrozumieniem. Należy przeczytać cały plik. Zrozumieć wzorzec. Dopiero potem pisać.
Nie odkładaj. TODO, FIXME i HACK to znaczniki odłożonej jakości. W środowisku ograniczonym czasowo odkładanie jest racjonalne: naprawi się później, gdy będzie czas. Gdy jakość jest jedyną zmienną, odkładanie jest irracjonalne. Agent jest dostępny. Kontekst jest załadowany. Naprawa kosztuje tyle samo teraz co później. Zrób to teraz.
Zasada Jiro
Jiro Ono robi sushi od ponad 70 lat. Jego restauracja ma trzy gwiazdki Michelin i dziesięć miejsc. Nie zmienił menu ani metody. Doskonalił metodę każdego dnia przez 70 lat.
Gdy ktoś pyta Jiro, czy kawałek sushi jest wystarczająco dobry, odpowiedź nigdy nie opiera się na tym, jak zajęta jest restauracja, ilu klientów czeka ani ile kosztowała ryba. Odpowiedź opiera się na tym, czy sushi spełnia jego standard. Standard jest absolutny. Okoliczności są nieistotne.
Oto ta zasada zastosowana do inżynierii: standardem jest kod, nie sprint. Funkcja jest albo poprawna, czysta i dobrze przetestowana, albo nie. Termin nie zmienia oceny. Budżet nie zmienia oceny. Jedyne pytanie brzmi, czy artefakt spełnia standard.
Agenci AI czynią tę zasadę praktyczną po raz pierwszy w historii inżynierii oprogramowania. Przed agentami zasada Jiro była aspiracyjna. Ludzki koszt perfekcji był zbyt wysoki. Każdy skrót miał racjonalne uzasadnienie: wysyłamy w czwartek, budżet się wyczerpał, inżynier jest wypalony. Z agentami koszt zrobienia tego dobrze jest taki sam jak koszt zrobienia tego źle. Skróty tracą swoje uzasadnienie.
Sprawdzian dumy
Po każdej nietypowej zmianie zadaję pięć pytań:
- Czy doświadczony inżynier uszanowałby to podejście?
- Czy kod tłumaczy się sam?
- Czy przypadki brzegowe są obsłużone?
- Czy to odpowiedni poziom prostoty?
- Czy zostawiłem codebase w lepszym stanie, niż go zastałem?
Te pytania nie dotyczą poprawności. Bramka dowodowa zajmuje się poprawnością. Sprawdzian dumy zajmuje się rzemiosłem. Poprawny kod, którego nikt nie chce utrzymywać, nie przechodzi pytania 1. Sprytny kod wymagający komentarzy do zrozumienia nie przechodzi pytania 2. Kod obsługujący ścieżkę sukcesu, ale ignorujący ścieżkę błędu, nie przechodzi pytania 3.
Pytanie 4 jest najtrudniejsze. „Odpowiedni poziom prostoty” to nie „najprostsza możliwa wersja”. Jednoliniowy hack jest prostszy niż właściwa abstrakcja, ale hack reprezentuje niewłaściwy poziom prostoty, jeśli problem będzie się powtarzać. Właściwa prostota to minimalna złożoność, która rozwiązuje faktyczny problem bez rozwiązywania hipotetycznych przyszłych problemów.
Pytanie 5 dotyczy trajektorii. Każda sesja powinna zostawiać codebase w lepszym stanie niż go zastała. Nie tylko konkretne zmodyfikowane pliki, ale też otaczający kontekst: zaktualizowane testy, uporządkowane importy, poprawione komentarze, usunięty martwy kod. Standardem nie jest „czy ukończyłem zadanie?”. Standardem jest „czy projekt jest lepszy, bo tu byłem?”
Kontrargument
Oczywisty kontrargument: szybkość ma znaczenie. Wysyłanie ma znaczenie. Perfekcyjny codebase, który nigdy nie wychodzi na produkcję, jest gorszy niż chaotyczny codebase, który rozwiązuje realny problem.
Kontrargument jest trafny w świecie, gdzie jakość i szybkość są odwrotnie skorelowane. W świecie, gdzie agent AI produkuje wysokiej jakości wyniki z tą samą prędkością co niskiej jakości wyniki, ta korelacja się załamuje. Jakość i szybkość stają się zmiennymi niezależnymi. Można mieć jedno i drugie.
Pozostałym kompromisem jest uwaga, nie czas. Przeczytanie całego pliku wymaga uwagi. Uruchomienie bramki dowodowej wymaga uwagi. Zastosowanie sprawdzianu dumy wymaga uwagi. Czas agenta jest darmowy. Uwaga użytkownika jest skończona.
Jakość jest jedyną zmienną, ale uwaga jest ograniczeniem jakości. Rozwiązaniem nie jest obniżenie standardu. Rozwiązaniem jest budowanie infrastruktury, która zmniejsza koszt uwagi wymagany do utrzymania standardu: hooki wyłapujące typowe błędy automatycznie, skille kodujące przepływy jakości i systemy pamięci przenoszące kontekst między sesjami, by nie trzeba było ponownie wyprowadzać decyzji.
To złożony kontekst w służbie jakości. Każdy element infrastruktury zmniejsza koszt uwagi kolejnej sesji. Po wystarczającej liczbie sesji standard utrzymuje się sam.
FAQ
Czy to dotyczy wszystkich projektów programistycznych?
Zasada ta odnosi się najściślej do projektów, w których agenci AI wykonują implementację. W projektach w pełni implementowanych przez ludzi czas i koszt pozostają realnymi ograniczeniami. Zasada staje się bardziej adekwatna w miarę wzrostu możliwości agentów i spadku czasu ludzkiej implementacji.
A co z prototypowaniem?
Prototypy z definicji są jednorazowe. Standard jakości dla prototypu to „czy odpowiada na pytanie, które badamy?”. Jeśli odpowiedź brzmi tak, prototyp spełnił swoje zadanie niezależnie od jakości kodu. Zasada dotyczy kodu, który ma przetrwać, nie kodu, który zostanie odrzucony.
Czy to po prostu perfekcjonizm?
Perfekcjonizm to nieskończony standard, którego nic nie spełnia. Jakość to skończony standard zdefiniowany przez bramkę dowodową: poprawny, czysty, przetestowany, wolny od regresji i rozwiązujący faktyczny problem. Spełnienie standardu jest osiągalne. Przekraczanie go jest zbędne. Standard jest wysoki, ale nie nieskończony.
Jak radzić sobie z długiem technologicznym?
Nie tworząc go. Dług technologiczny to odłożona jakość. Gdy jakość jest jedyną zmienną, odkładanie traci swoje uzasadnienie. Agent jest dostępny teraz. Naprawa kosztuje tyle samo teraz co później. Nie ma stopy procentowej od długu technologicznego wytworzonego przez agenta, bo nie ma powodu, żeby go zaciągać.
Źródła
Opisana tu filozofia czerpie z tradycji Shokunin japońskiego rzemiosła oraz doświadczeń produkcyjnych udokumentowanych w serii AI Engineering. Przywołane konkretne implementacje:
- Bramka dowodowa: sześć kryteriów weryfikacji ukończenia
- Sprawdzian dumy: pięć pytań oceny rzemiosła
- System hooków: 84 hooki jako infrastruktura jakości (Every Hook Is a Scar)
- Złożony kontekst: infrastruktura zmniejszająca koszt uwagi wymagany do utrzymania jakości (Compound Context)