跳至正文
上新GPT Image 2.6 Flare / Sunburst 已上線:支援動圖 GIF、向量 SVG,官方價 7.5 折查看模型
HopBase
← 返回博客

大模型 API 用量對帳與部門分攤:實扣金額、明細驗算、按 Key 分攤 | HopBase

大模型 API 用量對帳與部門分攤:實扣金額、明細驗算、按 Key 分攤 | HopBase

先說答案:大模型 API 的帳要對得上,靠的不是服務商的「透明計費」口號,而是三層能自己複算的資料。第一層是單個任務:在 HopBase,影片、非同步生圖等非同步任務結束後,查詢介面的回應裡直接帶 usage.cost_usd(這一單從餘額實際扣掉的金額;非串流的同步回應也帶同一欄位),失敗且未扣費的任務報 0,用一條 curl 就能核。第二層是逐筆明細:控制台「使用記錄」可按日期、Key、成員、部門、建立人篩選後匯出 CSV,每行都帶官方費用、折扣、折算率和扣費金額,可以按「官方費用 × 折扣 ÷ 折算率 = 扣費金額」逐行驗算。第三層是分攤:每把 Key 顯示建立人、可以按 Key 看消耗趨勢圖,部門負責人能看、能管本部門成員的 Key 和用量,額度可以按 Key、成員、部門分別設。三層對齊了,財務按部門分攤就只是一次篩選加匯出。

為什麼大模型帳單難對

一家公司同時用對話、生圖、影片模型時,計費單位至少有四種:對話按 token,生圖多按張,影片按秒或按 video token,還有一些按次收費。再疊加幾個現實問題,帳就很難對上:

  • 非同步任務的錢在「結束時」才確定:影片提交時只是預估,真正扣多少要等任務完成;失敗的任務是否扣費、扣多少,各家口徑不同。
  • 失敗請求的口徑:請求失敗一般不計費,但如果客戶端在輸出已經生成之後才斷開,已生成的部分通常要計費。帳單裡如果不標清楚,就會出現「明明報錯了還扣錢」的爭議。
  • 多幣種:官方牌價多是美元,帳戶餘額可能是另一種幣種,中間差一個折算率;少了這個除數,任何人都沒法複算。
  • 多人共用:一把 Key 被多個專案共用,事後就分不清是誰花的。

所以對帳的目標很具體:任何一筆錢都能追到「哪個任務 / 哪次請求、哪把 Key、誰建的 Key、屬於哪個部門」,並且金額能用公開牌價複算出來。

第一層:單個任務,查詢回應裡直接拿實扣金額

非同步任務(影片、非同步生圖等)結束後(完成、失敗或取消),單任務查詢介面的回應根物件會多出一個 usage 物件:

  • usage.cost_usd:這個任務從 USD 餘額實際扣掉的金額,和使用記錄裡的扣費金額是同一個數;
  • usage.cost 是同一筆扣費的人民幣金額,usage.currency 只標註 cost 的幣種(恆為 CNY)——對帳以 cost_usd 為準;
  • 失敗且沒有扣費的任務報 0;個別生圖任務在扣費結算之後才失敗(比如模型沒有返回可用圖片),報的是實際扣費;
  • 任務進行中不返回這個欄位;而且只有建立任務的那把 Key 查得到。

覆蓋的查詢路徑:GET /v1/video/tasks/{task_id}(Seedance、Grok Imagine、可靈、MiniMax、Midjourney)、GET /api/v1/tasks/{task_id}(萬相、快樂馬)、GET /v1/images/tasks?task_id=...(GPT Image 與 Gemini 生圖的非同步任務)。自己核一下只要一條命令:

# 用提交任務的那把 Key 查詢;jq 只挑出狀態和費用
curl -s https://api.hop-base.com/v1/video/tasks/$TASK_ID \
  -H "Authorization: Bearer $HOPBASE_API_KEY" \
  | jq '{status: (.task.status // .status), usage}'

# 任務結束後的輸出形如(金額僅作示意):
# { "status": "completed", "usage": { "cost": 2.4, "cost_usd": 0.352941, "currency": "CNY" } }

Seedance 的回應裡 task.usage 是計費用的 token 數,根物件的 usage.cost_usd 才是金額,兩者別混;MiniMax、萬相這類本來就有根 usage 的,cost_usd、cost 與 currency 會合並進去。這一層的用處是:業務系統可以在任務結束時把實扣金額直接寫進自己的訂單或工單,不用再定時去控制台翻記錄,也不用拿提交時的預估當成本。

第二層:逐筆明細,匯出 CSV 並逐行驗算

