synops/docs/infra/robusthet.md
vegard 4d7852f466 Spesifiser robusthet: fallback-kjede, bot-nedetid, function calling
Nytt infra-dokument for robusthet og fallback:
- LLM fallback-kjede via LiteLLM (Claude → GPT-4 → lokal modell)
- Automatisk nedetid-melding til brukere ved bot-feil
- Function calling: ekstern API-bot dispatcher CLI-verktøy via
  portvokteren (structured output → generisk dispatch)
- Tilgangskontroll for bot-actions per brukerrolle
- Onboarding som statisk dispatch (null LLM-kostnad)
- PG som eneste reelle SPOF, mitigering via backup+snapshot

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 11:06:32 +00:00

4.7 KiB

Robusthet og fallback

Lagmodell

Lag 1: LLM-leverandør (Claude API, OpenAI, etc.)  → utenfor vår kontroll
Lag 2: LiteLLM (AI Gateway)                        → lokal Docker
Lag 3: Portvokteren                                 → lokal native (systemd)
Lag 4: CLI-verktøy (synops-*)                       → per-kall, isolert
Lag 5: PostgreSQL                                   → lokal Docker, SPOF

Deteksjon

Bot-nedetid

Portvokteren overvåker synops-respond sin exit-kode. Ved feil:

@bot (ingen respons på 30 sek)
  → Portvokteren sender automatisk i chatten:
    "⚠ Boten er midlertidig utilgjengelig.
     Meldingen din er lagret og blir besvart
     når tjenesten er tilbake."
  → Oppretter work_item i innboks: "Bot-nedetid" + tagged "bug"
  → Logger i ai_usage_log med error-status

Brukeren vet at meldingen er mottatt. Når boten er tilbake, kan den prosessere ubesvarte meldinger.

Healthcheck

Portvokteren eksponerer /health som sjekker:

  • PG-tilkobling
  • STDB-tilkobling
  • LiteLLM-tilgjengelighet
  • Disk-status

Systemd restarter portvokteren ved gjentatte feil.

LLM fallback-kjede

LiteLLM håndterer modell-fallback. @bot fungerer uansett hvilken modell som svarer:

synops-respond → LiteLLM
                   ├── Claude (primær)
                   ├── GPT-4 (fallback 1)
                   ├── Gemini (fallback 2)
                   └── Lokal modell (fallback 3, alltid oppe)

Brukeren merker kanskje kvalitetsforskjell, men tjenesten er oppe. Fallback-kjeden konfigureres i LiteLLM — ingen endring i portvokteren eller synops-respond.

Ekstern API-bot og CLI-verktøy

En LLM via API har ikke shell-tilgang. Den trenger det heller ikke — portvokteren er mellomleddet.

Function calling / tool use

Bruker: "@bot sjekk om RSS-feeden oppdaterte seg"
  → portvokteren → synops-respond → LLM API

LLM svarer med structured output:
  {
    "response": "Jeg sjekker RSS-feeden for deg.",
    "actions": [
      { "tool": "synops-rss",
        "args": { "collection_id": "abc123" } }
    ]
  }

Portvokteren:
  1. Poster chat-svaret i samtalen
  2. Spawner: synops-rss --payload-json '{"collection_id":"abc123"}'
  3. Poster resultatet som oppfølgingsmelding

LLM-en beskriver hva som skal gjøres. Portvokteren gjør det. Navnekonvensjonen (synops-{tool}) betyr at portvokteren kan dispatche uten hardkodet mapping — samme generiske dispatch som jobbkøen (se docs/retninger/unix_filosofi.md).

Tilgangskontroll for actions

Ikke alle brukere skal kunne trigge alle verktøy via @bot. Portvokteren sjekker:

  1. Brukerens rolle i konteksten (owner/admin/member/reader)
  2. Verktøyets tilgangsnivå (fra cli_tool-nodens metadata)
  3. Rate limiting per bruker

En reader kan spørre @bot om informasjon, men ikke trigge synops-render eller synops-audio.

Fallback per situasjon

Situasjon Deteksjon Fallback Brukeropplevelse
Claude API nede LiteLLM timeout Neste modell i kjeden Svarer, kanskje litt dårligere
Alle LLM-er nede synops-respond exit != 0 Statisk "utilgjengelig" + work_item Vet at meldingen er mottatt
Portvokteren nede Systemd healthcheck → restart CLI fungerer for Claude Code Web-brukere venter, terminal funker
PG nede Connection refused Alt stopper Eneste reelle SPOF
STDB nede Reconnect-loop PG-fallback for lesing, skriving bufres Sanntid borte, data trygt

PG som eneste SPOF

PostgreSQL er den eneste komponenten der nedetid stopper alt. Men det er også den mest stabile — PG krasjer sjelden, og gjenoppbygging fra backup er veldokumentert (se docs/setup/produksjon.md).

Mitigering:

  • Automatisk PG-dump (se oppgave 12.2)
  • STDB kan gjenoppbygges fra PG
  • synops-snapshot sikrer at docs-fallback finnes i repo
  • CAS-filer er uavhengig av PG (filsystem)

Onboarding som statisk dispatch

Første @bot i en ny brukers velkomst-chat trenger ikke LLM-roundtrip. Portvokteren gjenkjenner mønsteret og serverer onboarding-noden direkte:

if is_welcome_chat && is_first_bot_mention {
    return serve_static_node(ONBOARDING_NODE_UUID);
}

Null latency, null AI-kostnad, fungerer selv om alle LLM-er er nede. Onboarding-teksten er en vanlig node — oppdaterbar uten redeploy.

Etter første melding fungerer chatten normalt med LLM.

Bygger på

  • docs/infra/ai_gateway.md — LiteLLM fallback-kjeder
  • docs/retninger/unix_filosofi.md — generisk dispatch
  • docs/retninger/maskinrommet.md — portvokter-rollen
  • docs/concepts/arbeidstavlen.md — @bot-konvensjonen
  • docs/concepts/selvdokumenterende_system.md — onboarding-node