, , , ,

Billig eller dyr modell? To-knapp-routing i en produksjonsapp

Terminal som viser billig- og dyr-modell-routing med kostnad i kroner

Prisgapet mellom åpne vektmodeller og de kommersielle frontier-modellene har krympet kraftig i 2026. For rutinearbeid er en open-weight-modell ofte god nok, mens de tunge oppgavene fortsatt trenger frontier. Den fornuftige konklusjonen er å rute per oppgave: billig modell til det enkle, dyr modell til det harde. Jeg bygde det inn i en produksjonsapp jeg drifter, og her er hva som faktisk skjedde.

To knapper i stedet for én

Appen har en AI-funksjon som gjør promptdrevne kodeendringer: en admin skriver hva som skal endres, en runner kjører en kodeagent headless (klon, endre, kjør tester, push), og deploy skjer automatisk. Den eneste endringen i brukergrensesnittet var å bytte den ene «Send»-knappen med to: Billig og Dyr. Valget lagres på jobben som model_tier og følger med når runneren plukker den opp.

Runneren bygger miljøet til kodeagenten ut fra hvilken tier som er valgt. Dyr peker rett på frontier-APIet. Billig peker på OpenRouter, som eksponerer et Anthropic-kompatibelt /api/v1/messages. Det betyr at den samme kodeagenten kjører uendret mot begge, uten proxy imellom.

Routing-diagram: én jobbkø splittes i billig (OpenRouter) og dyr (frontier), begge samles i samme runner som kjører kodeagenten headless
Én kø, to ruter. Tier-valget avgjør bare hvilke miljøvariabler runneren setter før den starter kodeagenten.

Fella nummer én: alle fem modellvariablene

For at kodeagenten skal snakke med OpenRouter holder det ikke å sette base-URL og token. Agenten har flere interne modell-slotter (hoved, liten/rask, og standardvarianter). Setter du bare noen av dem, faller de andre tilbake til Anthropic-modellnavn som OpenRouter ikke kjenner, og kallet feiler. Alle må peke på samme OpenRouter-modell:

# Billig: hele settet må settes
export ANTHROPIC_BASE_URL=https://openrouter.ai/api
export ANTHROPIC_AUTH_TOKEN=sk-or-v1-...
export ANTHROPIC_MODEL=openai/gpt-oss-120b
export ANTHROPIC_SMALL_FAST_MODEL=openai/gpt-oss-120b
export ANTHROPIC_DEFAULT_HAIKU_MODEL=openai/gpt-oss-120b
export ANTHROPIC_DEFAULT_SONNET_MODEL=openai/gpt-oss-120b
export ANTHROPIC_DEFAULT_OPUS_MODEL=openai/gpt-oss-120b

Fella nummer to: kostnaden agenten rapporterer er feil

Kodeagenten regner ut total_cost_usd med frontier-priser uansett hvilket endepunkt den peker mot. En triviell filendring mot den billige modellen ble rapportert til 0,167 USD, som er frontier-pris for det token-forbruket, ikke det OpenRouter faktisk tar. Stoler du på det tallet, er hele poenget med billig-ruten borte i regnskapet.

Løsningen er å ignorere agentens kosttall for billig-jobber og regne selv fra token-forbruket ganger dine egne OpenRouter-satser:

kost_usd = (tokens_inn  / 1_000_000) * PRIS_INN_USD
         + (tokens_ut   / 1_000_000) * PRIS_UT_USD

Konsekvensen er en enkel regel: bytter du modell, må du bytte prisene i samme slengen. Prisene bor derfor som miljøvariabler ved siden av modellnavnet, ikke hardkodet.

Tallene

Samme type jobb, målt ende til ende mot den ekte kodeagent-loopen:

Jobb   Tier    Modell               Kost
#2     dyr     frontier             24,58 kr
#3     dyr     frontier              4,55 kr
#4     billig  openai/gpt-oss-120b   0,33 kr

