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>
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:
- Brukerens rolle i konteksten (owner/admin/member/reader)
- Verktøyets tilgangsnivå (fra
cli_tool-nodens metadata) - 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-snapshotsikrer 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-kjederdocs/retninger/unix_filosofi.md— generisk dispatchdocs/retninger/maskinrommet.md— portvokter-rollendocs/concepts/arbeidstavlen.md— @bot-konvensjonendocs/concepts/selvdokumenterende_system.md— onboarding-node