# Tallene AI-en ikke får finne på

> Hallusinerte tall er den største innvendingen mot AI i markedsføringsrapportering. Vi løste det ved å ta regnestykket fra modellen. 184 deterministiske KPI-formler, en tall-gate som avviser alt uten kilde, 124 regresjonssjekker og 22 netter med automatisk gransking av våre egne svar. Her er arkitekturen — og funnene vi ikke pyntet på.

- Publisert: Juli 2026 (2026-07-30)
- Forfatter: m51.ai Lab
- Lesetid: 12 min lesing
- Serie: m51 Plattform
- Kanonisk HTML-utgave: https://m51.ai/lab/tallene-ai-en-ikke-far-finne-pa
- English edition (Markdown): https://m51.ai/en/lab/tallene-ai-en-ikke-far-finne-pa.md
- Alle Lab-artikler (Markdown-indeks): https://m51.ai/lab/index.md

---

## Hovedfunn (TL;DR)

- Språkmodeller er gode til å skrive og dårlige til å regne. I m51.ai regner de derfor ikke: hvert tall i en rapport kommer fra én av 184 deterministiske KPI-formler i en egen motor, ikke fra modellen.
- Modellen får se tall, men bare de godkjente. En allowlist avviser hvert tall i et utkast som ikke kan spores til et godkjent faktum — med egne unntaksklasser for årstall, datoer og telefonnumre, så gaten ikke slår ut på det som ikke er en ytelsespåstand.
- Deteksjon er deterministisk, formulering er modellens jobb. 16 playbooks finner problemene med regler; språkmodellen har kun rollen som avgrenset dommer over det reglene allerede fant.
- 124 automatiske regresjonssjekker kjører uten et eneste LLM-kall mot datapakker med kjent fasit, innenfor et hardt budsjett på 175 sekunder, og holder baselinen på null kritiske og null alvorlige avvik.
- Ett lag er et uavhengig orakel: det regner hovedtallene på nytt rett fra rå API-svar og sammenligner med det pipelinen kom fram til. Det er den eneste sjekken som ikke stoler på vår egen utregning.
- Gjennom 22 netter i juli har en automatisert gransking lest våre egne chat-svar og dømt dem mot en rubrikk med seks dimensjoner. 103 turer er dømt. Vi publiserer hva den fant, inkludert det som var galt.

---

## Hvorfor tall er det vanskeligste AI gjør

Et markedsføringsteam kan leve med at en AI-generert setning er litt klosset. Det kan ikke leve med at ROAS-en i rapporten er 4,2 når den egentlig er 3,1. Det første er en redigeringsjobb. Det andre er en beslutning tatt på feil grunnlag, og i verste fall et budsjett flyttet feil vei.

Problemet er at språkmodeller er bygget for å produsere plausibel tekst, ikke korrekte tall. En modell som har sett tusenvis av rapporter vet nøyaktig hvordan en ROAS-setning ser ut, og hvilke tall som pleier å stå i den. Den har ingen intern mekanisme som skiller «tallet jeg faktisk leste i datagrunnlaget» fra «tallet som passer i denne setningen». Begge deler føles like riktige innenfra.

**Derfor er «vi bruker en bedre modell» ikke et svar på hallusinerte tall. Bedre modeller hallusinerer sjeldnere, men de hallusinerer fortsatt, og de gjør det mer overbevisende. Svaret må være arkitektonisk: modellen må settes i en posisjon der den ikke kan finne på et tall, fordi den aldri var den som produserte det.**

Vi har bygget seks lag rundt det prinsippet. Her er hvert av dem, og hva de faktisk fanger.

## Lag 1: Modellen regner ikke

Alle KPI-er i m51.ai beregnes av KPIRegistry, en egen motor i backend som per i dag inneholder 184 registrerte KPI-formler fordelt på ti domenemoduler: Google Ads, SEO, GA4, CRO, GEO, paid social, LinkedIn, Performance Max, porteføljestyring og rapport-KPI-ene.

En formel er vanlig kode. ROAS er konverteringsverdi delt på kostnad, og ingenting annet. Den kjører før språkmodellen i det hele tatt blir spurt om noe. Når agenten senere skal skrive analysen, får den KPI-verdien ferdig utregnet, sammen med perioden den gjelder for, enheten, og hvilken råfeltsti verdien ble hentet fra.

