為每個請求選擇 Auto、TokenLab Verified 或 Official,並預先顯示價格。查看最新動態

AI 模型棄用與版本控制:保持 API 整合穩定

·2026年9月19日·約 10 分鐘閱讀·更新 2026年10月2日·1742 次瀏覽
#模型生命週期#AI API#模型基礎設施#TokenLab
AI 模型棄用與版本控制:保持 API 整合穩定

模型字串(model string)是您程式碼庫中最危險的常數。團隊常將其視為標籤,但它卻決定了哪個檢查點(checkpoint)進行回答、呼叫成本為何,以及請求是否能成功。因此,AI 模型棄用與版本控制應納入您的發布流程,而非一次性的啟動決策。本指南使用 TokenLab 的公開模型 API(觀察於 2026-10-03),展示您可以自動檢查的項目、必須在其他地方驗證的內容,以及當 ID 停止運作時該如何處理。

重點摘要

  • 生命週期資料存在於模型物件中。請從 Get a Model(觀察於 2026-10-03)讀取 tokenlab.lifecycle,而不是從部落格文章中複製日期。
  • 我們在 2026-10-03 檢查的所有五個模型皆為 active,且沒有棄用或停用日期。我們的證據中沒有實際棄用的模型,因此下方的失敗路徑是記錄在案的行為,而非我們觀察到的實際案例。
  • 缺失的模型會回傳 model_not_found,但狀態碼會因端點而異。請根據 code 進行分支判斷,切勿僅依賴狀態碼。
  • 鎖定確切的 ID 並將其保留在一個設定層中。TokenLab 表示它不會自動替換您發送的模型。
  • 備援(fallback)必須是經過測試且預先核准的選擇。不同模型之間的效能、請求格式、限制和價格皆有所不同。

AI 模型棄用與版本控制在 API 中的呈現方式

Get a Model 參考文件(觀察於 2026-10-03)指出 lifecycle 欄位涵蓋了可用性、發布日期、棄用日期和替換模型。List Models 參考文件(觀察於 2026-10-03)則在每個清單項目中增加了 tokenlab.lifecycle、tokenlab.aliases、tokenlab.commercial 和 tokenlab.badges。同一頁面列出了 tokenlab.accepted_request_formats 和 token 限制,這些對於任何模型更換都至關重要。

以下是我們在 2026-10-03 從 claude-sonnet-5 的即時模型 API 中讀取的內容。這是觀察值的濃縮呈現。我們的證據記錄了數值,而非原始的巢狀鍵名,因此請對照即時回應確認確切的鍵名。

GET https://api.tokenlab.sh/v1/models/claude-sonnet-5
category:             chat
lifecycle stage:      active
released:             2026-06-30
replacement model:    None
deprecated_at:        None
retired_at:           None
max input tokens:     1000000
max output tokens:    128000
accepted formats:     anthropic_messages, openai_chat_completions

將這五個生命週期概念對應到這些欄位,如下所示:

概念 觀察到的回應欄位 claude-sonnet-5 的值
階段 (Stage) lifecycle stage active
發布 (Release) released 2026-06-30
棄用 (Deprecation) deprecated_at None
停用 (Retirement) retired_at None
替換 (Replacement) replacement model None

空值並不總是代表有問題。對於 glm-5.2 和 gpt-5.5,即時 API(觀察於 2026-10-03)顯示 released 為 None,而階段為 active。檢查程式應在設定了 deprecated_at、retired_at 或階段非 active 時失敗,而不應在缺少發布日期時失敗。

我們也讀取了 deepseek-v4-pro 和 deepseek-v4-flash(皆於 2026-04-24 發布,皆為 active,無替換模型)。這使得五個模型皆無棄用訊號。已棄用模型的替換欄位是我們唯一無法觀察到已填入數值的欄位。

當依賴項目出錯時會失敗的指令碼

下方的檢查程式僅使用已記錄的 GET /v1/models/{model} 端點,由於目錄是公開的,因此不需要 API 金鑰。它會在 ID 缺失、設定了 deprecated_at 或 retired_at、階段非 active,或是模型不再接受請求格式時失敗。

#!/usr/bin/env python3
"""當我們依賴的模型 ID 缺失、已棄用或已停用時失敗。"""
import json
import sys
import urllib.error
import urllib.request

BASE = "https://api.tokenlab.sh/v1/models/"