同步的對話請求不產生任務。非串流的 JSON 回應體同樣帶 usage.cost_usd / usage.cost / usage.currency,並有回應頭 X-HopBase-Cost-USD;串流回應沒有(扣費要等串流結束後才知道),金額以使用記錄為準。控制台「使用記錄」頁的匯出按鈕會按頁面當前的篩選(日期區間、Key、成員、部門、Key 建立人)匯出 CSV,單個檔案最多 5 萬行、最長 400 天。每行十三列:

  1. 時間、模型、用量(輸入+快取讀寫+輸出合計 token);
  2. 官方牌價幣種、官方費用(原幣);
  3. 折扣、折算率、扣費金額(USD);
  4. 說明;
  5. API Key、密鑰狀態、使用者、部門。

其中四列從左到右正好讀成驗算式:官方費用 × 折扣 ÷ 折算率 = 扣費金額。折算率為 1 時留空,等式退化成「官方費用 × 折扣 = 扣費金額」。官方費用可以拿廠商官方價格頁自己算,折扣就是你所在分組的折扣,所以每一行都能獨立複算,不需要相信任何人的彙總數。沒法套這個等式的行——沒有牌價快照的早期記錄、按張/按次固定價計費的呼叫——這四列留空,而不是寫一個誤導人的 0。

失敗請求在說明列寫明「請求未成功,未計費」;客戶端中途斷開、但輸出已經生成的請求,寫明「請求中斷,按已產生用量計費」;按張/按次計費的呼叫寫明「非文本調用,按次計費」,檔案末尾分別彙總條數。這正是最容易起爭議的幾類行,把口徑寫在明細裡,比事後解釋省事得多。需要自動化時,GET /v1/usage 用 API Key 就能查餘額和這把 Key 的額度用量。

第三層:按 Key、按部門分攤

分攤的前提是「一個成本中心一把 Key」。HopBase 的企業帳戶裡有成員和部門,幾個事實決定了分攤能不能落地:

  • 每把 Key 顯示建立人:成員自己建的、企業主或部門負責人代建指派給成員的,都分得開;匯出也能按建立人篩。
  • 按 Key 看消耗圖表:控制台可以按 Key 檢視消費趨勢、請求數和模型分佈,異常消耗一眼能看出來是哪把 Key。
  • 部門負責人的範圍:部門負責人能看到並管理本部門成員的 Key 和用量,能給本部門成員建 Key;看不到別的部門。企業主看全公司。成員調崗後,負責人的範圍隨之變化。
  • 分層額度:Key、成員、部門都可以設額度,任何一層用完都會攔截;超額時返回 402,資訊裡寫明是 Key 額度、成員額度還是部門額度用完,不會只丟一個籠統的「餘額不足」。

月底給各部門出帳,就是在使用記錄裡選部門、選月份、匯出;每個部門拿到的是自己那份明細,並且可以用上一節的等式自己複算。

一份可以拿去核任何服務商的對帳清單

  1. 非同步任務結束後,能否從 API 直接拿到這一單的實扣金額,而不是預估或基礎成本?
  2. 明細能否匯出,是否包含官方費用、折扣、折算率,能否逐行複算?
  3. 失敗請求與「中途斷開但已生成」的請求,明細裡是否分開標註?
  4. 金額欄位有沒有寫明幣種?牌價幣種與餘額幣種不同時,折算率是否可見?
  5. 能否按 Key、成員、部門篩選匯出,Key 有沒有建立人?
  6. 額度能否分層設定,超額報錯能否看出是哪一層?
  7. 你付費呼叫的是不是你以為的那個模型?這一項可以用API 保真檢測方法自己測。

這份清單每一項都能用 curl 或匯出檔案驗證,拿去評估任何服務商都適用,包括我們。

常見問題

任務查詢裡的 usage.cost_usd 和控制台的扣費金額一樣嗎?

一樣。usage.cost_usd 取的就是這筆任務使用記錄裡的實扣金額,也就是餘額真正減少的數,可以直接拿來和匯出明細逐筆對。

為什麼任務還在跑的時候看不到 usage.cost_usd?

非同步任務的最終費用要等任務結束才確定,進行中返回的任何數字都只能是預估。所以只在完成、失敗或取消之後返回;進行中的任務回應裡沒有這個欄位,按原來的邏輯繼續輪詢即可。

失敗的任務會扣費嗎?

影片任務失敗一律不扣費,查詢裡 usage.cost_usd 報 0。生圖任務極少數情況下會在扣費結算之後才失敗,這時報的是實際扣費,使用記錄裡也能看到同一筆。同步請求失敗不扣費;客戶端中途斷開但輸出已經生成的,按已產生的用量扣費,並在匯出明細裡單獨標註。

換一把 Key 查同一個任務,為什麼沒有費用欄位?

費用只對建立任務的那把 Key 返回。這是為了讓「一個成本中心一把 Key」的分攤邊界不被打破,也避免同帳戶下其他 Key 看到不屬於自己的消耗。

對話請求有沒有類似的單筆金額?

非串流的有:回應體帶 usage.cost_usd,回應頭帶 X-HopBase-Cost-USD。串流回應沒有,因為扣費要等串流結束才知道——請看控制台使用記錄,匯出 CSV 可以逐行驗算;按 Key 或部門彙總,用篩選加匯出即可。