Pracuję na trzech stackach: StackCompass.dev i moje portfolio stoją na Astro, dla klientów piszę wtyczki WordPressa i pracuję z WooCommerce, a w Laravelu buduję aplikacje backendowe. Ci sami agenci, te same modele, te same nawyki promptowania – i wyraźnie różne wyniki. W repo Astro agent potrafi przeprowadzić zmianę od pomysłu do zweryfikowanego commita niemal bez nadzoru. W Laravelu radzi sobie dobrze, dopóki trzymam go w konwencjach frameworka. W WordPressie pisze dobry kod, a strona i tak zachowuje się inaczej, niż ten kod zapowiada – często bez związku z jakością samej wtyczki.
Najprostszym wyjaśnieniem byłyby dane treningowe. WordPress napędza większą część internetu niż dwa pozostałe stacki razem wzięte. Publicznego kodu WordPressa, z którego modele mogą się uczyć, jest więcej niż Laravela i Astro łącznie. Gdyby skuteczność agentów zależała wprost od ilości znanego kodu, WordPress byłby najłatwiejszym stackiem do pracy z agentami. Nie jest. Ta odwrotność jest tu najciekawsza: pokazuje, od czego jakość tej pracy na danym stacku naprawdę zależy.
Agent potrzebuje czego innego niż programista
Człowiek pracujący na nieznanym systemie bez przerwy nadrabia brakujące informacje: klika po panelu, sprawdza staging, pamięta, że ten klient ma wtyczkę cache’ującą, pyta kolegę. Agent nie ma żadnego z tych kontekstów. Ma repozytorium, narzędzia, które mu udostępnisz, i to, co zdoła zweryfikować, uruchamiając dostępne polecenia.
Popularność stacka nadal ma znaczenie. Model zwykle lepiej zgaduje składnię, idiomy i typowe wzorce tam, gdzie widział więcej kodu – dlatego TypeScript w Astro oraz PHP w WordPressie i Laravelu dają mu łatwiejszy start niż niszowe środowiska. Ale to pomaga głównie w pierwszej propozycji rozwiązania. W pracy agentowej, a zwłaszcza w code review, ważniejsze jest coś innego: czy agent może oprzeć się na deterministycznym sygnale, zamiast na własnym poczuciu, że kod wygląda dobrze bo pasuje do wzorca.
Po przekroczeniu progu składniowej znajomości stacka skuteczność agenta zaczyna zależeć głównie od dwóch pytań:
Ile prawdy o systemie żyje w repo? Jeśli repozytorium jest całym systemem, model świata agenta jest kompletny. Każdy element zachowania, który mieszka gdzie indziej – wiersz w bazie, options table, przełącznik w adminie, hook innej wtyczki – to martwe pole, o którego istnieniu agent nie wie.
Jak tania jest weryfikacja? Agent, który może uruchomić build, type check albo testy, dostaje pętlę sprzężenia zwrotnego: proponuje zmianę, sprawdza ją, poprawia się. Forma sygnału znaczy przy tym tyle samo co jego istnienie. Astro i Laravel mają deterministyczne narzędzia review wbudowane w stack – build i type check w Astro, test runner w Laravelu – a każde z nich odpowiada kodem wyjścia: 0 albo 1. Przeszło albo nie, bez interpretacji, bez humorów. Ten binarny werdykt jest tym, na czym agent może działać autonomicznie. Agent, którego jedyną weryfikacją jest „człowiek wczyta stronę i popatrzy”, generuje kod prawdopodobny, niezweryfikowany. Ta różnica kumuluje się z każdym krokiem wieloetapowego zadania.
Ustaw trzy stacki na tych dwóch osiach, a wyniki, które widzę na co dzień, przestają dziwić.
Astro: repo jest całym systemem
Na statycznej stronie w Astro repozytorium jest systemem, a nie jego opisem. Treść żyje w plikach Markdown ze schematami pilnowanymi przez content collections. Routing to drzewo plików. Nie ma bazy, stanu w adminie ani konfiguracji runtime, która mogłaby rozjechać się z tym, co agent widzi w kodzie. Kiedy agent przeszuka repozytorium, zobaczy wszystko, co jest do zobaczenia.
Weryfikacja jest równie domknięta. astro build waliduje schematy treści, rozwiązuje każdą trasę i kończy się błędem na zepsutym polu frontmattera albo brakującym imporcie, a astro check dokłada przebieg TypeScriptu. Dla agenta ten zestaw poleceń odpowiada na większość pytania „czy coś zepsułem?” – i odpowiada w sekundy, bez deployu. Pętla „zaproponuj, zbuduj, popraw” mieści się w całości w zasięgu agenta.
Dlatego workflow na tej stronie tak daleko przesunął się w stronę delegowania. Agent nie tylko pisze tu kod; publikuje treści, przebudowuje komponenty i utrzymuje maszynowo czytelną dokumentację grafu modułów. Nic z tego nie wymagało mądrzejszego agenta. Wymagało podłoża, na którym nic istotnego dla projektu nie jest schowane.
Uczciwe zastrzeżenie: build weryfikuje strukturę i typy, nie wygląd ani dynamiczną logikę interakcji w przeglądarce. Agent może przejść wszystkie sprawdzenia i wypuścić wizualnie zepsutą kartę lub wadliwie filtrujący skrypt kliencki, bo regresje CSS i błędy zachowania UI w runtime nie wywalają statycznych buildów. To nie jest luka Astro, tylko martwe pole wspólne dla wszystkich trzech stacków. Żaden build ani type check nie sprawdza renderu w przeglądarce; weryfikacja wizualna i behawioralna UI wymaga ludzkiego oka albo dodanego osobno toolingu E2E (np. Playwright ze screenshotami), a ta inwestycja jest niezależna od wyboru stacka.
W Astro ten profil trzyma się tylko dopóki strona pozostaje statyczna. Dołóż server-side rendering, sesje i bazę, a Astro zaczyna dziedziczyć problemy z widocznością typowe dla stacka aplikacyjnego – bliższe Laravelowi niż WordPressowi. Schemat i polityki w repo nadal dają kontrakt; nie ma globalnego systemu hooków, w którym cudza wtyczka zmienia zachowanie Twojego kodu. To nadal nie jest statyczne Astro. To też nie jest WordPress.
Laravel: konwencje jako kontrakt
Laravel znajduje się pośrodku, bo jest wystarczająco przewidywalny, by agent mógł na nim pracować i wystarczająco aplikacyjny, by część prawdy wciąż mieszkała poza plikami. Konwencje frameworka – gdzie mieszkają kontrolery, jak migracje opisują schemat, jak policies wyrażają autoryzację, jak deklaruje się joby i harmonogramy – działają jak kontrakt. Nie dlatego, że model „zna Laravel z treningu”, tylko dlatego, że kontrakt widać w drzewie plików. Agent, który go przeczyta, wie, jakiego kształtu zmiany szukać, zanim zrozumie domenę. W aplikacji rejestrowej, o której pisałem wcześniej, prośba o akcję tylko dla admina oznacza trasę, kontroler, policy i test – wiadomo, gdzie każdej z tych rzeczy szukać.
Co kluczowe, schemat bazy żyje w repo jako migracje. Warstwa danych, która w wielu aplikacjach bywa niewidzialna, jest tu zadeklarowana w wersjonowanym kodzie. Dołóż php artisan test, a dostajesz pętlę weryfikacji mocniejszą niż sam build: agent może napisać feature test, uruchomić go i iterować na asercjach o zachowaniu, nie tylko na tym, czy PHP się parsuje. Zestaw testów działa jak wbudowany, deterministyczny reviewer – zwraca 0 albo 1. Ta pętla jest jednak warunkowa. Tam, gdzie testów nie ma, Laravel traci tę przewagę.
Martwe pole jest realne, ale ograniczone. Magia Eloquenta w runtime – dynamiczne atrybuty, fasady, niejawne relacje – sprawia, że sam model nie odsłania schematu, i agent potrafi z pełnym przekonaniem odwołać się do kolumny, której rename siedzi w migracji sprzed dwóch lat, tylko nikt nie kazał mu jej czytać. Część tej luki ma statyczną odpowiedź: Larastan uczy PHPStana patrzeć przez magię Eloquenta, więc widmowa kolumna wychodzi jako błąd analizy, a nie niespodzianka w runtime. Wartości środowiska i to, czy worker kolejek w ogóle działa, żyją poza repo; sam kod jobów – nie. Te luki są znane i w dużej mierze łapie je test, jeśli test istnieje. I to jest faktyczna linia podziału w świecie Laravela: na dobrze otestowanym repo agenci są mocni; na nieotestowanym tracą pętlę sprzężenia i osuwają się w zgadywanie.
WordPress: dobry kod, niepewny efekt
Agenci piszą kod WordPressa bardzo dobrze. Hooki, filtry, WP_Query, rejestracja bloków, endpointy REST – sama objętość WordPressa w danych treningowych sprawia, że składnia i idiom przychodzą bez wysiłku. Poproś o samodzielną wtyczkę ze stroną ustawień i obsługą zadań w tle, a kod, który wróci, często nadaje się do użycia od razu.
Awaria czai się gdzie indziej: w WordPressie repozytorium to mniejszościowy udział prawdy. Zachowanie strony współtworzą options table, post meta, aktywne wtyczki i ich wersje, nadpisania motywu, role użytkowników i konfiguracja mieszkająca w adminie – niczego z tego agent nie zobaczy, czytając pliki własnej wtyczki. Kod, który pisze, działa w runtime złożonym z części, których nigdy nie obserwował. Tak powstaje klasyczna awaria: wtyczka jest poprawna, a strona i tak zepsuta, bo warstwa cache, wtyczka security albo inny hook na tym samym filtrze zmieniły zachowanie w runtime.
Konkretny przypadek ze sklepu klienta na WooCommerce. Zadanie było trywialne: przestać pokazywać kategorie produktów na listingu. Agent zrobił to „czysto” – nie schował markupu w CSS przez display: none, tylko podpiął się hookiem u źródła, na danych o kategoriach. Zaakceptowałem ten wybór, bo mnie też wydawał się czystszy. Kategorie zniknęły. Rabaty B2B per kategoria też – po cichu. Ceny w tym sklepie obsługuje wtyczka B2B, której reguły są przypięte do kategorii produktów. Dopasowanie reguł czyta te same termy, które hook agenta właśnie odfiltrował. Nic nie rzuciło błędem. Żaden test, który agent mógł uruchomić, nie miał jak tego złapać: zależność nie żyła w jego repo, tylko we wtyczce innego vendora i w regułach rabatowych w bazie.
Lekcja jest odwróceniem. Według standardów jednego codebase’u hook był elegancką poprawką, a reguła CSS – hackiem. W złożonym runtimie ten hack był bezpieczną opcją, właśnie dlatego, że był powierzchowny: CSS zmienia wyświetlanie, a hook zmienia współdzieloną infrastrukturę, na której stoi nieznana liczba innych wtyczek. Agent rozumuje estetyką kodu, który widzi, a nie zależnościami między wtyczkami.
Testowanie domyślnie tego nie ratuje, i warto powiedzieć dlaczego. Popularna diagnoza brzmi „WordPress nie ma natywnych narzędzi do testów”. To bzdura. Narzędzia istnieją – PHPUnit z zestawem testowym WordPressa, wp-env, Playground, @wordpress/scripts dla bloków. Domyślnie testują jednak inną granicę niż ta, której potrzebujesz. Możesz przetestować swoją wtyczkę w izolacji i przejść, a strona i tak się psuje, bo awaria żyje w interakcji: ten zestaw aktywnych wtyczek, w tych wersjach, z tym motywem, tą options table, tymi danymi. Jednostką, którą umiesz przetestować, jest wtyczka; jednostką, którą wdrażasz, jest cały system zależności. Składa się on per strona, w bazie (active_plugins, options) i w runtime, przez globalny system hooków, w którym każda wtyczka może zmienić zachowanie każdej innej.
Nie ma domyślnego artefaktu „ta strona”, przeciw któremu dałoby się napisać deterministyczny test. Można go poskładać per projekt z przypiętych wersji, konfiguracji i zrzutu bazy – agencje robią dokładnie to Codeceptionem i wp-browser na klonie stagingu – ale to praca szyta na miarę, której core nie ustandaryzuje: to nie zaniedbanie ekosystemu, tylko konsekwencja modelu dystrybucji. Osobni autorzy, osobne repozytoria, montaż u klienta. Nowoczesny development bloków też z tego nie ucieka: @wordpress/scripts przynosi prawdziwy build, TypeScript i testy jednostkowe – autentyczny sygnał 0-albo-1, ale dla komponentu. System zależności pozostaje nieprzetestowany. Werdyktem review jest więc człowiek patrzący na wyrenderowaną stronę. Pętla agenta, bez dodatkowego oprzyrządowania, kończy się na „PHP się parsuje”.
Lukę da się zwęzić trzema różnymi dźwigniami. WP-CLI jest największą, bo odpytuje zmontowany runtime – jedyne miejsce, gdzie prawda faktycznie mieszka. wp option get, wp plugin list, wp db query zamieniają niewidzialny stan na wynik poleceń, czyli interfejs, w którym agenci są dobrzy. Ekosystem zresztą idzie w tę samą stronę: Abilities API i serwery MCP dla WordPressa to wczesne próby podania agentom tego zmontowanego runtime’u jako pełnoprawnego interfejsu, a nie obejścia przez shell. PHPStan ze stubami WordPressa przywraca sygnał statyczny, którego platforma natywnie nie daje. WordPress Playground daje jednorazowy runtime do faktycznego wykonania – ale tylko wtedy, gdy włożysz do niego tę samą kompozycję, a nie pusty WordPress. Z takim oprzyrządowaniem skuteczność agentów na WordPressie rośnie wyraźnie. W tym momencie jednak składać musisz ręcznie to, co Astro daje domyślnie, a Laravel – gdy testy istnieją.
Ranking: widoczność i weryfikacja
Ułożone w ten sposób porównanie przestaje dotyczyć tego, który framework agenci „znają”. Astro prowadzi nie dlatego, że znają je najlepiej – znają je najsłabiej z całej trójki – tylko dlatego, że statyczna strona trzyma strukturę w plikach i czyni jej weryfikację tanią i prostą. Laravel jest pośrodku, bo kontrakt widać w drzewie plików, a pętla testów jest mocna, gdy istnieje. WordPress zamyka stawkę nie dlatego, że agenci piszą zły kod – piszą znakomity – tylko dlatego, że platforma rozprasza prawdę po bazie i UI, czyli tam, dokąd z samego repo agent nie sięgnie.
Wzorzec się uogólnia: skuteczność agenta zależy od ułamka prawdy o systemie czytelnego z repo oraz od tego, jak tania jest pętla weryfikacji. Objętość danych treningowych jest drugorzędna. Ta para przewiduje zachowanie na stackach, których tu nie porównywałem: więcej prawdy w plikach i więcej weryfikacji w poleceniach poprawia delegowanie niezależnie od tego, co leży pod spodem.
Jedno uczciwe zastrzeżenie: ranking opisuje defaulty stacków, a dyscyplina pracy potrafi przetasować jego środek. Laravel bez testów traci pętlę weryfikacji i jest bliżej WordPressa, niż sugeruje jego reputacja. Projekt wordpressowy z WP-CLI, statyczną analizą i jednorazowym runtime’em wybija się wyraźnie ponad standard pracy deweloperskiej z WordPressem. Czego żadna dyscyplina pracy nie zmienia, to pozycja startowa i to, ile pracy kosztuje ruszenie z niej.
Czy przyjazność agentom powinna zmieniać wybór stacka?
Nie jako pierwsze kryterium. Kusi, żeby skończyć „wybierajcie Astro”. To zły wniosek. Aplikacja magazynowa jest w Laravelu, bo problem jest transakcyjny. Żadna ergonomia agentów tego nie zmienia. Sklepy klientów stoją na WooCommerce, bo liczba integracji z systemami e-commerce i prostota edycji to tam realna wartość, nie sentyment. Dopasowanie do problemu wciąż dominuje. Stack, który agenci kochają, ale który walczy z Twoim rozwiązaniem, kosztuje więcej niż delegowanie zadań agentowi kiedykolwiek zwróci.
Zmieniło się coś innego: gdy do problemu pasują dwa stacki, prostota pracy z agentami jest już ważnym punktem decyzji, bo różnicuje koszt utrzymania. Na jednym stacku istotną część rutynowych zmian da się delegować z tanią weryfikacją. Na drugim domyślnie zostaje człowiek w pętli, bo runtime widać z repo słabo, a tani sygnał z testów trzeba dopiero złożyć.
A kiedy stack jest już wybrany – czyli przez większość czasu – ta sama analiza mówi, gdzie inwestować: w spójne repo z dokumentacją i testami, nie w lepsze prompty i rozbudowane skille. Zbuduj brakującą oś: WP-CLI, statyczna analiza, jednorazowy runtime tej samej strony, testy, stan wyciągnięty z bazy do plików. Agenci nie potrzebują stacka, który byś dla nich wybrał. Potrzebują widzieć, co robią, i móc sprawdzić, czy to, co zrobili, zadziałało.