100 prosent KI-generert kode? Ja, hvis du tåler å gjøre forarbeidet!

– Vi tror vi er på vei inn i en hverdag der det blir uvanlig å skrive all kode for hånd, skriver Håkon Roald og Julie Krøgenes i Avo Consulting. Sånn gjør de spesifikasjonsdrevet utvikling med KI.

Julie Krøgenes og Håkon Roald i Avo Consulting stoler på KI-generert kode, men bare fordi de mener å gjøre det riktig.
Publisert

✍ leserinnlegg

Dette er et leserinnlegg fra en ekstern skribent, som betyr at innholdet ikke nødvendigvis speiler kode24s meninger. Vil du også bidra? Send oss en epost på [email protected], eller les mer her!

AI er din nye super-utvikler-kollega. Men hva betyr egentlig det i praksis? At vi gir Claude tilgang til repoet, trykker «play» og ser på mens koden skriver seg selv? 

Det er ikke rart utviklere steiler av den forenklingen. Mange har allerede sett kodeagenter drifte og loope på relativt enkle problemer. En agent som ikke finner en variabel du ser rett foran deg, og som svarer med å lage hundrevis av nye filer for å «fikse» det. Etter noen sånne runder er det naturlig å spørre: hvis dette er oppførselen i det små, hvordan skal vi kunne stole på at AI leverer kode med god nok kvalitet i det store? 

Finnes det likevel en måte å bruke AI til å generere kode på som både fungerer i praksis og oppleves trygg? Vår erfaring så langt er at svaret er ja. Det bygger på en eldgammel praksis: grundige forberedelser. 

De siste månedene har vi utforsket spesifikasjonsdrevet utvikling (Spec-Driven Development, SDD). I noen av løsningene vi jobber med nå, er faktisk all koden skrevet av AI. Det betyr ikke at vi har lent oss tilbake. Tvert imot har det krevd mange runder med avklaringer, iterasjoner på krav, brukerbehov og skisser, og kontinuerlig kvalitetssikring. Det meste av jobben skjer før AI skriver sin første kodelinje – og fortsetter gjennom hele implementeringen. Det krever erfaring med kode, et skarpt blikk for logikk og god forretnings- og prosessforståelse. 

Når vi gjør dette skikkelig, ser vi til gjengjeld en tydelig effekt: AI klarer å produsere kode med svært høy kvalitet, og gjør det raskere enn vi hadde klart på egen hånd. Resten av artikkelen handler om hvordan vi jobber for å få det til, hvor det går galt, og hvorfor vi likevel tør å stole på 100 % AI-generert kode i enkelte deler av prosjektene våre. 

Det er ikke et tegn på dårlig AI, men på manglende rammer.

AI kan skrive koden – ikke ta beslutningene 

I de fleste prosjekter er det sjelden selve koden som er hovedproblemet. Vi sitter ikke fast fordi vi ikke klarer å skrive funksjonen, komponenten eller API-endepunktet. Utfordringene dukker som oftest opp etterpå: når ulike deler av teamet har tolket oppgaven ulikt, når forutsetninger ikke var godt nok avklart, eller når viktige edge-caser først oppdages i test eller produksjon. Det er denne typen uklarhet som skaper friksjon i utviklingsløpet.

Når vi slipper AI løs på løse beskrivelser og uavklarte forventninger, forsterkes dette raskt. Modellen tar teknologivalg vi aldri har besluttet, introduserer felter og strukturer som ikke finnes i domenet, og produserer løsninger som kan være imponerende isolert sett, men som ikke passer inn i resten av systemet. Det er ikke et tegn på dårlig AI, men på manglende rammer. 

Når vi derimot gjør forarbeidet grundig, skjer det noe annet. Med en strukturert spesifikasjon og tydelige føringer treffer AI langt bedre på første forsøk. Koden henger tettere sammen med design, tester og dokumentasjon, og utviklerne kan bruke mer av tiden sin på å vurdere kvalitet, avgrensninger og konsekvenser – i stedet for å skrive og omskrive kjent boilerplate. 

Standpunktet vårt er derfor ganske rett frem: 100 % AI-generert kode kan ha høy kvalitet, men bare når spesifikasjonen er tydelig nok, og utviklerne fortsatt eier beslutningene som tas. 

Slik ser det ut i praksis hos oss 

I Avo har vi valgt å jobbe spesifikasjonsdrevet med AI som en integrert del av utviklingsløpet. Til dette bruker vi Spec Kit, et åpent rammeverk fra GitHub for strukturert spesifikasjonsarbeid, kombinert med AI-agenter (i hovedsak Claude) og Model Context Protocol (MCP) for å gjøre prosjektdata tilgjengelig for agenten på en kontrollert måte. 

Før vi starter på konkrete features, etablerer vi en felles grunnmur for prosjektet. Denne beskriver hvilke teknologier som gjelder, hvilke krav og prinsipper som er førende, og hvilke rammer AI skal operere innenfor. Hensikten er å gjøre beslutninger eksplisitte tidlig, slik at de ikke tas implisitt av en agent underveis i implementeringen. 

