– Slik hindrer jeg at mitt eget agentsystem blir et ekkokammer

Etter seks uker var agenten Bjørn E. Vaage bygget blitt til et ekkokammer. Disse grepene tok han for å rydde opp.

Bjørn E. Vaage bygger KI-systemer både på dagjobb og på kveldstid.
Publisert

✍ leserinnlegg

Dette er et leserinnlegg fra en ekstern skribent, som betyr at innholdet ikke nødvendigvis speiler kode24s meninger. Vil du også bidra? Send oss en epost på [email protected], eller les mer her!

Jeg har bygd et agentsystem i Claude Code de siste seks månedene. Jeg kaller det Ascent. 

Det er en selvforbedrende loop som leser signaler fra prosjektene mine, foreslår forbedringer, og loggfører beslutningene.

Det første oppsettet var én loop. En agent som leste signaler, scoret kandidatene, og foreslo endringer. Det fungerte. I tre uker.

Så begynte forslagene å gli. Subtilt først. Den foreslo de samme mønstrene oftere. Den scoret sine egne tidligere forslag høyere når den så dem igjen. 

Etter seks uker var Ascent et ekkokammer som bekreftet sine egne preferanser.

To ting ble klart. Én loop drifter, fordi forfatteren av en endring ikke kan også være den som tester den. Men selv tre roller drifter, hvis alle tre kun ser din egen output. Du trenger noe å måle mot utenfor systemet.

Tre roller, tre kontekstvinduer

Jeg endte med tre subagenter:

Observer ser på signaler. Endringer i kode, mønstre i diff, hvilke modeller som er pinnet i hvilke repo, hva som ble sagt på siste harness-eval. Den leverer strukturerte kandidater. Hver kandidat har en tittel, en begrunnelse, hvilke prosjekter den treffer, hvilke signaler som trigget den. Observer scorer ikke. Observer foreslår ikke endringer.

Judge mottar bare den strukturerte outputen fra Observer. Ikke begrunnelsen. Bare kandidaten som data. Judge gir scores fra 0 til 10 på fem akser, og en confidence fra 0 til 1. Judge ser også en liste over forslag som ble avvist tidligere, så samme mønster ikke kommer tilbake hver natt. Hvis confidence er under 0.6, går kandidaten ikke videre.

Proposer mottar bare scorede kandidater med confidence over 0.6. Den oppretter en branch i riktig repo, skriver commiten, men pusher ikke. Den filer forslaget med scores. Proposer ser ikke Observer sin begrunnelse heller.

Hver kjører som egen Agent-call i Claude Code, med subagent_type: "general-purpose". Hver subagent får sitt eget kontekstvindu. Det er ingen delt korttidshukommelse mellom dem.

Oversikt over arkitekturen: Tre roller, tre signalkilder, og gating-logikken.

Isolasjon i arkitekturen, ikke i prompten

Jeg prøvde først å få én agent til å skille rollene gjennom prompting. «Først er du Observer, så er du Judge.» Det fungerte ikke, fordi modellen aldri glemmer hva den nettopp sa. Output fra rolle 1 ligger i konteksten når rolle 2 evaluerer.

Når jeg flyttet skillet fra prompt til separate Agent-calls, forsvant problemet. Judge ser ikke hvor entusiastisk Observer var. Den ser kandidaten uten kontekst.

En bonus: modellvalg blir mulig. Jeg kjører Observer og Judge på Sonnet, Proposer på Opus. Pattern detection og scoring trenger ikke samme tyngde som kodeskriving.

Tre signalkilder utenfor egen boble

Tre roller fikser drift internt. Men hvis alle tre kun ser dine egne commits og dine egne tidligere forslag, konvergerer du mot et lokalt maksimum. Ascent får hyggelig tilbakemelding på hva den allerede gjør. Uten å bli bedre.

Løsningen er å la Observer lese fra signaler som ikke kommer fra deg.

I mitt oppsett henter Observer fra tre kilder:

  1. Interne signaler. Egne commits, hvilke modeller som er pinnet, hva CLAUDE.md sier i hvert repo, harness-eval-resultater.
  2. Vendorens egen utvikling. Anthropic sin changelog, SDK-endringer, nye Skills-features. Hvis et repo pinner en gammel modell og en ny er tilgjengelig, blir det en kandidat.
  3. Et håndplukket utvalg av mennesker. Tre stykker. Andrej Karpathy, Nate B Jones, Simon Scrapes.

Den tredje kilden er den viktigste, og den er ikke en YouTube-kanal. Det er en person. Karpathy publiserer lite på YouTube nå, men han skriver på X, legger ut kodeeksempler på GitHub, oppdaterer repoer som llm.c og nanoGPT, blogger på karpathy.github.io, og dukker opp i podcaster hos andre. 

Tracker-en min følger ham over alle seks kanalene, med egen dedup per kilde. Nate B Jones og Simon Scrapes er fortsatt YouTube-tunge, så for dem er det transkripsjoner. Du følger personen der signalet faktisk ligger, ikke plattformen.

Hvis Simon Scrapes viser et mønster i en video, eller Karpathy publiserer et kodeeksempel, og ingen av repoene mine bruker det, blir det en kandidat for Judge.

Like viktig er listen over hvem jeg ikke stoler på. Jeg har en eksplisitt tier 3 av kilder som lager innhold for clicks, ikke for innsikt. De brukes som materiale for motargumenter, ikke som kilde til endringer. Den listen er like nøye kuratert som tier 1. Det at jeg har bestemt hvem som ikke teller, er det som hindrer Observer i å hente “alt på YouTube om AI”.

Tilliten ligger ikke i agenten. Den ligger i listen.

Hva det koster

Tre kontekstvinduer betyr tre kalkulasjoner. Ascent bruker ca tre ganger så mange tokens som en single loop. Overkommelig fordi Sonnet er billig, og fordi det kjører én gang per natt.

  • Latens: Tre sekvensielle Agent-calls tar tre ganger så lang tid. Ikke et problem for nattlig batch.
  • State: Du må holde tidligere avvisninger tilgjengelige for Judge, ellers kommer samme dårlige forslag tilbake. Jeg lagrer dem i 180 dager.

Tips for deg som vil prøve

For det første, sjekk om systemet ditt drifter. Logg de siste 30 forslagene. Hvis tema gjentar seg, eller scoringer kompounderer i én retning, har du drift.

For det andre, ikke prøv å fikse det med prompting. Splitt rollene som separate Agent-calls.

For det tredje, gi Judge minne. Den må kunne se hva som ble avvist før.

For det fjerde, hold Observer kort. Strukturerte data eller ingenting. Ikke send begrunnelse videre.

For det femte, ha en confidence-terskel. Mitt valg er 0.6.

For det sjette, kuratér en tier 1 av eksterne kilder eksplisitt. Inkludér også en tier 3 av kilder du eksplisitt ikke stoler på. Listene er det som gir agenten retning.

Det viktigste

Selvforbedrende systemer drifter på to akser. Internt, fordi forfatteren ikke kan teste seg selv. Eksternt, fordi en agent som kun ser eget output finner bare lokale maksimum.

Tre roller fikser den første. Tre kilder utenfor egen boble fikser den andre. Begge sitter i arkitekturen, ikke i prompten.

Powered by Labrador CMS