Dlaczego kod z AI szybko staje się nieczytelny i trudny w utrzymaniu? Poznaj problem ai black box i sposoby, by odzyskać kontrolę nad projektem.
The AI Black Box Problem: dlaczego kod z AI przestaje być utrzymywalny
Na początku wszystko wygląda świetnie. Piszesz prompt. Dostajesz działający kod. Feature zamknięty szybciej niż kiedykolwiek wcześniej. Zespół zadowolony, klient też. A potem przychodzi moment, kiedy trzeba coś zmienić. I nagle okazuje się, że nie do końca wiesz… jak to działa. To właśnie jest moment, w którym trafiasz na tzw. ai black box problem.
I nie zrozum mnie źle ;). Problem nie polega na tym, że AI generuje zły kod. Wręcz przeciwnie – często generuje kod poprawny, a nawet lepszy niż Ty. Problem polega na tym, że generuje go bez kontekstu strukturalnego, który normalnie powstaje w głowie programisty., bo… AI nie buduje systemu. AI buduje odpowiedź.
Efekt?
- dostajesz rozwiązanie, które działa,
- ale nie masz mapy mentalnej,
- nie znasz decyzji architektonicznych,
- nie widzisz granic odpowiedzialności.
I dokładnie to jest sedno problemu ai black box – brak przejrzystości i możliwości zrozumienia, jak system dochodzi do swoich rezultatów
Dlaczego AI tworzy „czarne skrzynki”
Modele generujące kod optymalizują coś zupełnie innego niż Ty. Nie chodzi o utrzymywalność. Chodzi o:
- poprawność wyniku
- szybkość wygenerowania
- zgodność z promptem
A to prowadzi do bardzo konkretnych efektów.
Zamiast systemu dostajesz jeden plik, który robi wszystko: walidację, logikę biznesową, komunikację, side-effecty. To nie jest przypadek. To naturalna konsekwencja generowania „jednym strzałem”. AI bardzo często: przekazuje dane „przy okazji”, tworzy zależności niejawne, łączy komponenty bez kontraktów
Dla kompilatora, interpretera – OK. Dla człowieka – koszmar. Bo nie masz: interfejsów, jasno określonych boundary, odpowiedzialności klas. Masz implementację. A implementacja bez kontraktu to zgadywanie.
Bardzo często też dokumentacja = prompt (którego już nie ma). To IMHO jeden z ciekawszych efektów. Logika systemu często istnieje tylko w promptcie, który wygenerował kod. A tego promptu po pewnym czasie już nie masz.
Kiedy tak naprawdę zaczyna się problem?
Pierwsza wersja działa.
Druga też.
Problem pojawia się przy n-tej zmianie kodu wygenerowanego przez LLM.
To nie przypadek – zespoły zauważają, że początkowa produktywność jest o wiele większa, ale po czasie koszt zmian gwałtownie rośnie .
Dlaczego? Bo każda zmiana wymaga:
- przeczytania całego modułu
- zrozumienia ukrytych zależności
- sprawdzenia efektów ubocznych
Czyli… robisz reverse engineering (prawie) własnego kodu.
Przykład, przykład, przykład
Wyobraź sobie taki fragment kodziku.
class OrderService {
constructor(
private readonly paymentGateway: any,
private readonly validator: any,
private readonly notifier: any
) {}
public process(): void {}
}Na pierwszy rzut oka – wygląda sensownie, ale…
- czym jest
paymentGateway? - jakie są zasady walidacji?
- kiedy idzie powiadomienie?
- co się dzieje przy błędzie?
Tego nie wiesz, bo logika siedzi w środku i jest posklejana. No dobra, pa tera… Ten sam problem, ale z rozbitą strukturą:
class OrderValidator {
constructor() {}
public validate(): void {}
}
class PaymentProcessor {
constructor() {}
public charge(): void {}
}
class OrderNotifier {
constructor() {}
public notify(): void {}
}
class OrderService {
constructor(
private readonly validator: OrderValidator,
private readonly payment: PaymentProcessor,
private readonly notifier: OrderNotifier
) {}
public process(): void {}
}Nagle:
- masz granice
- masz odpowiedzialności
- możesz zmieniać elementy niezależnie
Czyli odzyskujesz kontrolę.
Dodatkowo, struktura projektu, która ratuje życie
Kod z AI bardzo często nie ma sensownej struktury. Dlatego warto ją narzucić ręcznie. Przykładowo:
src/
domain/
order/
Order.ts
OrderService.ts
OrderValidator.ts
application/
order/
ProcessOrderUseCase.ts
infrastructure/
payment/
PaymentGateway.ts
notification/
NotificationService.ts
shared/
errors/
utils/Już takie coś robi ogromną różnicę. Bo nawet jeśli kod w środku nie jest idealny, to:
- wiesz gdzie go szukać
- wiesz gdzie go zmienić
- wiesz gdzie go NIE zmieniać.
W tym kontekście, u mnie bardzo sprawdza się architektura vertical slice. Mamy małe chunki kodu, które skupione są na realizowaniu konkretnego zadania. Jest to przejrzysta organizacja plików zarówno dla LLM-a, jak i człowieka.
Najważniejsza rzecz, którą trzeba zrozumieć
AI nie tworzy chaosu. AI skaluje Twój poziom inżynierii.
Jeśli masz dobre fundamenty – przyspieszy Cię, bo to co Ci tutaj przedstawiam to po prostu software craftmanship. Dobre praktyki, które teraz, w dobie AI mają kolosalne znaczenie.
Jeśli nie masz fundamentów – cytując klasyka, pchasz się w gips ;).
To dlatego wielu developerów ma podobne doświadczenie:
działa świetnie… dopóki nie trzeba tego dotknąć
Podsumowanie
Jak nie wpaść w ai black box:
- rozbijaj kod zaraz po wygenerowaniu
- zawsze definiuj kontrakty (nawet ręcznie)
- traktuj AI jako juniora, nie architekta
- nie akceptuj „jednego pliku, który robi wszystko”
- refaktoryzuj zanim będzie za późno


Dodaj komentarz