# 模型 ID -> 我們程式碼實際發送的請求格式
DEPENDENCIES = {
    "gpt-5.5": "openai_chat_completions",
    "claude-sonnet-5": "anthropic_messages",
    "deepseek-v4-pro": "openai_chat_completions",
}

def fetch(model_id):
    req = urllib.request.Request(BASE + model_id, headers={"Accept": "application/json"})
    try:
        with urllib.request.urlopen(req, timeout=15) as resp:
            return resp.status, json.load(resp)
    except urllib.error.HTTPError as exc:
        try:
            body = json.load(exc)
        except ValueError:
            body = {}
        return exc.code, body

def check(model_id, fmt):
    try:
        status, body = fetch(model_id)
    except urllib.error.URLError as exc:
        return [f"could not verify: {exc.reason}"], {}, []
    if status in (400, 404):
        return [f"missing: HTTP {status}"], {}, []
    if status != 200:
        return [f"could not verify: HTTP {status}"], {}, []

    info = body.get("tokenlab", {})
    life = info.get("lifecycle") or {}
    problems = []
    if not life:
        problems.append("no lifecycle block returned")
    stage = life.get("stage")  # 請對照即時回應確認確切的鍵名
    if stage not in (None, "active"):
        problems.append(f"stage={stage}")
    for key in ("deprecated_at", "retired_at"):
        if life.get(key):
            problems.append(f"{key}={life[key]}")
    if fmt not in info.get("accepted_request_formats", []):
        problems.append(f"format {fmt} not accepted")
    return problems, life, info.get("aliases", [])

def main():
    failed = False
    for model_id, fmt in DEPENDENCIES.items():
        problems, life, aliases = check(model_id, fmt)
        if problems:
            failed = True
            print(f"FAIL {model_id}: {'; '.join(problems)}")
            if life:
                print(f"     lifecycle: {json.dumps(life)}")
        else:
            print(f"ok   {model_id} aliases={aliases}")
    sys.exit(1 if failed else 0)

if __name__ == "__main__":
    main()

請在 CI 和夜間排程中執行此指令碼,因為模型可能會在您未進行 commit 的情況下變更狀態。想像一個夜間作業在週二退出代碼為 1,而您上一次部署是在一週前。這就是重點:失敗會出現在管線中,而不是客戶的聊天視窗中。該指令碼會在失敗時列印整個生命週期區塊,以便人工查看替換值,而無需猜測鍵名。

已停用或未知模型的回傳內容

證據記錄了未知和不可用的模型,而不是單獨標記為「已停用」的回應。因此,在您驗證之前,我們將停用視為同一類錯誤。以下是文件內容,皆觀察於 2026-10-03:

位置 回應 來源
GET /v1/models/{model} 404 model_not_found Get a Model
使用拼寫錯誤或不可用模型的聊天請求 400 model_not_found,可選包含 did_you_mean, suggestions, hint Errors agents can act on
所選交付層級無供應量 503 all_channels_failed 或 503 delivery_tier_unavailable, retryable: false Errors agents can act on
金鑰缺乏模型存取權限 403 model_not_allowed Handle API errors

狀態碼在不同端點之間並不一致,因此一個修正重點很重要:我們原始文章的備援程式碼將 404 和 410 視為「識別碼已消失」。這對於聊天請求是錯誤的。記錄的聊天回應是 400,且錯誤指南建議透過 HTTP 狀態和 code 來處理錯誤。請根據 code == "model_not_found" 來編寫您的邏輯。

例如,文件顯示拼寫錯誤的 ID 會回傳 did_you_mean: "gpt-5.6-terra"。您的用戶端應按此順序反應:

  1. 不要重複發送未經修改的請求。錯誤指南將 400、403 和 404 標記為不可重複。
  2. 將 did_you_mean 視為建議。僅在您的產品已具備變更模型權限時才進行切換。
  3. 如果 503 回應主體顯示 retryable: false,請停止重試。文件指出名稱相似並不代表可用性。
  4. 將回應標頭中的 Request ID 與模型及您自己的作業 ID 一起儲存。
  5. 通知相關人員。已鎖定的 ID 消失是一個發布事件,而非暫時性錯誤。

鎖定確切 ID 或追蹤別名

最佳實踐指南(觀察於 2026-10-03)建議在每個請求中明確指定模型 ID,且不要自動切換模型。它警告說,替換模型可能會在未經程式碼變更的情況下改變品質、價格、上下文長度、工具或媒體支援。錯誤指南補充說,TokenLab 不會自動替換您發送的模型。

