SSD Nodes Learn Hosting plans →
Gidsen Matt ConnorDoor Matt Connor · Bijgewerkt 2026-08-28

Kostenbeheersing voor altijd actieve AI-agents op VPS

Voorkom onverwachte facturen van uw AI-agent op een VPS. Leer hoe u harde limieten instelt, prompt caching toepast en het tokenverbruik per lus monitort om kosten te beheersen.

Hoe u voorkomt dat een altijd actieve AI-agent onverwachte kosten veroorzaakt

Kostenbeheersing voor een AI-agent op een VPS (virtual private server) draait om limieten die u instelt voordat de agent start, aangezien niemand continu de meter in de gaten houdt terwijl deze draait. Begrens elk antwoord met max_tokens, beperk het aantal lus-iteraties in uw eigen code, cache het gedeelte van de prompt dat nooit verandert en log de verbruiksgegevens van elk antwoord om te zien welke taak kosten genereert. De serverhuur heeft een vaste maandprijs. De model-API wordt per token afgerekend en een onbeheerde lus is zeer efficiënt in het stilletjes verbruiken van tokens.

Dit gaat uit van een agent die al bestaat en de Messages API aanroept vanaf een server die u beheert. Een AI-agent bouwen met Claude op een VPS behandelt de techniek hierachter.

Waarom een onbeheerde agent een ander kostenplaatje heeft

Een interactieve sessie bevat een menselijke gebruiker. Wanneer het model een verkeerd pad inslaat of een logbestand van 40.000 regels leest, grijpt de toeschouwer in. Een onbeheerde agent heeft geen dergelijke rem: deze draait totdat de lus eindigt, waarna een timer het proces opnieuw start.

Frequentie is de vermenigvuldiger die vaak over het hoofd wordt gezien. Een taak met een schema van vijf minuten draait 288 keer per dag en ongeveer 8.640 keer per maand. Wat één uitvoering ook kost, dat is het getal waarmee u vermenigvuldigt. Veel "always-on" agents hoeven niet continu actief te zijn. Ze moeten binnen een bepaald aantal minuten antwoorden, wat neerkomt op een schema.

Een agent betaalt ook voor zaken waar een chatvenster niet voor betaalt.

  • Tooldefinities reizen mee met elk verzoek. De systeem-prompt voor toolgebruik kost 290 tokens op Claude Opus 4.8 met tool_choice van auto of none, en 410 met any of tool. De bash-tool voegt daar nog eens 325 aan toe. Elke MCP server die u koppelt voegt zijn schema's toe aan dat gewicht, waarbij MCP staat voor het model context protocol.
  • Toolresultaten zijn input-tokens. Een commando dat 8.000 regels print, plaatst 8.000 regels in het volgende verzoek, en in elk verzoek daarna in diezelfde beurt.
  • Opgehaalde pagina's zijn input-tokens. Een gemiddelde webpagina van 10 kB is ongeveer 2.500 tokens en een onderzoeks-PDF van 500 kB ongeveer 125.000. max_content_tokens kapt alleen tekstbestanden af, omdat dit "van toepassing is op tekstinhoud, niet op binaire inhoud zoals PDF's". Begrens een PDF in plaats daarvan met max_uses en allowed_domains.
  • Webzoeken wordt per zoekopdracht geprijsd, tegen $10 per 1.000 zoekopdrachten, ongeacht hoeveel resultaten er terugkomen. Een zoekopdracht die een fout geeft, wordt niet in rekening gebracht.

Niets daarvan is duur als het één keer gebeurt. Alles daarvan is duur als het 8.640 keer gebeurt.

Hard ceilings en soft ceilings lossen verschillende problemen op

max_tokens wordt afgedwongen. Dit is een harde limiet op de totale output van één verzoek, inclusief denkproces en antwoordtekst. Claude genereert nooit voorbij dit punt en het model kan het getal zelf niet zien. Het bereiken van deze limiet resulteert in stop_reason: "max_tokens" en een afgebroken antwoord. Het addertje onder het gras voor agents: elk verzoek in een tool-use loop bevat zijn eigen max_tokens, waardoor het één antwoord begrenst en niet de gehele taak. Tien tool-aanroepen van 4.000 tokens betekenen een plafond van 40.000 tokens voor de beurt.

