SSD Nodes Learn Hosting plans →
指南 Matt Connor作者: Matt Connor · 已更新 2026-08-30

如何控制常駐 AI agent 的 API 費用

無人值守 agent 每五分鐘執行一次,每月約 8,640 次。了解硬上限、任務預算、提示快取、批次處理,以及追蹤實際支出的 usage 欄位。

如何避免常駐 AI agent 產生高額費用

VPS(virtual private server)上的 AI agent 成本控制,重點是在 agent 啟動前設定上限,因為 agent 執行期間不會有人持續查看用量。使用 max_tokens 限制每次回應,並在自己的程式碼中限制迴圈迭代次數。快取提示中不會變動的部分,並記錄每次回應的用量數據,以確認是哪個工作消耗費用。伺服器租用費是固定的月費。模型 API 依 token 用量計費,而無人看管的迴圈很容易在不知不覺中持續消耗 token。

這裡假設你已經有一個 agent,且它會從你擁有的主機呼叫 Messages API。在 VPS 上使用 Claude 建立 AI agent 介紹 agent 本身的建置方式。

為何無人值守代理的成本結構不同

互動式工作階段中有人監看。模型走錯方向或讀取 40,000 行日誌時,監看者會將其停止。無人值守代理沒有這個煞車機制:它會持續執行直到迴圈結束,然後由計時器再次啟動。

人們容易忽略頻率所造成的倍增效果。每五分鐘執行一次的工作,每天會執行 288 次,每月約執行 8,640 次。單次執行的成本,就是要乘上的數字。許多「always-on」代理其實不需要持續運作。它們只需要在幾分鐘內回應,而這可以透過排程達成。

代理還會產生聊天視窗不會產生的成本。

  • 每個請求都會附帶工具定義。 在 Claude Opus 4.8 上,工具使用系統提示的成本為 290 tokens,使用 tool_choice 搭配 autonone 時如此;使用 anytool 時則為 410 tokens。bash 工具另外增加 325 tokens。每個 附加的 MCP server 都會將其結構描述加入這項負擔;MCP 是 model context protocol。
  • 工具結果會計入輸入 tokens。 若某個命令輸出 8,000 行,這 8,000 行會加入下一個請求,也會加入該回合後續的每個請求。
  • 擷取的頁面會計入輸入 tokens。 平均 10 kB 的網頁約為 2,500 tokens,500 kB 的研究 PDF 約為 125,000 tokens。max_content_tokens 只會截斷文字內容,因為它「適用於文字內容,不適用於 PDF 等二進位內容」。請改用 max_usesallowed_domains 限制 PDF 的大小。
  • Web search 依搜尋次數計價,每 1,000 次搜尋收費 $10,與返回多少結果無關。發生錯誤的搜尋不會計費。

這些項目單次都不昂貴。但全部執行 8,640 次時,成本就會很高。

硬上限與軟上限解決的是不同問題

max_tokens 會強制執行。 這是單一請求的總輸出硬上限,包含思考內容與回應文字。Claude 不會超過此上限,而且模型無法看見這個數值。達到上限時會產生 stop_reason: "max_tokens",並傳回截斷的答案。對代理程式而言,問題在於工具使用迴圈中的每個請求都有自己的 max_tokens,因此它限制的是單次回應,而不是整個工作。10 次工具呼叫、每次上限為 4,000,代表該回合的上限是 40,000 個 token。

工作預算是建議值。 task_budget 包含在 output_config 內,用來告知模型整個代理程式迴圈可使用多少 token,計入思考內容、工具呼叫、工具結果與輸出。

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

「工作預算是軟性提示,不是硬上限。」Claude 可能在某次動作中超過預算,而輸出的強制上限仍是 max_tokens。「只有模型能看見倒數」,回應中不會包含剩餘預算欄位。接受的 task_budget.total 最小值為 20,000 token,低於此值會傳回 400 錯誤。工作所需的預算過小會導致類似拒絕的行為,因此模型會縮小工作範圍或提早停止。

有一項設定不但不省錢,反而會增加費用。如果用戶端在每次後續請求中遞減 task_budget.remaining,變更後的值會使任何包含該值的快取前綴失效。請只在第一個請求中設定一次。

