cd ../back to blog
$Trust//June 4, 2026//7 min read

你的 Claude 真的是 Claude 嗎?四個測試揪出被重新包裝或降級的模型

model 欄位字串一樣,內容可能完全不同。用脈絡、tool calling、vision、快取四項測試,一分鐘區分真第一方模型與重新包裝的冒牌貨。

在一篇 姊妹文章 裡,我們檢驗了一個閘道是否誠實地依照真實 token 數計費。這篇文章要 檢驗另一個承諾:名稱底下的那個模型,是不是真的就是那個模型。轉售 業者可以回傳一個自稱 claude-sonnet-4-6 的東西,但實際上是一個更小的模型、一個微調版本、一段被固定範本 包起來的提示,或者是真模型本身、卻被悄悄削掉了脈絡視窗與原生功能。model 欄位裡的字串一模一樣,但在連線上流動的東西,是截然不同的兩回事。

你不需要單憑任何人的一面之詞。四個簡短的測試,就能把貨真價實的 第一方模型和重新包裝的冒牌貨區分開來。它們全都不靠去問模型 「你是誰」—— 因為模型對於自己的身分,是個靠不住的敘述者。要直接 探測的是 能力

模型被造假的四種手法

  • 偷天換日。 在旗艦模型的名稱底下,端出一個更便宜、更小的模型。運行成本最低, 在簡單的提示上也最不容易被察覺。
  • 範本代理。 你的提示在抵達模型之前,被塞進一套固定的鷹架裡 —— 這會改變模型的 行為,而且 還會用你根本沒寫過的文字,把你的 token 帳單灌水撐大。
  • 削短視窗。 號稱有 200K 脈絡,實際上卻截斷成其中 一小部分,默默丟掉長輸入的中段。
  • 閹割功能。 tool use、vision 或 prompt caching 被 拿掉或造假,於是除了純聊天以外的一切都會劣化。

測試 1 —— 脈絡視窗

把一個事實藏進一份很長的文件深處,再請它找回來。貨真價實的 200K 脈絡模型能取回它;被截斷的降級貨則會在輸入時報錯,或是丟失中段:

test_context_window.py
# test_context_window.py
# 在名稱底下被偷換的降級模型,根本撐不住它所宣稱的脈絡長度。
# 把一個事實藏進一份很長的文件深處,再請它把那個事實找回來。
from openai import OpenAI
client = OpenAI(api_key="sk-brievio-...", base_url="https://api.brievio.com/v1")

needle = "The launch code is HORIZON-7741."
filler = ("This sentence is filler. " * 9000)          # 約 5 萬個 token 的雜訊
haystack = filler + "\n\n" + needle + "\n\n" + filler

resp = client.chat.completions.create(
    model="claude-sonnet-4-6",
    messages=[
        {"role": "system", "content": "Answer only from the document."},
        {"role": "user", "content": haystack + "\n\nWhat is the launch code?"},
    ],
    max_tokens=20,
)
print(resp.choices[0].message.content)   # 真貨會回答:「HORIZON-7741」
# 被截斷的降級代理,要嘛在長輸入時直接報錯,要嘛默默丟掉中段、
# 回一句「我不知道」。把填充內容塞到超過模型宣稱的視窗(例如 200K 模型
# 就塞超過 150K token),看看它會在哪裡崩掉。

測試 2 —— 原生 tool calling

要求一次 tool call,並檢查 tool_calls。真模型會回傳一個 結構化的呼叫;只是假裝支援 tool 的重新包裝貨,則會回傳 null,並把一坨 JSON 丟進文字裡:

test_tools.py
# test_tools.py — 是原生 tool calling,還是冒牌貨?
resp = client.chat.completions.create(
    model="claude-sonnet-4-6",
    messages=[{"role": "user", "content": "What's the weather in Tokyo? Use the tool."}],
    tools=[{
        "type": "function",
        "function": {
            "name": "get_weather",
            "parameters": {"type": "object", "properties": {"city": {"type": "string"}}},
        },
    }],
    tool_choice="auto",
)
msg = resp.choices[0].message
print("tool_calls:", msg.tool_calls)   # 真貨會回傳:結構化的 get_weather(city="Tokyo")
# 只是假裝支援 tool 的轉包代理會回傳 tool_calls=None,
# 改成把一坨 JSON 當成純文字硬塞進 message.content。這就是破綻所在。

測試 3 —— vision

送出一張你早就知道內容的圖片,請模型把它讀出來。被降級成純文字的 模型辦不到 —— 它會出現幻覺,或是直接報錯:

test_vision.py
# test_vision.py — 它真的「看得見」嗎?
resp = client.chat.completions.create(
    model="claude-sonnet-4-6",
    messages=[{
        "role": "user",
        "content": [
            {"type": "text", "text": "Reply with only the exact text shown in this image."},
            {"type": "image_url", "image_url": {"url": "https://your-host/known-text.png"}},
        ],
    }],
    max_tokens=30,
)
print(resp.choices[0].message.content)   # 真貨會回答:圖片裡的文字
# 被降級成純文字的模型讀不出來 —— 它會出現幻覺、在 image 部分報錯,
# 或乾脆無視它。請用一張你早就知道內容的圖片。

測試 4 —— 快取與帳單

第四項檢查,是從那篇 token 灌水文章 借來的:把同一段很長的前綴送兩次,確認第二次時 cached_tokens 不為零,並且確認你的 prompt_tokens 和你實際送出的文字相符。範本代理在這兩點上都會失敗 —— 它沒辦法 快取一段自己改寫過的前綴,而且還會連同包裝層一起向你收費。模型的 真實性與計量錶的誠實度,是結伴同行的;請一起檢查它們。

把它們組合起來

貨真價實的模型,四項全過:它撐得住完整脈絡、回傳真正的 tool call、 讀得懂圖片、會快取前綴,並且依照你送出的 token 數計費。重新包裝或 降級的貨,至少會在其中一項上崩掉 —— 通常是那些造假成本最高的項目 (長脈絡、vision)先出問題。在你導入一個閘道時,把這整套測試跑一遍; 日後只要覺得某個模型的回答悄悄變差了,就再跑一遍。這裡出現的退步 (regression),正是無聲降級現形的時刻。

誠實的基準線

Brievio 透過一線雲端通道,路由貨真價實的第一方模型 —— Claude 經由 AWS Bedrock、Gemini 經由 Google Vertex —— 完整的脈絡視窗、原生 tool use、vision 與 prompt caching,全都原封不動地直通而過;而且你 請求的是哪個模型,拿到的就是哪個模型。把上面所有測試都拿來對著 Brievio 跑一遍,它應該都能乾乾淨淨地通過。 模型目錄 列出了每個模型真實的能力與脈絡長度,而 文件 則展示了這裡用到的請求的精確格式。

「它是不是真模型」和「計量錶說的是不是實話」—— 這兩個問題,值得拿來 問任何一個 AI 閘道,包括 Brievio 在內。兩者都只要大約一分鐘就能得到 答案。動手問吧。