SSD Nodes Learn
Panduan Matt ConnorOleh Matt Connor · Dikemas kini 2026-07-24

Cara kawal kos ejen AI pada VPS

Elakkan pembaziran token pada VPS dengan menetapkan had tugasan, prompt caching dan pemantauan penggunaan API bagi mengawal kos ejen AI tanpa pengawasan.

Cara mengawal kos ejen AI yang sentiasa aktif

Kawalan kos ejen AI pada VPS (virtual private server) bergantung pada had yang anda tetapkan sebelum ejen bermula. Ini kerana tiada sesiapa yang memantau penggunaan semasa ia sedang berjalan. Hadkan setiap respons dengan max_tokens, tetapkan had iterasi gelung dalam kod anda, simpan cache bagi bahagian prompt yang tidak berubah, dan log setiap angka penggunaan respons untuk melihat tugasan yang menggunakan banyak kos. Sewaan pelayan adalah harga bulanan tetap. API model dikira mengikut token, dan gelung yang berjalan tanpa pengawasan boleh menghabiskan token dengan cepat.

Ini mengandaikan ejen sudah sedia ada dan memanggil Messages API dari pelayan milik anda. Membina ejen AI dengan Claude pada VPS membincangkan mekanisme tersebut.

Mengapa ejen tanpa pengawasan mempunyai struktur kos yang berbeza

Sesi interaktif melibatkan manusia. Apabila model tersilap langkah atau membaca log sebanyak 40,000 baris, pemerhati boleh menghentikannya. Ejen tanpa pengawasan tidak mempunyai brek tersebut: ia berjalan sehingga gelung tamat, kemudian pemasa akan memulakannya semula.

Kekerapan adalah faktor pendarab yang sering diabaikan. Tugasan dengan jadual setiap lima minit berjalan sebanyak 288 kali sehari dan kira-kira 8,640 kali sebulan. Berapapun kos satu larian, itulah angka yang perlu didarabkan. Banyak ejen "sentiasa aktif" tidak perlu sentiasa aktif. Ia hanya perlu menjawab dalam tempoh beberapa minit, yang merupakan satu jadual.

Ejen juga membayar perkara yang tidak perlu dibayar oleh tetingkap sembang.

  • Definisi alatan disertakan dalam setiap permintaan. Prompt sistem penggunaan alatan menelan kos 290 token pada Claude Opus 4.8 dengan tool_choice daripada auto atau none, dan 410 dengan any atau tool. Alatan bash menambah 325 lagi. Setiap pelayan MCP yang anda sambungkan menambah skema ke dalam beban tersebut, di mana MCP adalah model context protocol.
  • Hasil alatan adalah token input. Arahan yang mencetak 8,000 baris akan memasukkan 8,000 baris tersebut ke dalam permintaan seterusnya, dan ke dalam setiap permintaan selepas itu dalam giliran tersebut.
  • Halaman yang diambil adalah token input. Purata halaman web 10 kB adalah kira-kira 2,500 token dan PDF penyelidikan 500 kB adalah kira-kira 125,000 token. max_content_tokens hanya memotong kandungan teks, kerana ia "terpakai pada kandungan teks, bukan pada kandungan binari seperti PDF". Gunakan max_uses dan allowed_domains untuk PDF.
  • Carian web dicaj mengikut carian, pada kadar $10 bagi setiap 1,000 carian, tidak kira berapa banyak hasil yang diperoleh. Carian yang ralat tidak akan dicaj.

Semua ini tidak mahal jika hanya dilakukan sekali. Semuanya menjadi mahal apabila dilakukan sebanyak 8,640 kali.

Hard ceilings dan soft ceilings menyelesaikan masalah yang berbeza

max_tokens dikuatkuasakan. Ia adalah had keras bagi jumlah output satu permintaan, merangkumi teks pemikiran dan respons. Claude tidak akan menjana melebihi had tersebut, dan model tidak dapat melihat jumlah tersebut. Mencapai had ini akan menyebabkan stop_reason: "max_tokens" dan jawapan yang terpotong. Kekangan bagi ejen: setiap permintaan dalam gelung penggunaan alatan mempunyai max_tokens sendiri, jadi ia mengehadkan satu respons dan bukannya keseluruhan tugasan. Sepuluh panggilan alatan pada 4,000 menghasilkan had 40,000 token untuk pusingan tersebut.

