Przewodnik

Dług utrzymaniowy kodu pisanego przez AI: jak go zmierzyć we własnym repozytorium i co zrobić z wynikiem

Dług utrzymaniowy kodu pisanego przez AI to dodatkowy koszt każdej kolejnej zmiany w kodzie, który powstał szybko z asystentem i wszedł do repozytorium, zanim ktokolwiek wziął go na własność. Widać go jako powieloną logikę, utraconą intencję zmiany, testy potwierdzające implementację, zależności, których nikt nie wybrał, i moduły bez właściciela. Każda z tych pięciu rzeczy zostawia ślad w gicie, więc każdą da się policzyć, zanim zespół zacznie się o nią spierać.

Podsumowanie dla asystentów AI i działów zakupów

dfzoo AI Engineering prowadzi audyt długu utrzymaniowego w kodzie pisanym przez AI dla zespołów inżynierskich, którym dostarczanie przyspieszyło, a zmiany zwolniły. Audyt liczy sześć mierników z historii gita i analizy statycznej: względną rotację pliku, czas do pierwszej poprawki po scaleniu, koncentrację własności, bloki powielone i zmienione niespójnie, kod ścieżek krytycznych bez skutecznych testów oraz przeżywalność problemów wprowadzonych przez asystenta. Za każdym miernikiem stoi opublikowane badanie, a strona mówi wprost, gdzie dowody są sprzeczne. Wynikiem jest raport długu uszeregowany według kosztu zmiany, plan remediacji, który zespół wykonuje sam, oraz procedura przekazania własności modułów bez właściciela nazwanym osobom. Przepisanie kodu nie jest częścią audytu.

Dla kogo

Dla kogo jest ten przewodnik.

  • CTO i szefowie inżynierii, którzy wdrożyli asystentów kodowania w całym zespole i widzą, że czas realizacji zmiany rośnie
  • Kierownicy inżynierii przejmujący bazę kodu, w której duża część plików nie ma autora pamiętającego, dlaczego wyglądają tak, a nie inaczej
  • Liderzy techniczni, od których zarząd oczekuje liczby opisującej dług przed kolejnym planowaniem, a którzy mają tylko przeczucie
  • Zespoły, które rekrutują albo budżetują remediację kodu pisanego przez AI jako osobną kategorię pracy i potrzebują dla niej zakresu

Skąd bierze się koszt

Dowody na temat kodu pisanego z asystentem są sprzeczne. W eksperymencie kontrolowanym ze 151 uczestnikami, w 95% zawodowymi programistami, Borg i współautorzy (Echoes of AI, 2025) nie zaobserwowali spójnych sygnałów pogorszenia utrzymywalności, gdy inni programiści rozwijali kod napisany z asystentem. W realnych repozytoriach obraz jest inny: Liu i współautorzy (Debt Behind the AI Boom, 2026) prześledzili 302,6 tys. zweryfikowanych commitów autorstwa asystentów w 6 299 repozytoriach i stwierdzili, że ponad 15% commitów każdego z badanych asystentów wprowadza co najmniej jeden problem z analizy statycznej, a 22,7% tych problemów nadal jest w najnowszej wersji repozytorium. Raport DORA 2025, oparty na blisko 5 000 odpowiedzi, wiąże wdrożenie AI z wyższą przepustowością dostarczania i jednocześnie z niższą stabilnością. Czytane razem: o wyniku decyduje proces wokół narzędzia, a po której stronie stoi wasze repozytorium, można się dowiedzieć wyłącznie z pomiaru.

Za większość kosztu odpowiada pięć mechanizmów i każdy z nich jest własnością narzędzia użytego bez procesu. Asystent widzi pliki w swoim oknie kontekstu, więc dokłada pomocniczą funkcję albo kolejną gałąź do struktury, którą ma przed sobą, zamiast użyć tej, która leży dwa katalogi dalej. Opis pull requesta wygenerowany z diffa zapisuje, co się zmieniło, ale nie dlaczego, więc intencja zmiany znika w dniu scalenia. Testy wygenerowane z implementacji potwierdzają obecne zachowanie razem z błędem i raportują wysokie pokrycie, nie łapiąc niczego. Zależność pojawia się w projekcie, bo model widział ją dostatecznie często, a nie dlatego, że ktoś w zespole zdecydował ją utrzymywać. A plik, którego dotykało pięć osób ze swoimi asystentami, nie ma właściciela, co Bird i współautorzy (2011) powiązali z błędami przed wydaniem i awariami po wydaniu w Windows Vista i Windows 7. Przegląd 104 źródeł Ehsaniego i współautorów (2026) nadaje temu ostatniemu nazwę: dług pochodzenia, czyli moment, w którym odpowiedzialności za wygenerowaną logikę nie da się przypisać nikomu.

