--- name: models description: 查詢目前可用哪些模型並依 spec-model 的固定標籤體系標註(能力等級/成本/延遲/上下文/用途/可用性),維護 `~/.claude/jsc/models.json` 快取,並依任務類型推薦模型或檢查當前模型是否符合指定模型。提供 `--refresh`(重跑探測與 smoke test 並重寫快取)、`--task `(依對映表推薦模型+一行理由+次選)、`--check `(比對指定模型與當前模型,不符則依強制切換規則輸出錯誤並回非零狀態)、`--json`(結構化輸出)四個參數,預設模式讀快取(過期或不存在則自動探測)輸出模型 × 標籤表格。當使用者問現在有哪些模型可用、要幫某個任務選模型、要檢查目前模型對不對、要重新驗證模型可用性、或提到 `models` skill、模型標籤、模型快取、`~/.claude/jsc/models.json` 時觸發。不適用於:切換模型本身(使用者自行執行 `/model`)、產生指定模型的 `todo.md`(用 `/jsc-shared:todo`,它會呼叫本 skill 取推薦)、與模型選型無關的一般查詢。 argument-hint: "[--refresh] [--task ] [--check ] [--json]" --- # models — 取得可用模型並加上標籤 依 `/jsc-shared:spec-model` 的標籤體系與來源優先序,查詢目前帳號/CLI 可用的模型、標註標籤、維護快取,並提供任務推薦與模型檢查兩種決策輔助。**本 skill 是 spec-model 的唯一可執行入口**——其他 skill(如 `/jsc-shared:todo`、`worklog --tune`)需要模型清單或推薦時,一律呼叫本 skill,不得自行重寫探測或推薦邏輯。 | 模式 | 用途 | 是否重跑探測 | | --- | --- | --- | | 預設(無參數) | 輸出模型 × 標籤表格 | 快取有效才不跑;過期或不存在才自動探測 | | `--refresh` | 強制重跑探測+smoke test,重寫快取 | 一律重跑 | | `--task ` | 依任務對映表推薦模型 | 沿用當前有效快取(無效才先探測) | | `--check ` | 檢查指定模型與當前模型是否一致 | 沿用當前有效快取(無效才先探測) | `--json` 可疊加在任一模式上,改變輸出格式,不改變邏輯。 --- ## 共用規範(必要前置) 先載入 `/jsc-shared:spec-preflight` 並依其流程處理;載入不到即代表 shared plugin 未安裝, 依該 spec 詢問使用者是否安裝 `https://gitea.jsc.idv.tw/plugins/shared.git`,不安裝則中斷本 skill。 本 skill 需要的規範:`spec-model`、`spec-output`、`spec-execution`、`spec-time-log`、`spec-skill-invocation` `spec-model` 是本 skill 的行為本體(標籤體系、任務對映表、來源優先序、快取設計、強制切換規則五節),下文只描述**本 skill 如何呼叫這五節**,不重抄內容;標籤字彙、對映表、來源優先序、快取欄位、錯誤訊息格式如與本檔敘述有出入,一律以 `spec-model` 當次實際載入到的內容為準。 --- ## 參數 | 參數 | 說明 | 預設 | | --- | --- | --- | | `--refresh` | 忽略快取新鮮度,強制依 spec-model 第三節重跑探測與 smoke test,重寫快取 | 不帶則只在快取過期/不存在時才探測 | | `--task ` | 依 spec-model 第二節對映表推薦模型 | 不帶則不做推薦,走預設表格輸出 | | `--check ` | 指定模型 id 或別名,比對當前模型 | 不帶則不做檢查 | | `--json` | 輸出結構化 JSON 取代 Markdown 表格/文字 | 不帶則輸出 Markdown | **參數互斥與優先序**:`--refresh` 是修飾詞,可與任何模式並存(一律先重跑探測,再往下做該模式的動作)。`--check` 與 `--task` 同時出現時,兩者語意不同不建議並用;若使用者仍同時帶入,以 `--check` 為主要動作、`--task` 的推薦結果附帶輸出,並在回報開頭註明「同時指定 `--check` 與 `--task`,本次以 `--check` 的判定結果為準」。都未帶時走預設模式(表格輸出)。 --- ## 快取 路徑與欄位固定依 `spec-model` 第四節:`~/.claude/jsc/models.json`,每筆 `{ id, aliases[], tags[], context, pricing, verified_at, verdict, reason }`,`verified_at` 超過 30 天視為過期。 - **讀取**:優先用助理的檔案讀取工具(Claude Code 為 Read)直接讀取並解析 JSON;shell 環境改用 `python3 -c "import json,sys; ..."` 解析,避免依賴 `jq`(是否安裝因環境而異)。 - **寫入**:優先用助理的檔案寫入工具(Write/Edit)整份覆寫,確保 UTF-8 無 BOM(依 `spec-output`);shell 環境改用 `python3` 組字典後 `json.dump(..., ensure_ascii=False, indent=2)` 寫檔,不用字串拼接手刻 JSON(容易漏跳脫字元)。 - **目錄不存在**:`~/.claude/jsc/` 不存在時,寫入前先建立(`mkdir -p ~/.claude/jsc`)。 - **`reason` 欄位一併記錄來源**:因快取欄位固定、不得新增欄位,「這筆是怎麼判定出來的」寫進 `reason`,格式建議:`<來源層次摘要(CLI 自陳 --help/使用痕跡 stats-cache.json/claude-api skill 文件)> + `。輸出表格的「來源」欄直接取這裡的內容,不另外judge。 - **內容邊界**:只准存模型中繼資料七個欄位,**絕不寫入任何工作內容、對話內容、專案路徑、議題內容或個資**——寫入前逐筆檢查是否越界。 --- ## 預設模式(無參數) 1. 檢查快取檔是否存在;不存在 → 視同過期,走步驟 3。 2. 存在則讀出每筆 `verified_at`,與目前時間(`TZ='Asia/Taipei' date +'%Y/%m/%d %H:%M:%S'`)比對,**任一筆超過 30 天** → 整份快取視為過期,走步驟 3;全部未過期 → 直接跳到步驟 4 用現有內容輸出。 3. **自動探測**(等同 `--refresh` 的探測部分,見下節「探測與 smoke test 流程」),完成後覆寫快取,再進入步驟 4。 4. **輸出模型 × 標籤表格**(Markdown,依 `/jsc-shared:spec-output`): | 模型 id | 別名 | 標籤 | 上下文 | 定價 | verified_at | 判定 | 來源/理由 | | --- | --- | --- | --- | --- | --- | --- | --- | | `claude-sonnet-5` | `sonnet` | `#均衡實作` `#實作` `#中成本` `#標準上下文` `#本機可用` | 200k | (查證當下定價) | 2026/08/11 10:00:00 | 本機可用 | CLI 自陳 + smoke test 通過 | (表格內容為格式示意,實際筆數與標籤依當次快取內容輸出,不得照抄範例值。) 5. `--json` 時改輸出: ```json { "cache_path": "~/.claude/jsc/models.json", "generated_at": "2026/08/11 10:00:00", "models": [ { "id": "...", "aliases": ["..."], "tags": ["..."], "context": 200000, "pricing": "...", "verified_at": "2026/08/11 10:00:00", "verdict": "本機可用", "reason": "..." } ] } ``` --- ## `--refresh`:探測與 smoke test 流程 不論快取是否有效都執行本節,完成後整份覆寫快取。依 `spec-model` 第三節,**前一項可取得就不往下**,但仍要把後續層次能補充的候選都納入再統一做 smoke test: 1. **`claude-api` skill**:以 Skill 工具載入,取得當下模型 id/定價/上下文長度清單,**不憑記憶、不援引本檔或過去對話中的舊數字**。這是候選清單與 `pricing`/`context` 欄位的權威來源。 2. **CLI 自陳**:Claude Code 執行 `claude --help`,解析 `--model` 說明列出的別名(如 `sonnet`/`opus`/`fable` 等,實際內容以當次輸出為準);非 Claude Code 助理依自身列出指令(`codex`、`opencode`、`agy`、`copilot` 各自對應指令),取不到就不強行湊數。 3. **使用痕跡(僅 Claude Code)**:讀 `~/.claude/stats-cache.json` 的 `dailyModelTokens`/`modelUsage` 等欄位,把出現過的模型 id 併入候選清單(只補充候選,不代表現在仍可用)。 4. **Smoke test**(所有候選逐一跑,Claude Code 專屬做法;其他助理見下節「非 Claude Code 助理」): ```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` → 該筆 `verdict = 不可用`;正常回應 → `verdict = 本機可用`;因不在此 CLI 驗證範圍(例如純文件記載、非本帳號方案)而無法判定 → `verdict = 未驗證`。 ⚠️ 每個候選都要帶 `CLAUDE_CODE_CHILD_SESSION=1`,避免觸發巢狀 session 與 SessionStart hook。 5. **貼標籤**:依 spec-model 第一節標籤字彙表,對每個候選同時判斷能力等級、成本(依步驟 1 查到的定價分三段,不憑記憶)、延遲、上下文(`context ≥ 1,000,000` 記 `#長上下文`,否則 `#標準上下文`)、用途(可多個)、可用性(步驟 4 的判定結果)。 6. **寫回快取**:`verified_at` 取本次完成時間,`reason` 依上節「`reason` 欄位一併記錄來源」的格式寫入,整份以 `models.json` 覆寫(不是逐筆 append,避免殘留已下架模型的舊紀錄;若某模型本次探測不到但快取內既有記錄,先詢問是否移除或保留標記為 `#不可用`,不擅自沉默刪除)。 7. 完成後照預設模式步驟 4/5 輸出表格。 --- ## `--task ` 1. 確保快取有效(無效先走上節探測流程)。 2. 依 `spec-model` 第二節對映表,把參數值對應到任務類型與必要/加分標籤: | 參數值 | 對映任務類型 | 必要標籤 | 加分標籤 | | --- | --- | --- | --- | | `analysis` | 需求分析/拆 TODO/架構決策 | `#深度推理` `#分析` `#本機可用` | `#長上下文` | | `implement` | 依清單實作/規格落地 | `#均衡實作` `#實作` `#本機可用` | `#中成本` | | `review` | code review/findings 判讀 | `#深度推理` `#審查` `#本機可用` | — | | `summary` | 逐輪摘要(worklog)/分類 | `#輕量快速` `#摘要` `#延遲敏感可用` `#低成本` | — | | `persona` | 人格對話 | `#對話人格` `#本機可用` | `#延遲敏感可用` | 參數值不在上表 → 回報「不支援的任務類型 `<值>`,可用值:analysis/implement/review/summary/persona」並停止,不猜測近似值。 3. 篩出快取中**同時具備全部必要標籤**的模型;都不具備 → 回報「目前快取內沒有符合『<必要標籤>』的模型,建議先執行 `--refresh` 重新探測」並停止。 4. 候選排序:加分標籤命中數較多者優先;仍並列則 `verified_at` 較新者優先。 5. 輸出**推薦 id + 一行理由 + 次選**: ``` 推薦:()—— <一行理由,說明命中哪些必要標籤與加分標籤> 次選:()—— <一行理由>(若只有一個候選則省略此行並註明「無其他候選」) ``` 6. `--json` 時改輸出: ```json { "task": "implement", "required_tags": ["#均衡實作", "#實作", "#本機可用"], "bonus_tags": ["#中成本"], "recommended": { "id": "...", "alias": "...", "reason": "..." }, "alternatives": [ { "id": "...", "alias": "...", "reason": "..." } ] } ``` --- ## `--check ` 用於判斷「當前執行者的模型」是否等於指定模型,供其他 skill(例如開啟帶 `model:` frontmatter 清單檔時)呼叫,行為依 `spec-model` 第五節: 1. 確保快取有效(無效先走探測流程),在快取的 `id`/`aliases[]` 中解析 ``(可傳 id 或別名);快取查不到 → 仍照字面值往下比對,並在輸出中註明「快取未收錄此模型,僅做字面比對」。 2. 取得「當前模型」:**Claude Code 沒有環境變數可讀當前模型 id**,以 agent 對自身系統提示所述的 exact model id 自我回報為準;自我回報不確定時,請使用者執行 `/status` 確認後再比對,**不得用猜的**。 3. 比對指定模型(含別名)與當前模型: - **相符** → 輸出 `[時間][模型檢查][INF]: 當前模型 符合指定的 ()。`(時間格式依 `/jsc-shared:spec-time-log`),視為成功結束。 - **不符** → 依 spec-model 第五節格式輸出並停止,**不得自行降級或升級頂替,不得先做一部分**: ``` [yyyy/MM/dd HH:mm:ss][模型檢查][ERR]: 本清單/本 skill 指定 (),當前模型為 。 請執行 /model 切換後重新載入,本次不進行任何修改。 ``` **回非零狀態**:本 skill 以 agent 對話形式執行時沒有 process exit code 可回傳,以上述 `[ERR]` 行本身作為失敗訊號——呼叫方(其他 skill 或以 headless 模式呼叫本 skill 的腳本)應以輸出是否含 `[模型檢查][ERR]` 判定失敗;若未來新增腳本化實作(例如 `shared/scripts/lib` 的參考實作),該腳本須以 `exit 1` 對應此狀態。 4. `--json` 時改輸出: ```json { "check_model": "sonnet", "resolved_id": "claude-sonnet-5", "current_model": "claude-opus-5", "match": false, "message": "[2026/08/11 10:00:00][模型檢查][ERR]: 本清單/本 skill 指定 sonnet(claude-sonnet-5),當前模型為 claude-opus-5。請執行 /model sonnet 切換後重新載入,本次不進行任何修改。", "exit_status": 1 } ``` 相符時 `match: true`、`exit_status: 0`,`message` 改為 INF 那行。 --- ## 非 Claude Code 助理 `claude-api` skill(來源優先序第 1 層)與 `~/.claude/stats-cache.json` 使用痕跡(第 3 層)都是 Claude Code 專屬,其他 CLI(Codex/OpenCode/Antigravity/GitHub Copilot)不可取得,**只能做到**: - **CLI 自陳**(第 2 層):各自的模型列出指令(例如 `codex` 的設定/說明輸出、`opencode models`、`agy` 對應指令、`copilot` 對應指令),取得到就以此作為候選與別名來源。 - **smoke test**(第 4 層):以該 CLI 自己的無互動單輪呼叫方式驗證候選模型可用性(例如 `codex exec`、`opencode run`、`agy -p`、`copilot -p` 等一次性呼叫,回應正常記 `#本機可用`、明確報錯記 `#不可用`),需在該助理環境下能否比照 Claude Code smoke test 的無害單輪呼叫方式自行判斷;判斷不出對應方式就不勉強跑。 無法取得 `pricing`/`context`(需要 `claude-api` skill 才查得到的欄位)時,**不得憑記憶填入**,該筆欄位留空或標註「未知(無法在此 CLI 取得)」;無法完成第 2、4 層探測的模型,**整批標 `#未驗證`**,`reason` 寫「僅文件記載,未能於此 CLI 驗證」。 **不得中斷**:不論第 1、3 層缺失、或第 2、4 層部分候選探測失敗,都要照常完成本次模式並輸出結果,缺失的部分如實標註,不視為錯誤而中止整個 skill。 --- ## 呼叫方式 依 `/jsc-shared:spec-skill-invocation` 的統一呼叫方式,本 skill 的實際參數格式與範例: | 助理 | 呼叫 | | --- | --- | | Claude Code / Antigravity | `/jsc-shared:models`、`/jsc-shared:models --refresh`、`/jsc-shared:models --task implement`、`/jsc-shared:models --check sonnet`、`/jsc-shared:models --task analysis --json` | | Codex | `$models --task review`,或用 `/skills` 選單 | | OpenCode | 依本 skill 的 description 自動觸發,或以自然語言描述「幫我查現在有哪些模型可用」等同預設模式 |