已發佈
工程

假 Claude 偵測器現已成為開源函式庫

ai-model-verifier 是我們模型測試器背後的引擎,現以 AGPL-3.0 授權發布於 npm。給它一個基礎 URL、一把金鑰和一個模型,它就能告訴你該端點提供的是否就是它所販售的模型,現在還新增了思考簽章與 token 計費檢查。

·閱讀約 4 分鐘·作者:UnoRouter 團隊
工程公告

四月時我們公布了假 Claude 轉售商的數據:8 家供應商的 183 個通道以 Kiro、Codeium 或其他掛著 Claude 名牌的模型作答。抓到它們的探針當時位於我們的同步管線內部。現在它們位於任何人都能安裝的套件中。

ai-model-verifier 以 AGPL-3.0 授權發布於 npmGitHub。它接收基礎 URL、API 金鑰與模型名稱,回傳三種判定之一:genuinesuspiciousunverified,並附上觸發的規則以及探針的原始回應。

為什麼做成函式庫

同一套檢查現在在三個地方執行:在你瀏覽器裡的模型測試器中,在我們為公開排行榜服務的伺服器上,以及在決定 UnoRouter 究竟開放哪些上游通道的同步管線裡。一份樣式清單複製三份必然各自漂移。一個套件則不會。

它刻意做成同構的。只使用 Web 標準 API,沒有 node: 匯入,零執行期相依。HTTP 呼叫由外部注入,因此瀏覽器可以繞過 CORS,伺服器可以走防 SSRF 的 fetch。供應商與偵測器是獨立的進入點,所以檢查 Anthropic 時永遠不會打包 Gemini 的設定。

四月以來的新內容

第一篇文章裡的四個行為探針仍然是核心:小貓的故事、俳句、身分提問與模型名稱提問,現在支援 Anthropic、OpenAI 與 Gemini 格式的端點。圍繞它們新增了一批不依賴於詢問模型「你是誰」的檢查。

  • 思考簽章。Claude 會在每個思考區塊附上伺服器產生的簽章。提供其他模型的中繼無法產生它。身分探針可以用系統提示詞誘導,簽章卻不行。
  • token 計帳。中繼可以轉發真正的 Claude,卻在每次呼叫時灌水 input_tokens。兩個僅相差一段固定文字的提示詞,其計費 token 數必須在已知區間內產生差異,count_tokens 必須與計費值一致,輸出必須維持在 max_tokens 以下。Opus 4.7 與 4.8 使用不同的分詞器,因此這個區間同時也是一項層級檢查。
  • 層級不符與替換。按 Opus 計費卻提供 Sonnet 能夠騙過行為探針,因為 Sonnet 也能寫出一篇像樣的小貓故事。模型名稱探針會抓到說出較便宜層級的回答,信封檢查會抓到回傳模型 ID 與請求不符的端點。
  • 回應串擾與語言外洩。每個提示詞都帶有一個 nonce。回傳了別人 nonce 的回答代表代理在使用者之間混淆了回應。對英文提示詞的回答裡出現 CJK 字元,則指向被替換的中文模型。
  • 信封中繼資料。Anthropic 格式回覆裡出現 chatcmpl- 前綴的 ID,或 Messages 回應裡出現 OpenAI 的 usage 欄位,代表你和模型之間有一層轉換層。這只作為觀察結果回報,而非判定:我們自己的閘道正是這樣的一層。
  • 吞吐量。越大的模型每個 token 越慢,所以一條按 Opus 計費卻跑出 Sonnet 速度的通道值得留意。只取樣,從不設門檻:有意義的比較發生在提供同一模型的多條通道之間,而這只有呼叫方才能拼得出來。

它無法證明什麼

一個有效的簽章證明是真正的 Anthropic 鏈路在作答。它無法證明是哪個層級:Sonnet 被當作 Opus 販售時同樣會回傳完全有效的簽章,所以這裡通過了仍然需要層級檢查。把思考區塊回傳給 Anthropic 重新驗證簽章聽起來像是最終測試。我們實作了它,但它無法穿過中繼。兩個線上上游對真實的區塊,以及把簽章換成 308 位元組隨機 base64 的同一個區塊,都回傳了 200。中繼會把這一輪重新發給自己的後端,因此沒有任何東西真正做了驗證。該選項預設關閉,並如實寫在文件裡。

簽章檢查與 token 檢查移植自同為 AGPL 的 veridrop,其容差是對照官方 API 校準的。我們保留了那些看起來偏鬆的邊界,因為真實的 Anthropic 回應就落在它們附近。

如何使用

模型測試器會在你的瀏覽器裡執行全套檢查,包含簽章與 token 檢查,除了發往你供應商的呼叫之外沒有任何資料離開你的機器。排行榜頁面發布的是人們主動選擇分享的結果。在你自己的管線裡:

typescript
import { runVerification } from "ai-model-verifier";

const result = await runVerification({
  provider: "anthropic",
  baseUrl: "https://YOUR-PROVIDER",
  apiKey: process.env.YOUR_KEY,
  model: "claude-opus-4-8",
  mode: "server",
  checkSignature: true,
  checkTokenTruth: true,
});

console.log(result.verdict, result.reasons);
// "suspicious" [ "tier-mismatch: requested claude-opus-4-8, served sonnet" ]

按需開啟。checkSignaturecheckTokenTruth 各自需要額外請求,因此不指定就維持關閉。信封中繼資料與吞吐量從本次執行已取得的回應中讀取,不產生任何開銷。

測試一個供應商,閱讀四月的文章了解這一切的起點數據,或在某個真實端點得到錯誤判定時到 GitHub 提交 issue。

相關文章