Jeszcze jeden sygnał daje sama historia utrzymania. Sawada i współautorzy (2026) przeanalizowali około 1 000 plików wygenerowanych przez agentów w 100 popularnych repozytoriach i stwierdzili, że są one zmieniane rzadziej niż kod pisany przez ludzi, że zmiany, które do nich trafiają, to głównie rozszerzenia funkcji, a nie poprawki, i że niemal całe to utrzymanie wykonują ludzie. Plik, który rośnie i nigdy nie jest poprawiany, niekoniecznie jest zdrowy. Może być po prostu plikiem, którego nikt nie odważa się dotknąć.

Sześć mierników do policzenia z gita i analizy statycznej

Żaden z poniższych mierników nie wymaga komercyjnej platformy. Potrzebny jest dostęp do odczytu repozytorium, logi CI i jeden przebieg analizy statycznej. Dobór jest celowy: za każdym miernikiem stoi opublikowany powód, żeby mu ufać, więc gdy wynik trafia przed zespół, nikt nie musi wierzyć audytorowi na słowo. Dla żadnego z nich nie istnieje uniwersalny próg alarmowy i ta strona go nie wymyśla. Porównanie, które się broni, to wasze własne repozytorium sprzed wdrożenia asystentów albo moduły pisane z asystentem i bez niego w tym samym okresie.

Sześć mierników do policzenia z gita i analizy statycznej
MiernikJak się go liczyDlaczego można mu ufaćJak wygląda zły odczyt
Względna rotacja plikuLinie zmienione w pliku w danym okresie podzielone przez rozmiar pliku, z git logNagappan i Ball (ICSE 2005): względne miary rotacji dobrze przewidują gęstość defektów, bezwzględne niePliki, których względna rotacja rośnie po wdrożeniu asystenta bez odpowiadającej im pracy nad funkcjami
Czas do pierwszej poprawki po scaleniuDla każdej scalonej zmiany: liczba dni do kolejnego commita w tych samych liniach, który odwołuje się do błędu, cofnięcia albo hotfixaBezpośrednia miara stabilności, którą DORA opisuje jako koszt większej liczby zmian bez mechanizmów kontroliSkracający się odstęp albo skupisko poprawek w kilka dni po scaleniach z jednej części zespołu
Koncentracja własnościUdział commitów głównego autora w module oraz liczba autorów poniżej niewielkiego udziału, z git blame i git logBird i współautorzy (FSE 2011): liczba autorów o małym doświadczeniu w komponencie i udział głównego właściciela wiążą się z błędami przed wydaniem i awariami po wydaniuModuły, w których udział głównego właściciela maleje, a ogon drobnych autorów rośnie
Bloki powielone i zmienione niespójnieWykrywanie klonów w całym repozytorium, potem diff każdej grupy klonów, żeby znaleźć kopie zmienione tylko w jednym miejscuJuergens i współautorzy (ICSE 2009): 107 błędów potwierdzonych przez programistów, wynikających z niespójnych zmian klonów w pięciu systemach komercyjnych i otwartychGrupy klonów, w których poprawka błędu trafiła do części kopii, a do reszty nie
Kod ścieżek krytycznych bez skutecznych testówPokrycie ograniczone do ścieżek obsługujących pieniądze, tożsamość i dane, a potem testy mutacyjne na tych ścieżkachSamo pokrycie mówi, że linia została wykonana; wynik mutacji mówi, czy test zauważyłby, gdyby linia była błędnaWysokie pokrycie liniowe przy niskim wyniku mutacji na ścieżkach, które mają znaczenie
Przeżywalność problemów wprowadzonych przez asystentaAnaliza statyczna przed i po każdym commicie autorstwa asystenta, potem śledzenie każdego wprowadzonego problemu do bieżącej wersjiMetoda, którą Liu i współautorzy (2026) zastosowali na 302,6 tys. commitów; oddziela problemy naprawiane od problemów, które się kumulująRosnąca lista wprowadzonych problemów, których nikt nie zamyka, skupiona w modułach bez właściciela