Deretter jobber vi systematisk med spesifikasjon før koding. For hver feature beskriver vi mål, brukerbehov, akseptansekriterier og relevante design- og tekniske føringer. Ved hjelp av AI lar vi spesifikasjonen bli lest kritisk, med spørsmål rundt uklarheter, edge- caser og feiltilfeller. Disse avklaringene legges tilbake i spesifikasjonen før kode genereres. Målet er ikke å eliminere all usikkerhet, men å redusere den til et nivå som gjør implementeringen forutsigbar. 

Når spesifikasjonen er tilstrekkelig moden, lar vi AI-agenten generere førsteutkast til kode og tester, og i noen tilfeller også dokumentasjon. For å gi agenten best mulig kontekst, bruker vi MCP-er til å tilgjengeliggjøre relevante data direkte fra verktøy som design- og kodebaser, i stedet for at agenten må gjette eller basere seg på antakelser og gamle treningsdata. Utviklernes rolle er fortsatt avgjørende: vi reviewer alt som produseres, justerer løsninger og oppdaterer spesifikasjonen når nye beslutninger tas.

AI håndterer mye av det strukturelle arbeidet, mens mennesker har ansvar for kvalitet, helhet og videreutvikling. 

Diagram som viser hvilke MCP tjenester vi benytter i utviklingsløpet.

Diagram som viser hvilke MCP tjenester vi benytter i utviklingsløpet. 

Det er viktig å understreke at denne arbeidsformen ikke er lineær eller «låst» etter at spesifikasjonen er skrevet. I praksis har vi jobbet svært iterativt også etter at Spec Kit- kommandoene er kjørt. Når vi har sett behov for justeringer – særlig i grensesnitt og brukeropplevelse – har vi gått i direkte dialog med Claude om endringene. 

Noen nyanser er vanskelige å spesifisere fullt ut, både tekstlig og visuelt, som for eksempel hvordan drag-and-drop-funksjonalitet skal oppleves når elementer «snapper» på plass i en struktur. Her har vi erfart at dialogbaserte justeringer fungerer godt: agenten løser oppgaven, samtidig som spesifikasjonen oppdateres slik at endringene faktisk flyter videre i resten av utviklingsløpet. 

Konkret case: Gantt-basert fartøysplanlegging 

Et av prosjektene der vi tydelig merket effekten av denne arbeidsformen, var utviklingen av et system for Marivida, som løser fartøysplanlegging i havbruksnæringen. Oppgaven kombinerte et krevende domene med et komplekst brukergrensesnitt, og var derfor godt egnet til å teste hvor langt vi kunne ta spesifikasjonsdrevet og AI-assistert utvikling. 

Målet var å gi brukerne oversikt over hvilke behandlingsfartøy som er allokert hvor og når til ulike operasjoner, samtidig som de kunne planlegge og justere disse over tid.

Løsningen måtte vise både pågående og fremtidige operasjoner, og gjøre det tydelig hvilke konsekvenser en endring i én del av planen ville få for resten. Vi endte med en Gantt-lignende visualisering, der hver behandlingsoperasjon vises som en blokk på en tidslinje, knyttet til riktig fartøy, lokasjon og merd. Når én operasjon flyttes, må flere andre justeres, og disse følgeeffektene må være tydelige for brukeren. 

Frontend-logikken var i seg selv krevende, med mange samtidige operasjoner, avhengigheter og regler som måtte håndteres konsistent. Vi laget flere iterasjoner med Figma-skisser, hentet inspirasjon fra etablerte verktøy som Figma og Miro, og testet ulike interaksjonsmønstre for blant annet drag-and-drop, zoom og visualisering av konflikter. Underveis ble spesifikasjonen kontinuerlig oppdatert basert på det vi lærte gjennom brukertester og diskusjoner i teamet. 

Først da vi opplevde at vi hadde tilstrekkelig forståelse for domenet, et design som hang godt sammen, og tydelige akseptansekriterier, lot vi AI ta hånd om selve implementeringen. Dette ga oss et langt bedre utgangspunkt for å bruke AI effektivt, uten at vi mistet kontroll over løsningens helhet og kvalitet. 

For det første blir det færre misforståelser mellom design og utvikling.

Hva vi faktisk får igjen for dette 

Når vi jobber spesifikasjonsdrevet på denne måten, ser vi tre helt konkrete effekter. 

  • For det første blir det færre misforståelser mellom design og utvikling. Design er ikke lenger et vedlegg, men en del av spesifikasjonen. AI jobber mot faktiske designverdier og -variabler, og akseptansekriteriene blir presise nok til at «det ser riktig ut» ikke lenger holder som fasit. 
  • For det andre blir leveransene mer forutsigbare. Features spesifiseres på samme måte hver gang, og oppgaver som opprettes i verktøy som Linear er direkte knyttet til spesifikasjonen. Det gjør det enklere å se hva som faktisk er ferdig, hva som gjenstår, og hva som er endret underveis – både internt og overfor kunde. 
  • For det tredje kommer vi raskere til en fungerende første versjon. AI tar mye av det repeterende arbeidet, som standardmønstre, boilerplate og deler av testoppsettet. Utviklernes tid brukes i større grad på arkitektur, avgrensninger og kvalitet. Ikke fordi alt går av seg selv, men fordi fokuset flyttes fra gjentakelser til beslutninger.