Det betyr at ingen språkmodell utfører en divisjon i produksjonspipelinen vår. Den beskriver et regnestykke noen andre allerede har gjort. Skillet høres akademisk ut, men det er hele forskjellen: en beskrivelse kan være dårlig formulert, men den kan ikke gi feil svar på et regnestykke som er ferdig før den ble spurt.

### Hvem gjør hva

| Oppgave | Hvem utfører den | Hvorfor |
| --- | --- | --- |
| Hente rådata fra GA4, Google Ads, Meta og Search Console | Deterministisk kode | API-kall har fasit |
| Regne ut KPI-er | KPIRegistry — 184 formler | Aritmetikk skal ikke sannsynlighetsberegnes |
| Finne avvik og terskelbrudd | Playbook-regler i et predikat-språk | En regel treffer likt hver gang |
| Forklare hva som skjedde og hva som bør gjøres | Språkmodell | Dette er det modeller faktisk er best til |
| Kontrollere at forklaringen holder | Guardian-agent og deterministiske gater | Forfatteren skal ikke godkjenne seg selv |

## Lag 2: Tall uten kilde slipper ikke ut

Lag 1 sikrer at tallene som finnes, er riktige. Det hindrer ikke at en modell skriver et tall som aldri var i datagrunnlaget i det hele tatt. Derfor har utgående innhold sin egen tall-gate.

Nyhetsbrevmodulen har den strengeste implementasjonen, og er et godt eksempel nettopp fordi den skriver kundevendt tekst som sendes på e-post uten at noen nødvendigvis leser korrektur først. Genereringen skjer i to steg — først en plan, så et utkast — og begge stegene passerer samme gate.

Modellen får en eksplisitt liste over godkjente fakta, hentet fra KPI-laget. Hvert faktum har en id. Foreslår modellen en KPI-blokk, må den referere en id som finnes i listen. Er listen tom, får den ikke lov til å lage KPI-blokken overhodet.

Deretter tokeniseres teksten, og hvert tall i utkastet holdes opp mot allowlisten. Det er her det blir interessant, for en naiv tall-gate er ubrukelig i praksis: den slår ut på årstall, datoer, klokkeslett og telefonnumre, og da lærer redaktøren seg på tre dager å ignorere den.

Gaten har derfor egne trygge klasser. Årstall mellom 1900 og 2099 vurderes i kontekst — står det «i 2026» eller «siden 2024», er det en tidsangivelse, ikke en ytelsespåstand. Telefonnumre gjenkjennes på både format og omkringliggende ord. Datoer og klokkeslett slipper gjennom. URL-er maskeres i stedet for at hele feltet forkastes, slik at et tall inne i en sporingslenke ikke feller en ellers korrekt setning.

Og det viktigste unntaket: tall kunden selv har skrevet i briefen. Skriver du «vi feiret 20 år i mai» i briefteksten, skal ikke systemet nekte å gjenta det. En egen allowlist trekkes derfor ut av briefen og gjelder både plan- og utkaststeget, token-eksakt.

**Overskriftsflater — emnelinje, preheader og overskrifter — er strengere enn brødteksten. De arver kun bare tall fra briefen, ikke tall med modifikator. «20 %» kan stå i brødteksten hvis kunden skrev det; det får ikke stå i emnelinjen på samme grunnlag. En emnelinje er den mest siterte setningen i en e-post, og fortjener den strammeste gaten.**

## Lag 3: Reglene finner problemet, modellen forklarer det

Den vanligste måten å bygge en AI-analysemotor på er å gi modellen alle dataene og be den finne det interessante. Det gir imponerende demoer og upålitelig produksjon, fordi «finn det interessante» er nøyaktig den oppgaven der en modell har mest frihet til å konstruere et mønster som ikke er der.

Vi gjør det motsatte. m51.ai har 16 playbooks i produksjon — budsjett-pacing, søkeordsløsing, Performance Max-helse, innholdsforfall i SEO, striking distance, konverteringssporing, landingssideytelse og kreativ-helse i Meta, blant andre. Hver av dem er en deterministisk regel skrevet i et predikat-språk. Regelen kjører mot KPI-verdiene og treffer, eller treffer ikke.