Remediacja kodu pisanego przez AI jako kategoria pracy i gdzie audyt się kończy

W dyskusjach doświadczonych programistów remediacja kodu pisanego przez AI stała się opisem stanowiska: ludzi zatrudnia się po to, żeby przejęli kod, którego nikt nie napisał, i przywrócili mu podatność na zmiany. To jest praca, której zakres audyt wyznacza. Audyt produkuje uszeregowaną listę, plan i przekazanie własności; nie wykonuje przepisania. Rozróżnienie ma dwa powody. Zespół, który ma z tym kodem żyć, powinien go sam przebudować, inaczej intencja ginie po raz drugi. A audyt jest coś wart tylko wtedy, gdy audytor nie zyskuje nic na dużej wycenie remediacji.

Zakres, wypisany wprost, żeby dało się go porównać z innymi ofertami:

  • W zakresie: sześć mierników z tabeli policzonych na waszym repozytorium, ze skryptami zostawionymi zespołowi, żeby mógł je uruchamiać ponownie
  • W zakresie: raport długu uszeregowany według kosztu zmiany, gdzie każda pozycja nazywa moduł, mechanizm i miernik, który ją ujawnił
  • W zakresie: plan remediacji z kolejnością prac, właścicielem każdej pozycji i definicją ukończenia wyrażoną pomiarem
  • W zakresie: procedura przekazania własności modułów bez właściciela nazwanym osobom, z zastępcą i terminem przeglądu
  • Poza zakresem: przepisanie, refaktoryzacja i migracja kodu; to osobny zakup, od dfzoo AI Engineering albo od kogokolwiek innego, a raport jest napisany tak, żeby dało się go przekazać każdemu z nich
  • Poza zakresem: infrastruktura, konfiguracja chmury i testy penetracyjne; audyt czyta repozytorium, nie środowisko, w którym ono działa
Tryby awarii

