Hoppa till innehållet
AI-grafen
E· Universitetagenter-verktyg· ca 60 min· utvecklande· verifierad 2026-09-20

Budget, stoppvillkor och kostnadskontroll

Kunna sätta budgetar och stoppvillkor så en agent aldrig springer iväg.

Förkunskaper

Intuition

En agent som loopar kostar pengar varje varv. Till skillnad från ett enskilt anrop finns ingen naturlig gräns — agenten bestämmer själv när den är klar, och ibland gör den aldrig det.

Fem oberoende stoppvillkor. Alla behövs, eftersom de fångar olika sorters haveri:

VillkorFångar
Max stegloopar
Max tidlångsamma verktyg, hängningar
Max kostnaddyra modellanrop
Max verktygsanrop per typen agent som anropar samma sak om och om igen
Ingen framstegagenten upprepar sig utan att komma vidare

Det sista är det svåraste att implementera och det mest värdefulla: en agent kan vara inom alla numeriska gränser och ändå inte göra något meningsfullt.

Formellt

Att upptäcka utebliven framsteg. Tre signaler, i ordning efter hur lätta de är att implementera:

SignalHur
Identiskt verktygsanrop upprepashash argumenten och räkna
Observationerna slutar ändrashash tillståndet efter varje steg
Ingen ny informationjämför entropin eller nyheten i observationerna

Den första räcker långt: om samma anrop med samma argument görs tre gånger är agenten fast.

Budget som degraderar värdigt. En agent som bara stannar vid 100 % av budgeten ger användaren ingenting. Bättre är att trappa ner:

Förbrukad budgetBeteende
< 50 %normalt
50–75 %byt till en billigare modell för rutinsteg
75–90 %«avsluta det du håller på med, inga nya delmål»
90–100 %sammanfatta vad som gjorts och vad som återstår
100 %stopp med en användbar delleverans

Den fjärde raden är den som gör skillnad: en agent som säger «jag hann göra A och B, C återstår och här är vad jag vet» är användbar. En som bara avbryts är det inte.

Kostnadsattribution per steg gör det möjligt att förbättra:

Vad som loggasVarför
Tokens in och ut per anropvar kostnaden ligger
Vilket verktyg och hur längelångsamma verktyg
Vilket delmål steget hörde tillvilken del av uppgiften som är dyr
Om steget gav ny informationineffektivitet

Den vanligaste kostnadsdrivaren i agenter är inte modellen utan kontexten. Historiken växer för varje steg, och eftersom hela historiken skickas med varje gång växer kostnaden kvadratiskt med antalet steg. En agent med 30 steg kan kosta mer än tio gånger en med 10 steg, inte tre gånger.

Motmedel: sammanfatta gamla steg, släng verktygsutdata som inte längre behövs, och använd prompt-caching på den fasta delen.

Sätt budgeten per uppgift, inte per anrop. Frågan «vad är den här uppgiften värd?» har ett svar; «vad är ett anrop värt?» har det inte.

Kod

import hashlib, json, time
from collections import Counter
from dataclasses import dataclass, field

@dataclass
class Budget:
    max_steg: int = 30
    max_sekunder: float = 300.0
    max_kr: float = 5.0
    max_per_verktyg: int = 8
    max_upprepningar: int = 3

    steg: int = 0
    kr: float = 0.0
    start: float = field(default_factory=time.perf_counter)
    verktygsantal: Counter = field(default_factory=Counter)
    anropshashar: Counter = field(default_factory=Counter)
    tillstandshashar: list = field(default_factory=list)
    logg: list = field(default_factory=list)

    def forbrukad(self) -> float:
        return max(self.steg / self.max_steg,
                   (time.perf_counter() - self.start) / self.max_sekunder,
                   self.kr / self.max_kr)

    def lage(self) -> str:
        f = self.forbrukad()
        if f < 0.50: return "normal"
        if f < 0.75: return "spara"          # billigare modell för rutinsteg
        if f < 0.90: return "avsluta"        # inga nya delmål
        if f < 1.00: return "sammanfatta"
        return "stopp"

    def kontrollera(self, verktyg: str, argument: dict, tillstand: str):
        h = hashlib.sha256(
            f"{verktyg}:{json.dumps(argument, sort_keys=True)}".encode()).hexdigest()[:16]
        self.anropshashar[h] += 1
        if self.anropshashar[h] > self.max_upprepningar:
            return False, f"samma anrop till {verktyg} upprepat {self.anropshashar[h]} gånger"
        if self.verktygsantal[verktyg] >= self.max_per_verktyg:
            return False, f"maxantal anrop till {verktyg}"
        self.tillstandshashar.append(tillstand)
        if len(self.tillstandshashar) >= 4 and len(set(self.tillstandshashar[-4:])) == 1:
            return False, "tillståndet har inte ändrats på fyra steg"
        if self.lage() == "stopp":
            return False, "budget slut"
        return True, self.lage()

    def registrera(self, verktyg, in_tok, ut_tok, pris_in, pris_ut, ny_information: bool):
        kostnad = (in_tok * pris_in + ut_tok * pris_ut) / 1e6
        self.steg += 1
        self.kr += kostnad
        self.verktygsantal[verktyg] += 1
        self.logg.append({"steg": self.steg, "verktyg": verktyg, "kr": round(kostnad, 4),
                          "in_tok": in_tok, "ny_information": ny_information})

    def rapport(self):
        onodiga = sum(1 for r in self.logg if not r["ny_information"])
        return {"steg": self.steg, "kr": round(self.kr, 3),
                "sekunder": round(time.perf_counter() - self.start, 1),
                "dyraste_verktyg": self.verktygsantal.most_common(3),
                "andel_steg_utan_ny_information": round(onodiga / max(self.steg, 1), 3),
                "kontexttillvaxt": [r["in_tok"] for r in self.logg]}

# Kontexten växer kvadratiskt om historiken skickas med varje gång
def kostnad_utan_komprimering(steg, tokens_per_steg=800, pris_in=30.0):
    return sum((i * tokens_per_steg) * pris_in / 1e6 for i in range(1, steg + 1))

for n in (10, 20, 30):
    print(f"{n:>2} steg: {kostnad_utan_komprimering(n):.3f} kr")
# 10 steg: 1.320 kr
# 20 steg: 5.040 kr
# 30 steg: 11.160 kr     ← tre gånger fler steg, åtta gånger dyrare

Sista utskriften är det viktigaste talet i noden: kostnaden växer med kvadraten på antalet steg om historiken inte komprimeras.

Behärskning innebär

  • Sätter flera oberoende stoppvillkor
  • Upptäcker loopar och ineffektivitet
  • Designar en budget som degraderar värdigt

Logga in för att göra övningarna och bygga upp din behärskning.

Källor

Alla källor och licenser