Architektura aplikacji rozwijanych z AI. Przegląd badań i opinii
To przegląd badań i opinii praktyków o architekturze aplikacji rozwijanych z pomocą AI. Zestawia klasyczne zasady modularności z pracami z lat 2021–2026, pokazując, jak poszerzał się zakres oceny modeli: od generowania pojedynczych funkcji, przez zmiany w istniejących repozytoriach, po próby utrzymywania kodu przez kolejne modyfikacje. Teksty Martina Fowlera, Jimmy’ego Bogarda, Chrisa Richardsona i Birgitty Böckeler uzupełniają te badania o argumenty projektowe.
Przywołane badania nie rozstrzygają, czy agentom AI lepiej pracuje się z modularnym monolitem, czy z mikroserwisami. Dostarczają obserwacji o kontekście, zależnościach, abstrakcjach i weryfikacji zmian, ale dotyczą różnych zadań i warunków. Wpis pokazuje, co z tych obserwacji wynika i gdzie kończy się ich zastosowanie. Wskazówki w końcowej części są warunkową interpretacją inżynierską, a nie wynikiem bezpośredniego porównania obu architektur.
1972–2018: dobre granice miały ograniczać koszt zmiany
Punkt wyjścia powstał długo przed współczesnymi modelami językowymi. W pracy z 1972 roku o kryteriach podziału systemu na moduły David Parnas porównał dwa sposoby organizacji tego samego programu. W jednym moduły odpowiadały kolejnym etapom przetwarzania. W drugim ukrywały decyzje projektowe, takie jak sposób przechowywania danych. Dzięki temu zmiana reprezentacji danych mogła pozostać wewnątrz jednego modułu, zamiast wymuszać poprawki w całym programie.
To rozróżnienie nadal pomaga w rozmowie o AI. Podział na dziesięć plików niewiele daje, jeżeli każdy z nich musi znać szczegóły pozostałych dziewięciu. Użyteczna granica pozwala wykonać konkretną zmianę bez odtwarzania działania całego systemu.
W „Monolith First” z czerwca 2015 roku Martin Fowler argumentował, że na początku projektu trudno dobrze wyznaczyć granice usług. Ich późniejsze przesuwanie jest kosztowniejsze w systemie rozproszonym. Zalecał więc rozważenie startu od monolitu, jednocześnie otwarcie przyznając, że opiera się na ograniczonej liczbie doświadczeń i że nie ma jednomyślności. Dzisiejsza rekomendacja modularnego monolitu ma zatem starsze uzasadnienie: pozwala poznawać domenę przed poniesieniem kosztów rozdzielenia wdrożeń.
Jimmy Bogard opisał w „Vertical Slice Architecture” z kwietnia 2018 roku organizowanie kodu wokół przypadków użycia. Zmiana funkcji aplikacji często obejmuje interfejs użytkownika, walidację i zapis danych. Vertical slice, czyli przekrój przez te warstwy, grupuje elementy potrzebne do obsługi danego żądania. Bogard podkreślał też konieczność rozpoznawania złych rozwiązań i refaktoryzacji. Sam układ katalogów nie zwalnia z projektowania wspólnej logiki.
Te trzy idee dotyczą różnych decyzji: ukrywania szczegółów, sposobu wdrażania oraz organizacji kodu. Można je łączyć. Modularny monolit może zawierać przekroje funkcjonalne, a pojedynczy mikroserwis również może być wewnętrznie uporządkowany według przypadków użycia.
2021–2023: od poprawnej funkcji do zmiany w repozytorium
W 2021 roku praca przedstawiająca Codex i HumanEval sprawdzała generowanie samodzielnych funkcji Pythona na podstawie opisów. HumanEval zawierał 164 ręcznie przygotowane zadania z testami. Pozwalał ocenić, czy model potrafi napisać działający program, lecz nie mierzył kosztu odnalezienia reguły biznesowej w aplikacji ani zachowania jej spójności po kilku miesiącach rozwoju. W takiej próbie korzyść z dobrej architektury dużego systemu może być po prostu niewidoczna.
Opublikowany po raz pierwszy w październiku 2023 roku SWE-bench zmienił zakres zadania. Model otrzymywał opis rzeczywistego zgłoszenia i repozytorium, w którym miał przygotować poprawkę. Zbiór obejmował 2294 problemy z 12 projektów Pythona. Trzeba było znaleźć właściwy kod i niekiedy skoordynować zmiany w kilku plikach. Ocenę nadal opierano na testach dla pojedynczego zgłoszenia; benchmark nie zestawiał alternatywnych architektur tej samej aplikacji.
2024: poprawa po modularizacji nie dowodzi jeszcze jej przyczyny
„LLM-Assisted Code Cleaning for Training Accurate Code Generators”, opublikowane na ICLR 2024, badało przekształcanie przykładów używanych do uczenia modeli. Autorzy stosowali zmianę nazw zmiennych, wydzielanie funkcji pomocniczych i dodawanie opisów planu rozwiązania. W eksperymentach z Code Llama 7B na zadaniach algorytmicznych APPS i CodeContests uczenie na przekształconym, modularnym kodzie dawało lepsze wyniki niż na pierwotnych przykładach. Był to argument za badaniem jakości danych i struktury kodu podawanego modelowi.
Jesienią pojawiło się „Revisiting the Impact of Pursuing Modularity for Code Generation” na EMNLP 2024. Deokyeong Kang, Ki Jung Seo i Taeuk Kim zwrócili uwagę na problem z przypisaniem przyczyny: model przepisujący kod może poprawić więcej niż jego podział na funkcje. Przygotowali więc między innymi wariant, w którym z przekształconego kodu ręcznie usunięto modularność, wstawiając treść funkcji w miejsca ich wywołań. Pozwalało to lepiej oddzielić efekt podziału od innych zmian wniesionych przez LLM.
Na APPS i CodeContests, dla badanych wariantów Code Llama, DeepSeekCoder i GPT-4o-mini, modularne przykłady nie dawały konsekwentnej przewagi. Ten wynik zawęża wcześniejszą interpretację: udane „uporządkowanie kodu przez AI” nie pozwala automatycznie stwierdzić, która cecha uporządkowania pomogła. Obie prace dotyczyły programów rozwiązujących zadania algorytmiczne w Pythonie. Żadna nie sprawdzała, czy zespół szybciej rozwija system płatności jako monolit czy zestaw usług.
2025: agent musi odnaleźć i wykorzystać istniejące zależności
RepoExec, przedstawiony w „On the Impacts of Contexts on Repository-Level Code Generation” na NAACL 2025, dodał do poprawności funkcjonalnej pytanie o użycie istniejących zależności. Badanie obejmowało 18 modeli i 355 zadań generowania funkcji w kontekście repozytorium. Porównywano podawanie implementacji potrzebnych zależności, ich sygnatur z dokumentacją oraz samych sygnatur.
Ogólnie najlepsze wyniki dawał pełny kontekst zależności. „Pełny” oznacza tu informacje o zależnościach wybranych dla zadania, a nie bezwarunkowe wklejenie całego repozytorium. Autorzy obserwowali również rozwiązania przechodzące testy, które ponownie implementowały dostępną funkcjonalność. Mierzyli więc osobno używanie wskazanych zależności. Samo ich wywołanie również nie gwarantowało poprawnego programu.
We wrześniu 2025 roku zespół Anthropic opisał podobny problem od strony narzędzi w „Effective context engineering for AI agents”. Zalecał staranny dobór informacji oraz doczytywanie potrzebnych materiałów w trakcie pracy. Nazwy plików, struktura katalogów i dostępne narzędzia wyszukiwania miały pomagać agentowi odnajdywać właściwy fragment. To opis praktyki producenta, bez porównania monolitu i mikroserwisów.
Z tych dwóch źródeł wynika użyteczna wskazówka projektowa: warto ograniczać ilość nieistotnego kodu, przez który agent musi przejść, zachowując dostęp do wszystkich informacji potrzebnych do zmiany. Krótki prompt pomijający ważny kontrakt może być równie kłopotliwy jak ogromny prompt pełen niepowiązanych plików.
2025: kod może wyglądać modularnie i nadal łamać granice
W „The Modular Imperative” z warsztatu ACM LMPL 2025 Anastasiya Kravchuk-Kirilyuk, Fernanda Graciolli i Nada Amin opisały niewielkie eksperymenty z generowaniem i modyfikowaniem aplikacji. W próbie z pulpitem blogowym Cursor z Claude Sonnet 4 tworzył osobne komponenty, lecz pozostawiał ukryte zależności, duplikował dane i zwiększał złożoność. Późniejsze przeniesienie do React przebiegło sprawniej dla wersji zapisanej w jednym pliku.
Nie jest to porównanie wdrażanego monolitu z mikroserwisami. Autorki zestawiały małe implementacje, a modularny wariant miał już konkretne wady. Zaznaczały również możliwość niedopasowania jego organizacji do modelu komponentów React. Praca formułuje postulaty badawcze i ilustruje je przykładami; w części prób używa Rubric DSL, narzędzia związanego z Midspiral, afiliacją jednej ze współautorek. Najbardziej przydatna obserwacja dotyczy tego, jak powierzchowne uporządkowanie może maskować zależności utrudniające kolejną zmianę.
W rozmowie „LLMs and Building Abstractions” z sierpnia 2025 roku Unmesh Joshi i Martin Fowler rozdzielili odkrywanie abstrakcji od stosowania już ustalonych. Nazwy, granice i znaczenie pojęć dojrzewają podczas pracy nad kodem. Gdy są stabilne, łatwiej zlecać modelowi kolejne implementacje. Ich argument sugeruje, że warto oceniać abstrakcję przez to, czy pomaga jednoznacznie opisać następne zadanie, zamiast zakładać, że dodatkowa warstwa zawsze ułatwi pracę AI.
2026: generowanie usługi i utrzymywanie systemu to różne próby
Marcowy preprint „Can AI Agents Generate Microservices? How Far Are We?” badał już bezpośrednio mikroserwisy. Obejmował 144 wygenerowane implementacje w czterech projektach, dwa warianty promptów i dwa scenariusze pracy. Porównano Claude Code z Sonnet 4, Codex z GPT-5 oraz Code Qwen z Qwen3-Coder. Poprawność zależała od konfiguracji i projektu, a dodatkowe streszczenie implementacji nie zapewniało poprawy.
Ważne ograniczenie dotyczy sposobu oceny. Odtwarzanie usługi w istniejącym systemie sprawdzano testami jednostkowymi, natomiast wariant clean state testami integracyjnymi korzystających z niej usług. Wyższych wyników drugiego scenariusza nie można więc odczytać jako czystego dowodu, że mniej kontekstu pomaga: zmieniono także to, co sprawdzają testy. Badanie nie zawierało monolitycznej grupy porównawczej. Potwierdza możliwości i problemy generowania mikroserwisów w określonych warunkach, lecz nie ustala ich przewagi nad inną architekturą.
Inny kierunek reprezentuje SWE-CI, opisany w preprincie z 4 marca 2026 roku. Pierwsza wersja obejmowała 100 zadań utworzonych z par wersji rzeczywistych repozytoriów. Dzieliły je średnio 233 dni i 71 commitów historycznego rozwoju. W eksperymencie agent pełniący rolę architekta wyznaczał kolejne wymagania, a agent programujący zmieniał kod. Autorzy ustawili limit 20 iteracji i sprawdzali również regresje, czyli psucie wcześniej działającego zachowania.
Liczby dotyczą historii projektów, nie czasu, przez który agent pracował samodzielnie. Wymagania w pętli wyprowadzano z różnicy względem testów docelowej wersji, więc nadal jest to kontrolowane przybliżenie utrzymania oprogramowania. Pozwala jednak obserwować skutki wcześniejszych zmian w kolejnych iteracjach. Tego właśnie brakowało w próbie sprowadzonej do jednej poprawki. SWE-CI także nie rozstrzyga wyboru między monolitem a mikroserwisami.
2026: praktycy wskazują na szybkość weryfikacji, ale różnią się w wyborze architektury
Chris Richardson w „GenAI-based software delivery needs a fast flow architecture” z lutego 2026 roku przedstawia mocny argument za mikroserwisami przy większej skali organizacji. Mała usługa ogranicza zakres zmiany, jej testy mogą szybko przekazać wynik agentowi, a niezależne wdrożenia pozwalają obsłużyć wiele zmian równolegle. Richardson uwzględnia monolit jako rozwiązanie dla małych aplikacji i niewielu zespołów. To argumentacja autora „Microservices Patterns” i konsultanta specjalizującego się w tym podejściu, oparta na własnościach architektury, bez kontrolowanego eksperymentu porównującego skuteczność agentów.
Warunkiem tego rozumowania jest dobrze wyznaczona granica usługi. Jeżeli zmiana zasad zwrotu wymaga jednoczesnego poprawienia płatności, zamówień i rozliczeń, mały rozmiar każdego repozytorium nie usuwa potrzeby zrozumienia całego procesu. Z kolei monolit z testami uruchamianymi przez godzinę i niekontrolowanymi zależnościami nie daje szybkiej informacji zwrotnej tylko dlatego, że ma jedno wdrożenie. W praktyce trzeba sprawdzić, gdzie przebiegają typowe zmiany.
Birgitta Böckeler w „Harness engineering for coding agent users” z kwietnia 2026 roku opisuje, jak otoczenie agenta może kierować jego pracą i wykrywać błędy. Instrukcje wyjaśniają reguły przed zmianą, a testy, kontrola typów i analiza zależności dostarczają informacji po jej wykonaniu. Wyraźne granice modułów pomagają, ponieważ można zapisać je jako automatycznie sprawdzane reguły. Autorka zaznacza przy tym, że sprawdzanie struktury nie rozwiązuje problemu błędnie zrozumianych wymagań.
W tym podejściu architekturę ocenia się również przez możliwość jej sprawdzania: czy naruszenie kontraktu, niedozwolona zależność albo regresja szybko wrócą do agenta jako konkretny błąd. To uzupełnia wcześniejszy temat niezależnych kryteriów weryfikacji kodu generowanego przez AI.
ModulithBench zadaje właściwe pytanie, lecz jego wynik wymaga ostrożności
ModulithBench zawiera odpowiadające sobie implementacje domen w Java/Spring i zadania wymagające zmian między modułami. Autor repozytorium wyraźnie argumentuje za modularnym monolitem. Sam fakt przygotowania benchmarku nie potwierdza jednak tej tezy.
W dostępnym raporcie uruchomienia Antigravity z 14 maja 2026 roku końcowe oceny opisano jako samoocenę. Pole wersji modelu zawiera nazwę organizacji, a nie dokładny identyfikator. Raport podaje również, że mikroserwisów formalnie nie zweryfikowano. Taki zapis nie wystarcza do rzetelnego porównania poprawności. Zadania mogą posłużyć jako materiał do własnego eksperymentu, po dopracowaniu walidacji i warunków obu wariantów.
Co ten przegląd podpowiada przy projektowaniu aplikacji
Przy projektowaniu aplikacji można wykorzystać opisane obserwacje o lokalności zmian, dostępności kontekstu i szybkości weryfikacji. Nie wystarczają one jednak do wyboru sposobu wdrażania systemu. Dla aplikacji bez wyraźnej potrzeby niezależnych wdrożeń modularny monolit, z kodem organizowanym wokół przypadków użycia, jest rozsądnym punktem wyjścia do sprawdzenia. Uzasadnieniem jest możliwość zmieniania granic oraz sprawdzania całego procesu przy mniejszej liczbie elementów wymagających osobnego uruchomienia. To warunkowa rekomendacja projektowa, której skuteczność dla danego zespołu i jego agentów wymaga pomiaru.
Rozważmy przykładową zmianę: klient może otrzymać częściowy zwrot, ale suma zwrotów nie może przekroczyć wpłaconej kwoty. Agent powinien łatwo odnaleźć regułę obliczania dostępnego zwrotu, kontrakt operatora płatności oraz test ponowionego żądania. Przydatny przekrój funkcjonalny skupia obsługę tego przypadku, a wspólna reguła pozostaje w jednym module. Kopiowanie jej do kilku obsługiwanych żądań skraca pojedynczy plik, lecz utrudnia późniejszą zmianę limitu we wszystkich miejscach.
W systemie mikroserwisowym trzeba dodatkowo udostępnić agentowi kontrakty i ustalenia dotyczące częściowego niepowodzenia. Przykładowo operator wykonał zwrot, ale aplikacja nie otrzymała odpowiedzi. Własność „ponowienie nie wypłaci pieniędzy drugi raz” musi być jawna niezależnie od liczby usług. Także monolit korzystający z zewnętrznego operatora ma ten problem; jedna lokalna transakcja bazodanowa nie obejmuje automatycznie operacji wykonywanej przez operatora.
Granice warto połączyć z kontrolami. W Javie ArchUnit pozwala sprawdzać zależności pakietów, warstw i cykle. Można na przykład zabronić modułowi zamówień sięgania do wewnętrznych klas płatności, pozostawiając dostęp przez publiczny kontrakt. Wtedy agent, który naruszy tę regułę, otrzyma błąd podczas walidacji. Dokumentacja powinna wyjaśniać powód ograniczenia, aby model nie próbował „naprawić” testu przez jego usunięcie.
Mikroserwisy pozostają uzasadnione, gdy potrzebne są niezależne wdrożenia, osobne skalowanie lub autonomia zespołów. Praca z AI dodaje do tej decyzji pytania o dostępność kontekstu i koszt sprawdzania zmian. Nie zastępuje wymagań operacyjnych aplikacji.
Jak sprawdzić wybór architektury we własnym zespole
Przy porównaniu obu struktur warto przygotować te same wymagania i równoważne kryteria akceptacji. Należy ustalić wersję modelu, narzędzia, budżet, dostęp do dokumentacji oraz zasady interwencji człowieka. Próby trzeba powtarzać, zmieniając kolejność wariantów. Zadania powinny obejmować zarówno zmiany lokalne, jak i przekraczające granice modułów, w proporcjach odpowiadających rzeczywistej pracy zespołu.
Pomiar powinien uwzględniać:
- poprawność nowych funkcji oraz regresje w istniejącym zachowaniu;
- czas i koszt pracy agenta, łącznie z wyszukiwaniem kodu i uruchamianiem testów;
- czas poprawek i przeglądu wykonywanych przez człowieka;
- naruszenia granic, duplikowanie reguł i koszt kolejnych modyfikacji.
Po pierwszym zadaniu trzeba zachować wygenerowany kod i przekazać następne wymaganie. Jeśli za każdym razem zaczynamy od czystej wersji, usuwamy z eksperymentu skutki wcześniejszych decyzji. Seria na przykład 30 zmian pozwoli zobaczyć, czy początkowo wygodna struktura nadal pomaga, gdy dochodzą nowe przypadki, wyjątki i integracje. Dopiero taki wynik może wesprzeć decyzję o architekturze dla konkretnego zespołu i jego agentów.
Wykorzystuję treści generowane przez AI jako część mojego codziennego procesu nauki.