工作預算目前在 Claude Fable 5、Claude Opus 4.8 與 Claude Opus 4.7 上處於 beta 階段。Claude Sonnet 5 與 Claude Haiku 4.5 列為 Not supported,而工作預算不適用於 Claude Code,因此 在 tmux 中分離的 Claude Code 工作階段 取決於工作階段管理是否妥善。

第三個上限位於 Claude Console:為代理程式建立專屬 workspace,然後在該 workspace 上設定每月支出上限與每分鐘速率限制。「你無法在 Default Workspace 上設定限制」,而且「Organization-wide limits 一律適用,即使各 workspace 的限制總和更高」。請加入支出通知,讓系統在達到上限前,於超過指定門檻時通知你。

每個工作選擇模型,以及實際改變成本的設定

模型選擇取決於個別工作。截至 2026 年 7 月,每百萬 tokens 的輸入與輸出價格如下:Claude Fable 5 分別為 $10 和 $50,Claude Opus 4.8 與 Opus 4.7 分別為 $5 和 $25,Claude Sonnet 5 分別為 $3 和 $15,Claude Haiku 4.5 分別為 $1 和 $5。目前 Sonnet 5 的實際價格低於標示價格,因為「每百萬輸入/輸出 tokens $2/$10 的 introductory pricing 有效至 2026 年 8 月 31 日」。只分類 log 行的步驟不需要 Opus。忙碌的工作排程也沒有免費額度可供消耗,因為 Claude API 沒有免費方案,註冊時提供的小額 credit 除外。

Effort 是第二個調整項目。output_config.effort 接受 lowmediumhighxhighmax,預設值是 high,因此明確設定 high 等同於省略此設定。降低 effort 不只會縮短推理長度:文件指出,這會讓 Claude 減少 tool calls,並將多項操作合併為一次。對 agent 而言,這能節省更多成本,因為少一次 tool call,就代表少發出一個完整 request。

問題在於,effort 會與快取互相牴觸。在不同 request 之間變更此值,會使 prompt caching 失效。在文件的範例中,request 2 回報 cache_read_input_tokens: 3546;request 3 將 effort 從 high 改為 medium 後,回報 3546 中的 cache_creation_input_tokens,以及 0 中的 cache_read_input_tokens。因此,請在不同工作負載之間調整 effort,不要在同一個已快取的對話中變更。若要在不破壞快取的情況下調整深度,請在 prompt 中指定:例如在最新的 user message 加入「直接回答,不要反覆推敲。」即可保留先前的 breakpoints。

Thinking tokens 按 output rates 計費,並計入 max_tokens,因此答案遭截斷時,通常表示 thinking 已耗用預算。請查看 usage.output_tokens_details.thinking_tokens 取得數值。Claude token 費用實際由哪些項目構成 會拆解這項計費內容。

快取穩定的前綴,避免意外破壞

在五分鐘快取中,寫入快取的成本是基本輸入價格的 1.25 倍;在一小時快取中則是 2 倍。讀取快取的成本是 0.1 倍。因此,使用五分鐘快取時,讀取一次快取就能回本(寫入成本為 1.25x);使用一小時快取時,讀取兩次就能回本(寫入成本為 2x)。

有一句話說明這為何適合常駐代理程式:「每次使用快取內容時,快取都會以零額外成本重新整理。」每兩分鐘對五分鐘快取執行一次的工作,只需寫入一次,就能讓前綴整天保持在快取中。

以下是三種可能在未察覺的情況下遺失快取的方式。

前綴發生變更。「快取前綴會依下列順序建立:toolssystem,接著是 messages。」只要這個順序中較前面的任何位元組發生變更,後面的所有內容都會失效;編輯工具定義則會使整個快取失效。最常見的自我造成問題,是在系統提示中加入時間戳記或執行識別碼。如此一來,每個請求都會帶有不同的前綴,以 1.25x 的成本寫入新項目,且不會讀取到任何快取。若外觀相同的呼叫中,usage.cache_read_input_tokens 都是 0,通常表示發生了這個問題。請將易變內容移至最新的使用者訊息。

