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>
148 lines
4.7 KiB
Markdown
148 lines
4.7 KiB
Markdown
# 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:
|
|
|
|
```rust
|
|
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
|