Først når en regel har truffet, kobles språkmodellen inn — og da i en avgrenset dommerrolle. Den vurderer om funnet er verdt å foreslå for akkurat denne kunden, og skriver begrunnelsen. Den kan avvise et funn. Den kan ikke legge til et.

Konsekvensen er at motoren er propose-only og revisjonsbar hele veien. Et forslag kan alltid spores tilbake til regelen som utløste det, hvilken versjon av regelen som kjørte, og verdiene den traff på.

## Lag 4: Et orakel som ikke stoler på oss

Alle lagene over deler en svakhet: det er vår egen kode som kontrollerer vår egen kode. Har KPIRegistry en feil i en formel, vil hvert nedstrøms lag reprodusere feilen helt lojalt.

Derfor finnes recompute-orakelet. Sjekken tar rå API-svarene fra en faktisk kjøring — ikke datapakken pipelinen bygget, men det plattformene faktisk returnerte — og regner ut hovedtallene på nytt med en uavhengig implementasjon. Så sammenligner den med det pipelinen kom fram til.

Orakelet dekker fem headline-KPI-er for ukes- og månedsrapporten, og 26 KPI-er fordelt på de fem audit-workflowene for Google Ads, SEO, paid social, CRO og GEO. Avviker de to utregningene mer enn toleransen, flagges det.

To presiseringer hører hjemme her. Orakelet dekker 31 av de 184 KPI-ene — headline-tallene beslutninger faktisk tas på — så flertallet av formlene har énveis, ikke dobbel, utregning. Og uavhengigheten er teknisk, ikke organisatorisk: begge implementasjonene er skrevet av oss, på de samme faglige definisjonene. Tar definisjonen feil, tar begge feil. Den eneste fasiten utenfor huset er plattformenes egne tall — og den sammenligningen kan du gjøre selv, fordi hver KPI-verdi bærer kilden og perioden den er hentet fra.

**Det er den eneste sjekken i suiten som ikke bruker et eneste tall pipelinen selv har produsert, og derfor den eneste som kan fange en feil i fasiten.**

## Lag 5: 124 sjekker på under tre minutter

Over dette ligger en deterministisk regresjonssuite. Den kjører 124 sjekker uten et eneste LLM-kall, mot pinnede datapakker med kjent fasit, innenfor et hardt tidsbudsjett på 175 sekunder — lavt nok til at den kan stå som gate i CI på hver eneste endring.

83 av sjekkene er substratuavhengige kontrakts- og invariantsjekker. 34 krever pinnede fixturer med fasitverdier. 7 krever et ferskt snapshot fra ekte API-er.

Sjekkene håndhever ting som ikke skal kunne være sanne. En prosentvis endring kan ikke eksistere uten en forrige verdi å endre seg fra. En periode kan ikke slutte før den starter. En beskrivelse kan ikke være ordrett identisk med begrunnelsen sin. Et pengebeløp kan ikke sammenlignes på tvers av valuta uten at en kurs er brukt. Slike sjekker er kjedelige å skrive, og fanger nøyaktig den typen feil som ellers når kunden.

Baselinen står på null kritiske og null alvorlige avvik — der «kritisk» betyr et kontraktsbrudd som aldri skal kunne være sant, og «alvorlig» betyr en kvalitetsregresjon en leser ville merket i rapporten. Det er den strengeste tilstanden fila kan ha, og den er gate: bryter en endring den, blir den ikke merget.

## Lag 6: Vi gransker våre egne svar hver natt

De fem første lagene handler om rapporter og generert innhold, altså flater der vi selv kontrollerer formatet. Det sjette handler om chat, der brukeren spør fritt og Nova svarer fritt. Der finnes det ikke ett skjema som dekker alt et svar kan inneholde — kontrollen må bygges sjekk for sjekk, funn for funn.

Løsningen er en nattlig, automatisert gransking. Hver natt hentes døgnets faktiske chat-turer fra produksjon, filtrert mot et valgt domene, og dømmes mot en versjonert rubrikk med seks dimensjoner: forankring i data, relevans, hjelpethet, tone, domenefaglig korrekthet og verktøybruk. Hvert funn skal være reproduserbart — det holder ikke å notere at et svar «virket svakt».

