synops/docs/proposals/agent_harness.md
vegard 988d60a939 synops-agent: sanntids token-regnskap per modell
Harnessen akkumulerer input/output tokens per modell gjennom hele
kjøringen. Brukes til budsjettovervåking, eskalering, effektivitets-
måling og orkestrator-input. HashMap<String, TokenUsage> i minne,
persisteres til ai_usage_log ved checkpoint/slutt.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 07:38:36 +00:00

18 KiB

Proposal: synops-agent — modell-agnostisk agent-runtime i Rust

Ambisjon

Ikke en kopi av Claude Code. Et superset. Modell-agnostisk, selvovervåkende, med innebygd oppgavestyring og prosesshåndtering. Claude Code er en utmerket interaktiv assistent — synops-agent er en autonom arbeider som kan kjøre i dager uten tilsyn.

Hva Claude Code gjør bra (og vi beholder)

  • Tool-loop (prompt → tool_calls → execute → loop)
  • Fil-operasjoner (read, edit, write, grep, glob)
  • Shell-tilgang (bash)
  • Plan-modus (tenk før du handler)
  • Kontekstbevissthet (CLAUDE.md, prosjektstruktur)

Hva vi gjør i tillegg (supersett)

1. Modell-agnostisk

Bruk hvilken som helst modell: Anthropic, Grok, Gemini, OpenRouter, Ollama, lokale modeller. Velg per oppgave, per steg, per budsjett.

synops-agent --model gemini-flash --task "oppdater alle TODO-kommentarer"
synops-agent --model grok-3 --task "research denne teknologien"
synops-agent --model claude-opus --task "redesign auth-systemet"

Modellvalg kan også være dynamisk: start med billig modell, eskaler til dyrere ved feil (allerede et mønster i orkestreringen).

2. Innebygd oppgavestyring

Ikke avhengig av eksterne scripts eller looper. Agenten eier sin egen arbeidsliste og kjører oppgaver sekvensielt eller parallelt.

synops-agent --tasklist tasks.md
synops-agent --tasklist "docs/fikseliste.md" --filter "[ ]"
  • Parser markdown-checklister (som tasks.md)
  • Plukker neste ugjorte oppgave
  • Markerer pågående, ferdig, feilet
  • Committer og pusher per oppgave
  • Gjenopptar etter krasj (leser tasklist, finner hvor den var)

3. Selvovervåking og gjenoppretting

Prosessen holder seg selv i live. Ingen externe watchdogs nødvendig.

  • Heartbeat: Skriver tidsstempel til en fil. Annen instans kan sjekke om agenten er aktiv.
  • Timeout-deteksjon: Oppdager om en tool-call henger (f.eks. bash som venter på input) og dreper den.
  • Kostnadstak: Stopper ved budsjettgrense per oppgave/sesjon. Rapporterer gjenstående arbeid.
  • Kontekstvindu-håndtering: Komprimerer historikk automatisk når konteksten nærmer seg grensen. Oppsummerer tidligere steg.
  • Feilgjenoppretting: Ved API-feil, retry med backoff. Ved gjentatte feil, eskaler modell eller rapporter og gå videre.

4. Prosesshåndtering (erstatter shell-scripts)

Innebygd daemon-modus som erstatter ad-hoc looper og cron.

synops-agent daemon --tasklist tasks.md --interval 5m
synops-agent daemon --watch "docs/fikseliste.md" --on-change run
  • Daemon-modus: Kjør som bakgrunnsprosess, plukk oppgaver
  • Filovervåking: Reager på endringer i arbeidslister
  • Intervall: Poll med konfigurerbart intervall
  • Signalhåndtering: SIGTERM → fullfør nåværende oppgave → avslutt
  • Pid-fil + lockfil: Forhindre dobbeltstart, tillat status-sjekk

5. Utvidet verktøykasse

Alt Claude Code har, pluss:

Verktøy Funksjon
read_file Les fil (med offset/limit, PDF, bilder, notebooks)
write_file Skriv fil
edit_file Finn-og-erstatt (unik match, replace_all)
bash Kjør shell-kommando (med timeout, bakgrunn)
grep Søk i filer (ripgrep, regex, multiline)
glob Finn filer etter mønster
web_fetch Hent URL (HTML → tekst, JSON-parsing)
web_search Søk på nett
synops_search Søk i Synops-grafen
synops_node Les/skriv noder og edges
synops_create Opprett noder, edges, kommunikasjoner
spawn_agent Start sub-agent med eget oppdrag og modell
notify Send varsel (epost, WebSocket, chat)
schedule Planlegg fremtidig kjøring
checkpoint Lagre mellomtilstand for gjenoppretting

6. Sub-agenter