Bajet tugasan adalah bersifat nasihat. task_budget berada di dalam output_config dan memberitahu model jumlah token yang tersedia untuk keseluruhan gelung ejen, termasuk pemikiran, panggilan alatan, hasil alatan, dan 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,
)

"Bajet tugasan adalah petunjuk lembut, bukan had keras." Claude mungkin melebihi satu had di tengah tindakan, dan had output yang dikuatkuasakan tetap pada max_tokens. "Kiraan detik hanya boleh dilihat oleh model", dan respons tidak mengandungi medan baki bajet. task_budget.total minimum yang diterima ialah 20,000 token, dan nilai yang lebih rendah akan mengembalikan ralat 400. Bajet yang terlalu kecil untuk kerja tersebut akan menghasilkan tingkah laku seperti penolakan, menyebabkan model mengecilkan skop tugasan atau berhenti awal.

Satu perincian melibatkan kos berbanding penjimatan. Jika klien anda mengurangkan task_budget.remaining pada setiap permintaan susulan, nilai yang berubah itu akan membatalkan sebarang awalan (prefix) yang tersimpan dalam cache yang mengandungi nilai tersebut. Tetapkannya sekali sahaja, pada permintaan pertama.

Bajet tugasan adalah dalam fasa beta pada Claude Fable 5, Claude Opus 4.8 dan Claude Opus 4.7. Claude Sonnet 5 dan Claude Haiku 4.5 disenaraikan sebagai Not supported, dan bajet tugasan tidak terpakai pada Claude Code, jadi sesi Claude Code yang terputus dalam tmux bergantung pada kebersihan sesi (session hygiene).

Had ketiga berada dalam Claude Console: berikan ejen ruang kerja (workspace) sendiri, kemudian tetapkan had perbelanjaan bulanan dan had kadar setiap minit padanya. "Anda tidak boleh menetapkan had pada Default Workspace", dan "Had peringkat organisasi sentiasa terpakai, walaupun jumlah had ruang kerja adalah lebih tinggi". Tambah pemberitahuan perbelanjaan supaya amaran ambang (threshold) dapat memaklumkan anda sebelum had dicapai.

Pilihan model bagi setiap tugasan, dan usaha yang sebenarnya mengubah kos

Pilihan model adalah keputusan bagi setiap tugasan. Setakat Julai 2026, bagi setiap satu juta token, input kemudian output: Claude Fable 5 pada $10 dan $50, Claude Opus 4.8 dan Opus 4.7 pada $5 dan $25, Claude Sonnet 5 pada $3 dan $15, Claude Haiku 4.5 pada $1 dan $5. Sonnet 5 berada di bawah harga asal buat masa ini, kerana "Harga pengenalan $2/$10 bagi setiap satu juta token input/output berkuat kuasa sehingga 31 Ogos 2026". Langkah yang hanya mengklasifikasikan baris log tidak memerlukan Opus.

Usaha (effort) adalah pemboleh ubah kedua. output_config.effort menerima low, medium, high, xhigh dan max, dan tetapan lalai ialah high, jadi menetapkan high secara eksplisit adalah sama seperti tidak menetapkannya. Usaha yang lebih rendah mengurangkan lebih daripada sekadar panjang penaakulan: dokumentasi menyatakan ia menyebabkan Claude membuat kurang panggilan alatan (tool calls) dan menggabungkan operasi menjadi satu. Bagi ejen, ini memberikan penjimatan yang lebih besar, kerana satu panggilan alatan yang dielakkan bermaksud satu permintaan yang tidak perlu dilakukan.

Perangkapnya ialah usaha bertentangan dengan cache. Menukar nilai antara permintaan akan membatalkan cache prom (prompt caching). Dalam contoh yang didokumentasikan, permintaan 2 melaporkan cache_read_input_tokens: 3546; permintaan 3, dengan usaha ditukar daripada tinggi ke sederhana, melaporkan cache_creation_input_tokens sebanyak 3546 dan cache_read_input_tokens sebanyak 0. Oleh itu, variasikan usaha merentasi beban kerja, jangan sesekali di dalam satu perbualan yang di-cache. Untuk mengawal kedalaman tanpa merosakkan cache, lakukan perkara tersebut di dalam prom: baris seperti "Jawab terus tanpa berfikir panjang." pada mesej pengguna terbaru akan mengekalkan titik henti (breakpoints) sebelumnya.

