Hopp til innhold

Hvordan bygger jeg regeletterlevende AI-agenter for norske bedrifter?

Del opp arbeidet slik at modellen aldri bærer den rettslige vekten. Tre deler gjør det: deterministiske verktøy som evaluerer versjonerte regler og returnerer en avgjørelse, en avgrenset legitimasjon pluss en kundedelegering som avgrenser hva agenten i det hele tatt kan nå, og en sporingslogg som registrerer hva som skjedde med en identifikator du kan koble på senere. Modellen velger hvilket verktøy som kalles og hvordan resultatet forklares. Den avgjør ikke hva norsk regelverk krever, fordi en flytende gjetning og et korrekt svar ser like ut i utdataene dens.

Modellen står utenfor en stiplet grense merket deterministisk, versjonert, loggført. Innenfor grensen står to bokser: en avgrenset nøkkel og delegering, som beskriver hva denne agenten kan nå, og regelevaluering, som avgjør hva svaret er. En pil går fra modellen inn i nøkkelboksen og videre inn i regelevalueringen. Under regelevalueringen registrerer en sporingsrad korrelasjons-IDen, aktøren og handlingen.Modellenvelger verktøyet som kallesdeterministisk, versjonert, loggførtAvgrenset nøkkel og delegeringhva denne agenten kan nåRegelevalueringavgjør hva svaret erSporingsradkorrelasjons-ID, aktør, handling
Alt med rettslig konsekvens ligger innenfor den stiplede grensen. Modellens jobb er å velge hvilket spørsmål som stilles, og det er der en språkmodell faktisk er pålitelig.

Hvorfor bør ikke modellen tolke norsk regelverk direkte?

Fordi du ikke kan se av utdataene om den visste det. Spør en språkmodell når merverdiavgiftsmeldingen til et norsk aksjeselskap forfaller, og du får en bestemt dato i en selvsikker setning. Den setningen har samme form enten modellen har regelen riktig, har den omtrent riktig, eller har gjengitt en regel som ble endret for to år siden. Det finnes ikke noe signal om sikkerhet i teksten som samsvarer med korrekthet, så en etterkontroll av formuleringen kjøper deg ingenting.

En regelevaluering har egenskaper en generert setning ikke har. Den er deterministisk, så samme selskap og samme regelversjon gir alltid samme avgjørelse. Den er versjonert, så svaret bærer en rulebook_version som sier hvilket regelsett som produserte det. Og den er mulig å inspisere: når noen bestrider utfallet, kan du peke på regelen som gjaldt framfor på et avsnitt modellen skrev. De tre egenskapene er det som gjør et svar mulig å forsvare framfor bare troverdig.

Den praktiske formen er en verktøygrense. Modellen leser brukerens spørsmål, velger verktøyet, og gjør den strukturerte avgjørelsen om til en forklaring. Verktøyet tar avgjørelsen. Hvis systemprompten din inneholder et sammendrag av norske innsendingsregler, har du lagt regelverket tilbake inn i modellen og gjeninnført nøyaktig den feilen denne strukturen finnes for å hindre.

Hvordan avgrenser jeg hva en agent har lov til å gjøre?

To uavhengige grenser, og det er verdt å forstå at de er uavhengige. Den første er API-nøkkelens scopes, som sier hvilke datakilder denne legitimasjonen kan nå: registeroppslag, Altinn-oppslag, policy- og valutakursoppslag, endringsarkivet, tørrkjøringsflaten, sporingsloggen, webhook-abonnementer og nøkkeladministrasjon. Hvert av dem navngir en datakilde framfor et tillitsnivå, så en nøkkels scope-liste sier hva agenten berørte, ikke bare hvor mye den ble stolt på.

Les den listen som settet i bruk framfor som et lukket vokabular. Det som faktisk håndheves er formatet domain:action og de reserverte prefiksene, så et scope-navn utenfor listen blir ikke avvist for å være ukjent. Den praktiske følgen er at det å tildele et scope ikke er det samme som at scopet betyr noe: sjekk hva et endepunkt krever framfor å anta at et troverdig navn er koblet til noe som helst.

Den andre grensen er delegeringen, som sier hvilke selskaper denne agenten kan opptre for. En nøkkel med alle tildelbare scopes svarer fortsatt ingenting selskapsinternt om et selskap som ikke har gitt systemet ditt tilgang. Den oppdelingen er den nyttige når du vurderer skadeomfang: en lekket nøkkel er avgrenset av de delegeringene som finnes, og en tilbaketrukket delegering snevrer inn hva nøkkelen kan nå uten at noen roterer den.

Jokertegn er smalere enn de ser ut, med hensikt. read:* gir alle lese-scopes, men domenejokeren *:*avvises av både databasebetingelsen og mellomvaren, så det finnes ingen scope-streng som betyr «alt». Og prefiksene write, act og delegate er reservert: de kan ikke tildeles noen nøkkel, så en nøkkel som bærer ett av dem gir ingenting. Avgrens agenten til det smaleste settet som virker, og la delegeringen gjøre resten.

