你打開 LLM 供應商後台,看見本月 API 花了 3,000 美元;接著業務問:「哪個客戶吃掉最多?客服摘要和報告生成,哪個功能其實在賠錢?」這時只看總帳就答不出來。這篇會從零搭出一套可稽核的LLM API 成本拆帳方法,把 Token、Cache、Tool Call、重試與共享成本,拆到每個客戶、功能與執行任務。
本文寫給正在做 AI SaaS、Agent、內部平台或接案系統的工程與產品團隊。你不必先懂 FinOps;我會用一個兩次 Attempt 的合成案例,帶你完成資料模型、成本計算、預算閘門與發票對帳。文中的美元只用於示範,供應商費率均以 2026 年 8 月 25 日官方文件快照計算。
先說結論:Trace 不是帳本
最重要的公式只有一條:客戶成本=Σ(每一次實際 Attempt 的 Token+Cache+Tool)+分攤共享成本。
Trace 像監視器,告訴你一次執行經過哪些模型與工具;Ledger(帳務事件帳本)像收銀機,每一筆可能計費的實際請求只記一次。Trace 可能被取樣、遺失或橫跨多次重試,所以不能直接當財務帳本;Ledger 也不必保存 Prompt,才能完成拆帳。

先判斷:你真的需要 Chargeback 嗎?
別一開始就蓋一座「AI 財務資料倉庫」。如果每月支出很小,拆得更細也不會改變定價、產品路線、容量或客戶續約,一份定期估算已經夠用。比較務實的成熟度階梯是:
- 總量:先看供應商 Dashboard,確認成本是否重要。
- Showback:把成本展示給團隊或客戶,但不移轉預算。
- Allocation:用明確規則分攤共享支出。
- Chargeback:真的把費用移到部門預算或客戶帳單。
FinOps Foundation 對 Showback 與 Chargeback 的說明也強調,後者涉及正式的費用移轉,並不天然比前者「更成熟」。若你打算向終端客戶收費,還要讓財務、法務與稅務確認方案;本文計算的是 cost-to-serve 與貢獻毛利,不直接替公司決定會計上的 COGS 或報表毛利。
LLM API 成本拆帳的核心資料模型
先把五個常被混在一起的 ID 分開。tenant_id 是客戶成本歸屬;project_id 是客戶內的預算單位;feature_key 是低基數、版本化的產品功能,例如 support_answer/v3;run_id 是一次使用者可理解的工作;trace_id 只負責觀測關聯。一次 Run 可以跨 Queue、重啟與多條 Trace。
再往下一層,一個 request_id 代表邏輯模型請求,一個 attempt_id 代表真正送到供應商的一次物理嘗試。SDK 自動重試、模型 Failover、逾時後重送,都必須新增 Attempt,不能覆蓋上一筆。想先補齊 Agent 執行鏈概念,可搭配 Agent Observability 教學與最小 AI Agent Harness 實作閱讀。
資料事件建議採 append-only:錯了就寫 usage.corrected 或 cost.adjusted,不要改掉歷史。每筆事件至少保留 idempotency_key、供應商回傳的 request ID、實際模型、狀態、發生時間與來源。金額用整數 micro-USD 或 Decimal,別用 binary float。
{
"event_type": "usage.observed",
"idempotency_key": "openai:resp_opaque:final",
"tenant_id": "t_opaque_7f2",
"project_id": "p_support",
"feature_key": "support_answer/v3",
"run_id": "run_01",
"trace_id": "optional_32_hex",
"request_id": "req_02",
"attempt_id": "att_02",
"provider": "openai",
"actual_model": "gpt-5.6-terra",
"source": "provider_response"
}
歸屬欄位必須由伺服器端的登入與授權上下文產生,不能信任瀏覽器傳來的 X-Tenant-ID。也不要把客戶姓名、Email、API Key、Prompt 或 Tool Result 放進標籤;使用不透明 ID,並把 ID 對照表放在權限更嚴格的帳務系統。
跨供應商 Usage 不能用同一條加法
這是最容易重複計費的地方。OpenAI 的 input_tokens 已包含 Cache Read 與 Cache Write;Anthropic 的 input_tokens 則是未快取部分,要再加上 Cache Create 與 Cache Read 才是總輸入;Gemini 的 promptTokenCount 已包含快取內容,但 Thinking 要和候選輸出相加。正確作法不是把所有欄位加總,而是先轉成互斥的 billable buckets。