Kan spawne sub-agenter for parallelt arbeid, akkurat som Claude Code sin Agent-tool, men med valgfri modell per sub-agent.

spawn_agent({
    model: "gemini-flash",
    prompt: "søk etter alle steder som bruker denne funksjonen",
    tools: ["grep", "glob", "read_file"],
    max_cost: 0.10,
})

7. Grafintegrasjon (Synops-spesifikt)

Agenten er en førsteklasses borger i Synops:

  • Har en agent-node i grafen
  • Kan lese/skrive noder og edges
  • Kan delta i kommunikasjonsnoder (chat)
  • Logger all aktivitet i grafen
  • Orkestreringer kan spawne agenten
  • Kan trigges av graf-events (ny node, ny edge)

Arkitektur

synops-agent
├── core/           — agent-loop, tool dispatch, kontekst
├── providers/      — API-adaptere (anthropic, openai, gemini, ollama)
├── tools/          — verktøy-implementasjoner
├── tasklist/       — parser og kjører markdown-checklister
├── daemon/         — bakgrunnsprosess, filovervåking, intervall
├── recovery/       — checkpoint, gjenoppretting, kontekstkomprimering
└── synops/         — grafintegrasjon via synops-common

Bygget som lib + CLI. Lib kan embeddes i maskinrommet for tettere integrasjon uten prosess-overhead.

API-abstraksjon

Rust-traits for leverandør-uavhengighet:

#[async_trait]
trait LlmProvider {
    async fn complete(&self, messages: &[Message], tools: &[Tool]) -> Result<Response>;
    fn supports_streaming(&self) -> bool;
    fn model_id(&self) -> &str;
    fn cost_per_token(&self) -> (f64, f64); // (input, output)
}

Implementasjoner for:

  • Anthropic (direkte, for beste tool_use-støtte)
  • OpenAI-kompatibelt (Grok, OpenRouter, vLLM, Ollama)
  • Gemini (direkte, for grounding og lange kontekster)
  • LiteLLM (fallback — dekker alt, men med overhead)

Differensiatorer vs Claude Code

Claude Code synops-agent
Modeller Kun Anthropic Alle
Modus Interaktiv Interaktiv + autonom + daemon
Oppgavestyring Manuelt Innebygd tasklist-parser
Gjenoppretting Manuelt Automatisk checkpoint + resume
Sub-agenter Samme modell Valgfri modell per agent
Prosesshåndtering Ingen Daemon, watchdog, signaler
Grafintegrasjon Filbasert Native node/edge-tilgang
Kostnadsovervåking Ingen Per-oppgave budsjett
Implementasjon Node.js (lukket) Rust (vår, åpen)

Hva dette erstatter

  • run-next-task.sh og lignende shell-scripts
  • Manuelle looper for å holde prosesser i gang
  • Ad-hoc cron-jobber for agentoppgaver
  • synops-respond (kan bli en modus i synops-agent)
  • Deler av orkestreringens executor

Faser

  1. Core loop + fil-verktøy: Agent-loop som kan lese, skrive, kjøre bash. Én provider (OpenAI-kompatibelt via LiteLLM).
  2. Flere providers: Anthropic direkte, Gemini, Ollama.
  3. Tasklist-parser: Les markdown-checklister, kjør oppgaver.
  4. Daemon-modus: Bakgrunnsprosess med intervall/filovervåking.
  5. Sub-agenter: Spawn med valgfri modell.
  6. Grafintegrasjon: synops-common for node/edge-tilgang.
  7. Checkpoint/recovery: Lagre og gjenoppta tilstand.

Research: eksisterende løsninger og mønstre (mars 2026)

Rust-rammeverk

Rig (rig.rs) — det mest modne Rust LLM-rammeverket. Trait-basert arkitektur med CompletionModel og EmbeddingModel traits. Agent-type som kombinerer modell + systemprompt + verktøy + kontekstdokumenter. I 2026-benchmarks: 24.3% CPU (lavest), <1.1 GB minne (Python >4.7 GB). Relevant for vår provider-abstraksjon.

AutoAgents (liquidos-ai) — multi-agent framework i Rust med type-safe agent-modell, strukturert tool calling, pluggbare backends. God referanse for sub-agent-spawning.

Åpen kildekode Claude Code-alternativer

OpenCode — den sterkeste open source-konkurrenten. Støtter 75+ LLM-providers. Nøkkelarkitektur: separasjon mellom agent-oppførsel og modellvalg. Agent eier planlegging/verktøy, bruker velger modell. Extended ReAct Loop med fire faser per tur:

  1. Automatisk kontekstkomprimering når token-budsjettet nærmer seg
  2. Valgfri tenke-fase for pre-action reasoning
  3. Valgfri selvkritikk-fase
  4. Standard Reason-Act-Execute-Observe