Token pemikiran (thinking tokens) dicaj pada kadar output dan dikira terhadap max_tokens, sebab itulah jawapan yang terpotong sering bermaksud pemikiran telah menghabiskan bajet. Baca usage.output_tokens_details.thinking_tokens untuk jumlah tersebut. Apa yang sebenarnya memenuhi bil token Claude memperincikan pengiraan tersebut.

Cache prefix yang stabil, dan elakkan kerosakan secara tidak sengaja

Kos penulisan cache adalah 1.25 kali ganda harga input asas untuk cache lima minit, dan 2 kali ganda untuk cache satu jam. Kos pembacaan cache adalah 0.1 kali ganda, jadi "caching memberikan keuntungan selepas hanya satu pembacaan cache untuk tempoh 5 minit (1.25x penulisan), atau selepas dua pembacaan cache untuk tempoh 1 jam (2x penulisan)".

Satu baris menjelaskan mengapa ini sesuai untuk ejen yang sentiasa aktif: "Cache dikemas kini tanpa kos tambahan setiap kali kandungan yang di-cache digunakan." Tugasan yang dijalankan setiap dua minit terhadap cache lima minit akan mengekalkan prefix yang aktif sepanjang hari dengan hanya satu penulisan.

Tiga cara untuk kehilangan cache tanpa disedari.

Prefix yang berubah. "Prefix cache dicipta mengikut urutan berikut: tools, system, kemudian messages." Sebarang perubahan bait lebih awal dalam urutan tersebut akan membatalkan semua yang mengikutinya, dan menyunting definisi alatan akan membatalkan keseluruhan cache. Kesilapan biasa yang dilakukan sendiri adalah penggunaan timestamp atau run id dalam sistem prompt: setiap permintaan kemudian membawa prefix yang berbeza, menulis entri baharu pada kos 1.25x, dan tidak membaca apa-apa semula. Petandanya ialah usage.cache_read_input_tokens bernilai 0 pada panggilan yang kelihatan serupa. Pindahkan teks yang berubah-ubah itu ke dalam mesej pengguna yang terbaharu.

Prefix yang terlalu pendek. Setiap model mempunyai panjang minimum yang boleh di-cache, dan di bawah had tersebut permintaan diproses tanpa caching dan "tiada ralat dikembalikan". Angka tersebut termasuk 1,024 token pada Claude Opus 4.8 dan Claude Sonnet 5, dan 4,096 pada Claude Haiku 4.5, jadi memindahkan tugasan daripada Sonnet ke Haiku boleh mematikan caching secara senyap.

Perbualan yang melebihi had pandang belakang. "Jendela pandang belakang adalah 20 blok." Sistem memeriksa maksimum 20 kedudukan bagi setiap breakpoint, kemudian berhenti. Dalam contoh yang didokumentasikan, satu pusingan yang memegang 35 blok dengan breakpoint pada blok 35 akan memeriksa blok 35 sehingga 16, dan entri pusingan sebelumnya pada blok 15 berada di luar jendela, jadi tiada hit berlaku. Ejen yang menambah beberapa blok penggunaan alatan dan hasil alatan bagi setiap pusingan akan melepasi had 20 dalam dua atau tiga pusingan. Anda mendapat empat breakpoint bagi setiap permintaan, jadi gunakan satu untuk mesej terbaharu.

Hantar sebarang tugasan yang boleh ditangguhkan ke Batches API

"Semua penggunaan dikenakan caj pada 50% daripada harga API standard", untuk input dan output. Pemprosesan batch adalah asinkronus, "dengan kebanyakan batch selesai dalam masa kurang daripada 1 jam", dengan hasil tersedia apabila setiap permintaan telah selesai atau selepas 24 jam, mana-mana yang terdahulu. Ini adalah jangkaan biasa, bukan jaminan.

Lakukan polling pada processing_status sehingga ia memaparkan ended. Permintaan yang mengembalikan errored, canceled atau expired tidak akan dikenakan caj. Satu peringatan jika anda menggunakan had perbelanjaan: "batch mungkin melebihi sedikit had perbelanjaan yang ditetapkan untuk Workspace anda."