截至 2026-08-25,OpenAI Responses usage會分出 cached 與 cache-write tokens;Anthropic Messages usage分出 cache creation、cache read 與 output;Gemini UsageMetadata另有 tool-use prompt 與 thoughts。請在 Adapter 內保存原始 payload、欄位對應版本和以下互斥分類:
input_uncached:一般輸入。cache_read:命中快取的輸入。cache_write_5m/cache_write_1h:可計費的快取建立。output_inclusive:已包含 reasoning/thinking 時,只計一次。tool_call、storage_token_hour、container_minute:不是 Token 的 meter。
total_tokens 適合做 checksum,不適合直接乘上一個單價。Cache 的節省與命中判讀,可延伸閱讀四回合 Prefix Cache Trace與Claude 省 Token 實戰。
LLM API 成本拆帳:7 步落地
步驟 1:在工作開始時凍結歸屬快照
建立 Run 時,就把 tenant_id、project_id、feature_key、環境和 allocation policy 版本寫進 durable job。之後客戶改名、專案移轉,舊帳仍能重建。若 Queue 重新投遞,沿用同一個 Run;只有再次送出供應商請求才產生新 Attempt。
步驟 2:每個物理 Attempt 只入帳一次
以 idempotency_key 加 Unique Constraint,做到 at-least-once ingestion 但 exactly-once accounting。同一 Key 若收到不同 payload hash,不要靜默更新,直接告警。失敗與逾時不能一律當成 0:供應商是否計費會依產品與情境不同,且 Client 斷線不代表後端沒有完成。
步驟 3:把 Trace 與帳本鬆耦合
可用 W3C traceparent 串起服務,也可參考 OpenTelemetry 的 GenAI 名稱;但不要發明 gen_ai.run.id 當私有欄位,更不要從 Trace 反推完整帳。OTel GenAI conventions 在 2026-08-25 仍標示為 Development,成本欄位提案也尚在演進。實務上請固定 Adapter 版本,並用自己的命名空間保存 tenant/run/attempt。
步驟 4:Pricebook 必須有生效區間
Pricebook Key 至少包含 provider account、實際回傳模型、service tier、region、batch mode、meter 與 effective_from/effective_to。計費要用 Attempt 被接受當下的價格,不是今天的價格,也不是請求時寫的模型 alias。找不到費率時先標成 PENDING,不能假設為 0。
步驟 5:用 Reserve → Settle 做預算閘門
在呼叫前,用最大輸出、最多重試、最多 Agent Step 和 Tool 上限估一筆 reserve;以整數金額做原子 conditional update。請求完成後用實際成本 settle,再釋放剩餘 reserve。服務掛掉時要有 idempotent recovery,並明確選擇帳務服務失效時是 fail-open 還是 fail-closed。
BEGIN;
UPDATE budget
SET reserved_microusd = reserved_microusd + :reserve
WHERE tenant_id = :tenant
AND spent_microusd + reserved_microusd + :reserve <= hard_limit_microusd;
-- 只有更新到 1 row 才允許呼叫;完成後以同一 idempotency_key settle
COMMIT;
供應商外層限制仍值得開啟,但不能取代每客戶閘門。以 OpenAI 為例,官方 Admin API 截至 2026-08-25 已分開提供 Spend Alerts 與專案級硬性 Spend Limit;文件也把後者描述為 hard limit。不過你仍要在自己的帳號測試資格、延遲、跨線請求與錯誤行為,不能只看到型別名稱就假設零超支。
步驟 6:先記原始成本,再做共享分攤
Gateway、向量資料庫、Observability、儲存、Egress、共同 Cache 和最低承諾用量,可能找不到唯一客戶。先把原始 Cost Item 記一次,再用版本化規則分攤:直接使用量、Token 權重、活躍客戶等分,或乾脆留在 Platform 中央成本。每筆 origin cost 的 allocation ratio 加總必須等於 1,未分攤殘值也要明列。
FinOps Allocation把固定、比例、代理指標與中央承擔都視為可選政策。關鍵不是找出唯一「正確」公式,而是讓規則可解釋、可版本化、可重算。
步驟 7:每天對 Usage,每月 True-up 發票
應用程式 Ledger 是即時估算;供應商 Usage/Costs API 是外部核對;最終發票才包含議價、Credits、Commitments、稅、FX 與四捨五入。三者不能相加,只能比對與 actualize。OpenAI 的 Costs API現已可依 project_id、line_item、api_key_id 分組;再由你的 Adapter 把這些供應商維度映射到內部 tenant 與 feature。
每日跑六個不變量:每個 Request 屬於一個 Run;(request_id, attempt_no) 唯一;Cache/Reasoning 子集合不可再加到總量;串流的 final cumulative usage 取代 partial,不是相加;每筆 Cost Item 只被分攤一次;同帳號、幣別、期間的 billed cost 與發票差異在核准容忍值內。
LLM API 成本拆帳範例:漏掉一次 Retry,少算近一半
以下不是實測,而是一個可自行重算的合成 Trace。假設短 Context 的 gpt-5.6-terra 在 2026-08-25 的 Standard 價格為:一般輸入每百萬 Token 2 美元、Cache Read 0.20 美元、輸出 12 美元;Web Search 每 1,000 次 10 美元。費率來自OpenAI 官方 Pricing。

