--- name: spec-model description: JSC plugins 共用「取得可用模型並加上標籤」規範:固定標籤體系(能力等級/成本/延遲/上下文/用途/可用性)、任務→必要標籤對映表、取得模型清單的權威來源優先序(`claude-api` skill/CLI 自陳/使用痕跡/smoke test)、`~/.claude/jsc/models.json` 快取設計(30 天過期)、強制切換規則,以及讀到帶 `model:` frontmatter 清單檔時的模型檢查義務。當其他 skill 內文引用 spec-model 或 /jsc-shared:spec-model、或需要挑選模型/驗證模型可用性/開啟帶 `model:` frontmatter 的清單檔時載入此 skill。單獨被使用者呼叫時,直接說明本規範內容。 --- # spec-model — 共用「取得可用模型並加上標籤」規範 所有 JSC skills 需要查詢目前可用哪些模型、為模型加上可供選型決策的標籤、依任務挑選推薦模型,或檢查執行者目前使用的模型是否符合某份清單/某個 skill 的要求時,一律遵守以下規範。 ## 一、標籤體系(固定字彙表,不可自由發揮) 下表為**唯一**標籤字彙表;新增或改名標籤前一律先改本表,不得在其他 skill 內文自創同義詞。 | 面向 | 標籤 | 判準 | | --- | --- | --- | | 能力等級 | `#深度推理` | 多步推理、架構設計、跨檔案分析、需求拆解 | | | `#均衡實作` | 一般編碼、文件重整、規格落地 | | | `#輕量快速` | 摘要、分類、格式轉換、固定欄位抽取 | | 成本 | `#高成本` `#中成本` `#低成本` | 依當下官方定價分三段,**不憑記憶**,每次都要查 | | 延遲 | `#延遲敏感可用` | 在使用者等待路徑上仍可接受 | | | `#可長時間跑` | 背景/批次工作 | | 上下文 | `#長上下文` | ≥ 1M(如 `[1m]` 變體) | | | `#標準上下文` | 200k 級 | | 用途 | `#分析` `#實作` `#審查` `#摘要` `#對話人格` | 一個模型可帶多個標籤 | | 可用性 | `#本機可用` | 已通過 smoke test | | | `#不可用` | smoke test 失敗(無權限或不存在) | | | `#未驗證` | 無法在此 CLI 驗證,只有文件記載 | ## 二、任務 → 必要標籤對映表 挑選模型時,先依任務類型找出下表的「必要標籤」——候選模型必須**同時具備**必要標籤才可推薦;「加分標籤」不具備也可推薦,只是排序上較後。 | 任務類型 | 必要標籤 | 加分標籤 | | --- | --- | --- | | 需求分析/拆 TODO/架構決策 | `#深度推理` `#分析` `#本機可用` | `#長上下文` | | 依清單實作/規格落地 | `#均衡實作` `#實作` `#本機可用` | `#中成本` | | code review/findings 判讀 | `#深度推理` `#審查` `#本機可用` | — | | 逐輪摘要(worklog)/分類 | `#輕量快速` `#摘要` `#延遲敏感可用` `#低成本` | — | | 人格對話 | `#對話人格` `#本機可用` | `#延遲敏感可用` | 同一任務有多個候選都滿足必要標籤時,優先挑加分標籤命中較多者;仍並列則挑 `verified_at`(見〔四、快取設計〕)較新者。 ### 與 SDLC 閘門標籤的對應 `jsc-cli/references/model-tags.md` 另有一組供程式判定用的英文標籤(機器可讀,`model-tags.sh` 與 `sdlc-gate.sh` 直接比對字面)。兩組標籤的對應如下,**新增或改名任一邊都要同步另一邊**: | 本規範標籤 | model-tags.md 標籤 | | --- | --- | | `#深度推理`(頂級一階) | `reasoning-max` | | `#深度推理`(可判讀規格) | `reasoning-high` | | `#均衡實作` | `coding` | | `#輕量快速` | `fast`、`cheap` | | `#長上下文` | `long-context` | SDLC 各階段的放行判定一律以 `model-tags.md` 的英文標籤為準;本節的中文標籤用於選型說明與人讀敘述。 ## 三、取得清單的權威來源優先序 依序取得可用模型清單與其中繼資料(id/定價/上下文長度),**前一項可取得就不往下**: 1. **Claude Code 內建 `claude-api` skill**——模型 id/定價/上下文長度的權威來源,**不憑記憶**,每次查都要實際載入這個 skill 取得當下資料,不可用過去對話中記得的數字代替。 2. **CLI 自陳**: - Claude Code:`claude --help` 的 `--model` 說明列出的 alias(例如 `fable`/`opus`/`sonnet` 這類最新模型別名,實際列出內容以當次 `--help` 輸出為準,不可硬編碼)。 - 其他 CLI(`codex`/`opencode`/`agy`/`copilot`)用各自的列出指令取得;取不到就把該模型標為 `#未驗證`,不得省略、也不得用其他 CLI 的結果替代。 3. **使用痕跡**:`~/.claude/stats-cache.json` 內 `dailyModelTokens`/`modelUsage` 等欄位出現過的模型 id(例如曾實際用過的 `claude-opus-5`、`claude-sonnet-5`、`claude-haiku-4-5-20251001`)。這一層**只當補充候選**,用來發現前兩層沒列出但實際上帳號可用的模型,**不當權威**——出現在這裡不代表現在仍可用,仍須走第 4 步驗證。 4. **Smoke test 驗證可用性**(標準做法,所有候選模型都要跑): ```bash CLAUDE_CODE_CHILD_SESSION=1 timeout 45 claude -p 'OK' --model ``` 不可用時 stderr/stdout 會出現「is not a model this version of Claude Code recognizes」或「There's an issue with the selected model」;出現任一即標 `#不可用`;正常回應則標 `#本機可用`。 ⚠️ **必須帶 `CLAUDE_CODE_CHILD_SESSION=1`**,否則會觸發巢狀 session 與 SessionStart hook,汙染 smoke test 結果也可能造成非預期副作用。 ## 四、快取設計 - 路徑:`~/.claude/jsc/models.json`。 - 每筆模型記錄的欄位:`{ id, aliases[], tags[], context, pricing, verified_at, verdict, reason }`。 - `id`:模型完整 id(如 `claude-sonnet-5`)。 - `aliases[]`:CLI 自陳取得的別名(如 `sonnet`)。 - `tags[]`:依〔一、標籤體系〕貼上的標籤陣列。 - `context`:上下文長度(依〔一〕分類為 `#長上下文`/`#標準上下文` 的依據數值)。 - `pricing`:查證當下的定價摘要(來源為 `claude-api` skill 或對應 CLI 文件)。 - `verified_at`:本筆最後驗證(含 smoke test)的時間,格式依 `/jsc-shared:spec-time-log`。 - `verdict`:`本機可用`/`不可用`/`未驗證` 三者之一,對應〔一〕的可用性標籤。 - `reason`:判定 `verdict` 的簡短依據(例如 smoke test 的錯誤訊息摘要、或「僅文件記載未能於此 CLI 驗證」)。 - **過期規則**:`verified_at` 距今**超過 30 天視為過期**(沿用 worklog 快取的年限慣例),過期記錄需重新走〔三、取得清單的權威來源優先序〕更新,不得直接沿用。 - **內容邊界(重要)**:快取檔**只准存模型中繼資料**(上述欄位),**不得寫入任何工作內容或使用者資料**(例如對話內容、專案路徑、議題內容、任何個資)。任何要寫進這份快取的內容,寫入前都要檢查是否落在這個邊界內。 ## 五、強制切換規則(供 `/jsc-shared:todo-wiki` 與其他 skill 使用) 任何 skill 宣告了必要標籤(依〔二〕的對映表)或直接指定模型時,執行者當前模型不符就**停止並要求使用者切換**: - **不得自行降級或升級**到別的模型頂替。 - **不得先做一部分**再提醒使用者切換——必須在動手前就完成檢查並停下。 - 錯誤訊息格式依 `/jsc-shared:spec-time-log` 的 `[時間][階段][等級]: 訊息`: ``` [yyyy/MM/dd HH:mm:ss][模型檢查][ERR]: 本清單/本 skill 指定 (),當前模型為 。 請執行 /model 切換後重新載入,本次不進行任何修改。 ``` - **取得當前模型 id 的優先序**(前一項可取得就不往下): 1. **transcript 記錄的實際值**——hook 收到的 stdin JSON 有 `transcript_path`,該 jsonl 每筆 assistant 訊息都帶 `model` 欄位;取尾端最後一筆即為實際使用的模型。實作見 `jsc-hooks/hooks/lib.sh` 的 `transcript_model`。**這是唯一可驗證的來源**,SDLC 階段閘門(`jsc-hooks/hooks/sdlc-gate.sh`)一律以它為準。 2. stdin JSON 的 `model` 欄位、環境變數 `JSC_MODEL`、`~/.claude/settings.json` 的 `model`——都是宣告值,未必等於實際跑的模型。 3. **agent 自我回報**——只在以上都取不到時當最後手段。自我回報無法驗證:模型可以宣稱自己具備某標籤而沒有任何東西擋得住,**因此不得作為放行依據**。不確定時請使用者執行 `/status` 確認,不得用猜測代替確認。 - **強制力落在程式層**:任何「必須用某能力的模型才能執行」的規則,判定都要由腳本做完並以 exit code 表態;只把要求寫在 skill 內文、交給模型自我檢查,等於沒有閘門。 ## 六、讀到帶 `model:` frontmatter 的清單檔時的檢查義務 任何 agent 開啟像 `todo.md` 這種帶 `model:` frontmatter 的清單檔時,**開始執行清單內容之前**都要先依〔五、強制切換規則〕做一次模型檢查: 1. 讀出清單檔 frontmatter 的 `model`(與可能並列的 `model_alias`)。 2. 依〔五〕的方式確認當前模型(agent 自我回報,不確定就請使用者 `/status` 確認)。 3. 兩者不符 → 依〔五〕的錯誤訊息格式停止,不得先執行清單中的任何一項再提醒。 4. 相符才繼續往下執行清單內容。 **具體操作步驟(可直接照做,不需另外解讀)**:開啟一份 `.md` 檔案、發現其 YAML frontmatter 含 `model` 欄位時,**在做任何修改前**先自我回報目前模型 id,並與 frontmatter 的 `model` 欄位比對;不符就依〔五、強制切換規則〕的錯誤訊息格式中斷,本次不進行任何修改;相符才繼續往下執行檔案內容。 本節會被 `/jsc-shared:todo-wiki`(產生指定模型 wiki TODO 頁的 skill)與其他消費這類清單檔的 skill(例如處理 `TARGET.md`、處理議題 TODO 的 skill)引用,各消費端不必重抄本節內容,直接引用本節即可。