Cline — 5M+ installasjoner. Har native sub-agenter for parallell utføring og headless CLI-modus for CI/CD.

Goose (Block) — CLI-first, DevOps-fokusert, gratis.

OpenHands — autonome koding-agenter på plattformnivå.

Arkitekturmønstre vi bør adoptere

Harness-mønsteret — harnessen er kontrollplanet som wrapper agentens utføring. Sitter mellom LLM og omverdenen. Styrer livssyklus, kontekstvindu, verktøytilgang og sikkerhetsgrenser. Modellen tar faglige beslutninger, harnessen tar operasjonelle beslutninger.

Adaptive Context Compaction (ACC) fra OpenCode/OpenDev:

  • 70% kapasitet: logging og trendovervåking
  • 80%: erstatt eldre verktøy-output med kompakte referansepekere
  • 90%: aggressiv oppsummering av historikk
  • Bruker prompt_tokens fra API-respons som kalibreringsanker

ToolRegistry-mønster: Sentralt register som dispatcher kall til typede handlers. Støtter batch parallell utføring og on-demand MCP tool discovery.

Worktree-isolasjon fra Claude Agent SDK: distribuer arbeid til sub-agenter i isolerte git worktrees, eliminer redigerings-kollisjoner. Hvert oppdrag får sin egen branch.

Skills-system: Organiserte mapper med instruksjoner, scripts og ressurser som agenter oppdager og laster dynamisk.

Designprinsipper fra Anthropic

  • Hold agentdesignet enkelt — de mest vellykkede implementasjonene bruker enkle, komponerbare mønstre fremfor komplekse rammeverk
  • MCP (Model Context Protocol) som standard for verktøy-integrasjon
  • Agenten er runtime-motoren — SDK-er delegerer til den, ikke omvendt

Referanser

Implikasjoner for synops-agent

  1. Bruk Rig som utgangspunkt for provider-abstraksjon — ikke skriv fra scratch. Rig sine traits er veldesignet og battle-tested.
  2. Implementer ACC for kontekstvindu — dette er state of the art.
  3. Extended ReAct Loop med tenke- og selvkritikk-fase, ikke bare enkel tool-loop.
  4. ToolRegistry med parallell dispatch — ikke sekvensiell.
  5. MCP-støtte fra dag 1 — industristandarder er viktigere enn egne protokoller.
  6. Worktree-isolasjon for sub-agenter som redigerer kode.
  7. Enkel arkitektur — Anthropic har rett: komponerbare patterns slår komplekse frameworks.

Orkestreringsmodell: smart leder, billige arbeidere

Kjørbar fra Claude Code

synops-agent er et CLI-verktøy. Claude Code kan kalle det via Bash. Det betyr at Claude Code (dyr, smart) kan delegere arbeid til billige modeller uten å bruke egne tokens:

# Claude Code kjører dette:
synops-agent --model gemini-flash --task "finn alle filer som importerer auth.ts"
synops-agent --model grok-3-mini --task "skriv enhetstester for denne funksjonen"
synops-agent --model claude-haiku --task "oppsummer disse 40 filene"

Claude Code beholder det store bildet. synops-agent gjør gruntarbeidet.

Tre intelligensnivåer

┌─────────────────────────────────────────────┐
│  ORKESTRATOR (Claude Opus / Sonnet)         │
│  Planlegger, arkitekturbeslutninger,        │
│  kvalitetsvurdering, strategi               │
├─────────────────────────────────────────────┤
│  MIDDELS (Sonnet / Grok / Gemini Pro)       │
│  Implementering, refaktorering,             │
│  code review, feilsøking                    │
├─────────────────────────────────────────────┤
│  BILLIG (Haiku / Flash / Grok Mini)         │
│  Søk, grep, oppsummering, formatering,      │
│  enhetstester, dokumentasjon, triage        │
└─────────────────────────────────────────────┘

Orkestratoren (Claude Code eller synops-agent med smart modell) bestemmer hvilket nivå hver deloppgave krever. Hvert nivå kan ha sin egen agent-loop med fulle verktøy.

Utfør billig, verifiser smart

Kjernestrategi for kostnadseffektiv kvalitet:

1. Orkestrator bryter ned oppgaven i steg
2. Billig modell utfører hvert steg (kode, søk, etc.)
3. Smart modell verifiserer resultatet
4. Ved feil: eskaler til middels/smart for retry
5. Ved gjentatt feil: orkestrator tar over selv

Eksempel — fiks 10 TODO-er i kodebasen:

Orkestrator (Opus): "Her er 10 TODO-er, fiks dem én om gangen"
  → Agent (Flash): fikser TODO #1, committer
  → Orkestrator (Opus): review diff — "OK, neste"
  → Agent (Flash): fikser TODO #2, committer
  → Orkestrator (Opus): review diff — "Feil. La meg forklare..."
  → Agent (Sonnet): fikser TODO #2 med bedre kontekst
  → Orkestrator (Opus): review diff — "Bra, neste"

