Det er med et splittet sinn jeg skriver om LLM-bruk. På den ene siden er det et helt magisk verktøy som har akselerert alle hobbyprosjektene mine til nye, mer ambisiøse høyder. På den andre siden er det ekstremt vanskelig å sette fra seg, da koden som produseres liksom aldri blir helt perfekt.
Det er litt enarmet banditt over det hele: «bare én prompt til, så blir alt perfekt». Selv med LLM-er som ikke er designet for å være maksimalt sykofantiske, er det vanskelig å slutte. Dog får man gjort mye når man bruker en LLM. Selv noen av de enklere modellene er nå, etter min erfaring, nyttige nok til at de kan brukes.
Omskriving, refaktorering, benchmarking og testing: Det er ingen grenser for hva man fort kan få lagt til i et prosjekt, og dermed kan fokusere like fullt på ytelse som på funksjonalitet. Det jeg gang på gang sliter med, er at når kravspesifikasjonen blir spesifikk eller kompleks nok, har modellen en tendens til å skrive litt vel kompleks kode, ofte også kode som ikke passer inn i et prosjekt. Så det blir fort en del arbeid med å rydde.
På den andre siden er det enklere å rydde opp i ting som allerede fungerer, så LLM-er er veldig greie for å kunne få testet og bekreftet at idéene man har, faktisk holder vann. Dette er en opplevelse mange utviklere har kjent seg igjen i med AI-generert kode; den er «nesten riktig», men tidkrevende å verifisere og feilsøke etter generering. [1]
Mine erfaringer peker på at LLM-er fungerer best når man har en tydelig referanse for hva som er riktig. Når en slik referanse finnes, flytter flaskehalsen seg fra å skrive kode til å definere korrekthet, teste resultatet og forstå konsekvensene av endringene man gjør.
Her er tre eksempler på ulik bruk av LLM og erfaringene jeg har gjort i prosessen:
Libpinyin
Jeg har lenge ønsket et rent Rust-bibliotek for å kunne skrive pinyin, altså kinesisk mandarin via alfabetet. Det finnes et eksisterende bibliotek, libpinyin, men det er skrevet i C++. Og som en ekte Rust-fanatiker vil jeg jo helst bare forholde meg til ren Rust-kode. [2]
Av ren nysgjerrighet tittet jeg litt på koden og tenkte at mye av dette nok kunne erstattes med Rust-crates. Deretter måtte jeg jo i min nysgjerrighet diskutere med en chatbasert LLM om hvilke pakker vi eventuelt kunne bruke for de ulike delene, og hvilke deler av algoritmen som måtte beholdes. Dette førte til at jeg ba LLM-en gi meg instruksjoner jeg kunne fôre inn i en LLM-agentflyt.
Etter en del frem og tilbake satt jeg igjen med et rent Rust-bibliotek for pinyin, som jeg i dag bruker for å skrive pinyin på Linux, i en egen hjemmesnekret løsning. Med andre ord: Å oversette et bibliotek på denne måten var en stor suksess. Det var et avgrenset domene, et fungerende bibliotek å teste mot, all data var tilgjengelig, og jeg skriver jo selv litt pinyin, så jeg kunne fint teste at alt fungerte slik det skulle. Her egnet LLM seg veldig godt til et brukbart sluttresultat. [3]
Den store ironien i det hele er at den sentrale algoritmen i libpinyin er en form for språkmodell, så jeg brukte altså en «Large Language Model» til å skrive en enkel «Language Model» og lærte litt om hvordan språkmodeller fungerer i løpet av prosessen.
Forbehold: libpinyin er lisensiert med GPL v3, så da har den omskrevne versjonen også så klart denne lisensen.
Wayland Keyboard
På Linux brukes det et tastaturbibliotek som heter xkbcommon, og som tar seg av layoutparsing, tastaturtilstand og resulterende tegn. For oss som skriver norsk håndterer biblioteket at når du trykker en bokstav på tastaturet, for eksempel «ø», så kommer «ø» eller «Ø» om du også trykker «Shift». [4]
I 2020 traff jeg på en begrensning i dette biblioteket. Jeg endret ett tegn i en layout fra «/» til «ㄙ». Det medførte fullstendig kapitulering av layoutprogramvaren, og til og med den dag i dag må jeg manuelt sette norsk som språk på denne maskinen. Maskinen er ellers dønn stabil og jeg bruker den primært til gaming, ergo har jeg ikke reinstallert den.
Høsten 2023 hadde jeg litt ledig tid og valgte å teste ut teorien min om at tastaturoppsett primært burde være mapping fra tastaturverdi til bokstav, altså en veldig datadrevet arkitektur. Jeg skrev kode og parser med en black-box-mentalitet, så jeg kunne fokusere på oppførsel og ikke bli påvirket av den meget komplekse arkitekturen i xkbcommon.
Etter tre år med koding, skrevet med egne kjøttfingre, var utdataene mellom mitt bibliotek og xkbcommon omtrent 90 prosent identiske. Utdata her er da det produserte tegnet, for eksempel «A» gitt at man presser «Shift+A». Men det var enormt mange spesialtilfeller, og siden jeg nå var gått litt lei og hadde lyst til å bevise at arkitekturen min var korrekt, enklere og raskere, fant jeg ut at jeg skulle erstatte min håndskrevne parser for XKB-filer med xkbcommon sin egen parser. Jeg ba en LLM bruke et program som heter C2Rust til å oversette hele xkbcommon fra C til Rust, og bare fikse feil i C2Rust på veien. C2Rust er et verktøy som oversetter C-kode til unsafe Rust. [5]
Deretter boltet jeg xkbcommon rett inn på mine datatyper, og for en gangs skyld var jeg kompatibel med de delene av xkbcommon sin funksjonalitet jeg hadde bestemt meg for å støtte i Wayland Keyboard. Xkbcommon har en del funksjonalitet som ikke er i bruk, så med kompatibel menes at jeg kjørte alle keycodes (1--701) inn i xkbcommon og Wayland Keyboard, og testet alle nivåer (1--8) og alle tilstander (Caps Lock, Num Lock, Shift og så videre), som kunne produsere et unikt tegn. Deretter brukte jeg månedsvis og mange forskjellige LLM-er for å sakte, men sikkert redusere min «unsafe» Rust-versjon av xkbcommon, omtrent 60 000 linjer med kode, ned til et par tusen linjer med minnesikker Rust, som nå kun gjør parsing. Resultatet var et mer minnesikkert og raskere bibliotek som bruker litt mindre RAM, og har omtrent like stor binærfil. [6] Siden jeg hadde xkbcommon som fasit og det jeg drev med omtrent var maskinoversettelser, var LLM-er meget nyttige og ga gode resultater.
Enterprise Legacy-prosjekt
De to første prosjektene hadde én viktig ting til felles: De hadde en definert teknisk fasit å teste opp mot. I enterprise-programvare derimot er det ofte nettopp denne fasiten som mangler. Dette erfarte jeg nylig da jeg jobbet hos en kunde under inntoget av LLM-er. Jeg har sett LLM-er gå fra en stokastisk papegøye til en uunnværlig del av arbeidsflyten hos kunden. Først var det bare små snutter med standardkode den kunne spytte ut. Så kunne den sakte, men sikkert klare hele skjelettet av en applikasjon, før den begynte å kunne erstatte større deler av arbeidsflyten. Enterprise-programvare er imidlertid ofte full av spesialtilfeller som den stokastiske modellen ikke får med seg. For meg gir dette mening: Store bedrifter utvikler seg organisk over tid, og da gjøres det fort ting i ytterkanten av en stokastisk modell, altså unike menneskelige valg. Man havner fort i en flaskehals der begrensningene ikke lenger er kode, men å finne tilstrekkelig med mennesker som kan teste og verifisere at koden stemmer. Legacy-koden man skriver om, er kanskje veldig gammel, den som skrev den har sluttet for mange år siden, og tusenvis av mennesker bruker programvaren hver dag. Med andre ord erfarer man at produksjonen av kode går opp, mens en organisasjons evne til å absorbere endringer blir flaskehalsen i stedet. Det er ingen enkel teknisk fasit, og korrektheten ligger fordelt mellom domenekunnskap, historiske særtilfeller, brukere og organisasjonen. [7]
Hva betyr dette for fremtiden?
Det er vanskelig å sette fingeren på nøyaktig hvordan fremtiden ser ut. Men jeg tror én ting kommer til å skje: Markedet for generell virksomhetsprogramvare vil krympe kraftig. Når kostnaden ved å lage og tilpasse programvare faller, blir det vanskeligere for mange virksomheter å forsvare kostnadene for typisk rigide CRM-, ERP- og CMS-løsninger. Om prisene på slik programvare blir for høye, kan man enten skrive sin egen løsning eller tilpasse fri og åpen programvare til sitt formål. Det betyr ikke at all programvare plutselig er enkel å lage. Men det betyr at terskelen for å eie den delen av programvaren som er spesielt viktig for ens eget arbeid, blir langt lavere. LLM-er er gode verktøy for å kunne implementere ting fort og kan assistere med drift, integrasjoner, sikkerhet, regelverk, datamigrering og vedlikehold. De kan dermed frigjøre utviklerressurser som ellers hadde blitt brukt på ren integrasjon av et programvareprodukt, slik at de heller kan skape direkte gevinst for brukerne sine uten å møte begrensninger som finnes i mer rigide produkter.
Jeg kan fort se for meg at hver avdeling i en bedrift har sitt unike grensesnitt tilpasset deres arbeidsmetoder, mens all relevant data og tilgangsstyring håndteres sentralt. Slik opprettholder man datakvalitet, samtidig som man forhindrer at hvert team lager sin egen versjon av sannheten. Jeg spenner ganske bredt når jeg sier «data», men med det mener jeg en felles datamodell, ett eller flere API-er og én eller flere databaser -- med andre ord et definert grensesnitt med sentral identitetsstyring.
Mine tre erfaringer har samme mønster. LLM-er gir mest når jeg kan definere hva som er riktig og har en måte å teste det på. Når det ikke finnes en enkel fasit, er det ikke kodeproduksjon som begrenser hvor fort man kan gå, men menneskene som må forstå, teste og ta ansvar for endringen. Selv om dette er en begrensning i dag, tror jeg LLM-er kommer til å fremtvinge restruktureringer som lar oss bygge langt mer programvare internt. LLM-er belyser fort ineffektive prosesser og tydeliggjør viktigheten av arkitektur, data og ansvarsfordeling.
Referanser
[1] Stack Overflow Developer Survey 2025 -- bruk av AI-verktøy, tillit, «nesten riktige» svar, debugging og utvikleres opplevde produktivitet.
[2] libpinyin -- upstream-prosjektet.
[3] rano-oss/libchinese -- Rust-implementasjonen, tester, dokumentasjon og lisens.
[4] xkbcommon -- prosjektets egen beskrivelse av XKB-implementasjon og bruksområder.
[5] C2Rust -- verktøyet brukt for oversettelse fra C til Rust.
[6] rano-oss/wkb -- prosjektet og benchmark- og kompatibilitetstestene omtalt over.
[7] DORA 2025 State of AI-Assisted Software Development -- AI-innføring som systemproblem, verdistrømmer og «legacy bottleneck».



