AI Workflow · part 23
[Claude Code] 六段 prompt 做出自己的資源儀表板:Claude Code mods 實作
❯ cat --toc
TL;DR
Claude Code 2.1.287 起支援 mods:放在 plugin 裡的 TypeScript 小程式,能在終端機畫面板、加按鈕、給 Claude 新工具。我照這篇的六段 prompt 在乾淨的 session 實測,第一段 3 分 41 秒就做出顯示 GPU 與硬碟的面板,之後每段加一張卡,最後 Claude 自己也能呼叫它查資源。不用寫程式,但每段都要讓它跑 claude plugin validate 到通過。

前言
開進停車場,入口的看板會寫 B1 剩 3 格、B2 已滿,你不用每層繞一圈找位子。
我的 Claude Code 以前沒有這塊看板。手上有幾台跑模型的機器、幾個 AI 訂閱,Claude 每次派工前都要自己一台一台 ssh 上去跑 nvidia-smi,看哪台有空,等於每層都繞一圈。
Claude Code 10 月初出了 mods,可以在終端機裡畫面板。我花一天做出自己的面板,再把做法拆成六段 prompt。照著貼完,就會長出這樣一塊面板:

這篇不教你抄我的程式碼。我的面板接的是我家的機器,對你沒用。六段 prompt 照順序貼給 Claude,它會做出連到你自己機器的版本。每一段我都開乾淨的 session 實際跑過。
mods 是什麼:一支能改 Claude Code 畫面與行為的小程式
把它想成 Claude Code 的外掛:裝上去以後,終端機裡會多出你自己設計的畫面和按鈕。技術上,mod 是放在 plugin 裡的一個 TypeScript 函式。Claude Code 啟動時呼叫它,它可以註冊自己要接哪些事件:
- 畫畫面:在終端機開一個面板(Pane),放文字、進度條、按鈕。
- 給 Claude 新工具:註冊一個工具,Claude 就能像呼叫 Bash 一樣呼叫它。
- 攔截工具呼叫:Claude 每次要跑工具之前,mod 可以先看一眼,必要時擋下來。
- 加斜線指令:例如
/my-dash重新打開面板。
官方的介紹在 Claude Code mods 公告,完整 API 在 mods 文件。
有一件事要先知道:mod 跟 Claude Code 同權限,沒有沙箱。它讀得到你的環境變數、看得到整段對話。所以裝來路不明的 mod 前,要先用 claude plugin validate 看它到底碰了什麼。這篇每段 prompt 我都叫 Claude 跑這個指令,一方面檢查語法,一方面你也看得到它掛了哪些事件。
開始前:確認版本、準備一個資料夾
mods 要 Claude Code v2.1.287 以上:
claude --version
# 2.1.289 (Claude Code)
版本不夠就 claude update。然後開一個空資料夾當工作區,在裡面啟動 Claude Code:
mkdir ~/my-dash-work && cd ~/my-dash-work
claude
接下來的六段 prompt 直接在這個 session 裡連續貼就好。我實測時每段都開新的 session(claude -p),只是為了確認 prompt 本身就夠清楚,不靠前一段的對話記憶。
第一段:3 分 41 秒做出 GPU 與硬碟面板
幫我做一個 Claude Code mod:在右邊開一個面板,顯示這台電腦的 GPU 顯示卡記憶體用量(有 NVIDIA 卡就用 nvidia-smi,沒有就顯示「沒有 NVIDIA 顯卡」)和家目錄所在硬碟還剩多少空間,每一項都畫一條用量條,每 10 秒自動更新一次。
mod 放在目前資料夾的 my-dash/ 底下。做完用 claude plugin validate 檢查到通過為止,最後告訴我怎麼讓 Claude Code 載入它。
我這次實測花 3 分 41 秒。Claude 做出來的資料夾長這樣:
my-dash/
├── .claude-plugin/plugin.json 名稱、版本、說明
├── hooks/hooks.json 指向 register.tsx
├── hooks/register.tsx 面板、/my-dash 指令、每 10 秒更新
├── hooks/parse.ts 解析 nvidia-smi 和 df 的輸出、畫用量條
├── hooks/my-dash.test.ts 測試
└── types/index.d.ts 面板讀的資料格式
它還順手寫了測試,終端機和 Desktop app 兩種介面各測一次。測試不是我要的,是 Claude Code 內建的 mod 寫作指引本來就要它寫。
載入方式它也會告訴你:
claude --plugin-dir ~/my-dash-work/my-dash
打開後面板就出現在對話上方,有兩欄:GPU 和家目錄硬碟,底下寫最後更新時間。我的 MacBook 沒有 NVIDIA 卡,所以 GPU 那欄顯示「沒有 NVIDIA 顯卡」,我截圖時硬碟那欄是「剩 232.0 GiB / 共 926.4 GiB」。
面板沒自己出現的話,打 /my-dash 就會打開。Claude 回報裡寫終端機要 144 欄以上才會在啟動時自動開,比較窄就要手動叫。
第二段:加 Claude 額度卡,每張卡都能收合
在 my-dash 面板加一張「Claude 額度」卡:顯示 5 小時和每週額度各用了幾 %、多久後重置(mod 可以從 session 的用量資訊讀到)。每張卡的標題都要能點一下就收合、再點一下展開。改完用 claude plugin validate 檢查到通過。
實測 136 秒。額度不用自己打 API 抓,mod 可以直接讀 Claude Code 狀態列用的那份用量資料。額度數字要等你用訂閱帳號送出第一則訊息之後才有,在那之前卡片會顯示「尚無額度資料(送出第一則訊息後才有)」。用 API key 的帳號一直都是這個狀態。
第三段:接上你的本地模型
在 my-dash 再加一張「地端模型」卡:每 10 秒打一次 http://localhost:8080/v1/models(我的本地模型服務是 OpenAI 相容 API),列出現在提供哪些模型;連不上就顯示「沒在跑」。網址寫成檔案開頭的一個常數,方便我改。validate 到通過。
實測 119 秒。/v1/models 是模型服務用來回報「我現在有哪些模型」的網址,格式跟 OpenAI 的一樣,所以叫 OpenAI 相容。網址換成你自己的服務就好,llama.cpp、vLLM、LM Studio、Ollama 都有 OpenAI 相容的 /v1/models,只是預設 port 不同。我把另一台機器的模型服務轉到本機 8080,Claude 做完還自己打了一次,確認回應格式對得上,卡片會列出 qwen38-27b-ud。
它還補了幾種例外處理:服務 3 秒沒回應也算「沒在跑」,免得整個面板等它;回錯誤碼時用紅字寫出原因,例如「讀取失敗:HTTP 503」;服務在跑但沒有模型時,顯示「服務在跑,但沒有提供模型」。
第四段:讓 Claude 自己也讀得到
讓 Claude 自己也讀得到這個面板:在 my-dash 註冊一個 Claude 可以呼叫的工具,叫 my_resources,回傳一段很短的文字,只講「能不能用」:Claude 額度還夠不夠、GPU 和硬碟還剩多少、地端模型有沒有在跑。validate 到通過,最後告訴我這個工具的完整名稱,以及我該怎麼請 Claude 在派工前先查它。
實測 196 秒。工具的完整名稱是 mcp__my-dash__my_resources,格式固定是 mcp__<mod 名稱>__<工具名>。我開一個新 session,叫 Claude 呼叫它、原文貼回來,拿到的是:
✓ Claude 額度:夠用(已用 5 小時 51%、每週 7%)
— GPU:這台沒有 NVIDIA 顯卡
✓ 硬碟 /System/Volumes/Data:剩 232.0 GiB(26%)
✓ 地端模型:在跑(qwen38-27b-ud)
要 Claude 派工前先查,把這句寫進專案的 CLAUDE.md:「派工前先呼叫 mcp__my-dash__my_resources,它標成不能用的資源不要派。」工具的說明裡已經寫了用途,但寫進 CLAUDE.md 比較穩。