Attempt 1 回傳了可用 Usage、狀態為 incomplete:80,000 input 中有 70,000 cached,輸出 2,000,另做 1 次 Web Search。成本是 10,000×2/1M + 70,000×0.2/1M + 2,000×12/1M + 0.01 = $0.068。
Attempt 2 重試成功:同樣 80,000 input 與 70,000 cached,輸出 3,000,沒有新 Search。成本是 $0.020 + $0.014 + $0.036 = $0.070。Run 總成本為 $0.138;若資料庫只保留最後成功結果,就少算 $0.068,約 49%。這就是每個物理 Attempt 都要獨立入帳的理由。
從成本到每客戶貢獻毛利
完成 Allocation 後,產品團隊可先計算:
客戶貢獻毛利率=(客戶收入-直接 AI 成本-已分攤共享成本)÷ 客戶收入
同時看 cost / successful outcome,不要只看 cost / token。便宜模型若讓重試率上升、工具鏈變長,單 Token 低價仍可能造成每次成功任務更貴。模型路由要用自己的任務 Eval 決定,可接著讀AI 模型路由與小型 Eval;離峰、Cache 與超價切換則可參考DeepSeek API 成本控制。
五個上線前一定要打的失敗測試
- SDK 自動重試:兩個 Attempt 都進帳,Run 只彙總一次。
- 串流中斷:partial usage 不和 final cumulative usage 重複相加。
- Queue 重送:同一事件 Key 不重複;真的再次送供應商才新增 Attempt。
- Cache 與 Thinking:子集合只用於拆價,不再疊加總 Token。
- 跨月改價:舊 Attempt 仍命中舊 Pricebook;發票 Credits 以 adjustment true-up。
還要做隱私測試:匯出的 Metric 與 Trace 中,不應出現姓名、Email、Prompt、API Key 或 Tool Result;高基數的 tenant/run/attempt 放在 Ledger 或經選擇的 Trace,不要放進一般 Prometheus labels。這會避免 Cardinality 爆炸,也降低個資外流面。
常見問題 FAQ
1. 一個客戶一把 API Key,是否最簡單?
不一定。它能增加供應商側可見度,但也帶來 Key 數量、輪替與權限管理成本;而 Feature、Run、Retry、共享成本仍要靠應用程式 Ledger。
2. 可以直接用 OpenTelemetry Metric 算帳嗎?
不建議。Metric 會聚合,高基數可能被折疊,Trace 也可能取樣。OTel 適合診斷與共通詞彙,財務完整性應由未取樣、具冪等性的事件 Ledger 提供。
3. 失敗請求都不會收費嗎?
不能這樣假設。不同供應商、狀態與產品規則不同;逾時或 Client 斷線也不等於後端沒完成。先保留 Attempt,等回傳 Usage、Costs API 或發票證據再 actualize。
4. Tool Call 只算模型 Token 嗎?
不一定。模型產生 Tool Call 會消耗 Token;Search、Container、Storage 等工具還可能有自己的 meter。Tool 執行與把結果送回模型,應分成不同 Request/Cost Item。
5. Application Cache 命中要怎麼收?
先記一筆 Cache Hit,直接成本為 0。前提是該命中確實沒有送出新的供應商 Attempt;若要收 Serving Fee 或攤提原始生成成本,請另建服務費或 Allocation 規則,不能把同一筆原始成本完整複製給每個命中客戶。
6. 預算到 100% 就一定完全不超支嗎?
仍要預留 overshoot 緩衝。在途請求、估算誤差、不同付費路徑與控制延遲都會影響落點。用原子 Reserve、每 Run 上限、供應商外層硬限額和對帳一起降低風險。
7. 估算成本和發票差多少才算異常?
請按自己的帳務結構設定。以 account/currency/period 建立容忍值,並把議價、Credits、稅、FX、Commitment 與 rounding 分開,差異才有可解釋性。
8. 什麼時候可以開始向客戶 Chargeback?
先從 Showback 開始。至少連續跑過重試、Cache、改價與月結 True-up,確定歸屬穩定,並讓財務、法務與稅務核准收費與四捨五入政策,再進到真正帳單。
給新手的 7 個重點
- 成本的最小財務單位是物理 Attempt,不是 Trace。
- Run 保存客戶與功能歸屬,Trace 只做診斷關聯。
- 先把供應商 Usage 轉成互斥 Meter,避免 Cache/Reasoning 重複計費。
- Pricebook 要版本化,費率缺失就 Pending,不能當 0。
- 預算控制用整數、原子 Reserve、Settle 與冪等 Recovery。
- 估算、供應商成本報告、應付發票是三層證據,只能對帳,不能疊加。
- 小額團隊先做 Showback;只有決策價值大於系統成本,才走到 Chargeback。
接著閱讀
左右滑動查看更多推薦
結語:先做一條能對帳的最小管線
第一週不必完成所有共享成本。先讓一個 Feature 把 tenant → run → request → attempt → usage → estimated cost 串起來,再故意觸發一次 Retry,確認兩筆 Attempt 都能對到供應商報表。接著加入 Pricebook 版本、Reserve/Settle 和月結 True-up;等 Showback 足以改變決策,再談 Chargeback。
想繼續建立完整 AI 工程能力,可以逛 AlphaLab AI 專區,或從 AlphaLab 課程把 Agent、模型評估與成本治理串成一套工作流。