Een taakbudget is adviserend. task_budget bevindt zich binnen output_config en geeft het model aan hoeveel tokens het heeft voor de gehele agent-loop, inclusief denkproces, tool-aanroepen, tool-resultaten en output.

resp = client.beta.messages.create(
    model="claude-opus-4-8",
    max_tokens=4096,
    betas=["task-budgets-2026-03-13"],
    output_config={"task_budget": {"type": "tokens", "total": 64000}},
    messages=messages,
)

"Taakbudgetten zijn een zachte hint, geen harde limiet." Claude kan een budget halverwege een actie overschrijden, terwijl de afgedwongen limiet op output nog steeds max_tokens blijft. "Het aftellen is alleen zichtbaar voor het model" en antwoorden bevatten geen veld voor het resterende budget. Het minimaal geaccepteerde task_budget.total is 20.000 tokens; een lager getal resulteert in een 400-foutmelding. Een budget dat te klein is voor de uit te voeren taak leidt tot gedrag dat lijkt op een weigering, waardoor het model de taak inkort of voortijdig stopt.

Eén detail kost geld in plaats van dat het besparingen oplevert. Als uw client task_budget.remaining verlaagt bij elk vervolgverzoek, maakt de gewijzigde waarde elke gecachte prefix die deze bevat ongeldig. Stel het budget één keer in, bij het eerste verzoek.

Taakbudgetten bevinden zich in bèta op Claude Fable 5, Claude Opus 4.8 en Claude Opus 4.7. Claude Sonnet 5 en Claude Haiku 4.5 staan vermeld als Not supported, en taakbudgetten zijn niet van toepassing op Claude Code. Een Claude Code-sessie losgekoppeld in tmux is daarom afhankelijk van sessiehygiëne.

Het derde plafond bevindt zich in de Claude Console: geef de agent een eigen werkruimte en stel vervolgens een maandelijkse bestedingslimiet en tarieflimieten per minuut in. "U kunt geen limieten instellen voor de Default Workspace" en "Organisatiebrede limieten zijn altijd van toepassing, zelfs als de som van de werkruimtelimieten hoger uitvalt". Voeg bestedingsmeldingen toe zodat een drempelwaarde u waarschuwt voordat de limiet wordt bereikt.

Modelkeuze per taak en de werkelijke invloed van effort

De modelkeuze is een beslissing die per taak wordt genomen. Per juli 2026 gelden per miljoen tokens de volgende prijzen voor input en output: Claude Fable 5 kost $10 en $50, Claude Opus 4.8 en Opus 4.7 kosten $5 en $25, Claude Sonnet 5 kost $3 en $15, en Claude Haiku 4.5 kost $1 en $5. Sonnet 5 is momenteel goedkoper dan de adviesprijs, omdat er tot en met 31 augustus 2026 een introductieprijs van $2/$10 per miljoen input/output-tokens geldt. Een stap die enkel logregels classificeert, heeft geen Opus nodig. Er is ook geen gratis tegoed om een druk schema op te vangen, aangezien de Claude API geen gratis laag heeft buiten het kleine tegoed dat bij aanmelding wordt verstrekt.

Effort is de tweede variabele. output_config.effort accepteert low, medium, high, xhigh en max, waarbij de standaardwaarde high is. Het expliciet instellen van high heeft daarom hetzelfde effect als het weglaten ervan. Een lagere effort-instelling bespaart meer dan alleen de redeneerduur: volgens de documentatie zorgt het ervoor dat Claude minder tool-aanroepen doet en operaties combineert. Bij een agent levert dit de grootste besparing op, omdat een vermeden tool-aanroep een volledig verzoek is dat niet plaatsvindt.

Het risico is dat effort de cache tegenwerkt. Het wijzigen van de waarde tussen verzoeken maakt prompt caching ongeldig. In het gedocumenteerde voorbeeld rapporteerde verzoek 2 cache_read_input_tokens: 3546; verzoek 3, waarbij de effort werd gewijzigd van high naar medium, rapporteerde cache_creation_input_tokens van 3546 en cache_read_input_tokens van 0. Varieer effort dus tussen verschillende workloads, maar nooit binnen één gecachte conversatie. Om de diepgang te sturen zonder de cache te verbreken, kunt u dit in de prompt doen: een regel als "Antwoord direct zonder beraadslaging" bij het nieuwste gebruikersbericht laat de eerdere breakpoints intact.

