每一個 AI API 都按權杖計費。你信任閘道回傳的 usage 物件 — prompt_tokens、 completion_tokens — 認為那就是真實的數量。但這個數字偏偏是 轉售商能完全掌控的唯一項目,也是最容易讓它悄悄向你超收的地方。它有個 客氣的名字,叫做 權杖灌水(token inflation):閘道回報的權杖數比你 實際送出或收到的還多,於是你付出誠實成本的 5 倍、10 倍,有時甚至 25 倍 — 不論用的是不是真正的模型。
這正是 Brievio 當初為了對抗而打造的失敗模式,所以值得把它講清楚:灌水 是怎麼運作的、一段你能對任何閘道(包含我們)執行的 20 行測試,以及該 怎麼判讀結果。
權杖灌水到底是什麼
誠實的權杖數,是供應商自己會替你的訊息 — 你的系統提示、你的 使用者內容、模型的回覆 — 所計算出的數量。值得信任的閘道會原封不動地 把它傳過去。會灌水的閘道則往裡頭塞東西。同一個請求,帳單卻天差地別:
# 誠實的權杖數 — 數量會對應你送出的文字,外加一點點
# 對話範本的額外開銷(role 標記、格式化權杖):
{"prompt_tokens": 24, "completion_tokens": 2, "total_tokens": 26}
# 灌水 — 你只送出約 20 個權杖的文字,卻被收 1,840 個:
{"prompt_tokens": 1840, "completion_tokens": 2, "total_tokens": 1842}
# ^ 一段你從未寫過、約 1,800 個權杖的系統提示被注入到這次請求裡,
# 再回頭算到你頭上。即使只是一個字的提問。每一次呼叫都這樣。最常見的手法是隱藏的注入式系統提示:轉售商在每一次 呼叫的最前面,塞進自己幾百到幾千個權杖的文字 —「安全」前言、路由 包裝、假人格。你從沒寫過、也看不到,卻在每一個請求上都得替它付費。 以 Sonnet 的輸入費率來算,一段 1,800 個權杖的幽靈前綴,光是一個字的 提問就約值 $0.0055 的純利。再乘上每月一百萬次呼叫。
20 行測試
你不必相信任何人的說法 — 包含我們的。送出一段你知道大小的提示,再把 閘道向你收費的數量,跟你的文字在自己機器上實際分詞出來的數量做 比較:
# token_inflation_test.py
# 你的閘道有沒有誠實回報權杖數?送出一段已知大小的
# 提示,再把閘道回報的 prompt_tokens,跟你用本機分詞器對
# 你實際送出的「那幾則訊息」算出的權杖數做比較。
import tiktoken
from openai import OpenAI
client = OpenAI(api_key="sk-brievio-...", base_url="https://api.brievio.com/v1")
messages = [
{"role": "system", "content": "You are a terse assistant."},
{"role": "user", "content": "Reply with the single word: ok."},
]
# 1. 閘道實際向你收費的量:
resp = client.chat.completions.create(
model="claude-sonnet-4-6", messages=messages, max_tokens=5,
)
reported = resp.usage.prompt_tokens
# 2. 你的訊息在本機實際分詞後的量:
enc = tiktoken.get_encoding("cl100k_base") # 只是近似值 — 詳見下方說明
local = sum(len(enc.encode(m["content"])) for m in messages)
print(f"gateway reported prompt_tokens: {reported}")
print(f"local token count of your text: {local}")
print(f"ratio: {reported / local:.1f}x")
# 正常 → 比率約 1.1~1.6 倍(role 標記 + 對話範本的額外開銷)
# 灌水 → 比率 2 倍 / 5 倍 / 25 倍(有一段隱藏提示正在塞滿你的輸入)怎麼判讀:有一小段固定的額外開銷是正常的 — 對話格式 會為 role 標記與訊息邊界加上幾個權杖,所以在很短的提示上,比率落在 1.1~1.6 倍 左右沒問題,而且提示越長就越會趨近 1.0 倍。但 2 倍、5 倍、25 倍 的比率不是四捨五入的誤差 — 那是塞料。
有一個誠實的提醒:tiktoken 的 cl100k_base 是 OpenAI 的分詞器,而 Claude 或 Gemini 的 分詞方式略有不同(通常落在 10~20% 之內)。所以請把本機算出的數字 當成近似值,而不是逐一權杖的精確稽核。它永遠無法解釋 2 倍的 落差,更別說 25 倍 — 想要精確數字,請改用供應商自家的分詞器或 count-tokens 端點。這個測試是為了抓出灌水,不是為了在單一權杖上錙銖 必較。
輸出與快取也要檢查
輸入是常見的下手目標,但同樣的塞料也可能藏在輸出權杖與快取裡。再做 兩個快速檢查:
# 輸出與快取一樣可能被灌水。再做兩個 30 秒就能完成的檢查:
#
# (a) 輸出: 要求剛好只回一個權杖,並設上限。
resp = client.chat.completions.create(
model="claude-sonnet-4-6",
messages=[{"role": "user", "content": "Reply with only: ok"}],
max_tokens=2,
)
print(resp.usage.completion_tokens) # 誠實: 約 1~2。灌水: 50、200、…
#
# (b) 快取: 在約 5 分鐘內把同一段長前綴送兩次。第二次呼叫
# 應該把輸入的大部分以較低的快取讀取費率計費。如果
# 「cached」欄位永遠是 0,代表你連快取命中都付了全額。
print(resp.usage.prompt_tokens_details.cached_tokens)如果你只要一個權杖卻被收了五十個,或是同一內容的重複呼叫,你的 cached_tokens 卻一直卡在零,那這個計量表就是錯的。
灌水從哪裡來
- 注入式系統提示。加進每一個請求的包裝前言 — 單一 最常見的來源。又大、又看不見、又照樣計費。
- 重新包裝的「範本代理」模型。你的提示在抵達模型 之前,會被塞進一個龐大的固定範本。那些範本權杖是真實的權杖 — 對 模型、對你的帳單都是 — 但它們不是你的。
- 捏造的 usage 數字。最粗糙的版本:
usage物件根本就跟現實對不上。上面那段測試會立刻抓到 它。 - 幽靈式輸出灌水。回報的
completion_tokens超過實際回傳的字數。
這些都不需要用到假模型。一個閘道可以提供真正的 Claude,卻照樣把計量表 灌水 — 模型的真實性與帳單的誠實性,是兩個各自獨立的承諾,兩者你都 該檢查。
誠實的基準
Brievio 原封不動地把供應商自己的權杖數傳過去,不在你的請求裡注入任何 東西,並在每一次呼叫上記錄真實的輸入與輸出權杖,以及確切的成本,這些 都能在你的 用量儀表板裡看到。對 Brievio 執行上面 那段測試,你應該會看到 reported ≈ local + 一點點額外開銷 — 這本來就該是每個地方都讀得到的樣子。我們的 定價把每個模型對照它的官方參考費率呈現, 讓折扣可被稽核,而 用量文件則明確寫清楚我們會回傳哪些 欄位。
如果一個閘道比定價低 80%,第一個該問的問題不是「模型是不是真的」 — 而是「計量表怎麼說」。把這 20 行跑一遍。它花不到一美分,卻是你 對任何供應商所能做、最便宜的盡職調查。