Diskaun adalah terkumpul, dan kerana satu batch boleh mengambil masa lebih daripada lima minit, dokumentasi mengesyorkan penggunaan cache satu jam untuk batch yang berkongsi konteks. Oleh itu, bahagikan kerja: apa-apa yang memerlukan tindakan segera daripada manusia atau webhook harus kekal pada laluan langsung, manakala ringkasan harian atau klasifikasi log semalam dimasukkan ke dalam batch pada separuh harga.

Log setiap medan penggunaan respons ke dalam stor anda sendiri

Anda tidak boleh mengagihkan perbelanjaan jika ia tidak pernah direkodkan. Setiap respons memberitahu anda kosnya.

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,
}

Tambah satu baris bagi setiap panggilan API ke dalam fail JSON-lines, dengan tag nama tugasan anda. Seminggu kemudian, anda boleh mengenal pasti tugasan mana yang menggunakan bajet dan mana yang hanya kelihatan sibuk. Perhatikan cache_read: kolum bernilai sifar adalah pepijat kos yang paling kerap berlaku pada ejen hos sendiri.

Satu medan mudah disalah tafsir. input_tokens hanya mengira token selepas titik henti cache yang terakhir, jadi saiz prom yang sebenar adalah total_input_tokens = cache_read_input_tokens + cache_creation_input_tokens + input_tokens. Ejen yang melaporkan input_tokens: 400 pada prom yang besar bukanlah murah: baki kos datang daripada cache.

Kira sebelum anda menghantar. Pengiraan token adalah percuma dan had kadarnya adalah berasingan daripada penciptaan mesej, jadi gunakan count_tokens untuk menolak lampiran yang terlalu besar daripada membayar untuk mengetahuinya. Hasilnya adalah anggaran, jadi ukur semula mengikut model dan jangan guna semula kiraan daripada tokenizer vendor lain. Claude Opus 4.7 dan model Opus kemudiannya, Claude Fable 5 dan Claude Sonnet 5 menggunakan tokenizer baharu yang "menghasilkan kira-kira 30% lebih banyak token untuk teks yang sama". Claude Sonnet 4.6 dan sebelumnya, termasuk Claude Haiku 4.5, menggunakan tokenizer yang lama.

Untuk pandangan autoritatif, Admin API melaporkan penggunaan pada https://api.anthropic.com/v1/organizations/usage_report/messages dan kos pada https://api.anthropic.com/v1/organizations/cost_report. Kedua-duanya memerlukan kunci admin (sk-ant-admin01-...) sebagai x-api-key: $ANTHROPIC_ADMIN_KEY dengan anthropic-version: 2023-06-01, dan menerima bucket_width=1d, group_by[]=model dan api_key_ids[]=. Satu had: "Admin API tidak tersedia untuk akaun individu."

Parameter terakhir itu adalah teknik atribusi yang murah: berikan setiap tugasan kunci API sendiri, tapis dengan api_key_ids[], dan pecahkan laporan mengikut kunci dengan group_by[]=api_key_id. Penapis adalah jamak, dimensi pengelompokan adalah tunggal. Simpan kunci dalam persekitaran (environment) dan bukannya dalam kod, seperti cara aplikasi Claude API pertama pada VPS mengendalikannya.

Hadkan gelung, kerana tiada cara lain

Bilangan iterasi yang dihadkan adalah wajib di sini. Gelung adalah di bawah kawalan anda, maka pemasa (counter) juga adalah di bawah kawalan anda:

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)

Kedua-dua had di atas tidak membantu anda: max_tokens mengehadkan satu respons, dan model hanya dimaklumkan tentang bajet tugasan.

Letakkan sekatan kedua di luar proses tersebut. Jalankan tugasan menggunakan systemd timer dan bukannya proses kekal, kemudian tetapkan RuntimeMaxSec= pada unit servisnya. Dengan RuntimeMaxSec=600, proses yang tergantung akan dihentikan selepas sepuluh minit dan bukannya terus berjalan sehingga anda menyedarinya. Menjalankan program sebagai servis dan timer systemd membincangkan fail unit itu sendiri. Baca hasil pelaksanaan dengan journalctl -u triage-agent.service --since "1 hour ago".

Hadkan juga percubaan semula (retries), kerana pengendali yang mencuba semula selama-lamanya akan mengenakan caj bagi setiap percubaan. Ralat 429 atau 500 wajar diberikan beberapa percubaan dengan tempoh bertenang (backoff). Ralat 400 tidak memerlukan sebarang percubaan semula, kerana permintaan yang sama akan gagal dengan cara yang sama.