Per 30. juli 2026 har rutinen kjørt 22 netter i løpet av 24 døgn, og 103 turer er dømt og lagret med begrunnelse. Gjennomsnittlig forankring ligger på 7,85 av 10 på de 84 turene der dimensjonen var målbar.

**Utvalget er ikke tilfeldig trafikk — det er målrettet mot det domenet vi til enhver tid mistenker mest, og dommen er bevisst adversariell: granskeren er instruert til å lete etter feil, ikke til å vurdere om svaret var greit nok. Med det utgangspunktet fikk 20 av de 103 turene minst ett defektflagg. Det er ikke en feilrate for plattformen — det er utbyttet av å lete der det er mest sannsynlig å finne noe.**

### Hva den faktisk fant

To eksempler fra siste uke, begge fikset.

28. juli fabrikkerte et Google Ads-svar et datapunkt i en graf. Prosaen var eksakt riktig. Grafen viste 82 GA4-sesjoner for en dag der tallet var 10 — og 82 var antall Google Ads-klikk samme dag. Modellen hadde kopiert nabo-seriens verdi. Verre enn feilen i seg selv: punktet opphevet visuelt nettopp den konklusjonen svaret bygget på, som handlet om gapet mellom klikk og sesjoner. Rotårsaken var at graf-blokker manglet et eget kontrollpunkt og lente seg på instruksen til modellen alene. Det er nå rettet: en deterministisk sjekk validerer graf-blokker i granskingen og flagger blant annet nettopp denne signaturen — et avvikende punkt som er identisk med nabo-serien.

30. juli parret et svar riktig pacing-prosent med feil nevner: «136 % pacing (7 029 kr av ~5 518 kr)». 7 029 av 5 518 er 127 %, ikke 136 %. Prosenten var korrekt hentet, men tallparet leseren fikk servert, var ikke reproduserbart. Det skjedde i to av fire turer som siterte pacing, mens to søsterturer på identisk datagrunnlag fikk det riktig — altså drift, ikke en systematisk feil formel.

Rotårsaken var verdt mer enn fiksen. Verktøyet returnerte to ulike budsjettnevnere per kampanje — forventet forbruk hittil i måneden og estimert månedsbudsjett — uten å oppgi hvilken av dem prosenten var regnet fra. Modellen valgte selv, og valgte ikke alltid likt. Fiksen var ikke å be modellen skjerpe seg, men å gjøre payloaden entydig: en eksplisitt lesekontrakt i selve svaret, på begge annonseplattformene.

**Det er mønsteret vi ser igjen og igjen. Når en modell «hallusinerer», er årsaken oftere en tvetydig kontrakt enn en uoppmerksom modell. Det er gode nyheter, for tvetydige kontrakter kan fikses permanent — det kan ikke uoppmerksomhet.**

### Én ærlig begrensning

Vi kjører også en online dommer som sampler turer fortløpende i produksjon. Natten til 30. juli lå samplingen på 12,5 prosent, og den traff ingen av turene der den grundigere nattlige gjennomgangen fant faktafeil. Samme observasjon natten før. Det er ikke dommerens kvalitet som er begrensningen, det er samplingsraten.

Det skal leses som det står: en feil den nattlige granskingen finner, er funnet i ettertid — svaret kan allerede være lest og brukt. Og 103 dømte turer er nok til å finne feilklasser, ikke til å tallfeste stabiliteten i en fri chat. Nattlig gransking er produktforbedring, ikke sanntidsverifisering av hvert svar. Derfor er stikkprøver heller ikke forsvarslinjen vår: hvert funn konverteres til noe som ikke er avhengig av å bli trukket ut i et utvalg — en deterministisk sjekk eller en entydig kontrakt i selve verktøys-svaret, slik både graf-sjekken og pacing-kontrakten over ble til. Vi skriver dette her fordi det er den typen tall som ellers aldri kommer ut av et selskap.

## Hva dette ikke løser