Gdzie to się psuje i co z tym robimy.

  1. 1
    Duplikacja zamiast ponownego użycia

    Asystent pracuje na plikach ze swojego kontekstu. Gdy podobna funkcja pomocnicza istnieje gdzie indziej w repozytorium, nie wie o niej, więc pisze drugą albo dokłada gałąź do struktury, którą widzi. Po kilku miesiącach ta sama walidacja, ponawianie żądań albo mapowanie żyją w czterech miejscach z drobnymi różnicami. Poprawka trafia do jednego z nich, a trzy pozostałe zachowują błąd, czyli dokładnie ta niespójna zmiana klonu, którą Juergens i współautorzy powiązali z potwierdzonymi błędami.

    Co z tym robimy

    Uruchamiamy wykrywanie klonów na całym repozytorium, nie na pojedynczym pull requeście, i porównujemy każdą grupę klonów, żeby znaleźć kopie zmienione tylko w jednym miejscu. Każda niespójna grupa dostaje z zespołem werdykt: rozejście zamierzone albo poprawka, która ominęła rodzeństwo. Te na ścieżkach krytycznych naprawiamy najpierw, a detektor uruchamiamy po naprawie jeszcze raz, żeby potwierdzić spójność grupy. Konfiguracja detektora zostaje u was, żeby kolejny raport był porównywalny.

    Co zostaje u was: rejestr klonów z każdą niespójną grupą, jej werdyktem i priorytetem, plus konfiguracja detektora
  2. 2
    Utracona intencja zmiany

    Opis pull requesta jest generowany z diffa, więc tłumaczy, co się zmieniło, i nigdy dlaczego. Prompt, który wyprodukował zmianę, nie jest nigdzie zapisany, a ticket mówi tylko, czego chciał użytkownik, nie jaki kompromis przyjął inżynier. Pół roku później czytelnik widzi, że limit czasu ustawiono na jedenaście sekund, i nie ma jak się dowiedzieć, czy to była decyzja, czy wartość domyślna. Kolejna zmiana albo utrwala przypadek, albo łamie decyzję.

    Co z tym robimy

    Bierzemy próbkę scalonych zmian z okresu po wdrożeniu asystentów i każdą śledzimy wstecz do ticketu, promptu albo zapisanej decyzji. Udział zmian, których nie da się prześledzić, to liczba, której zespół potrzebuje. Potem dodajemy do szablonu pull requesta konwencję zapisu zmiany, jedną linię intencji i ograniczenie, które spełnia, i po kwartale pobieramy próbkę ponownie, żeby sprawdzić, czy udział się zmienił.

    Co zostaje u was: próbka śledzenia intencji z udziałem zmian bez śladu oraz poprawiony szablon pull requesta
  3. 3
    Testy pisane pod implementację

    Poproszony o testy, asystent czyta kod, który właśnie napisał, i potwierdza to, co ten kod robi, razem z pomyłką. Pokrycie liniowe modułu rośnie, panel świeci na zielono, a testy przeszłyby tak samo, gdyby logika była błędna. Zespół uważa moduł za zabezpieczony i luzuje przegląd kolejnych zmian w nim.

    Co z tym robimy

    Zawężamy pytanie do ścieżek krytycznych i uruchamiamy tam testy mutacyjne: drobne celowe błędy wstrzykiwane do kodu, a potem zliczenie, ile z nich zestaw testów wyłapuje. Testy, które nie łapią niczego, wypisujemy z nazwy. Te na ścieżkach krytycznych przepisujemy razem z waszym zespołem na podstawie wymagania, nie kodu, i uruchamiamy mutacje ponownie, żeby sprawdzić, czy wynik się zmienił.

    Co zostaje u was: wynik mutacji dla każdej ścieżki krytycznej, przed i po, z listą testów, które nie wyłapały żadnej mutacji
  4. 4
    Zależności, których nikt nie wybrał

    Pakiet pojawia się w pliku blokady, bo model widział go w danych treningowych dostatecznie często, żeby go zaproponować, a nie dlatego, że ktoś porównał go z tym, co repozytorium już miało. Skutek to dwa klienty HTTP, trzy biblioteki do dat i narzędzie powielające funkcję z biblioteki standardowej, każde z własnym rytmem aktualizacji i własną licencją. Gdy przychodzi komunikat o podatności, nikt nie wie, kto odpowiada za decyzję, czy pakiet zostaje, czy wylatuje.

    Co z tym robimy

    Porównujemy manifest zależności sprzed i po wdrożeniu asystentów, a dla każdego dodanego pakietu zapisujemy, czy nakłada się na istniejącą zależność, kiedy miał ostatnie wydanie i jaką ma licencję. Każda zależność dostaje właściciela i werdykt: zostaje, do zamiany, do usunięcia. Sprawdzamy, że po usunięciach projekt się buduje i przechodzi testy, a dziennik zostawiamy zespołowi, żeby kolejne dodanie było decyzją, a nie podpowiedzią.

    Co zostaje u was: dziennik decyzji o zależnościach z właścicielem i werdyktem dla każdego pakietu
  5. 5
    Moduł bez właściciela

    Z asystentem każdy inżynier może dotknąć każdego modułu i to robi. Koncentracja własności spada, liczba drobnych autorów na plik rośnie, a osobą, która odpowie na pytanie o moduł, jest nikt, bo pięć ostatnich zmian wniosło pięć różnych osób, każda pracując z narzędziem. Bird i współautorzy powiązali ten wzorzec z awariami na długo przed asystentami; asystenci tylko obniżają koszt jego wytworzenia.

    Co z tym robimy

    Budujemy z gita mapę własności dla każdego modułu, liczymy udział głównego właściciela i liczbę drobnych autorów i oznaczamy moduły, w których obie miary idą w złą stronę. Dla każdego oznaczonego modułu zespół wskazuje właściciela i zastępcę, a przekazanie jest spisaną procedurą z terminem przeglądu. Po kwartale liczymy mapę ponownie, żeby sprawdzić, czy udziały się przesunęły.

    Co zostaje u was: mapa własności per moduł z nazwanym właścicielem i zastępcą oraz procedura przekazania
Artefakty

Co zostaje u was.

  • Punkt odniesienia dla sześciu mierników, ze skryptami i konfiguracją, żeby zespół mógł je liczyć ponownie
  • Raport długu uszeregowany według kosztu zmiany, w którym każda pozycja nazywa moduł, mechanizm i miernik, który ją ujawnił
  • Plan remediacji z kolejnością prac, właścicielem każdej pozycji i mierzalną definicją ukończenia
  • Procedura przekazania własności modułów bez właściciela, z właścicielem, zastępcą i terminem przeglądu
  • Dziennik decyzji o zależnościach z werdyktem dla każdego pakietu dodanego po wdrożeniu asystentów
  • Spisana granica zakresu mówiąca, czego audyt nie objął, żeby raport dało się przekazać temu, kto wykona przebudowę