Thinking-tokens worden gefactureerd tegen output-tarieven en tellen mee voor max_tokens. Dit is de reden waarom een afgebroken antwoord vaak betekent dat het denkproces het budget heeft verbruikt. Lees usage.output_tokens_details.thinking_tokens voor het aantal. Wat een Claude-tokenfactuur werkelijk bepaalt ontleedt de meter.

Cache het stabiele voorvoegsel en voorkom dat u dit per ongeluk verbreekt

Een cache-schrijfactie kost 1,25 keer de basisinvoerprijs voor de cache van vijf minuten en 2 keer voor de cache van één uur. Een cache-leesactie kost 0,1 keer, dus "caching loont al na één cache-leesactie voor de duur van 5 minuten (1,25x schrijven), of na twee cache-leesacties voor de duur van 1 uur (2x schrijven)".

Eén regel verklaart waarom dit geschikt is voor een agent die altijd actief is: "De cache wordt zonder extra kosten ververst telkens wanneer de gecachte inhoud wordt gebruikt." Een taak die elke twee minuten wordt uitgevoerd tegen de cache van vijf minuten, houdt het voorvoegsel de hele dag warm voor slechts één schrijfactie.

Drie manieren om de cache te verliezen zonder dat u het merkt.

Een voorvoegsel dat verandert. "Cache-voorvoegsels worden in de volgende volgorde aangemaakt: tools, system, daarna messages." Elke wijziging van een byte eerder in die volgorde maakt alles wat daarna komt ongeldig, en het bewerken van tooldefinities maakt de volledige cache ongeldig. De klassieke fout die men zelf maakt, is het opnemen van een tijdstempel of een run id in de systeemprompt: elk verzoek bevat dan een ander voorvoegsel, schrijft een nieuw item tegen 1,25x, en leest niets terug. Het teken hiervoor is usage.cache_read_input_tokens op 0 bij identiek ogende aanroepen. Verplaats de vluchtige tekst naar het nieuwste gebruikersbericht.

Een voorvoegsel dat te kort is. Elk model heeft een minimale cachebare lengte; daaronder wordt het verzoek verwerkt zonder caching en "wordt er geen foutmelding geretourneerd". De cijfers omvatten 1.024 tokens op Claude Opus 4.8 en Claude Sonnet 5, en 4.096 op Claude Haiku 4.5, dus het verplaatsen van een taak van Sonnet naar Haiku kan caching stilletjes uitschakelen.

Een conversatie die de terugblik overschrijdt. "Het terugblikvenster is 20 blokken." Het systeem controleert maximaal 20 posities per breekpunt en stopt dan. In het gedocumenteerde voorbeeld controleert een beurt met 35 blokken met een breekpunt op blok 35 de blokken 35 tot en met 16, en valt het item van de vorige beurt op blok 15 buiten het venster, waardoor er geen hit is. Een agent die per beurt meerdere tool-use en tool-result blokken toevoegt, overschrijdt de 20 in twee of drie beurten. U krijgt vier breekpunten per verzoek, dus besteed er één aan de recente berichten.

Verstuur taken die kunnen wachten naar de Batches API

"Al het gebruik wordt gefactureerd tegen 50% van de standaard API-tarieven", zowel voor input als output. Batchverwerking is asynchroon, "waarbij de meeste batches binnen 1 uur zijn voltooid", met resultaten zodra elk verzoek is afgerond of na 24 uur, afhankelijk van wat zich het eerst voordoet. Dit is een indicatie, geen garantie.

Poll processing_status totdat de status ended aangeeft. Verzoeken die errored, canceled of expired retourneren, worden niet in rekening gebracht. Een kanttekening als u gebruikmaakt van een bestedingslimiet: "batches kunnen het geconfigureerde bestedingslimiet van uw Workspace licht overschrijden."

De kortingen zijn cumulatief, en omdat een batch langer dan vijf minuten kan duren, adviseert de documentatie de cache van één uur voor batches die context delen. Splits het werk daarom op: alles waar een persoon of een webhook op wacht, blijft op het live-pad, terwijl een nachtelijk overzicht of de classificatie van logbestanden van gisteren in een batch tegen de halve prijs wordt verwerkt.

