Dług utrzymaniowy kodu pisanego przez AI: jak zmierzyć go we własnym repozytorium i co zrobić z wynikiem
Dług utrzymaniowy kodu pisanego przez AI to dodatkowy nakład na każdą późniejszą zmianę, wynikający z wcześniejszych decyzji albo zaniedbań w kodzie, który powstał z asystentem. Audyt mierzy go w waszym repozytorium sześcioma miarami z gita i analizy statycznej i kończy się planem naprawy z priorytetami. Mechanizmy, które ten dług tworzą, są opisane niżej.
23Minds audytuje dług utrzymaniowy w kodzie pisanym przez AI dla zespołów inżynierskich, u których dostarczanie przyspieszyło, a zmiany zwolniły. Audyt liczy sześć miar z historii gita i analizy statycznej: względną zmienność pliku, czas do pierwszej poprawki po scaleniu, koncentrację własności, zduplikowane i niespójnie zmieniane bloki, kod na ścieżkach krytycznych bez skutecznych testów oraz przeżywalność problemów wprowadzonych przez asystentów. Za większością miar stoi opublikowane badanie, a strona mówi wprost, gdzie dowody są niejednoznaczne i które miary są propozycją audytu. Wynik to raport długu uszeregowany według kosztu zmiany, plan naprawy, który zespół wykonuje sam, oraz procedura przekazania własności modułów bez opiekuna nazwanym osobom. Przepisanie kodu nie jest częścią audytu.
Kto skorzysta z tego przewodnika.
- CTO i szefowie inżynierii, którzy wdrożyli asystentów kodowania w całym zespole i widzą, jak zmiany publikują się częściej, a każda pojedyncza trwa dłużej
- Menedżerowie inżynierii przejmujący repozytorium, w którym duża część kodu nie ma autora, który pamięta, dlaczego wygląda tak, a nie inaczej
- Tech leadzi, których poproszono o liczbę opisującą dług przed następnym cyklem planowania, a mają tylko przeczucie
- Zespoły, które zatrudniają albo budżetują naprawę kodu pisanego przez AI jako osobną kategorię pracy i potrzebują jej zakresu
Skąd bierze się koszt
Dowody o kodzie pisanym przez AI są niejednoznaczne. W kontrolowanym eksperymencie ze 151 uczestnikami, w 95% zawodowymi programistami, Borg i współautorzy (Echoes of AI, 2025) nie zaobserwowali spójnych sygnałów pogorszenia utrzymywalności na poziomie kodu, gdy inni programiści rozwijali kod pisany z AI. W prawdziwych repozytoriach obraz jest inny: Liu i współautorzy (Debt Behind the AI Boom, 2026) prześledzili 302,6 tys. zweryfikowanych commitów autorstwa AI w 6 299 repozytoriach. Ponad 15% commitów od każdego asystenta wprowadzało co najmniej jeden problem wykrywany analizą statyczną, a 22,7% tych problemów pozostawało w kodzie na koniec badanego okresu. Raport DORA 2025, oparty na blisko 5 000 odpowiedzi, pokazuje dodatni związek adopcji AI z przepustowością i trwale ujemny ze stabilnością dostarczania. Te badania nie rozstrzygają, z czego wynikają różnice między zespołami. Jedyny sposób, żeby wiedzieć, po której stronie jest wasze repozytorium, to je zmierzyć.
Pięć mechanizmów powtarza się w opisanych badaniach i w audytach; każdy jest własnością narzędzia użytego bez procesu, a to, czy występuje u was, pokazuje pomiar. Asystent widzi pliki w swoim oknie kontekstu, więc dokłada pomocnika albo gałąź obok istniejącej struktury, zamiast użyć tego, co leży dwa katalogi dalej. Opis pull requesta wygenerowany z diffu zapisuje, co się zmieniło, ale nie dlaczego, więc intencja zmiany znika w dniu scalenia. Testy wygenerowane z implementacji sprawdzają obecne zachowanie razem z błędem. Raportują wysokie pokrycie, nie łapiąc niczego. Zależność pojawia się, bo model często ją widział, a nie dlatego, że ktoś w zespole zdecydował ją nieść. A rozproszone autorstwo pliku dotykanego przez pięć osób i ich asystentów wskazuje moduły, dla których warto potwierdzić opiekuna; Bird i współautorzy (2011) powiązali taki wzorzec z awariami przed wydaniem i 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, punkt, w którym odpowiedzialności za wygenerowaną logikę nie da się przypisać nikomu.
Sawada i współautorzy (2026) przeanalizowali około 1 000 plików wygenerowanych przez AI w 100 popularnych repozytoriach. Takie pliki dostają rzadszą konserwację niż kod pisany przez ludzi, zmiany, które dostają, to głównie rozszerzenia funkcji, a nie poprawki. Niemal całą tę konserwację wykonują ludzie. Plik, który ciągle 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ść miar, które policzycie z gita i analizy statycznej
Żadna z miar poniżej nie wymaga komercyjnej platformy. Potrzebują dostępu do odczytu repozytorium, logów CI, przebiegów analizy statycznej i możliwości uruchomienia testów na kopii. Za większością stoi opublikowany powód, żeby jej ufać; testy mutacyjne i czas do pierwszej poprawki są propozycją audytu opartą na tych badaniach. Dla żadnej nie ma uniwersalnego progu alarmowego. Porównanie, które się broni, to wasze własne repozytorium sprzed asystentów albo moduły pisane z nimi i bez nich. Commity autorstwa asystenta rozpoznajemy po oznaczeniach w historii, szablonie pull requesta i rozmowie z zespołem; tam, gdzie oznaczeń nie ma, pomiar obejmuje okres po wdrożeniu asystentów jako całość.
| Miara | Jak jest liczona | Dlaczego można jej ufać | Jak wygląda zły odczyt |
|---|---|---|---|
| Względna zmienność pliku | Linie zmienione w pliku w okresie, podzielone przez rozmiar pliku, z git log | Nagappan i Ball (ICSE 2005): względne miary zmienności dobrze przewidują gęstość defektów, bezwzględne nie | Pliki, których względna zmienność dalej rośnie po wdrożeniu asystenta, bez odpowiadającej pracy nad funkcjami |
| Czas do pierwszej poprawki po scaleniu | Dla każdej scalonej zmiany: dni do następnego commita dotykającego tych samych linii, który odwołuje się do błędu, cofnięcia albo hotfixa | Bezpośrednia miara stabilności, którą DORA opisuje jako koszt większej liczby zmian bez systemów kontroli | Skracający się odstęp między scaleniem a poprawką, czytany razem z liczbą i wagą poprawek; sam krótszy odstęp może też oznaczać sprawniejsze wykrywanie błędów |
| Koncentracja własności | Udział commitów najaktywniejszego autora w module oraz liczba autorów poniżej małego udziału, z git blame i log | Bird i współautorzy (FSE 2011): liczba autorów o niskiej znajomości modułu i udział głównego właściciela wiążą się z błędami przed wydaniem i awariami po nim | Moduły, w których udział głównego właściciela maleje, a ogon drobnych autorów rośnie |
| Zduplikowane i niespójnie zmieniane bloki | Wykrywanie klonów w całym repozytorium, potem diff każdej grupy klonów, żeby znaleźć kopie zmienione tylko w jednym miejscu | Juergens i współautorzy (ICSE 2009): 107 potwierdzonych przez programistów błędów z niespójnych zmian klonów w pięciu systemach komercyjnych i open source | Grupy klonów, w których poprawka błędu weszła do części kopii, a do reszty nie |
| Kod na ścieżkach krytycznych bez skutecznych testów | Pokrycie ograniczone do ścieżek obsługujących pieniądze, tożsamość i dane, potem testy mutacyjne na tych ścieżkach | Samo pokrycie mówi, że linia została wykonana; wynik testów mutacyjnych pokazuje, jaką część wprowadzonych mutacji wykryły testy | Wysokie pokrycie linii przy niskim wyniku mutacji na ścieżkach, które mają znaczenie |
| Przeżywalność problemów wprowadzonych przez asystenta | Analiza statyczna przed każdym commitem autorstwa asystenta i po nim, potem śledzenie każdego wprowadzonego problemu do bieżącej wersji | Metoda, którą Liu i współautorzy (2026) zastosowali na 302,6 tys. commitów; oddziela problemy naprawiane od tych, które się kumulują | Rosnąca zaległość wprowadzonych problemów, których nikt nie zamyka, skupiona w modułach bez właściciela |
Naprawa kodu pisanego przez AI jako kategoria pracy i gdzie audyt się kończy
W dyskusjach doświadczonych programistów naprawa kodu pisanego przez AI stała się osobną kategorią pracy: przejąć kod, którego nikt nie napisał, a potem sprawić, żeby znów dało się go zmieniać. Audyt wyznacza zakres tej pracy: daje uszeregowaną listę, plan i przekazanie własności, a nie wykonuje przepisania, z dwóch powodów. Zespół, który ma żyć z tym kodem, powinien być tym, który go porządkuje, inaczej intencja ginie drugi raz. A audyt i ewentualna naprawa są wyceniane osobno, żeby wynik audytu nie zależał od wielkości naprawy.
Zakres audytu:
- W zakresie: sześć miar powyżej policzonych na waszym repozytorium, ze skryptami zostawionymi u was, żeby zespół mógł je uruchamiać dalej
- W zakresie: raport długu uszeregowany według kosztu zmiany, w którym każda pozycja nazywa moduł, mechanizm i miarę, która go ujawniła
- W zakresie: plan naprawy 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 opiekuna nazwanym osobom, z zastępcą i datą przeglądu
- Poza zakresem: przepisywanie, refaktoryzacja albo migracja kodu; to osobny zakup, od 23Minds albo od kogokolwiek innego, a raport jest napisany tak, żeby dało się go przekazać jednym i drugim
- Poza zakresem: infrastruktura, konfiguracja chmury i testy penetracyjne; audyt czyta repozytorium, a nie środowisko, w którym ono działa
Co może pójść nie tak i co z tym robimy.
- 1Duplikacja zamiast ponownego użycia
Asystent pracuje na plikach ze swojego kontekstu. Gdy podobny pomocnik istnieje gdzie indziej w repozytorium, asystent o nim nie wie, więc pisze drugi albo dokłada gałąź do struktury, którą widzi. Po kilku miesiącach ta sama logika walidacji, ponowień albo mapowania żyje w czterech miejscach z drobnymi różnicami. Poprawka trafia do jednego z nich, a pozostałe trzy zachowują błąd. To dokładnie ta niespójna zmiana klonu, którą Juergens i współautorzy powiązali z potwierdzonymi błędami.
Co z tym robimyUruchamiamy wykrywanie klonów w całym repozytorium (nie per pull request) i porównujemy każdą grupę klonów, żeby znaleźć kopie zmienione tylko w jednym miejscu. Każda niespójna grupa dostaje werdykt uzgodniony z zespołem: rozbieżność zamierzona albo poprawka, która ominęła rodzeństwo. Te na ścieżkach krytycznych trafiają na początek planu naprawy, a po naprawie przez zespół detektor uruchamiamy ponownie, żeby potwierdzić spójność grupy. Zespół zatrzymuje konfigurację detektora, więc następny raport jest porównywalny.
Co zostaje u was: rejestr klonów z każdą niespójną grupą, jej werdyktem i priorytetem oraz konfiguracja detektora - 2Utracona intencja zmiany
Opis pull requesta jest generowany z diffu, więc wyjaśnia, co się zmieniło, a zwykle nie dlaczego. Prompt, który wyprodukował zmianę, nie jest nigdzie zapisany, a ticket mówi tylko, czego chciał użytkownik, a nie jaki kompromis przyjął inżynier. Pół roku później czytelnik widzi, że limit czasu ustawiono na jedenaście sekund. Nie ma jak się dowiedzieć, czy to była decyzja, czy wartość domyślna. Następna zmiana albo utrwala przypadek, albo psuje decyzję.
Co z tym robimyBierzemy próbkę scalonych zmian z okresu po wdrożeniu asystentów i śledzimy każdą 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, a po kwartale próbkujemy ponownie, żeby sprawdzić, czy udział się ruszył.
Co zostaje u was: próbka śledzenia intencji z udziałem zmian nie do prześledzenia oraz poprawiony szablon pull requesta - 3Testy pisane pod implementację
Poproszony o testy asystent czyta kod, który właśnie napisał. Sprawdza to, co ten kod robi, razem z błędem. Pokrycie linii w module rośnie, dashboard robi się zielony, a testy przeszłyby tak samo, gdyby logika była błędna. Zespół uznaje moduł za chroniony przez testy. Przez to mniej dokładnie sprawdza późniejsze zmiany.
Co z tym robimyZawężamy pytanie do ścieżek krytycznych i tam uruchamiamy testy mutacyjne: małe celowe błędy wstrzyknięte do kodu, potem zliczenie, ile z nich zestaw łapie. Testy, które nie łapią niczego, wypisujemy z nazwy. Te na ścieżkach krytycznych trafiają do planu naprawy z zaleceniem: przepisać z wymagania, a nie z kodu. Po naprawie przez zespół uruchamiamy mutacje ponownie, żeby sprawdzić, czy wynik się zmienił.
Co zostaje u was: wynik mutacji na każdej ścieżce krytycznej, przed i po, z listą testów, które nie złapały żadnego mutanta - 4Zależności, których nikt nie wybrał
Pakiet pojawia się w pliku blokady, bo model widział go w danych treningowych wystarczająco często, żeby go zaproponować, a nie dlatego, że ktoś porównał go z tym, co repozytorium już miało, a potem zdecydował go utrzymywać. W efekcie są dwa klienty HTTP, trzy biblioteki do dat i narzędzie, które dubluje funkcję z biblioteki standardowej, każde z własnym rytmem aktualizacji i licencją. Gdy przychodzi informacja o podatności, nikt nie wie, kto odpowiada za decyzję, czy pakiet zostaje.
Co z tym robimyPorównujemy manifest zależności sprzed wdrożenia asystentów i po nim, a przy każdym dodanym pakiecie zapisujemy, czy pokrywa się z istniejącą zależnością, kiedy miał ostatnie wydanie i na jakiej jest licencji. Każda zależność dostaje właściciela i werdykt: zostaje, do zamiany, do usunięcia. Sprawdzamy, czy po usunięciach projekt się buduje i przechodzi testy, a log zostawiamy zespołowi, żeby następne dodanie było decyzją, a nie podpowiedzią.
Co zostaje u was: log decyzji o zależnościach z właścicielem i werdyktem przy każdym pakiecie - 5Moduł bez właściciela
Z asystentem każdy inżynier może zmieniać każdy moduł i często to robi. Koncentracja własności spada, liczba autorów pojedynczych zmian na plik rośnie, a osobą, która mogłaby odpowiedzieć na pytanie o moduł, bywa nikt, bo ostatnie pięć zmian zrobiło pięć różnych osób, każda z narzędziem. Bird i współautorzy powiązali ten wzorzec z awariami na długo przed asystentami; asystenci tylko sprawiają, że taniej go wyprodukować.
Co z tym robimyBudujemy z gita mapę własności dla każdego modułu, liczymy udział głównego właściciela i liczbę autorów pojedynczych zmian 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 datą przeglądu. Po kwartale liczymy mapę ponownie, żeby sprawdzić, czy udziały się ruszyły.
Co zostaje u was: mapa własności per moduł z nazwanym właścicielem i zastępcą oraz procedura przekazania
Co zostaje u was.
- Punkt odniesienia dla sześciu miar, ze skryptami i konfiguracją, żeby zespół mógł je uruchamiać dalej
- Raport długu uszeregowany według kosztu zmiany; każda pozycja nazywa moduł, mechanizm i miarę, która go ujawniła
- Plan naprawy z kolejnością prac, właścicielem każdej pozycji i definicją ukończenia wyrażoną pomiarem
- Procedura przekazania własności modułów bez opiekuna, z właścicielem, zastępcą i datą przeglądu
- Log decyzji o zależnościach z werdyktem dla każdego pakietu dodanego od wdrożenia asystentów
- Spisana granica zakresu mówiąca, czego audyt nie objął, żeby raport dało się przekazać komukolwiek, kto zrobi przepisanie
Jak pracujemy.
- 11. Punkt odniesienia z gita
Z dostępem do odczytu liczymy zmienność, czas do pierwszej poprawki i własność dla każdego modułu i uzgadniamy z waszym zespołem, które ścieżki są krytyczne. Na tym etapie są tylko liczby i okres, który obejmują.
Tydzień 1 - 22. Analiza statyczna, klony i mutacje
Uruchamiamy wykrywanie klonów, śledzenie problemów w commitach autorstwa asystenta i testy mutacyjne na ścieżkach krytycznych. Każde ustalenie jest przypięte do modułu i miary.
Tydzień 1-2 - 33. Raport i priorytety
Szeregujemy ustalenia według kosztu zmiany i omawiamy je z ludźmi, którzy utrzymują kod. Gdy zespół nie zgadza się z kolejnością, niezgoda trafia do raportu razem z powodem.
Tydzień 2-3 - 44. Przekazanie własności i ponowny pomiar
Przekazujemy plan, procedurę i skrypty, a po kwartale wracamy, żeby policzyć punkt odniesienia ponownie i opisać wyniki ponownego pomiaru: które miary się poprawiły, które nie i dlaczego.
Tydzień 3, potem jeden pomiar po kwartale
Pozostałe strony z tej serii.
Analiza kosztów LLM i limity wydatku
Jak przypisać koszt LLM do wywołania, sesji i funkcji, co po cichu psuje cache promptów i gdzie alert o wydatkach powinien zamienić się w twardą blokadę.
Pomiar efektu AI w zespole
Dlaczego samo szybsze zamykanie zgłoszeń nie dowodzi efektu AI i jak go zmierzyć: punkt odniesienia sprzed wdrożenia, miary w parach, grupa porównawcza.
Porównanie narzędzi do AI code review
Porównanie narzędzi do AI code review na waszym kodzie: wykryte błędy, błędne komentarze i koszt na pull request, z protokołem do powtórzenia po zmianie modelu.
Usługi, które to wdrażają.
Audyt kodu pisanego przez AI
Niezależny audyt kodu pisanego przez AI według kryteriów opublikowanych w całości, z ceną ustaloną przed startem.
Utrzymanie aplikacji
Opieka nad funkcjami AI w waszej aplikacji: migracje modeli, testy jakości odpowiedzi po zmianach, aktualizacje zależności. Ogólne SRE tylko tam, gdzie styka się z AI.
Pokrycie testowe
Strategia testów dla projektów z kodem pisanym przez AI: co testować, co zastępować atrapą, co pominąć, oraz jak wykrywać błędy po kolejnych zmianach.
Skąd pochodzą daty i liczby.
- Liu i in., Debt Behind the AI Boom: A Large-Scale Empirical Study of AI-Generated Code in the Wild (arXiv:2603.28592, 2026)
- Borg i in., Echoes of AI: Investigating the Downstream Effects of AI Assistants on Software Maintainability (arXiv:2507.00788, Empirical Software Engineering 2026)
- Sawada i in., To What Extent Does Agent-generated Code Require Maintenance? An Empirical Study (arXiv:2605.06464, 2026)
- Ehsani i in., Faster Code, Deeper Debt? A Multivocal Literature Review on Technical Debt in LLM-Assisted Software Development (arXiv:2606.14796, 2026)
- Google Cloud, Announcing the 2025 DORA Report
- Bird i in., Don't Touch My Code! Examining the Effects of Ownership on Software Quality (ESEC/FSE 2011)
- Nagappan i Ball, Use of Relative Code Churn Measures to Predict System Defect Density (ICSE 2005)
- Juergens i in., Do Code Clones Matter? (ICSE 2009)
Pytania przed rozpoczęciem współpracy.
Porozmawiajmy o AI w waszej firmie.
Napiszcie, na jakim etapie jesteście z długiem utrzymaniowym w waszym kodzie pisanym przez AI. Odpowiedź w ciągu jednego dnia roboczego.