Kawalan kos ejen AI bermula dengan meneliti data anda sendiri

Tiada sesiapa boleh menentukan kos ejen yang sentiasa aktif, kerana kos tersebut adalah jumlah token bagi setiap larian didarabkan dengan jumlah larian sehari, dan kedua-dua nilai ini adalah milik anda. Jalankan sekali, baca baris penggunaan yang anda log, dan darabkan dengan jadual anda. Semak laporan kos dua hari kemudian berbanding pengiraan tersebut. Jika terdapat perbezaan, jurang itu biasanya disebabkan oleh cache yang rosak atau gelung (loop) yang berjalan lebih lama daripada yang dijangkakan.

Ini mengandaikan penggunaan kunci API, kerana ejen tersebut adalah program anda sendiri yang memanggil Messages API. Untuk kerja interaktif anda, pelan Claude mana yang sesuai dengan cara kerja anda merangkumi aspek langganan. Setiap harga dan had di sini telah disemak berpandukan dokumentasi Anthropic pada Julai 2026, jadi baca semula halaman harga sebelum anda membina bajet.

FAQ

Berapakah kos untuk menjalankan ejen AI sentiasa aktif pada VPS?

Terdapat dua bil dan hanya satu yang boleh diramal. Harga pelayan adalah tetap setiap bulan. API model dikira mengikut token, jadi kosnya adalah jumlah penggunaan satu larian didarab dengan kekerapan ia dijalankan. Anthropic tidak menerbitkan sebarang angka untuk ejen sentiasa aktif yang dihoskan sendiri, jadi anggap sebarang angka yang diberikan sebagai anggaran. Log usage daripada satu larian sebenar dan darab dengan jadual anda.

Apakah perbezaan antara max_tokens dan bajet tugasan?

max_tokens dikuatkuasakan dan tidak kelihatan oleh model. Ia mengehadkan output bagi satu permintaan, termasuk pemikiran, dan jika had ini dicapai, ia akan menghasilkan stop_reason: "max_tokens". Bajet tugasan adalah sebaliknya: model diberitahu jumlah tersebut dan mengatur kitaran ejen berdasarkannya, tetapi "Task budgets are a soft hint, not a hard cap" dan had yang dikuatkuasakan tetap max_tokens.

Mengapa cache_read_input_tokens sentiasa sifar untuk ejen saya?

Kerana awalan (prefix) berubah antara panggilan, atau ia terlalu pendek untuk disimpan dalam cache. Punca biasa adalah cap masa atau ID larian yang dimasukkan ke dalam prompt sistem: cache menggunakan awalan sebagai kunci, jadi sebarang perubahan bait akan membatalkan semua data selepasnya. Mengubah definisi alatan atau nilai effort akan memberikan kesan yang sama. Selain itu, ia mungkin disebabkan oleh saiz, kerana prompt yang lebih pendek tidak disimpan dalam cache dan tiada ralat akan dikembalikan.

Bagaimanakah cara untuk menghentikan ejen AI daripada melakukan pusingan (looping) selama-lamanya?

Kira iterasi dalam kod pusingan anda dan berhenti pada had maksimum yang tetap, kerana max_tokens mengehadkan satu respons manakala ejen menghasilkan banyak respons. Tambah had masa (wall-clock limit) di luar proses: mulakan tugasan daripada pemasa systemd dengan RuntimeMaxSec= yang telah ditetapkan, supaya larian yang tersangkut akan dihentikan mengikut jadual. Hadkan juga percubaan semula (retries), kerana kitaran percubaan semula akan mengenakan caj bagi setiap percubaan.

Bolehkah saya menetapkan had perbelanjaan pada satu kunci API Claude?

Had perbelanjaan yang didokumentasikan adalah bagi setiap ruang kerja (workspace) dan bukannya bagi setiap kunci, jadi berikan ejen ruang kerja sendiri dan tetapkan had perbelanjaan bulanannya di sana. "You cannot set limits on the Default Workspace". Tambah pemberitahuan perbelanjaan supaya amaran diberikan apabila mencapai ambang tertentu. Untuk tujuan pengesanan, berikan setiap tugasan kunci sendiri, kemudian kumpulkan laporan penggunaan dengan group_by[]=api_key_id.

#claude#ai#agents#api#cost