我的面板一開始把所有細節都塞給 Claude,後來改成只回三塊「能不能用」:額度、地端模型、ComfyUI。Claude 派工前要的是「可不可以派」,不是 tok/s 和 VRAM 數字。
第五段:加按鈕
在 my-dash 的「地端模型」卡加一個「開啟」按鈕,按下去用瀏覽器打開 http://localhost:8080;面板最下面加一個「立即更新」按鈕,按下去馬上重新讀一次所有資料。validate 到通過。
實測 93 秒。「開啟」在 macOS 用 open、Linux 用 xdg-open,兩個都失敗就跳一則提示請你自己開網址。
按鈕按下去跑的是你電腦上的動作,可以是開網頁、跑一支腳本、寫一個旗標檔。我面板上的「暫停」就是寫旗標檔,讓 Claude 暫時不准派工到那台機器。
第六段:Desktop app 也要好看
my-dash 也要在 Claude Desktop app 裡好看:Desktop 用比例字型,用字元畫的進度條會溢出欄位、蓋住後面的數字。請在 Desktop 上改用 SVG 畫進度條,終端機維持原樣。validate 到通過。
實測 185 秒。Claude 中途踩到一個坑、自己修掉了:它一開始用「元件表裡有沒有 Svg」判斷能不能畫 SVG,但在測試環境裡,終端機的元件表也有 Svg,結果終端機上的進度條直接消失。它改成看畫面類型是不是 terminal 才過。
同一個 mod 在 Desktop app 的 Claude Code 分頁也會畫出來,而且大部分排版不用改。會壞的只有用字元畫的進度條:終端機是等寬字型,每個 █ 剛好佔一格;Desktop 是比例字型,同樣一排字元會變寬,蓋到後面的數字。這一段我是看到自己面板在 Desktop 上壞掉才加的。
讓它每次都自動載入
試用時用 --plugin-dir。確定要常駐,就加進 ~/.claude/settings.json:
{
"env": {
"CLAUDE_CODE_PLUGIN_DIRS": "/Users/你/my-dash-work/my-dash"
}
}
多個 mod 用冒號隔開。Desktop app 沒辦法加 --plugin-dir 參數,也是靠這個環境變數。之後每次改 mod:
- 終端機裡開著的 session 會盯著 mod 資料夾,存檔就重新載入。
- Desktop app 開著的 session 不會。要嘛開新的 session,要嘛在同一個
env加"CLAUDE_CODE_PLUGIN_DIR_WATCH": "1"。
進階:我的面板怎麼長出來的
不讀這節不影響使用。這裡是一天下來踩到的坑,給想往下做的人和 AI 參考。
踩到的坑
中文對不齊。 第一版用 padEnd 補空白對齊欄位,中文一個字佔兩格,整欄歪掉。改成每一欄放進固定寬度的 Box,讓排版引擎算寬度。
面板寬度不要自己算。 我一開始用事件裡的 viewport.columns 決定寬度,結果那是整個對話區的寬度,不是面板的。拿掉寬度設定、讓 flex 自己貼合,面板就會跟著你拖的寬度走。
validate 會擋的三種寫法。 同一個事件掛兩個沒有篩選條件的 hook 會被拒,要併成一個;用到 $ 的函式要寫在檔案最外層;用 atom 存的狀態要在型別檔裡宣告,不然會報 is not declared。
一個變數名讓整個面板消失。 機器卡的 hosts.map(h => …) 用了 h 當參數名,剛好遮住 JSX 編譯後用的 h。只要有機器快照,整個面板就直接報錯、什麼都不畫。測試沒餵快照所以全過,是在真終端機上才發現。
Desktop 的進度條。 前面第六段講過:比例字型讓 ━ 溢出,改用 SVG。判斷畫在哪裡用事件的 e.surface,terminal 以外才換。
三個 session 改同一支檔。 那天我同時開了三個 session 在調面板,其中一個把卡框統一改成灰色,另一個在它的版本上繼續改,第三個又改回彩色。mod 只有一支 register.tsx,後存檔的會蓋掉前面的。改 mod 最好固定在一個 session 做,改完 commit。
Claude Code 自己升級了。 mods 的 API 標著 early access,版本之間可能會變。我在 ~/.claude.json 設了 autoUpdates: false,當天還是從 2.1.288 升到 2.1.289。最後在 settings.json 的 env 加 DISABLE_AUTOUPDATER=1 才停住,要升級時手動 claude update。
常見問題
- Claude Code mods 要什麼版本才能用?
- 官方文件寫的是 v2.1.287 起、預設開啟。先跑 claude --version 確認版本,太舊就 claude update。Desktop app 用的是 app 內建的引擎,跟著 app 自己更新。
- 不會寫 TypeScript 也能做 mod 嗎?
- 可以。mod 本身是 TypeScript,但 Claude Code 內建寫 mod 的說明,直接用中文描述你要的面板,它會寫好、跑 claude plugin validate 檢查,再告訴你怎麼載入。這篇六段 prompt 都是在乾淨的 session 實際跑過的,每段 1 分半到 4 分鐘。
- 做好的 mod 要怎麼讓 Claude Code 每次都自動載入?
- 臨時試用用 claude --plugin-dir <資料夾>。要常駐,在 ~/.claude/settings.json 的 env 裡加 CLAUDE_CODE_PLUGIN_DIRS,值是 mod 資料夾的絕對路徑,Desktop app 開的 session 也吃這個設定。終端機裡開著的 session 會盯著 mod 資料夾,存檔就重新載入;Desktop app 開著的 session 不會,要開新的,或在同一個 env 加 CLAUDE_CODE_PLUGIN_DIR_WATCH=1。
- mod 安全嗎?
- mod 跟 Claude Code 同權限,沒有沙箱,讀得到環境變數和你的對話。裝別人的 mod 前先跑 claude plugin validate,它會列出這個 mod 掛了哪些事件、用了哪些 API、讀寫哪些環境變數。
接著讀
- 2026-08-31[Dev Workflow] AI 味不在破折號,在結構:一篇論文教我怎麼檢查自己的文章
StoryScope 完全不看文風,只看敘事結構,93.2% macro-F1 就分得出人寫的與 AI 寫的。我拿它的五個問題掃自己已發布的文章,同一個教訓被抓到講了四次。
- 2026-08-21[AI Agent] 從 41 分鐘到 73 秒:一張小工單的病理解剖
派給 Codex CLI 的小工單常常一跑就是 40 分鐘起跳。這篇拆開近兩週 41 個執行紀錄,量出「牆鐘時間≈工具呼叫次數×14.3 秒」的公式,揪出 41 分鐘裡機器真正做事只有 4.4 分鐘,再用四刀把同型工單壓到 73 秒。
- 2026-07-29[Dev Workflow] Skill 裡的檢查完全寫對了,但它一次都沒跑過
一篇技術文五關全過,唯一的人類讀者一句話就命中:同一個句型在稿子裡出現了五次。查下去發現該抓的規則白紙黑字寫在 skill 裡、內容也對,但它標著「人工掃」——沒有指令、沒有 exit code、擋不住任何東西,所以從來沒運作過。門檻怎麼用五篇舊文校準、兩次真實攔截、以及一個機械檢查永遠抓不到的變體。
- 2026-07-17[Dev Workflow] 幫 AI agent 的 skill 減肥:193 個塞爆 2% 預算,砍到剩 7 個
AI Workflow 系列第 15 篇。某天早上我讀 codex 紀錄,滑到一行:skill 描述被剪短,才塞得進 2% 的 context 預算。我共用的 root 累到 193 個 skill,全載進去撐爆上限,每條描述都被截斷——我天天在用的,被剪掉是為了替我從不碰的一百多個騰位子。這篇講怎麼用 per-agent allowlist(不是刪)砍到 7 個、薄殼配深引擎壓低每個 skill 的載入成本,再用一個閘門加稽核加可逆退場區守住,不讓它肥回去。
不想錯過新文章?
訂閱我確保不漏接!
隨時一鍵退訂。