
Hvorfor koden din ikke blir bedre med AI
"Vi er mye mer produktive siden vi begynte med AI."
En setning jeg hører stadig. Men produktivitet og kodekvalitet er ikke det samme, og jeg tror vi blander dem oftere enn vi innrømmer. Det er en distinksjon som fortjener mer oppmerksomhet enn den får.
En ting bør sies med én gang: dette er ikke et argument mot AI i utvikling. Jeg bruker det selv, og ser verdien av det daglig. Jeg har tidligere skrevet om vibecoding og hva det egentlig koster. Dette innlegget er en forlengelse av det. AI gjør mye, men den overtar ikke vurderingen. Den overtar ikke ansvaret. Og den rydder ikke opp i koden over tid, i hvert fall ikke uten at noen ber den om det.
Hva er egentlig god kode
Kodekvalitet er ett av de begrepene alle bruker og ingen definerer. Jeg skal forsøke.
God kode løser problemet den er skrevet for. Det høres banalt ut, men det er et høyere krav enn det virker. Kode som teknisk sett virker, men som er umulig å forstå seks måneder senere, løser ikke problemet særlig godt. Det gjør heller ikke kode som fungerer i dag men sprekker under litt andre forutsetninger.
I praksis er det noen konkrete egenskaper utviklere ser etter. Koden er lesbar, det vil si at en annen person kan forstå hva den gjør uten å bruke uforholdsmessig lang tid. Den er vedlikeholdbar, slik at du kan endre én ting uten at ti andre ting ryker. Den er testbar, slik at du kan verifisere at den gjør det den skal. Og den er enkel, ikke nødvendigvis kort, men uten kompleksitet som ikke betaler seg.
Det siste punktet er det viktigste og det vanskeligste. Enkelhet krever at noen aktivt har tatt stilling til hva som ikke skal være der. Det oppstår ikke av seg selv. Kode vokser naturlig, og det å holde den enkel er en bevisst handling, ikke et biprodukt av å skrive mye kode raskt.
Det er nettopp her AI-verktøy har en strukturell svakhet, og det er ikke fordi de er dårlig laget.
Hva AI faktisk er
Store språkmodeller, altså det som driver Copilot, ChatGPT, Claude og lignende verktøy, er statistiske systemer. Ikke i en nedlatende forstand, men helt bokstavelig. En LLM (Large Language Model), er en modell som, gitt en ufullstendig tekst, forutsier hvordan teksten sannsynligvis vil fortsette.
Når man snakker om AI, blir ordet tokens ofte brukt. Et token er ikke det samme som et ord. Det er en liten tekstbit, kanskje et halvt ord, kanskje et helt, kanskje bare et tegn. Modellen ser på alt som kom før, regner ut en sannsynlighetsfordeling over alle mulige neste tokens, og plukker ett. Så gjør den det igjen og igjen. Det er bokstavelig talt alt som skjer, gjentatt milliarder av ganger.
Bak det ligger hundrevis av milliarder parametere, tall og vekter som justeres under trening for å gjøre modellen bedre til nettopp dette: å forutsi neste token. Treningsprosessen fungerer som en optimaliseringsøvelse der modellen belønnes for å gjette riktig og straffes for å gjette feil. Over tid lærer den hvilke mønstre som henger sammen, hvilke ord som følger hverandre, hvilke kodestrukturer som er vanlige. Men den lærer aldri intensjonen bak. Den lærer overflaten, ikke tanken.
Det er lettere å se hvis vi sammenligner med noe enklere. Et spamfilter bygget på naiv Bayesiansk klassifikasjon, en av de enkleste maskinlæringsmetodene som finnes, vet ikke hva spam er. Det har aldri forstått at noen prøver å lure deg. Det vet bare at ordet "reklameklikk" forekommer 53 ganger så hyppig i spam som i vanlige e-poster, og bruker det til å ta en beslutning. Det er mønstergjenkjenning, ikke forståelse. En språkmodell gjør nøyaktig det samme, bare i en enormt mye større skala med langt mer komplekse mønstre. Prinsippet er identisk.
Bygget for å legge til, ikke ta bort
Modellen lærer av det som finnes. Den har aldri sett en erfaren utvikler sitte og slette halvparten av koden sin fordi problemet viste seg å være enklere enn antatt. Den har ikke lært at den beste løsningen noen ganger er å ikke skrive noe.
For at en maskinlæringsmodell skal generalisere, må treningsdataene inneholde informasjon som er relevant for problemet den skal løse. I treningsdataene for en språkmodell er kode noe man legger til. Repositories vokser. Commits legger til linjer. Det er det modellen har sett milliarder av ganger, og det er det den er blitt god på å reprodusere.
GitClear analyserte 211 millioner endrede kodelinjer fra 2020 til 2024. I 2024 økte forekomsten av dupliserte kodeblokker åtte ganger sammenlignet med to år tidligere. Andelen kode som ble refaktorert og omstrukturert falt fra rundt 24 prosent i 2020 til under 10 prosent i 2024. Og 2024 ble det første året i datasettet der kopiering av kode oversteg refaktoreringsaktivitet.
AI legger til. Den fjerner ikke. Den kopierer. Den rydder ikke opp.
Her er det verdt å nyansere. Modellene har faktisk sett sletting. GitHub-historikk er offentlig, og treningsdataene inneholder commits med diff der kode forsvinner. Men det er et spørsmål om signalstyrke. For hver linje som slettes, er det mange flere som legges til. Og når en utvikler sletter kode, er begrunnelsen sjelden eksplisitt i committen. "Removed unused function" sier ingenting om hvorfor funksjonen var unødvendig, hvilken innsikt som lå bak, eller hva som ble vurdert og avvist. Modellen ser handlingen, ikke tanken.
Det er derfor mer presist å si at modellen har en strukturell preferanse for generering over forenkling. Den spør ikke om koden burde eksistere. Den spør bare hva som sannsynligvis bør komme neste.
Microsoft-forskere stilte for noen år siden et direkte spørsmål: forstår disse modellene faktisk kodelogikk, eller leser de kode som tekst? Svaret var klart. Modellene behandler kode som en uordnet samling av nøkkelord, ikke som logiske strukturer med mening og hensikt. De gjenkjenner mønstre de har sett før, og reproduserer dem. Det er som å be noen oversette en juridisk kontrakt ved å matche ord fra andre kontrakter, uten å forstå hva de faktisk forplikter seg til.
En AI kan ikke se på en kodebase og vurdere hva som ikke trengs. For å slette kode, refaktorere og forenkle kreves en intensjon om å gjøre noe mindre. Den intensjonen finnes ikke i en sannsynlighetsfordeling.
Og sikkerheten da
Det er lett å glemme sikkerheten når samtalen handler om produktivitet og hastighet. Men det er verdt å stoppe opp ved.
AI kopierer mønstre. Det er hele poenget. Men det betyr også at sårbare mønstre kopieres like effektivt som gode. En svakhet som ligger i treningsdataene dukker opp igjen og igjen i ny kode, uten at noen nødvendigvis legger merke til det. Elements of AI beskriver det samme fenomenet i forbindelse med algoritmisk diskriminering: hvis treningsdataene inneholder menneskelige feil og fordommer, lærer modellen seg å reprodusere akkurat de. Det er litt som da dårlige StackOverflow-svar spredte seg i produksjonskodebaser, bare i et mye større tempo.
Veracode testet over 100 store språkmodeller og fant at 45 prosent av AI-generert kode inneholdt kjente sikkerhetssårbarheter. Det som er mer bekymringsfullt enn selve tallet, er at det ikke har forbedret seg, selv etter at modellvendorene annonserte sikkerhetsbevisst trening. Større modeller presterte ikke bedre enn mindre.
Tilliten er litt for høy
Problemet forsterkes av noe menneskelig. AI-generert kode godtas ofte uten tilstrekkelig gjennomgang. Det henger delvis sammen med tempo, det går raskt å generere, så det føles raskt å godkjenne. Uverifisert kode merges, teknisk gjeld hoper seg opp, og til slutt er det noen som må rydde opp.
De fleste kjenner på sukket av å åpne en altfor stor pull request med dusinvis av endrede filer. Det er nesten ironisk: AI genererer mer kode enn nødvendig, og det gjør oss mindre kritiske til den. Terskelen for hva som godkjennes synker. Man ser at det ser riktig ut, ikke at det er riktig.
Resultatet er at kodebasen vokser raskere enn den gjennomgås. GitClears data viser det samme. Andelen kodelinjer som ble revidert innen to uker etter innsjekking nesten doblet seg fra 2020 til 2024. Koden skrives raskt, sendes inn raskt, og rettes deretter raskt. Det er ikke effektivitet. Det er å skyve problemet fremover i tid, og gjøre det dyrere å løse. Google sitt DORA-team fant noe tilsvarende: mer AI-bruk ga raskere leveranser, men også lavere leveringsstabilitet. Mer kode ute, men mer å håndtere når noe går galt.
AI genererer ikke dårlig kode med vilje. Men den genererer mer enn nødvendig, uten å vurdere om det burde eksistere.
Hva det betyr i praksis
Det hjelper å ha klart for seg hva disse verktøyene faktisk er. En LLM kan ikke refaktorere bort et lag den ikke er bedt om å se. Den er ikke bygd for å bestemme at en funksjon er overflødig, i hvert fall ikke uten eksplisitt instruksjon. Den kan ikke prioritere enkelhet over fullstendighet, fordi treningsdataene belønner kode som finnes, ikke kode som mangler.
Hver gang du ber AI om å legge til noe, er det sannsynlig at du får mer kode enn du trenger. Det er ikke en bug. Det er slik systemet er bygd.
Det merkes gjerne i det små. Du ber om en funksjon for å validere et skjema, og får tilbake femti linjer som håndterer edge cases du ikke visste du hadde. Du ber om å fikse en bug, og får en løsning som introduserer et nytt lag med abstraksjon ingen ba om. Koden virker. Den er bare ikke enkel. Det er lett å tenke at AI var smart og tenkte på ting du ikke tenkte på selv, men det er også her tilliten kan bli litt for høy.
Verktøyet er godt til det det er laget for. Det genererer, det fullfører, det foreslår. Men det stiller aldri spørsmålet som faktisk skiller god kode fra dårlig: trenger vi dette? Den vurderingen tilhører fortsatt deg.
Du er fortsatt den som bestemmer
Koden din blir ikke automatisk bedre med AI. Den kan bli raskere å skrive, og det er ikke ingenting. Men raskere skrevet og bedre er ikke det samme.
Matematikken og statistikken som driver disse verktøyene er optimert for sannsynlige fortsettelser av eksisterende kode. Ikke for renhet, ikke for enkelhet, ikke for å fjerne det som ikke burde vært der i utgangspunktet. Å forvente at et neste-token-system skal lede deg mot en slankere kodebase er litt som å forvente at telefonens autofullfør skal gjøre meldingene dine kortere.
Bruk AI som et verktøy for å komme raskere i gang, skrive boilerplate og utforske løsninger. Men styr retningen selv. Ansvaret for arkitektur, refaktorering og sikkerhet er ditt. Det har alltid vært det, og AI endrer ikke det. Den gjør det bare lettere å glemme at det finnes.
Det er du som må stille spørsmålene AI aldri stiller: trenger vi dette? Er dette enkelt nok? Vil vi forstå dette om seks måneder? De spørsmålene er ikke tekniske. De er faglige. De lar seg ikke delegere til statistikk, i alle fall ikke ennå.
Kilder
- GitClear, AI Copilot Code Quality 2025 – analyse av 211 millioner kodelinjer (2020–2024): gitclear.com
- GitClear, Coding on Copilot (2024): gitclear.com
- Qi et al. (2024), Is Next Token Prediction Sufficient for GPT? Exploration on Code Logic Comprehension, Microsoft/arXiv: arxiv.org/abs/2404.08885
- Veracode (2026), Despite Claims, AI Models Are Still Failing Security: veracode.com
- Center for Security and Emerging Technology (CSET), Cybersecurity Risks of AI-Generated Code, november 2024: cset.georgetown.edu
- arXiv preprint (2026), Debt Behind the AI Boom: A Large-Scale Empirical Study of AI-Generated Code in the Wild: arxiv.org/abs/2603.28592
- Google DORA, State of DevOps Report 2024: dora.dev
- LeadDev, How AI generated code compounds technical debt (2025): leaddev.com
- University of Helsinki og NTNU, Elements of AI – introduksjonskurs i kunstig intelligens: elementsofai.com/no