前綴過短。 每個模型都有可快取長度下限。低於此長度時,請求會在未使用快取的情況下處理,而且「不會傳回錯誤」。相關數值包括 Claude Opus 4.8 與 Claude Sonnet 5 的 1,024 個 token,以及 Claude Haiku 4.5 的 4,096 個 token。因此,將工作從 Sonnet 移至 Haiku,可能會在沒有明顯提示的情況下停用快取。

對話超出回溯範圍。「回溯視窗包含 20 個區塊。」系統會在每個斷點最多檢查 20 個位置,之後停止。根據文件中的範例,某個回合包含 35 個區塊,且第 35 個區塊設有斷點時,系統會檢查第 35 到第 16 個區塊。前一個回合位於第 15 個區塊的項目已超出視窗,因此不會命中快取。代理程式每個回合附加數個工具使用與工具結果區塊時,兩到三個回合就會超過 20 個區塊。每個請求有 4 個斷點,因此請將其中一個用於最近的訊息。

將所有可以延後的工作提交至 Batches API

「所有使用量均按標準 API 價格的 50% 計費」,輸入與輸出皆適用。批次處理是非同步的,「大多數批次會在 1 小時內完成」;結果會在所有請求完成時提供,或最晚於 24 小時後提供,以較早者為準。這是一般情況,並非保證。

持續輪詢 processing_status,直到其值為 ended。回傳 erroredcanceledexpired 的請求不會計費。若你依賴支出上限,需注意一點:「批次的支出可能會略微超過 Workspace 設定的支出上限。」

這些折扣可以疊加使用。此外,由於批次處理可能超過 5 分鐘,文件建議對共用內容的批次使用 1 小時快取。因此應將工作分開:人員或 webhook 必須等待的工作保留在即時處理流程;夜間摘要或前一天的日誌分類則提交至批次,以半價處理。

將每次回應的用量欄位記錄到自己的儲存區

未記錄的支出無法歸屬。每次回應都會告訴你它的成本。

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

每次 API 呼叫都在 JSON-lines 檔案中附加一列,並標記工作名稱。一週後,你就能知道哪些工作真正產生成本,哪些工作只是看起來很忙。請注意 cache_read:整欄都是 0,是自架 agent 最常見的成本記錄錯誤。

有一個欄位很容易誤讀。input_tokens 只計算最後一個 cache breakpoint 之後的 token,因此實際的 prompt 大小是 total_input_tokens = cache_read_input_tokens + cache_creation_input_tokens + input_tokens。大型 prompt 的 agent 若回報 input_tokens: 400,並不代表成本低廉;其餘內容是從 cache 取得的。

在傳送前先計算。Token 計算免費,且其 rate limit 與訊息建立分開,因此可使用 count_tokens 拒絕過大的附件,不必付費後才發現問題。結果只是估算值,因此請針對每個 model 重新測量,絕不要重複使用其他 vendor tokenizer 的計數結果。Claude Opus 4.7 及後續的 Opus models、Claude Fable 5 與 Claude Sonnet 5 使用較新的 tokenizer,該 tokenizer「對相同文字產生約多 30% 的 token」。Claude Sonnet 4.6 及更早版本(包括 Claude Haiku 4.5)使用舊版 tokenizer。

如需權威資料,Admin API 會在 https://api.anthropic.com/v1/organizations/usage_report/messages 回報用量,並在 https://api.anthropic.com/v1/organizations/cost_report 回報成本。兩者都接受 admin key(sk-ant-admin01-...)作為 x-api-key: $ANTHROPIC_ADMIN_KEY,搭配 anthropic-version: 2023-06-01 使用,並接受 bucket_width=1dgroup_by[]=modelapi_key_ids[]=。有一項限制:「Admin API 不提供個人帳戶使用。」

最後一個參數是低成本的歸屬技巧:為每個工作提供自己的 API key,使用 api_key_ids[] 篩選,再以 group_by[]=api_key_id 依 key 分組報表。篩選條件是複數,分組維度是單數。請將這些 key 存放在環境變數中,不要寫入程式碼,方式與 在 VPS 上建立第一個 Claude API 應用程式 相同。