Log gebruiksvelden van elk antwoord naar uw eigen opslag

U kunt geen kosten toeschrijven die u niet heeft geregistreerd. Elk antwoord geeft aan wat het heeft gekost.

u = resp.usage
row = {
    "job": job_name,
    "model": resp.model,
    "uncached_input": u.input_tokens,
    "cache_write": u.cache_creation_input_tokens,
    "cache_read": u.cache_read_input_tokens,
    "output": u.output_tokens,
    "stop_reason": resp.stop_reason,
}

Voeg per API-aanroep één rij toe aan een JSON-lines bestand, voorzien van de naam van uw taak. Een week later kunt u bepalen welke taak kosten genereert en welke alleen maar druk leek. Let op cache_read: een kolom met nullen is de meest voorkomende kostenfout bij een zelfgehoste agent.

Eén veld is gemakkelijk verkeerd te interpreteren. input_tokens telt alleen de tokens na het laatste cache-breekpunt, dus de werkelijke promptgrootte is total_input_tokens = cache_read_input_tokens + cache_creation_input_tokens + input_tokens. Een agent die input_tokens: 400 rapporteert bij een grote prompt is niet goedkoop: de rest kwam uit de cache.

Tel voordat u verzendt. Het tellen van tokens is gratis en de rate limits hiervoor staan los van het aanmaken van berichten, dus gebruik count_tokens om een te groot bijgevoegd bestand te weigeren in plaats van te betalen om erachter te komen. Het resultaat is een schatting, dus meet opnieuw per model en hergebruik nooit een telling van de tokenizer van een andere leverancier. Claude Opus 4.7 en latere Opus-modellen, Claude Fable 5 en Claude Sonnet 5 gebruiken een nieuwere tokenizer die "ongeveer 30% meer tokens produceert voor dezelfde tekst". Claude Sonnet 4.6 en eerder, waaronder Claude Haiku 4.5, gebruiken de vorige versie.

Voor een officieel overzicht rapporteert de Admin API het gebruik op https://api.anthropic.com/v1/organizations/usage_report/messages en de kosten op https://api.anthropic.com/v1/organizations/cost_report. Beide vereisen een admin-sleutel (sk-ant-admin01-...) als x-api-key: $ANTHROPIC_ADMIN_KEY met anthropic-version: 2023-06-01, en accepteren bucket_width=1d, group_by[]=model en api_key_ids[]=. Eén beperking: "De Admin API is niet beschikbaar voor individuele accounts."

Die laatste parameter is een goedkope truc voor toeschrijving: geef elke taak een eigen API-sleutel, filter met api_key_ids[] en splits het rapport per sleutel met group_by[]=api_key_id. Het filter is meervoudig, de groeperingsdimensie is enkelvoudig. Bewaar de sleutels in de omgeving in plaats van in de code, op de manier zoals een eerste Claude API-app op een VPS ze verwerkt.

Begrens de lus, want niets anders doet dat

Een begrensd aantal iteraties is hier niet optioneel. De lus is van u, dus de teller is ook van u:

for step in range(MAX_STEPS):          # MAX_STEPS = 12, never "while True"
    resp = client.messages.create(...)
    if resp.stop_reason != "tool_use":
        break
else:
    log.warning("job %s hit MAX_STEPS=%d, giving up", job_name, MAX_STEPS)

Geen van de bovenstaande limieten volstaat: max_tokens begrenst slechts één antwoord en het model wordt alleen geadviseerd over een taakbudget. Een gehost product zou u hier stoppen, op de manier waarop de limiet van Claude op tool-aanroepen binnen één beurt een sessie beëindigt die er te veel heeft gemaakt, maar een lus die u zelf hebt geschreven, wordt zonder dergelijke beveiliging geleverd totdat u er een toevoegt.

Plaats een tweede rem buiten het proces. Voer de taak uit via een systemd timer in plaats van een permanent proces en stel RuntimeMaxSec= in op de service-unit. Met RuntimeMaxSec=600 wordt een vastgelopen uitvoering na tien minuten beëindigd in plaats van dat deze blijft draaien totdat u het opmerkt. Een programma uitvoeren als systemd service en timer behandelt de unit-bestanden zelf. Lees wat een uitvoering heeft gedaan met journalctl -u triage-agent.service --since "1 hour ago".