策略 行為 主要風險
鎖定確切 ID(如 gpt-5.5) 您會獲得該模型,否則會收到錯誤 如果 ID 被移除,會導致嚴重失敗
追蹤別名 名稱隨時間推移可能指向新位置 行為和成本可能在未更動程式碼的情況下改變
設定檔中的內部路由名稱 您的程式碼請求 primary_chat;設定檔將其對應到確切 ID 您需自行負責並測試對應關係

關於別名,我們發現了一個缺口。List Models 參考文件稱每個項目都有 tokenlab.aliases。我們擁有的五個即時摘錄(claude-sonnet-5, deepseek-v4-pro, deepseek-v4-flash, glm-5.2, gpt-5.5)中,沒有一個顯示別名值。我們無法告訴您這些模型今天有哪些別名。上述指令碼會為每個依賴項目列印 aliases,請執行它並閱讀輸出。

另外兩個目錄事實有助於理解。2026-10-02 的目錄將版本列為單獨的確切 ID,例如 claude-sonnet-4-6, claude-sonnet-5 和 claude-sonnet-5-5。並列並不代表其中一個是另一個的繼承者。replacement 值是唯一應該體現這種關係的地方。一個 ID grok-voice-latest 的名稱中包含 "latest"。我們沒有證據顯示它繼承自什麼,因此在信任它之前請檢查其模型頁面。市場風格的前綴 ID 並非 TokenLab 別名。遷移指南稱 TokenLab ID 不帶有 OpenRouter 提供者前綴,並建議將您自己的 LiteLLM 別名與 TokenLab ID 分開。

針對已消失之鎖定模型的備援模式

將備援視為您預先測試過的第二個鎖定模型。請針對每個呼叫點進行選擇,記錄哪個模型處理了每個回答,並使用相同的夜間指令碼進行驗證。在配對之前比較兩個模型:

模型 (即時 API,觀察於 2026-10-03) 每 1M token 輸入/輸出 最大輸入/輸出 token 請求格式 列出的能力
gpt-5.5 $1.50 / $9.00 1,000,000 / 128,000 openai_chat_completions, openai_responses coding, json-mode, prompt-cache, reasoning, tool-use, vision
claude-sonnet-5 $0.90 / $4.50 1,000,000 / 128,000 anthropic_messages, openai_chat_completions json-mode, prompt-cache, reasoning, tool-use, vision
deepseek-v4-pro 離峰 $0.66 / $1.98;尖峰 $1.32 / $3.96 1,000,000 / 384,000 anthropic_messages, openai_chat_completions, openai_responses json-mode, prompt-cache, tool-use

這三者的定價最後更新於 2026-10-02T16:53:30.068Z。差異很重要。claude-sonnet-5 不接受 openai_responses,因此基於 Responses 的呼叫者無法備援至此。deepseek-v4-pro 未列出 vision 或 reasoning,因此帶有圖片的請求會在此失敗。DeepSeek 的尖峰時段為北京時間 09:00-12:00 和 14:00-18:00。

以下是成本估算範例。假設每日負載為 10M 輸入和 2M 輸出 token,這是我們的說明用數字,而非實際測量值:

  • gpt-5.5: 10 × $1.50 + 2 × $9.00 = $15 + $18 = 每日 $33。
  • claude-sonnet-5: 10 × $0.90 + 2 × $4.50 = $9 + $9 = 每日 $18。
  • deepseek-v4-pro 離峰: 10 × $0.66 + 2 × $1.98 = $6.60 + $3.96 = 每日 $10.56。
  • deepseek-v4-pro 尖峰: 10 × $1.32 + 2 × $3.96 = $13.20 + $7.92 = 每日 $21.12。

這些僅為估算值,且快取輸入的定價方式不同。下方的程式碼僅在重試無法修復的錯誤時進行備援。429 或可重試的 5xx 錯誤應遵循正常的重試規則。

import logging
import os

import openai

log = logging.getLogger("model-routing")

client = openai.OpenAI(
    api_key=os.environ["TOKENLAB_API_KEY"],
    base_url="https://api.tokenlab.sh/v1",
    timeout=30.0,
    max_retries=0,  # 我們自行決定什麼情況適合重複發送
)

ROUTES = {
    "primary_chat": {"model": "gpt-5.5", "fallback": "claude-sonnet-5"},
    "coding_agent": {"model": "claude-sonnet-5", "fallback": "deepseek-v4-pro"},
}

