Dzisiejsze AI potrafi napisać funkcję, komponent czy cały endpoint w kilka sekund. Problem nie pojawia się tam, gdzie ludzie go oczekują — w składni czy szybkości. Pojawia się w chwili, gdy AI musi dotknąć istniejącego systemu: dziesiątek plików, historii decyzji, reguł biznesowych, które nie są zapisane nigdzie poza „głowami" programistów. Jak systematycznie zapobiegać temu problemowi — to temat całej tej serii, a narzędzie, do którego stopniowo dojdziemy, nazywa się AITM.
Zanim tam dotrzemy, warto zadać pytanie, na które każdy zespół pracujący z agentami AI prędzej czy później odpowiada — łatwą albo drogą drogą: skąd właściwie wiadomo, że wynik, który agent oddał jako „gotowy", jest naprawdę poprawny, a nie tylko na taki wygląda? Odpowiedź znajdzie się na końcu tego wpisu — ale najpierw zobaczmy, dlaczego to wcale nie jest takie oczywiste pytanie.
Jak to wygląda w praktyce
Typowy scenariusz: prosisz agenta AI o zmianę jednej funkcji. Agent ją poprawia — ale zapomina, że ta funkcja jest wywoływana z trzech innych miejsc z różnymi oczekiwaniami. Albo „ulepsza" strukturę kodu, bo wydawało mu się to logiczne, i przy okazji psuje logikę w dalszej części, której nawet nie widział.
To nie są pojedyncze błędy — to problem systemowy: agent AI nie ma kontekstu całego systemu, tylko to, co mieści się w prompcie i co uda mu się odczytać przez wyszukiwanie pełnotekstowe. Decyduje na podstawie słów, a nie logiki biznesowej. Jeśli dostępna jest dokumentacja, często ładuje całą jej treść — także część, która nie ma nic wspólnego z danym promptem. I dotyczy to nawet najmocniejszych dostępnych modeli (Opus, Fable, Astra i podobnych): nie chodzi o to, że model nie jest dość mądry, lecz o to, że nie ma gdzie systematycznie przechowywać tej wiedzy między poszczególnymi interwencjami.
Wraz ze wzrostem liczby linii kodu źródłowego, komplikowaniem się logiki biznesowej i coraz silniejszym powiązaniem poszczególnych modułów i klas to wyszukiwanie działa gorzej. Do AI trafiają dane, które nie mają nic wspólnego z poprawką — a wynikiem jest kod technicznie poprawnie napisany, ale zgodny z błędną logiką biznesową. Powstała funkcjonalność jest zepsuta albo „naprawiony" zostaje fragment kodu, którego nikt nie chciał ruszać.
Gdzie dokładnie to się zacina
Zasadniczą przeszkodą jest halucynacja — i bardzo trudno ją wyeliminować. Drugim problemem jest jakość promptu, na którą my jako użytkownicy możemy już częściowo wpływać. Nad obydwoma ciąży jednak twardsze ograniczenie: limit kontekstu. Nawet przy największych dostępnych modelach mówimy mniej więcej o milionie tokenów — dla środowisk liczących setki tysięcy linii kodu.
Z doświadczenia praktyczny próg, od którego podstawy, takie jak skill czy hint w pliku md, przestają wystarczać, to mniej więcej około 150 000 linii kodu. Około 300 000 linii środowisko staje się naprawdę złożone — codzienny stan zaczyna się sypać, a rzeczy psują się same. Mówimy o oprogramowaniu zbudowanym na OOP, ze skomplikowanymi warunkami logicznymi i częściami połączonymi przez mechanizmy komunikatów/zdarzeń i podobne techniki. W takim kodzie odwołanie między wywołaniem a jego obsługą nie zawsze jest oczywiste, a AI ma z tą częścią spore trudności — całkiem prawdopodobne, że nie odnajdzie całego kodu powiązanego z daną metodą.
Do tego dochodzi kolejna warstwa: sam agent AI na podstawie promptu często uruchamia własnych subagentów — a tworzenie tych subagentów samo podlega kontroli AI, co wprowadza jeszcze jedno źródło błędów. Jeśli AI przypisze większą wagę słowu, które wstawiłeś do zdania tylko dla płynności gramatycznej (a nie jako instrukcję), może uruchomić na jego podstawie subagenta, który przetworzy coś, czego w ogóle nie chciałeś. A subagent może przekazywać własne błędy dalej innym agentom — więc pojedyncze halucynacje mogą się propagować i kumulować w całym łańcuchu.
Wydawałoby się, że agent sprawdzający, którego zadaniem jest zweryfikowanie, że wszystko wykonano zgodnie ze specyfikacją, powinien to rozwiązać. Ale co właściwie znaczy „zweryfikować"? Jeśli inne AI ocenia zadanie w ten sam sposób, w jaki zostało przetworzone, otrzymuje się jedynie potwierdzenie tego samego osądu, a nie niezależną kontrolę. Dopiero użycie innego i lepszego LLM do kontroli realnie zwiększa szansę wychwycenia błędu — ale to wybór, którego ktoś musi dokonać świadomie, a nie automatyczny wynik tego, że „kontrola się odbyła".
Zostaje jeszcze jedna ścieżka: uruchomić aplikację lub istniejący test, odczytać błąd z logu i naprawić go tak, aby test przechodził. Jednak nawet tu pozostaje pytanie, co właściwie zostało naprawione — czy to naprawdę błąd, czy błąd wywołany zmianą logiki biznesowej, którą wcześniejszy krok wprowadził nieumyślnie? Sama poprawka jest zwykle jednoznaczna, a błąd znika, ale często przy okazji psuje inną część kodu. Wiele zależy od tego, jak złożony jest kod i jakie ma zależności.
W przypadku prostszych rzeczy — powiedzmy formularza webowego z edycją, walidacją po wypełnieniu i zapisem danych przez logikę biznesową — zwykle nie jest to wymagające, a prawdopodobieństwo sukcesu jest bliskie 99%. Przy bardziej złożonych strukturach można naprawdę dojść do stanu, w którym struktura kodu zaczyna się rozpadać, a jeden błąd goni drugi. Wielokrotne uruchamianie testów i testów e2e może to stopniowo naprawić, ale w naprawdę złożonym systemie może to wymagać wielu prób — a każda coś kosztuje.
Odpowiedź obiecana na początku
Wracając do pytania otwierającego: skąd wiadomo, że wynik jest naprawdę poprawny, a nie tylko wygląda na gotowy? Na podstawie samego promptu i następczej kontroli nie da się tego wiarygodnie ocenić. Widzieliśmy dlaczego: ograniczony kontekst, halucynacje propagujące się między subagentami, kontrola, która w najgorszym razie tylko potwierdza ten sam błąd, oraz poprawka sterowana logiem, która nie odróżnia prawdziwego błędu od efektu ubocznego.
To metody, których programiści powszechnie używają dziś i przy prostszych zmianach sprawdzają się dobrze. Kolejnym poziomem jest orkiestracja z użyciem AI — przygotowuje się określone dane o systemie i utrzymuje je aktualne, aby móc przekazać AI lepsze informacje i tym samym zmniejszyć jego pole do zrobienia czegoś innego, niż się prosiło. Właśnie do tego został stworzony AITM — AI Task Manager: zanim agent piszący kod w ogóle zobaczy żądanie, system ściąga kontrakty (udokumentowane zachowanie), mapę DOM i logikę biznesową dla danego obszaru — i dopiero z tą wiedzą składa zadanie. Nie polega na pojedynczym agencie bezpośrednio, lecz na całym pipeline i innych metodach, które AITM stosuje, aby uzyskać lepsze wyniki.
Kolejne dni pokażą dokładnie, jak to wygląda w AITM na konkretnych promptach, agentach i krokach pipeline — i dlaczego to inny sposób pracy z AI niż ten, do którego programiści są przyzwyczajeni w zwykłej konsoli.