限制迴圈,因為沒有其他機制會替你處理

這裡不能省略有限的迭代次數。迴圈由你撰寫,因此計數器也由你控制:

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)

上方的兩個上限都不會替你處理這件事:max_tokens只會限制單一回應,而模型只會得知任務預算。代管產品會在這裡停止,就像Claude 在單次回合中的工具呼叫上限會停止已經呼叫過多次工具的工作階段;但自行撰寫的迴圈在你加入限制前,不會內建這類保護機制。

另外,在程序外部再加一道限制。不要使用永久執行的程序,而是透過 systemd timer 執行工作,並在其服務單元中設定RuntimeMaxSec=。搭配RuntimeMaxSec=600後,失控的執行會在 10 分鐘後終止,不會持續執行到你發現問題為止。將程式設為 systemd 服務與 timer會說明服務單元檔案本身。使用journalctl -u triage-agent.service --since "1 hour ago"查看某次執行的結果。

也要限制重試次數,因為無限重試的處理常式會為每次嘗試計費。429 或 500 錯誤可搭配退避機制重試幾次。400 錯誤則不應重試,因為相同的請求會以相同方式失敗。

AI 代理程式的成本控管始於讀取自己的數據

沒有人能直接告訴你常駐代理程式的成本,因為成本等於每次執行的 token 數乘以每日執行次數,而這兩項都取決於你的設定。先執行一次,讀取你記錄的用量欄位,再乘以排程頻率。兩天後查看成本報告,並與這項計算結果比對。兩者不一致時,差異幾乎總是來自快取失效,或迴圈執行時間超出預期。

這裡假設使用 API key,因為代理程式是由你自行撰寫、呼叫 Messages API 的程式。若是自行進行互動式工作,哪個 Claude 方案符合你的工作方式可協助你選擇訂閱方案。本文列出的所有價格與限制,均已在 2026 年 7 月對照 Anthropic 的文件確認;建立預算前,請重新查看定價頁面。

FAQ

在 VPS 上執行全天候 AI 代理程式的費用是多少?

費用分為兩項,只有其中一項可以預測。伺服器是固定的月費。模型 API 依 token 計費,因此成本取決於單次執行消耗的 token 數量,再乘以執行頻率。Anthropic 沒有公布自架全天候代理程式的費用,因此任何引用的數字都只能視為估算。記錄一次實際執行的 usage,再依排程計算。

max_tokens 與 task budget 有什麼差異?

max_tokens 會由系統強制套用,模型本身看不到。它會限制單次請求的輸出量,包括思考內容;達到限制時會得到 stop_reason: "max_tokens"。task budget 則相反:模型會得知這個數字,並依此調整代理程式迴圈的執行方式,但「Task budgets are a soft hint, not a hard cap」,實際強制套用的限制仍是 max_tokens

為什麼我的代理程式的 cache_read_input_tokens 一直是 0?

因為多次呼叫之間的前綴有所變更,或前綴太短而無法快取。最常見的原因是將時間戳記或執行 ID 插入 system prompt:快取依前綴建立索引,因此任何位元組變更都會使其後的全部內容失效。變更工具定義或 effort 值也會造成相同結果。否則問題可能出在大小,因為較短的 prompt 不會快取,且不會回傳錯誤。

如何避免 AI 代理程式無限迴圈?

在迴圈程式碼中計算迭代次數,並在達到固定上限時停止,因為 max_tokens 只限制單次回應,而代理程式會執行多次請求。在程序外部加入實際經過時間限制:使用 systemd timer 啟動工作,設定 RuntimeMaxSec=,讓卡住的執行依排程終止。也要限制重試次數,因為每次重試都會產生費用。

可以為單一 Claude API key 設定支出上限嗎?

文件所述的支出上限是以 workspace 為單位,而不是以 key 為單位。因此,請為代理程式建立專用 workspace,並在該 workspace 設定每月支出上限。「You cannot set limits on the Default Workspace」。加入支出通知,讓系統在達到門檻時先通知你。若要追蹤各工作用量,請為每項工作發放專用 key,再使用 group_by[]=api_key_id 彙整用量報告。