Hva bør sporingsloggen fange opp?

Nok til å rekonstruere en beslutning uten å kjøre den på nytt. Hvert kall bærer en korrelasjons-ID, gjentatt på svarhodet og skrevet til sporingsraden bak kallet, slik at én identifikator syr sammen forespørselen, evalueringen og oppføringen. Lagre den. Det er forskjellen på å kunne svare «hvorfor sa produktet deres det til klienten min» og bare å kunne si at produktet gjorde det.

Radene Apier skriver registrerer hvem som handlet, mot hvilken organisasjon, med hvilken handling, under hvilken regelversjon, og om handlingen ble startet av et menneske eller en maskin. Det siste feltet betyr mer etter hvert som agenter gjør mer: en sporingslogg som ikke kan skille en operatør fra en autonom kaller, svarer på feil spørsmål. Det de radene ikke fanger opp, er din side av grensen, som er agentens resonnement, verktøyet den valgte, og hva den fortalte brukeren.

Så logg begge halvdeler og koble dem på korrelasjons-IDen. For å inspisere Apier-halvdelen returnerer sporingsendepunktet dine egne rader for en gitt organisasjon, og veiledningen om sporingsinspeksjon går gjennom hvordan én handling rekonstrueres fra en kvittering og ned til oppføringene bak den.

Gjør det første kallet

Sandkassekallet returnerer responsformen et agentverktøy faktisk leser, så det er en fornuftig ting å bygge et verktøyskjema mot. Det andre leser tilbake hva som skjedde i ettertid.

# Nøkkelløs sandkasse: formen et agentverktøy faktisk leser.
curl -s https://www.apier.no/api/v1/sandbox/public/company/999999999/summary
// Hva agenten gjorde, i ettertid. Avgrenset til dine egne rader.
const res = await fetch(
  "https://www.apier.no/api/v1/company/999999999/audit",
  { headers: { Authorization: `Bearer ${process.env.APIER_API_KEY}` } },
);

const { data } = await res.json();
for (const entry of data.entries) {
  // correlation_id kobler raden til svaret agenten så.
  console.log(entry.timestamp, entry.action, entry.correlation_id);
}

Ofte stilte spørsmål

Bør jeg la modellen resonnere om norsk regelverk direkte?
Nei. En språkmodell som blir spurt om hva et norsk selskap må sende inn, produserer et flytende svar enten den vet det eller ikke, og du kan ikke skille de to fra utdataene. Legg regelverket bak et verktøy som evaluerer versjonerte regler og returnerer en avgjørelse med regelversjonen påheftet. Modellen avgjør så hvilket spørsmål som skal stilles, som er det den faktisk er god til.
Hvilke scopes kan jeg gi en agents API-nøkkel?
De du faktisk kommer til å bruke er read:brreg, read:altinn, read:digdir, read:norgesbank, read:changes, read:actions, read:audit, subscribe:webhooks og admin:keys. Se det som arbeidslisten framfor et lukket sett: det databasen og mellomvaren håndhever er formatet domain:action og de reserverte prefiksene, ikke en liste over godkjente navn. Jokertegn virker bare på handlingssegmentet, så read:* gir alle lese-scopes mens domenejokeren avvises helt. Prefiksene write, act og delegate er reservert og kan ikke tildeles noen nøkkel i det hele tatt.
Hvordan gjør jeg en agents oppførsel reproduserbar?
Lagre rulebook_version og korrelasjons-IDen fra hvert svar agenten handlet på. De samme inndataene mot samme regelversjon gir alltid samme resultat, så de to feltene gjør en tidligere beslutning til noe du kan utlede på nytt framfor å diskutere på nytt. Uten dem har du en logg over hva agenten sa, som ikke er det samme som en oppføring om hvorfor.
Kan en agent ha en nøkkel som lar den handle autonomt?
Den kan lese og validere autonomt. Den kan ikke utløse en bindende handling, fordi scopet som ville latt den gjøre det er reservert og ikke kan tildeles noen nøkkel. Dette er en strukturell grense framfor et konfigurasjonsvalg, som betyr at spørsmålet i en sikkerhetsgjennomgang ikke er om du avgrenset nøkkelen riktig, men om scopet i det hele tatt finnes.
Hva bør jeg logge på min side?
Som et minimum korrelasjons-IDen, verktøyet som ble kalt, inndataene, avgjørelsen og regelversjonen. Apier skriver sin egen sporingsrad per kall, men den registrerer hva API-et gjorde, ikke hva agenten din konkluderte med eller hva den så fortalte en bruker. Koblingen mellom de to er korrelasjons-IDen, så ta den med inn i dine egne poster framfor å lage en parallell identifikator.