Kostnad: ~90% av arbeidet på billigste modell, ~8% på middels, ~2% på dyreste. Kvaliteten til dyreste modell.

Automatisk modellvalg

synops-agent kan velge modell basert på oppgavens karakter:

Signal Nivå Modell
--task "søk etter..." Billig Flash/Mini
--task "implementer..." Middels Sonnet/Pro
--task "design..." Smart Opus
Feilet med billig Eskaler Middels → Smart
--verify flagg Smart Opus (kun review)
--budget 0.10 Auto Billigst mulig

Maskinrommets ai_job_routing-tabell kan styre default-mappingen.

Claude Code som super-orkestrator

Det ultimate mønsteret:

Claude Code (interaktiv med Vegard)
  │
  ├── "Fiks alle bugs i fikseliste.md"
  │     └── synops-agent --model sonnet --tasklist fikseliste.md
  │           ├── Bug 1 → agent (flash) → verifiser (sonnet) ✓
  │           ├── Bug 2 → agent (flash) → verifiser (sonnet) ✗
  │           │            → eskaler → agent (sonnet) → verifiser ✓
  │           └── Bug 3 → agent (flash) → verifiser (sonnet) ✓
  │
  ├── "Research denne teknologien"
  │     └── synops-agent --model grok-3 --task "..." (sanntidsinfo)
  │
  └── "Optimaliser databasespørringene"
        └── synops-agent --model gemini-pro --task "..."
             └── Sub-agent (flash): "profiler denne spørringen"

Claude Code bruker sin kontekst til å forstå hva som trengs, delegerer utføringen, og bruker resultatet. Billigere, raskere, og med tilgang til modeller Claude Code ikke har (Grok for sanntid, Gemini for lange kontekster, lokale modeller for sensitive data).

Token-regnskap

Harnessen teller og akkumulerer token counts per modell gjennom hele kjøringen. Ikke bare logging i etterkant — sanntids regnskap som brukes til aktive beslutninger.

┌────────────────────────────────────────────────┐
│ synops-agent sesjon #4721                      │
│ Oppgave: "Fiks 10 TODO-er i kodebasen"        │
│                                                │
│ Modell           Input    Output    Kostnad    │
│ gemini-flash     284k     12k       $0.02      │
│ claude-sonnet    18k      4k        $0.08      │
│ claude-opus      3k       1k        $0.12      │
│ ────────────────────────────────────────────── │
│ Totalt           305k     17k       $0.22      │
│ Budsjett brukt: 22% av $1.00                   │
└────────────────────────────────────────────────┘

Implementasjon:

  • Hvert API-kall returnerer usage.input_tokens og usage.output_tokens
  • Harnessen akkumulerer per modell i en HashMap<String, TokenUsage>
  • Kostnad beregnes fra modellens pris per token (konfigurerbar tabell)
  • Tilgjengelig for orkestratoren via --stats eller som verktøy-output
  • Ved budsjettgrense: stopp, rapporter gjenstående, foreslå billigere modell
  • Skrives til ai_usage_log i PG ved sesjonsslutt (og ved checkpoint)

Bruksområder for sanntids token-regnskap:

  • Budsjettovervåking: Stopp før kostnadssprekk
  • Modellvalg: "Flash har brukt 200k tokens uten resultat — eskaler"
  • Effektivitetsmåling: Tokens per fullført oppgave per modell
  • Rapportering: Vegard ser daglig/ukentlig forbruk per modellnivå
  • Orkestrator-input: Claude Code kan lese stats og justere strategi

Eksperimentering med modellvalg

synops-agent logger modell, oppgavetype, kostnad, tid og resultat (suksess/feil/eskalert) i ai_usage_log. Over tid bygges data som viser:

  • Hvilke modeller som er best per oppgavetype
  • Kostnadsoptimal eskaleringsterskel
  • Modeller som feiler oftere på spesifikke oppgaver
  • ROI for verify-steg (fanger det faktisk feil?)

Claude Code kan analysere denne dataen og justere strategi: "Gemini Flash feiler på 40% av refaktoreringsjobber — bruk Sonnet for de fra nå av, men behold Flash for søk og dokumentasjon."

Prioritet

Middels-høy. Erstatter fragil infrastruktur (shell-scripts, looper) med noe robust. Kan bygges inkrementelt — fase 1 er allerede nyttig. Rig som avhengighet reduserer scope for fase 1-2 betydelig. Orkestrerings-mønsteret gir umiddelbar verdi: Claude Code kan delegere til billige modeller fra dag 1 av fase 1.