Billig-jobben landet på 0,33 kr mot 24,58 kr for den dyreste. To størrelsesordener. Det er dette som gjør routing verdt bryet: ikke at den billige modellen er like god, men at den er god nok til nok av oppgavene til at snittkostnaden stuper.

Hvilke modeller duger til å faktisk endre kode

En modell som scorer bra på benchmarks er ikke det samme som en modell som klarer å kalle verktøy, lese filer og skrive tilbake i en agent-loop. Jeg testet tre mot ekte filendringer:

openai/gpt-oss-120b     OK    $0.037 / $0.17   (valgt)
qwen/qwen3-coder        OK    $0.30  / $1.00   (reserve, mest token-effektiv)
deepseek/...-v4-flash   FEIL  tomt svar, null verktøykall

Deepseek-varianten returnerte tomt innhold og gjorde ingen verktøykall i det hele tatt. På papiret en kodemodell, i praksis ubrukelig i denne loopen. Test alltid mot din egen agent, ikke mot en benchmark-tabell.

Slik oppfører den billige modellen seg

Selve kodeendringen ble korrekt, og modellen fikset til og med sin egen feilende test i reparasjonsrunden. Kjernen kan den. Det som glapp var alt rundt:

  • Den satte en changelog-oppføring midt inne i et eksisterende avsnitt og brøt en setning i to.
  • Den lagde en ny testfil med duplisert hjelpekode i stedet for å utvide den eksisterende testklassen.
  • Commit-meldingen beskrev reparasjonsrunden, ikke selve endringen.
  • Den brukte Unicode-bindestrek og krøllete anførselstegn i markdown.

Ingenting av dette er farlig, men alt må ryddes. Konklusjonen ble: billig passer til små, avgrensede endringer, og regn med litt opprydding i dokumentasjon etterpå. Sikkerhetsnettet står uansett fast for begge tiers: tester må være grønne før push, det kjøres en røyktest etter deploy, og feiler noe rulles endringen tilbake automatisk.

Synkront kall eller egen runner

Ikke alt trenger en agent-loop. Den samme billige modellen brukes et annet sted i systemet til en samtalefunksjon, og der kalles OpenRouter helt synkront rett fra PHP, uten kø. For korte, chat-lignende kall er det enklere og responsen kommer med en gang.

Grensa går ved tid. Kodeendringene kan ta minutter, og infrastrukturen rundt har en hard grense på 120 sekunder på synkrone fjernkall. Alt som er langvarig må derfor kjøres som en bakgrunnsjobb via runneren, med logging og polling, ellers blir det kuttet midtveis. To integrasjonsmønstre for samme modell, valgt ut fra hvor lenge kallet varer.

En liten detalj verdt å nevne: gpt-oss-120b er en reasoning-modell. Svaret ligger i content mens resonnementet ligger i et eget felt, og setter du token-kappet for lavt fylles hele budsjettet av resonnementet slik at content kommer tomt tilbake. Reasoning-tokenene telles med i completion_tokens, så kosten fanges riktig, men gi modellen nok takhøyde til at det faktisk kommer et svar.

Når velge hva

Regelen jeg endte på er enkel. Billig til avgrensede endringer i én eller få filer: rett en feilmelding, juster en validering, legg til et felt. Dyr til det som krever at modellen holder mange filer i hodet samtidig eller resonnerer seg gjennom et design: refaktorering, ny modul, noe med reell arkitektur. Er du i tvil, start billig og eskaler. Den billige jobben koster brøkdeler av en krone, så et bomskudd er gratis lærdom.

Hybrid routing er ikke et kompromiss der du later som den billige modellen er like god. Det er en erkjennelse av at de fleste oppgaver er små, og at det er dumt å betale frontier-pris for å bytte en feilmelding.


Trenger du hjelp med dette?

Ta kontakt for en uforpliktende prat om hvordan jeg kan hjelpe deg.



Navn