def _error(exc):
    body = exc.body if isinstance(exc.body, dict) else {}
    err = body.get("error", body)
    return err if isinstance(err, dict) else {}

def _chat(model_id, text):
    resp = client.chat.completions.create(
        model=model_id,
        messages=[{"role": "user", "content": text}],
    )
    return resp.choices[0].message.content

def call_model(route, text):
    """回傳 (回答的模型, 文字)。請記錄回答的模型。"""
    cfg = ROUTES[route]
    try:
        return cfg["model"], _chat(cfg["model"], text)
    except openai.APIStatusError as exc:
        err = _error(exc)
        code = err.get("code")
        gone = code == "model_not_found"
        no_supply = (
            code in ("all_channels_failed", "delivery_tier_unavailable")
            and err.get("retryable") is False
        )
        if not (gone or no_supply):
            raise  # 401/402/403/429 等錯誤需要不同的修復方式
        log.warning("鎖定的模型 %s 不可用 (%s);使用 %s",
                    cfg["model"], code, cfg["fallback"])
        return cfg["fallback"], _chat(cfg["fallback"], text)

備援只會跳轉一次,絕不連鎖。如果備援也失敗,請拋出錯誤並通知相關人員。靜默的連鎖替換是漂移問題的另一種形式。

AI 模型棄用與版本控制的發布檢查清單

在變更生產環境模型 ID 之前執行此清單。它呼應了最佳實踐指南(觀察於 2026-10-03)並增加了生命週期檢查。

  1. 列出所有生產環境中的模型 ID,並標註每個 ID 的呼叫點。一個設定層應該能在幾秒鐘內回答這個問題。
  2. 針對當前和候選 ID 執行生命週期指令碼。讀取 deprecated_at, retired_at, 階段和替換模型。
  3. 使用 Get a Model 中的 accepted_request_formats,確認候選模型接受您的程式碼所發送的請求格式。
  4. 對照您最長的實際請求和輸出上限,比較最大輸入和最大輸出 token。
  5. 比較能力。在產品依賴的情況下,確認 vision, tool-use, json-mode 和 reasoning。
  6. 根據當前價格重新計算成本,並附上計算過程。對於 DeepSeek,請分開計算尖峰和離峰時段。
  7. 使用您將要發布的確切候選 ID 和格式重播代表性請求。包含一個失敗案例,例如未知的 ID。
  8. 驗證錯誤路徑。您的用戶端應根據 code 進行分支,保留 Request ID,且不要重試 400, 403 或 404。
  9. 將變更作為設定檔編輯發布,並將舊 ID 保留為記錄在案的回滾值。
  10. 檢查每個回應記錄是否儲存了實際處理該請求的模型。
  11. 發布後重新執行夜間指令碼。確認備援 ID 也通過檢查。

在文件未說明的地方,檢查清單就是保障。它們沒有提供棄用提前通知期,也沒有通知管道。請分開驗證提供者的通知,並檢查模型頁面是否有任何生命週期說明。

常見問題

如何判斷 TokenLab 模型是已棄用還是已停用?

呼叫 GET /v1/models/{model} 並讀取 tokenlab.lifecycle。檢查階段、deprecated_at、retired_at 和替換模型。截至 2026-10-03,我們讀取的五個模型皆為 active,且未設定日期。請再次輪詢,因為該值僅反映您詢問當下的狀態。

未知模型 ID 會回傳什麼 HTTP 狀態碼?

這取決於端點。Get a Model 回傳 404 model_not_found,而使用錯誤模型的聊天請求則回傳 400 model_not_found。在所選交付層級無供應量的模型會回傳 503。請根據 code 欄位進行分支判斷。

我應該重試 model_not_found 錯誤嗎?

不應該。重複相同的請求不會改變結果。如果存在 did_you_mean 和 suggestions,請檢查它們,但僅在您的產品已具備權限時才切換模型。否則,請使用預先核准的備援並通知您的團隊。

如果我的模型消失,TokenLab 會自動將我的請求切換到另一個模型嗎?

文件指出它不會自動替換您發送的模型。請發送明確的 ID 並自行處理錯誤。您的備援應該是一個經過測試的設定值,而不是對平台的假設。

在下一次模型變更之前,請在模型目錄中比較當前的 ID、限制和價格。

來源

價格觀測於 2026-10-03

相關模型

最近發布的模型

用本文涉及的模型開始構建

比較價格、測試路由,把文章研究直接變成可執行的 API 呼叫。