Hvor går det typisk galt 

Dette er ikke en snarvei uten risiko. 

Når spesifikasjonene er svake, eller teamet ikke har nok teknisk erfaring til å vurdere det som genereres, ser vi raskt at AI begynner å drifte. Løsninger blir inkonsistente, unødvendig komplekse eller vanskelige å videreutvikle. 

Det kan også oppstå et falskt trygghetsnivå når mye kode genereres automatisk. Hvis utviklere slutter å gjøre grundig review og ta eierskap til beslutningene, forsvinner mye av kvalitetssikringen som metoden er avhengig av. 

Til slutt er det en praktisk begrensning i hvor mye kontekst AI klarer å håndtere samtidig. Store spesifikasjoner og brede features må deles opp for å fungere godt i praksis. Uten denne disiplinen forsvinner både presisjon og forutsigbarhet. 

Hvis du vil teste dette selv nå 

Du trenger ikke bygge en hel «AI-pipeline» for å se om dette fungerer hos dere. Start lite, men seriøst: 

  • Velg én konkret feature med moderat kompleksitet – stor nok til å ha reelle avklaringer, liten nok til å overskues. 
  • Lag så en mini-konstitusjon på en halv side. Den skal være praktisk, ikke poetisk: hvilken stack som gjelder, hvilke kvalitetskrav som er ufravikelige (for eksempel tilgjengelighet), hvordan dere forventer at tester skal se ut, og hva AI eksplisitt ikke har lov til å gjøre (typisk å introdusere nye rammeverk eller «finne opp» nye domeneobjekter). 
  • Deretter spesifiserer du før du koder. Skriv ned brukerhistorier, konkrete akseptansekriterier, feiltilfeller og edge-caser, og knytt det til designet (Figma eller skisser). Be så AI lese spesifikasjonen kritisk og stille spørsmål der den er uklar. Svar, oppdater spesifikasjonen, og gjenta til dere faktisk er enige om hva som skal bygges. 

Først når dette sitter, lar du AI generere førsteutkast til kode og tester. Gjør grundig review, juster, og legg beslutninger tilbake i spesifikasjonen i stedet for å «fikse det i koden». Avslutt med en ærlig evaluering: Ble dere faktisk raskere? Ble leveransen mer forutsigbar? Og hvor oppstod friksjonen – i spesifikasjonen, i AI-en, eller i egne arbeidsvaner? 

Denne tilnærmingen endrer heller ikke behovet for klassisk kvalitetssikring. Ytelsestesting, sikkerhetstesting, penetrasjonstester og annen «hygiene» er like relevant her som i tradisjonell utvikling. Det finnes ingen kodebase der man har full kontroll til enhver tid – enten koden er skrevet av en AI, eller av mange mennesker med ulike vaner, praksiser og nivå av konsistens. 

Enkelte områder må alltid følges opp tettere enn andre, uavhengig av om koden skrives av mennesker eller av AI. Autentisering, sikkerhet og domenekritisk logikk krever ekstra oppmerksomhet – særlig der feil kan føre til tap av liv og helse, stans i virksomheten eller alvorlige konsekvenser for brukere. Det samme gjelder sentrale prosesser der riktig dataflyt er avgjørende, og der flaskehalser lett kan oppstå. 

Når store deler av koden genereres automatisk, blir det enda viktigere å sette av tid til målrettet kvalitetssikring av nettopp disse områdene. Det gjelder både hvordan og når testing gjennomføres, og hvordan funn faktisk følges opp. Uansett hvem som har skrevet koden, må kritiske funksjoner forstås, testes og vurderes grundig – og det ansvaret forsvinner ikke med AI. 

Vi tror vi er på vei inn i en hverdag der det blir uvanlig å skrive all kode for hånd.

Når AI skriver koden, må noen eie helheten 

Vi tror vi er på vei inn i en hverdag der det blir uvanlig å skrive all kode for hånd. 

Det betyr ikke at utviklerrollen forsvinner, men at ansvaret endrer karakter. Mindre tid brukes på å produsere kode, mer tid på å forstå problemet som skal løses, ta bevisste valg og sikre kvalitet over tid. 

Vår erfaring er at jo mer ansvar vi gir AI, desto viktigere blir struktur og forberedelser. Spesifikasjonen er ikke et fossefallsdokument som låser løsningen, men et levende grunnlag som endres i takt med innsikt, testing og nye behov. Brukt riktig fungerer dette godt i smidige og iterative prosesser, ikke i motsetning til dem. 

AI kan produsere store mengder kode raskt og med høy kvalitet. Men kvaliteten oppstår ikke av seg selv. 

Den forutsetter at noen eier helheten – intensjonen, avgrensningene og beslutningene – også når koden ikke lenger skrives for hånd.

Powered by Labrador CMS