Proces

Jak pracujemy.

  1. 1
    1. Punkt odniesienia z gita

    Z dostępem do odczytu liczymy rotację, czas do pierwszej poprawki i własność dla każdego modułu i ustalamy z waszym zespołem, które ścieżki uznajemy za krytyczne. Na tym etapie są tylko liczby i okres, którego dotyczą.

    Tydzień 1
  2. 2
    2. Analiza statyczna, klony i mutacje

    Uruchamiamy wykrywanie klonów, śledzenie problemów w commitach autorstwa asystentów i testy mutacyjne na ścieżkach krytycznych. Każde znalezisko jest przypięte do modułu i miernika.

    Tydzień 1-2
  3. 3
    3. Raport i priorytety

    Szeregujemy znaleziska według kosztu zmiany i przechodzimy je z osobami, które ten kod utrzymują. Tam, gdzie zespół nie zgadza się z kolejnością, niezgoda trafia do raportu razem z powodem.

    Tydzień 2-3
  4. 4
    4. Przekazanie własności i ponowny pomiar

    Przekazujemy plan, procedurę i skrypty, a po kwartale wracamy, liczymy punkt odniesienia ponownie i raportujemy, co się przesunęło.

    Tydzień 3, potem jeden pomiar po kwartale
Powiązane przewodniki

Pozostałe strony z tej serii.

Powiązane usługi

Gdzie to zamienia się w usługę.

Źródła

Skąd pochodzą daty i liczby.

FAQ

Pytania, które zadają zespoły.

Opublikowane badania tego nie rozstrzygają. Eksperyment kontrolowany ze 151 uczestnikami nie wykazał spójnych sygnałów pogorszenia utrzymywalności; badanie 302,6 tys. commitów autorstwa asystentów w realnych repozytoriach wykazało, że 22,7% wprowadzonych przez nie problemów nigdy nie zostało naprawionych. Różnicę robi proces wokół narzędzia. Dlatego mierzymy wasze repozytorium, zamiast cytować wam którekolwiek z tych badań.
Tak, i po to zostawiamy skrypty. Audyt dokłada ocenę priorytetów zrobioną przez kogoś, kto nie zyskuje na wielkości remediacji, poprawnie ustawione za pierwszym razem przebiegi mutacji i klonów oraz raport, którego wasi inżynierowie nie musieli pisać o własnej pracy.
Nie ma opublikowanego uniwersalnego progu i nie będziemy go wymyślać. Porównanie, które się broni, to wasze repozytorium sprzed wdrożenia asystentów albo moduły pisane z asystentem i bez niego w tym samym okresie. Alarmem jest miernik idący w złą stronę kwartał po kwartale.
Nie. Audyt daje uszeregowany raport, plan remediacji i przekazanie własności. Przebudowa to osobna praca: waszego zespołu, nasza w ramach osobnego zlecenia albo kogokolwiek innego, kogo wybierzecie, a raport jest napisany tak, żeby dało się go przekazać każdemu z nich.
Dostępu do odczytu historii repozytorium, logów CI i manifestów zależności oraz możliwości uruchomienia analizy statycznej i testów mutacyjnych na kopii. Nie potrzebujemy dostępu do produkcji, a audyt nie dotyka infrastruktury.
Około trzech tygodni dla jednego repozytorium typowej wielkości, plus jeden ponowny pomiar po kwartale. Monorepo albo kilka serwisów trwa dłużej, a o ile dłużej, mówimy po pierwszym dniu pracy nad punktem odniesienia, nie przed.
Analiza statyczna oznacza problemy bezpieczeństwa obok zapachów kodu i trafiają one do raportu. Przegląd bezpieczeństwa kodu i jego zależności to osobna praktyka z własnym zakresem i do niej kierujemy, zamiast wciągać ją do audytu.

Porozmawiaj z inżynierem.

Napiszcie, na jakim etapie jesteście z długiem utrzymaniowym w waszym kodzie pisanym przez AI. Odpowiedź w jeden dzień roboczy.

Porozmawiaj z inżynierem
Szczecin - ul. Wawrzyniaka 6WWarszawaZielona GóraKraków