Bakgrunnsjobber⚓︎
Oversikt⚓︎
Regelanalyse kjøres asynkront fordi prosessen tar lang tid (hente dokumenter, indeksere, vente på indexer, kjøre LLM). Kai bruker Azure Queue Storage for å koble fra brukerinteraksjonen fra selve analysen.
QueueWorker⚓︎
QueueWorker er en BackgroundService som poller jobs-køen hvert 5. sekund.
Nøkkeldetaljer:
- Maks 1 melding om gangen (
maxMessages: 1) - 5 minutters visibility timeout
- Entrådet:
_isRunning-flagg forhindrer parallell prosessering - Meldinger slettes alltid etter prosessering — ingen retry-kø
Ingen retry
Feilede jobber legges ikke tilbake i køen. Meldingen slettes for å unngå uendelige retry-løkker. Feil logges og sendes som proaktiv melding tilbake til brukeren.
JobProcessor — Analysepipeline⚓︎
JobProcessor utfører selve analysen i følgende steg:
graph TD
A[Motta jobb fra kø] --> B[Hent arkivsak fra WebSak]
B --> C[Finn innkommende journalposter]
C --> D[Last opp dokumenter til Blob Storage]
D --> E[Kjør Azure AI Search indexer]
E --> F[Vent på indeksering<br/>5s intervall, maks 1 min]
F --> G[Hent regler for virkemiddel]
G --> H{Dokumenter funnet?}
H -->|Nei, retry| F
H -->|Ja| I[Send LLM-analyse<br/>Gemini, temp=0.0]
I --> J[Cache resultat]
J --> K[Send proaktiv melding<br/>til bruker i Teams]
Steg for steg:
- Hent arkivsak — Henter saksstruktur fra WebSak-API-et
- Filtrer dokumenter — Ignorerer XML-filer, vedleggsfiler (
_A.pdf), og kjente maler. Dedupliserer på checksum. - Last opp — Hvert dokument lastes opp til Blob Storage under sakens mappestruktur
- Indekser — Kjører Azure AI Search-indexeren og venter opptil 1 minutt
- Søk med retry — Søker etter dokumenter med opptil 5 forsøk (2s delay)
- Hent regler — Henter analyseregler basert på virkemiddel og ERS-status
- LLM-analyse — Sender dokumenter og regler til Gemini med deterministic settings (
Temperature=0.0, TopP=0.1, TopK=1, Seed=42) - Cache — Resultatet caches via
QueryCacheService - Proaktiv melding — Resultatet sendes tilbake til Teams-samtalen via
ProactiveMessageService
LLM-innstillinger⚓︎
Analysen bruker deterministiske innstillinger for reproduserbare resultater:
| Parameter | Verdi | Formål |
|---|---|---|
Temperature |
0.0 | Ingen kreativitet |
TopP |
0.1 | Smal sannsynlighetsmasse |
TopK |
1 | Velg mest sannsynlige token |
Seed |
42 | Reproduserbare resultater |
Scheduled jobs (TickerQ)⚓︎
For tidsbasert / cron-schedulert behandling bruker Kai TickerQ 10.3.0 — separat fra det meldings-drevne QueueWorker-systemet beskrevet over.
ErsStatusPollingJob⚓︎
Schedulert jobb som henter nye saker fra Mimir (ERS-status 0/1) og trigger automatisk regelanalyse.
flowchart TD
Start([TickerQ Cron tick]) --> Fetch[IMimirService<br/>GetSakerByVirkemiddelAsync]
Fetch --> Dedup{Filtrer ut allerede<br/>Succeeded saker via<br/>IPollingProcessedCaseStore}
Dedup -->|tom| End([Tick ferdig])
Dedup -->|N saker| Cap[Ta max<br/>MaxCasesPerTick]
Cap --> Loop[For hver sak]
Loop --> Extract[DocumentUnderstandingProcessor<br/>ProcessDocuments]
Extract -->|kaster| MarkFail1[MarkFailedAsync]
Extract -->|OK| Trigger[IKaiWorkflowClient<br/>POST /workflow/trigger]
Trigger -->|kaster| MarkFail2[MarkFailedAsync]
Trigger -->|202| MarkOK[MarkSucceededAsync]
MarkFail1 --> NextOrEnd{Flere saker?}
MarkFail2 --> NextOrEnd
MarkOK --> NextOrEnd
NextOrEnd -->|ja| Loop
NextOrEnd -->|nei| End
Dedup: polling_processed_cases-tabellen lagrer Succeeded/Failed-rader per saksnummer. Saker med minst én Succeeded-rad skippes på neste tick. Failed-rader gir audit-trail, men skipper ikke (retry på neste tick).
Dashboard⚓︎
TickerQ Dashboard kjører i Worker-prosessen på /tickerq. Basic-auth med credentials fra Kai:TickerQ:Dashboard:Username/Password. Lokal utvikling: bruk user-secrets. Produksjon: KeyVault.
Konfigurasjon⚓︎
| Nøkkel | Type | Default | Beskrivelse |
|---|---|---|---|
Kai:ErsPolling:CronExpression |
string | 0 */5 * * * * |
TickerQ 6-felt cron-uttrykk |
Kai:ErsPolling:VirkemiddelIds |
long[] |
[] |
Mimir-filter. Tom liste → oppstart-feil |
Kai:ErsPolling:ErsStatuses |
int[] |
[0, 1] |
ERS-statuser som regnes klare |
Kai:ErsPolling:SoknadSendtMonthsBack |
int | 3 |
Rullerende vindu (måneder) |
Kai:ErsPolling:MaxCasesPerTick |
int (1–1000) | 50 |
Hard cap per tick |
Kai:TickerQ:Dashboard:Username |
string | admin |
Dashboard basic-auth |
Kai:TickerQ:Dashboard:Password |
string | (tom) | User-secrets/KeyVault |
Kai:KaiApi:BaseUrl |
string | http://kai-api |
Aspire service discovery URL |
Kai:KaiApi:AccessToken |
string | (tom) | Bearer-token Worker→API |
Detaljert spec: ErsStatusPollingJob design.