Paano i-cap ang gastos ng AI agent sa VPS 24/7
Walang nagbabantay sa metro. Hard cap sa response, loop limit, prompt caching, at usage log para makita kung aling trabaho ang kumakain ng tokens.
Paano pigilan ang always-on AI agent na lumobo ang bill
Ang cost control ng AI agent sa VPS (virtual private server) ay tungkol sa mga limitasyong itatakda mo bago magsimula ang agent, dahil walang nagbabantay sa metro habang tumatakbo ito. I-cap ang bawat response gamit ang max_tokens, i-bound ang loop iterations sa sarili mong code, i-cache ang bahagi ng prompt na hindi nagbabago, at i-log ang usage numbers ng bawat response para makita kung aling trabaho ang gumagastos. Ang server rental ay fixed monthly price. Ang model API ay metered per token, at ang unattended loop ay napakahusay sa tahimik na paggastos ng tokens.
Ipinapalagay nito na mayroon nang agent na tumatawag sa Messages API mula sa isang box na pagmamay-ari mo. Pagbuo ng AI agent gamit ang Claude sa isang VPS ang sumasaklaw sa mismong makinarya.
Bakit iba ang hugis ng gastos ng unattended agent
May tao sa isang interactive session. Kapag lumihis ang modelo o nagbasa ng 40,000-linyang log, pinipigilan ito ng taong nakamasid. Walang ganitong preno ang unattended agent: tatakbo ito hanggang matapos ang loop, saka ito sisimulan ulit ng timer.
Ang frequency ang multiplier na madalas nakakaligtaan. Ang job na naka-schedule kada limang minuto ay tumatakbo nang 288 beses sa isang araw at humigit-kumulang 8,640 beses sa isang buwan. Anuman ang gastos ng isang run, iyon ang numerong imu-multiply mo. Maraming "always-on" agent ang hindi kailangang naka-on. Kailangan lang nilang sumagot sa loob ng ilang minuto, na isang schedule.
Nagbabayad din ang agent para sa mga bagay na hindi binabayaran ng chat window.
- Sumasabay ang tool definitions sa bawat request. Ang tool-use system prompt ay nagkakahalaga ng 290 tokens sa Claude Opus 4.8 na may
tool_choicengautoonone, at 410 kapag mayanyotool. Dagdag pa ang 325 ng bash tool. Bawat MCP server na ikinakabit mo ay nagdaragdag ng mga schema nito sa bigat na iyon, ang MCP ay ang model context protocol. - Input tokens ang tool results. Ang command na nagpi-print ng 8,000 linya ay naglalagay ng 8,000 linya sa susunod na request, at sa bawat request pagkatapos nito sa turn na iyon.
- Input tokens ang mga fetched page. Ang average na 10 kB web page ay halos 2,500 tokens at ang 500 kB research PDF ay halos 125,000. Ang
max_content_tokensay pinuputol lamang ang mga text, dahil ito ay "applies to text content, not to binary content such as PDFs". Itakda ang bound ng PDF gamit angmax_usesatallowed_domainssa halip. - May presyo ang web search kada search, sa $10 bawat 1,000 searches, anuman ang dami ng resultang bumalik. Ang search na nag-error ay hindi sinisingil.
Wala sa mga iyan ang mahal kapag isang beses lang. Lahat ng iyan ay mahal kapag 8,640 beses.
Iba ang problema na sinosolve ng hard ceiling at soft ceiling
max_tokens ay ini-enforce. Ito ay hard cap sa kabuuang output ng isang request, kasama ang thinking at response text. Hindi lalampas si Claude dito, at hindi nakikita ng model ang numero. Kapag na-reach ito, makakakuha ka ng stop_reason: "max_tokens" at putol na sagot. Ang catch para sa mga agent: bawat request sa tool-use loop ay may sariling max_tokens, kaya isang response lang ang binobound nito at hindi ang buong task. Sampung tool call sa 4,000 ay 40,000-token ceiling para sa turn.
Ang task budget ay advisory. Ang task_budget ay nasa loob ng output_config at sinasabi sa model kung ilang token ang meron ito para sa buong agentic loop, kasama ang thinking, tool calls, tool results at 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,
)"Ang task budgets ay soft hint, hindi hard cap." Pwedeng lumampas si Claude dito mid-action, at ang ini-enforce na limit sa output ay max_tokens pa rin. "Ang countdown ay nakikita lang ng model", at walang remaining-budget field ang mga response. Ang minimum na tinatanggap na task_budget.total ay 20,000 tokens, at kapag mas mababa, 400 error ang ibabalik. Ang budget na masyadong maliit para sa trabaho ay nagpo-produce ng refusal-like behaviour, kaya iniiscope down ng model ang task o maagang humihinto.
May isang detalye na nagko-cost ng pera imbes na makatipid. Kung ang client mo ay nagde-decrement ng task_budget.remaining sa bawat follow-up request, ang binagong value ay nag-iinvalidate ng anumang cached prefix na naglalaman nito. I-set ito nang isang beses, sa unang request.
Ang task budgets ay nasa beta sa Claude Fable 5, Claude Opus 4.8 at Claude Opus 4.7. Ang Claude Sonnet 5 at Claude Haiku 4.5 ay nakalista bilang Not supported, at hindi nag-aapply ang task budgets sa Claude Code, kaya ang Claude Code session na naka-detach sa tmux ay nakadepende sa session hygiene imbes.
Ang ikatlong ceiling ay nasa Claude Console: bigyan ang agent ng sarili nitong workspace, tapos mag-set ng monthly spend limit at per-minute rate limits dito. "Hindi ka pwedeng mag-set ng limits sa Default Workspace", at "Ang Organization-wide limits ay laging nag-aapply, kahit na mas mataas ang total ng workspace limits". Magdagdag ng spend notifications para may threshold na mag-aalert sa iyo bago pa ang cap.
Pagpili ng modelo bawat trabaho, at kung ano talaga ang binabago ng effort
Ang pagpili ng modelo ay desisyon bawat trabaho. Simula Hulyo 2026, kada milyong token, input saka output: Claude Fable 5 sa $10 at $50, Claude Opus 4.8 at Opus 4.7 sa $5 at $25, Claude Sonnet 5 sa $3 at $15, Claude Haiku 4.5 sa $1 at $5. Ang Sonnet 5 ay mas mababa sa sticker price nito sa ngayon, dahil "Introductory pricing of $2/$10 per million input/output tokens is in effect through August 31, 2026". Ang hakbang na nagki-classify lang ng log lines ay hindi kailangan ng Opus.
Ang effort ang pangalawang lever. Tumatanggap ang output_config.effort ng low, medium, high, xhigh at max, at ang default ay high, kaya ang pag-set ng high nang explicit ay pareho lang sa pag-omit nito. Ang lower effort ay nagbabawas ng higit pa sa haba ng reasoning: sabi ng documentation, ginagawa nitong mas kaunti ang tool calls ni Claude at pinagsasama ang mga operasyon sa isa. Sa isang agent, iyon ang mas malaking tipid, dahil ang naiwasang tool call ay isang buong request na hindi na mangyayari.
Ang bitag ay nilalabanan ng effort ang cache. Ang pagbabago ng value sa pagitan ng requests ay nag-i-invalidate ng prompt caching. Sa documented example, ang request 2 ay nag-report ng cache_read_input_tokens: 3546; ang request 3, na binago ang effort mula high patungong medium, ay nag-report ng cache_creation_input_tokens na 3546 at cache_read_input_tokens na 0. Kaya i-iba ang effort sa iba't ibang workload, huwag sa loob ng isang cached conversation. Para i-steer ang depth nang hindi sinisira ang cache, gawin ito sa prompt: ang linyang tulad ng "Answer directly without deliberating." sa pinakabagong user message ay iniiwang buo ang mga naunang breakpoint.
Ang thinking tokens ay nagbi-bill sa output rates at binibilang laban sa max_tokens, kaya ang truncated na sagot ay kadalasang nangangahulugang naubos ng thinking ang budget. Basahin ang usage.output_tokens_details.thinking_tokens para sa numero. Ano talaga ang pumupuno sa Claude token bill ang naghihimay ng metro.
I-cache ang stable prefix, at iwasang masira ito nang hindi sinasadya
Ang isang cache write ay nagkakahalaga ng 1.25 beses ng base input price sa five-minute cache at 2 beses sa one-hour cache. Ang isang cache read ay nagkakahalaga ng 0.1 beses, kaya "nagbabayad ang caching pagkatapos ng isang cache read lang para sa 5-minute duration (1.25x write), o pagkatapos ng dalawang cache read para sa 1-hour duration (2x write)".
Isang linya ang nagpapaliwanag kung bakit ito angkop para sa isang always-on agent: "Ang cache ay nire-refresh nang walang karagdagang gastos sa tuwing ginagamit ang naka-cache na content." Ang isang job na tumatakbo kada dalawang minuto laban sa five-minute cache ay pinananatiling warm ang prefix nito sa buong araw para sa isang write.
Tatlong paraan para mawala ang cache nang hindi napapansin.
Isang prefix na nagbabago. "Ang mga cache prefix ay ginagawa sa sumusunod na pagkakasunod-sunod: tools, system, pagkatapos ay messages." Anumang pagbabago ng byte nang mas maaga sa pagkakasunod-sunod na iyon ay nag-i-invalidate ng lahat pagkatapos nito, at ang pag-edit ng tool definitions ay nag-i-invalidate ng buong cache. Ang klasikong sugat na gawa ng sarili ay isang timestamp o isang run id sa system prompt: bawat request ay may dalang ibang prefix, nagsusulat ng bagong entry sa 1.25x, at walang binabasang anuman pabalik. Ang palatandaan ay usage.cache_read_input_tokens na 0 sa magkakaparehong hitsurang mga tawag. Ilipat ang volatile text sa pinakabagong user message.
Isang prefix na masyadong maikli. Bawat modelo ay may minimum na cacheable length, at kapag mas mababa rito, ang request ay pino-process nang walang caching at "walang error na ibinabalik". Kasama sa mga numero ang 1,024 tokens sa Claude Opus 4.8 at Claude Sonnet 5, at 4,096 sa Claude Haiku 4.5, kaya ang paglipat ng isang job mula Sonnet patungong Haiku ay maaaring mag-off ng caching nang tahimik.
Isang conversation na lumalampas sa lookback. "Ang lookback window ay 20 blocks." Ang system ay tumitingin ng hindi hihigit sa 20 posisyon bawat breakpoint, pagkatapos ay humihinto. Sa dokumentadong halimbawa, ang isang turn na may hawak na 35 blocks na may breakpoint sa block 35 ay tumitingin sa blocks 35 pababa sa 16, at ang entry ng nakaraang turn sa block 15 ay nahuhulog sa labas ng window, kaya walang hit. Ang isang agent na nag-a-append ng ilang tool-use at tool-result blocks bawat turn ay lumalampas sa 20 sa loob ng dalawa o tatlong turn. Nakakakuha ka ng apat na breakpoints bawat request, kaya gumastos ng isa sa mga recent messages.
Ipadala ang anumang pwedeng maghintay sa Batches API
"Lahat ng usage ay sinisingil sa 50% ng standard API prices", sa parehong input at output. Ang batch processing ay asynchronous, "na karamihan ng batches ay natatapos nang wala pang 1 oras", na may resulta kapag tapos na ang bawat request o pagkalipas ng 24 oras, alinman ang mauna. Iyan ay tipikal, hindi garantisado.
I-poll ang processing_status hanggang mabasa nito ang ended. Ang mga request na nagbabalik ng errored, canceled o expired ay hindi sinisingil. Isang caveat kung umaasa ka sa spend cap: "ang mga batch ay maaaring bahagyang lumampas sa naka-configure na spend limit ng iyong Workspace."
Ang mga discount ay nagsasama-sama, at dahil ang isang batch ay maaaring tumagal nang higit sa limang minuto, inirerekomenda ng dokumentasyon ang one-hour cache para sa mga batch na nagbabahagi ng context. Kaya hatiin ang trabaho: anumang hinihintay ng tao o webhook ay nananatili sa live path, at ang nightly digest o klasipikasyon ng log kahapon ay napupunta sa isang batch.
I-log ang mga usage field ng bawat response sa sarili mong store
Hindi mo maa-attribute ang gastos na hindi mo naitala. Bawat response ay nagsasabi sa iyo kung magkano ang nagastos nito.
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,
}Mag-append ng isang row kada API call sa isang JSON-lines file, na naka-tag gamit ang job name mo. Makalipas ang isang linggo, masasabi mo kung aling job ang gumagastos at alin ang mukha lang busy. Panoorin ang cache_read: ang column ng mga zero ang pinaka-karaniwang cost bug sa isang self-hosted agent.
May isang field na madaling ma-misread. Ang input_tokens ay binibilang lang ang mga token pagkatapos ng huling cache breakpoint, kaya ang tunay na prompt size ay total_input_tokens = cache_read_input_tokens + cache_creation_input_tokens + input_tokens. Ang isang agent na nagre-report ng input_tokens: 400 sa isang malaking prompt ay hindi mura: ang natitira ay galing sa cache.
Magbilang bago magpadala. Ang token counting ay libre at ang rate limits nito ay hiwalay sa message creation, kaya gamitin ang count_tokens para i-refuse ang isang oversized na attachment imbes na magbayad para matuklasan ito. Ang resulta ay isang estimate, kaya mag-re-measure kada modelo at huwag kailanman mag-reuse ng count mula sa tokenizer ng ibang vendor. Ang Claude Opus 4.7 at mga mas bagong Opus model, Claude Fable 5 at Claude Sonnet 5 ay gumagamit ng mas bagong tokenizer na "nagpo-produce ng humigit-kumulang 30% na mas maraming token para sa parehong text". Ang Claude Sonnet 4.6 at mas maaga, kasama ang Claude Haiku 4.5, ay gumagamit ng nauna.
Para sa authoritative view, ang Admin API ay nagre-report ng usage sa https://api.anthropic.com/v1/organizations/usage_report/messages at cost sa https://api.anthropic.com/v1/organizations/cost_report. Pareho silang tumatanggap ng admin key (sk-ant-admin01-...) bilang x-api-key: $ANTHROPIC_ADMIN_KEY na may anthropic-version: 2023-06-01, at tumatanggap ng bucket_width=1d, group_by[]=model at api_key_ids[]=. Isang limitasyon: "Ang Admin API ay hindi available para sa mga individual account."
Ang huling parameter na iyon ay isang murang attribution trick: bigyan ang bawat job ng sarili nitong API key, mag-filter gamit ang api_key_ids[], at i-split ang report kada key gamit ang group_by[]=api_key_id. Ang filter ay plural, ang grouping dimension ay singular. Panatilihin ang mga key sa environment imbes na sa code, sa paraang hinahandle ng isang unang Claude API app sa isang VPS ang mga ito.
Limitahan ang loop, dahil walang ibang gagawa nito
Hindi optional dito ang bounded iteration count. Iyo ang loop, kaya iyo ang counter:
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)Wala sa mga ceiling sa itaas ang gagawa nito para sa iyo: max_tokens ay naglilimita ng isang response, at ang model ay inaabisuhan lang ng task budget.
Maglagay ng pangalawang preno sa labas ng proseso. Patakbuhin ang trabaho mula sa systemd timer sa halip na permanenteng proseso, at itakda ang RuntimeMaxSec= sa service unit nito. Gamit ang RuntimeMaxSec=600, ang hung run ay papatayin pagkalipas ng sampung minuto sa halip na umikot hanggang mapansin mo. Pagpapatakbo ng isang program bilang systemd service at timer ay sumasaklaw sa mga unit file mismo. Basahin ang ginawa ng isang run gamit ang journalctl -u triage-agent.service --since "1 hour ago".
Limitahan din ang retries, dahil ang handler na walang katapusang nagre-retry ay sinisingil ang bawat attempt. Ang 429 o 500 ay nararapat ng ilang tries na may backoff. Ang 400 ay hindi nararapat ng anuman, dahil ang parehong request ay pumapalpak sa parehong paraan.
Ang pagkontrol sa gastos ng AI agent ay nagsisimula sa pagbabasa ng sarili mong mga numero
Walang makakapagsabi sa iyo kung magkano ang gastos ng isang always-on agent, dahil ang gastos ay tokens per run na minu-multiply sa runs per day, at parehong bahagi ay nasa iyo. Patakbuhin ito nang isang beses, basahin ang usage row na na-log mo, at i-multiply sa schedule mo. I-check ang cost report pagkalipas ng dalawang araw laban sa arithmetic na iyon. Kapag hindi magkatugma ang dalawa, ang gap ay halos palaging broken cache o isang loop na tumakbo nang mas matagal kaysa sa inakala mo.
Ipinapalagay nito ang isang API key, dahil ang agent ay sarili mong program na tumatawag sa Messages API. Para sa sarili mong interactive na trabaho, kung aling Claude plan ang akma sa paraan ng pagtatrabaho mo ay sumasaklaw sa subscription side. Bawat presyo at limitasyon dito ay na-check laban sa dokumentasyon ng Anthropic noong July 2026, kaya basahin muli ang pricing page bago ka bumuo ng budget.
FAQ
Magkano ang gastos para magpatakbo ng always-on AI agent sa isang VPS?
May dalawang bill at isa lang ang predictable. Ang server ay fixed monthly price. Ang model API ay metered per token, kaya ang gastos ay kung ano ang kinokonsumo ng isang run na minultiply sa kung gaano kadalas ito tumakbo. Walang inilalathala ang Anthropic na figure para sa self-hosted always-on agent, kaya ituring ang anumang quoted number bilang hula. I-log ang usage mula sa isang totoong run at i-multiply sa iyong schedule.
Ano ang pagkakaiba ng max_tokens at task budget?
Ang max_tokens ay enforced at invisible sa model. Nililimitahan nito ang output ng isang request, kasama ang thinking, at kapag na-hit ito ay nagbibigay ng stop_reason: "max_tokens". Ang task budget ay kabaligtaran: sinasabihan ang model ng number at dito ibinabagay ang agentic loop, pero "Task budgets are a soft hint, not a hard cap" at ang enforced limit ay max_tokens pa rin.
Bakit laging zero ang cache_read_input_tokens para sa aking agent?
Dahil nagbabago ang prefix sa pagitan ng mga tawag, o ito ay masyadong maikli para i-cache. Ang karaniwang dahilan ay isang timestamp o run id na naka-interpolate sa system prompt: ang cache ay naka-key sa prefix, kaya anumang pagbabago ng byte ay nag-i-invalidate ng lahat pagkatapos nito. Ang pagbabago ng tool definitions o ng effort value ay ganito rin ang epekto. Kung hindi, ito ay dahil sa laki, dahil ang mas maiikling prompt ay hindi naka-cache at walang error na ibinabalik.
Paano ko pipigilan ang isang AI agent sa pag-loop nang tuluy-tuloy?
Magbilang ng iterations sa iyong loop code at huminto sa isang fixed maximum, dahil ang max_tokens ay nagba-bound ng isang response at ang isang agent ay gumagawa ng marami. Magdagdag ng wall-clock limit sa labas ng process: simulan ang job mula sa isang systemd timer na may naka-set na RuntimeMaxSec=, para ang isang wedged run ay ma-kill sa schedule. I-cap din ang retries, dahil ang isang retry loop ay nagbi-bill sa bawat attempt.
Maaari ba akong magtakda ng spending limit sa isang Claude API key?
Ang documented spend limit ay per workspace sa halip na per key, kaya bigyan ang agent ng sarili nitong workspace at i-cap ang monthly spend nito doon. "You cannot set limits on the Default Workspace". Magdagdag ng spend notifications para ang isang threshold ay alertuhan ka muna. Para sa attribution, bigyan ang bawat job ng sarili nitong key, pagkatapos ay i-group ang usage report gamit ang group_by[]=api_key_id.