synops/docs/features/ressursforbruk.md
vegard 7eae02eeb5 Fullfør oppgave 7.5: Segmenttabell-migrasjon og SRT-pipeline
Oppretter transcription_segments-tabellen i PostgreSQL som master-kopi
for alle transkripsjoner. transcribe.rs er oppdatert fra verbose_json
til SRT-format med full parse → segment-innsetting pipeline.

Endringer:
- Migration 005: transcription_segments med GIN fulltekstsøk (norsk)
- transcribe.rs: SRT-parser, segment-innsetting, node-oppdatering
- Miljøvariabler: WHISPER_MODEL (default "medium"), WHISPER_INITIAL_PROMPT
- Docker-compose: nye env vars for maskinrommet-containeren
- Docs: oppdatert podcastfabrikken, arkitektur, primitiver, CLAUDE.md

Tabellen kjørt på server, maskinrommet restartet med nye env vars.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 18:19:00 +01:00

5.1 KiB

Ressursforbruk — Måling og synliggjøring

Konsept

Alle ressurskrevende operasjoner logges med naturlige enheter. Forbruket akkumuleres på tre akser: noden som ble behandlet, brukeren som utløste det, og samlingen det skjedde i.

Formålet er synliggjøring og innsikt, ikke fakturering.

Ressurstyper

Ressurstype Enhet Hva måles
ai tokens inn / tokens ut LLM-kall via AI Gateway
whisper sekunder prosessert lyd Transkripsjons-pipeline
tts tegn Tekst-til-tale-generering
cas bytes Lagring i CAS (store/delete)
bandwidth bytes ut Servering av mediefiler og publisert innhold
livekit deltaker-minutter WebRTC-sesjoner (møter, opptak)
graph noder / edges Opprettelse av noder og edges i grafen

Logg-skjema

CREATE TABLE resource_usage_log (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    target_node_id UUID NOT NULL REFERENCES nodes(id),
    triggered_by UUID REFERENCES nodes(id),  -- null for system-jobber
    collection_id UUID REFERENCES nodes(id),
    resource_type TEXT NOT NULL,  -- 'ai', 'whisper', 'tts', 'cas', 'bandwidth', 'livekit'
    detail JSONB NOT NULL,
    created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);

CREATE INDEX idx_resource_usage_target ON resource_usage_log(target_node_id);
CREATE INDEX idx_resource_usage_triggered ON resource_usage_log(triggered_by);
CREATE INDEX idx_resource_usage_collection ON resource_usage_log(collection_id);
CREATE INDEX idx_resource_usage_type_time ON resource_usage_log(resource_type, created_at);

Detail-struktur per type

AI (LLM-kall)

{
    "model_level": "fast",       // "fast" | "smart" | "deep"
    "model_id": "gemini-2.0-flash",
    "tokens_in": 1240,
    "tokens_out": 380,
    "job_type": "auto_tag"       // hva jobben var
}

Modellnivåer:

Nivå Semantikk Typiske modeller
fast Billig, lav latens Gemini Flash, Haiku
smart Balansert Sonnet, Gemini Pro
deep Grundig, dyr Opus, GPT-4

Whisper (transkripsjon)

{
    "model": "medium",           // "small" | "medium" | "large-v3"
    "duration_seconds": 2520,    // lengde på prosessert lyd
    "language": "no",
    "mode": "batch"              // "live" | "batch"
}

TTS (tekst-til-tale)

{
    "provider": "elevenlabs",    // "elevenlabs" | "local"
    "characters": 8200,
    "voice_id": "norwegian_male_1"
}

CAS (lagring)

{
    "hash": "sha256-abc123...",
    "size_bytes": 84000000,
    "mime": "audio/mp3",
    "operation": "store"         // "store" | "delete"
}

Bandwidth (servering)

{
    "size_bytes": 84000000,
    "path": "/media/podcast/ep47.mp3",
    "client": "Apple Podcasts"   // parsert fra User-Agent
}

LiveKit (sanntid)

{
    "room_id": "meeting-abc123",
    "participant_minutes": 180,
    "tracks": 4                  // antall aktive lyd/video-spor
}

Graph (noder og edges)

Trenger ikke logges i resource_usage_log — kan telles direkte fra nodes og edges-tabellene med COUNT + GROUP BY created_by eller GROUP BY collection. Billig spørring, ingen ekstra lagring.

Vises i bruker- og samlingsvisning som kontekst:

Vegard:
  423 noder opprettet
  1 204 edges

Sidelinja:
  2 891 noder
  8 340 edges

Aggregering

Tre naturlige visninger, alle er GROUP BY-spørringer mot samme tabell:

Per node

Synlig i node-detaljer for eieren. Gir innsikt i hva en spesifikk node har kostet i ressurser.

Episode 47:
  AI (smart)     12k tokens inn, 3k ut — 4 jobber
  Whisper        42 min prosessert (medium)
  TTS            8 200 tegn
  CAS            84 MB lagret
  Båndbredde     2.3 GB servert
  LiveKit        180 deltaker-minutter
  12 noder, 34 edges

Per bruker

Synlig for brukeren selv i sin profil/innstillinger. Sum av alle noder brukeren har utløst arbeid på.

Vegard denne måneden:
  AI         fast: 42k / smart: 18k / deep: 3k tokens
  Whisper    3.2 timer prosessert
  TTS        24k tegn
  423 noder opprettet, 1 204 edges

Per samling

Synlig for samlingens eiere/admins. Sum av alt forbruk i samlingen. Nyttig for å forstå hvilke samlinger som bruker mest ressurser.

Sidelinja (mars 2026):
  AI         148k tokens totalt
  Whisper    12.4 timer prosessert
  CAS        2.1 GB lagret
  Båndbredde 48 GB servert
  2 891 noder, 8 340 edges

Triggered-by-regler

Scenario triggered_by
Bruker klikker "oppsummer" Brukeren
Bruker sender melding som trigger auto-tag Brukeren
Nattlig samlings-digest null (system)
Podcast-nedlasting av ekstern lytter null (system)

Når triggered_by er null, tilhører forbruket kun samlingen — det belaster ingen spesifikk bruker.

Logging-ansvar

Maskinrommet logger all ressursbruk. Hver handler (AI, Whisper, TTS, CAS, LiveKit) skriver til resource_usage_log som siste steg etter vellykket operasjon. Feilede jobber logges ikke — ingen ressurs ble forbrukt.

Båndbredde-logging skjer via Caddy-logg-parsing i nattlig batch-jobb (samme mønster som docs/features/podcast_statistikk.md).