Arkitekturen over er bygget mot én bestemt feilklasse: at modellen finner på et tall som ikke finnes. Den andre klassen — at systemet henter eller tolker et eksisterende tall feil — er en egen jobb: feil konverteringshandling, feil attribusjonsvindu, feil periode, feil valuta, feil nevner, feil metrikk. Deler av den dekkes deterministisk: recompute-orakelet regner perioder og aggregeringer på nytt fra rå data, og invariant-sjekkene stopper blant annet valutasammenligning uten kurs. Men semantiske tolkningsfeil slipper forbi et aritmetikk-forsvar — som da SEO-agenten presenterte Keyword Planners konkurranseindeks som SEO-vanskelighetsgrad. Riktig verdi, feil betydning. Det funnet kom fra samme nattrutine, og den feilklassen er grunnen til at granskingen finnes.

Graf-funnet fra 28. juli ga en beslektet lærdom: kontroller er per flate. En gate som dekker prosaen, dekker ikke automatisk grafen ved siden av, og en ny utdataflate — tabell, PDF, chat-svar — regnes som udekket til den har fått sin egen sjekk. Det er slik «hvert tall har en kilde» forblir en praksis og ikke en påstand: flate for flate.

Den erstatter heller ikke faglig gjennomlesning. Alt agentene produserer av forslag går gjennom en godkjenningsflyt der et menneske bestemmer hva som tas videre. Det er et bevisst designvalg, ikke en midlertidig sikkerhetsventil vi planlegger å fjerne.

## Hva det betyr for teamet ditt

- Tallene i rapporten er beregnet med faste formler og sporbare tilbake til rådataene fra Google Ads og GA4 — ikke gjengitt av en modell. Det fjerner modellgenererte tallfeil; de feilkildene som gjenstår, er testbare.
- Hvert forslag kan spores tilbake til regelen som utløste det, og til verdiene regelen traff på.
- Innhold som sendes ut til mottakere kan ikke inneholde en ytelsespåstand uten et godkjent faktum bak seg.
- Vi finner våre egne feil før du gjør det, og vi skriver ned hva vi fant.

**Vil du se hvordan dette ser ut på dine egne data? Book en demo — så setter vi deg opp med 14 dager gratis prøveperiode.** [Book en demo](https://m51.ai/#kontakt)

## Ofte stilte spørsmål

### Betyr dette at m51.ai aldri kan gi et feil tall?

Nei, og vi ville ikke stolt på noen som påstod det. Det betyr at feilkildene er flyttet til steder som kan testes: en formel i kode, en datakilde som leverer noe uventet, eller en tvetydig kontrakt mellom verktøy og modell. Alle tre kan fanges av en test og fikses permanent. En modell som gjetter et tall, kan ikke det.

### Hvorfor ikke bare bruke en enda bedre språkmodell?

Vi bruker de beste modellene som finnes, og det hjelper på formuleringskvalitet. Det løser ikke aritmetikk, fordi problemet ikke er modellens evne, men dens rolle. Så lenge modellen er den som produserer tallet, finnes det ingen uavhengig fasit å sjekke det mot.

### Publiserer dere virkelig funn fra deres egen kvalitetssikring?

Tallene og eksemplene i denne artikkelen kommer fra våre egne nattlige kjøringer, inkludert de to defektene fra siste uke. Vi mener et selskap som selger AI-drevet analyse skylder markedet å vise hva kvalitetsarbeidet faktisk avdekker, ikke bare at det finnes.

### Er noe av dette uavhengig verifisert?

Nei. Alt i denne artikkelen er selvrapportert — det finnes ingen ekstern revisjon av testdekningen eller feilratene våre ennå, og tallene bør leses med det forbeholdet. Det vi kan tilby i stedet, er etterprøvbarhet i produktet: hver KPI-verdi bærer kilde, periode og feltsti, hvert forslag viser regelen og verdiene som utløste det, og påstander er sporbare til kildedokument og dato. Du trenger ikke stole på arkitektur-beskrivelsen — du kan ettergå hvert enkelt tall.

### Kan jeg se hvor et tall i rapporten kommer fra?

Ja. Hver KPI-verdi bærer med seg kilden og feltstien den ble hentet fra, og påstandene agentene bygger på er sporbare til kildedokument, dato og modellen som hentet dem ut. Det er samme proveniens-prinsipp som ligger til grunn for M51 Cortex.

---

*Dette er en maskinlesbar Markdown-utgave av HTML-artikkelen på https://m51.ai/lab/tallene-ai-en-ikke-far-finne-pa. Innholdet genereres fra samme kilde som nettsiden.*