Begrens ook het aantal pogingen, want een handler die oneindig opnieuw probeert, brengt elke poging in rekening. Een 429 of een 500 verdient een paar pogingen met backoff. Een 400 verdient er geen, aangezien hetzelfde verzoek op dezelfde manier blijft falen.

Kostenbeheersing voor AI-agents begint bij het inzien van uw eigen cijfers

Niemand kan u vertellen wat een altijd actieve agent kost, omdat de kosten bestaan uit tokens per run vermenigvuldigd met het aantal runs per dag, en beide variabelen zijn afhankelijk van uw gebruik. Voer de agent één keer uit, lees de gebruiksregel die u heeft gelogd en vermenigvuldig dit met uw planning. Controleer twee dagen later het kostenoverzicht en vergelijk dit met uw berekening. Wanneer deze twee niet overeenkomen, wordt het verschil bijna altijd veroorzaakt door een defecte cache of een lus die langer liep dan u had aangenomen.

Dit gaat uit van een API key, omdat de agent uw eigen programma is dat de Messages API aanroept. Voor uw eigen interactieve werkzaamheden behandelt welk Claude-abonnement past bij uw manier van werken de abonnementskant. Elke prijs en limiet in dit document is in juli 2026 gecontroleerd aan de hand van de documentatie van Anthropic; lees daarom de prijsinformatiepagina opnieuw door voordat u een budget opstelt.

FAQ

Wat zijn de kosten voor het draaien van een altijd actieve AI-agent op een VPS?

Er zijn twee soorten kosten, waarvan er slechts één voorspelbaar is. De server heeft een vaste maandelijkse prijs. De model-API wordt afgerekend per token; de kosten zijn dus het verbruik van één run vermenigvuldigd met de frequentie. Anthropic publiceert geen cijfers voor een zelfgehoste, altijd actieve agent, dus beschouw elk genoemd bedrag als een schatting. Log usage van één echte run en vermenigvuldig dit met uw planning.

Wat is het verschil tussen max_tokens en een taakbudget?

max_tokens wordt afgedwongen en is onzichtbaar voor het model. Het begrenst de output van één verzoek, inclusief het denkproces, en het overschrijden ervan resulteert in stop_reason: "max_tokens". Een taakbudget is het tegenovergestelde: het model wordt op de hoogte gesteld van het getal en stemt de agent-loop hierop af, maar "taakbudgetten zijn een zachte richtlijn, geen harde limiet" en de afgedwongen grens blijft max_tokens.

Waarom is cache_read_input_tokens altijd nul voor mijn agent?

Omdat het voorvoegsel verandert tussen aanroepen, of omdat het te kort is om te cachen. De gebruikelijke oorzaak is een tijdstempel of een run-id die in de systeemprompt wordt geïnterpoleerd: de cache is gekoppeld aan het voorvoegsel, dus elke wijziging in een byte maakt alles wat daarna komt ongeldig. Het wijzigen van tooldefinities of de effort-waarde heeft hetzelfde effect. Anders is het de grootte, aangezien kortere prompts niet worden gecachet en er geen foutmelding wordt geretourneerd.

Hoe voorkom ik dat een AI-agent in een oneindige lus raakt?

Tel de iteraties in uw loop-code en stop bij een vast maximum, omdat max_tokens één antwoord begrenst en een agent er vele maakt. Voeg een tijdslimiet toe buiten het proces: start de taak vanuit een systemd-timer met RuntimeMaxSec= ingesteld, zodat een vastgelopen run volgens schema wordt beëindigd. Begrens ook het aantal retries, aangezien een retry-loop elke poging in rekening brengt.

Kan ik een bestedingslimiet instellen op een enkele Claude API-sleutel?

De gedocumenteerde bestedingslimiet geldt per werkruimte in plaats van per sleutel; geef de agent dus een eigen werkruimte en begrens daar de maandelijkse uitgaven. "U kunt geen limieten instellen op de Default Workspace". Voeg bestedingsmeldingen toe zodat een drempelwaarde u tijdig waarschuwt. Voor toewijzing kunt u voor elke taak een eigen sleutel uitgeven en vervolgens het gebruiksrapport groeperen met group_by[]=api_key_id.