技能建立器 (Skill Creator)
一個用於建立新技能並持續迭代改進的技能。
整體而言,建立技能的流程如下:
- 決定你希望技能做什麼,以及大致的實作方式
- 撰寫技能的草稿
- 建立幾個測試提示詞,並在具有該技能的 Claude 上執行
- 協助使用者從質性和量化兩方面評估結果
- 在背景執行測試的同時,如果還沒有量化評估則撰寫一些(如果已有,可以直接使用或視需要修改)。然後向使用者解釋這些評估
- 使用
eval-viewer/generate_review.py腳本向使用者展示結果,同時讓他們查看量化指標
- 根據使用者評估結果的回饋重寫技能(以及量化基準測試中發現的明顯缺陷)
- 重複直到滿意為止
- 擴大測試集並在更大規模上再次測試
你使用此技能時的工作是判斷使用者在這個流程中的位置,然後協助他們繼續推進。例如,也許他們說「我想做一個 X 的技能」。你可以幫助釐清他們的意思、撰寫草稿、編寫測試案例、了解他們想要如何評估、執行所有提示詞,然後重複。
另一方面,也許他們已經有了技能的草稿。在這種情況下,你可以直接進入評估/迭代的部分。
當然,你應該始終保持靈活,如果使用者說「我不需要執行一堆評估,跟我一起隨意試試就好」,那就這樣做。
然後在技能完成之後(但同樣,順序是靈活的),你也可以執行技能描述改善器,我們有一個專門的腳本來優化技能的觸發。
與使用者溝通
技能建立器可能被各種程度的使用者使用,從不熟悉程式術語的新手到經驗豐富的開發者都有。現在有一個趨勢:Claude 的強大能力正在啟發水電工打開終端機、讓父母和祖父母去搜尋「如何安裝 npm」。另一方面,大多數使用者可能相當懂電腦。
所以請注意上下文線索來理解如何措辭你的溝通!在預設情況下,給你一些參考:
- 「evaluation(評估)」和「benchmark(基準測試)」是可以接受的邊界用語
- 對於「JSON」和「assertion(斷言)」,你需要從使用者那裡看到明確的線索,確認他們知道這些是什麼,才能在不解釋的情況下使用
- 如果不確定,可以簡短地解釋術語,並在需要時用簡短的定義澄清
建立技能
捕捉意圖
首先理解使用者的意圖。目前的對話可能已經包含使用者想要捕捉的工作流程(例如他們說「把這個做成技能」)。如果是這樣,先從對話歷史中提取答案 —— 使用的工具、步驟順序、使用者做出的修正、觀察到的輸入/輸出格式。使用者可能需要填補空白,並在繼續下一步之前確認。
- 這個技能應該讓 Claude 能做什麼?
- 這個技能應該在什麼時候觸發?(什麼使用者用語/情境)
- 預期的輸出格式是什麼?
- 我們是否需要設定測試案例來驗證技能是否正常運作?具有客觀可驗證輸出的技能(檔案轉換、資料擷取、程式碼生成、固定工作流程步驟)受益於測試案例。具有主觀輸出的技能(寫作風格、藝術)通常不需要。根據技能類型建議適當的預設值,但讓使用者決定。
訪談與研究
主動詢問關於邊界情況、輸入/輸出格式、範例檔案、成功標準和相依性的問題。等到這部分釐清後再撰寫測試提示詞。
檢查可用的 MCP —— 如果對研究有用(搜尋文件、尋找類似技能、查找最佳實踐),如果有子代理可用則並行研究,否則在行內進行。準備好上下文以減輕使用者的負擔。
撰寫 SKILL.md
根據使用者訪談,填入以下組件:
- name:技能識別碼
- description:何時觸發、做什麼。這是主要的觸發機制 —— 包含技能做什麼以及使用它的具體情境。所有「何時使用」的資訊放在這裡,不在本文中。注意:目前 Claude 傾向於「觸發不足(undertrigger)」技能 —— 在技能有用時不使用它們。為了解決這個問題,請讓技能描述稍微「積極」一些。例如,不要寫「如何建立一個簡單快速的儀表板來顯示內部資料」,你可以寫「如何建立一個簡單快速的儀表板來顯示內部資料。請確保在使用者提到儀表板、資料視覺化、內部指標、或想要顯示任何類型的公司資料時使用此技能,即使他們沒有明確要求『儀表板』。」
- compatibility:所需工具、相依性(可選,很少需要)
- 技能的其餘內容 :)
技能撰寫指南
技能的結構
skill-name/
├── SKILL.md (必要)
│ ├── YAML frontmatter(name、description 為必要欄位)
│ └── Markdown 指令
└── 附帶資源 (可選)
├── scripts/ - 用於確定性/重複性任務的可執行程式碼
├── references/ - 按需載入上下文的文件
└── assets/ - 用於輸出的檔案(範本、圖示、字型)
漸進式披露 (Progressive Disclosure)
技能使用三層載入系統:
- 元資料(name + description)—— 始終在上下文中(約 100 字)
- SKILL.md 本文 —— 技能觸發時在上下文中(理想 <500 行)
- 附帶資源 —— 按需載入(無限制,腳本可以在不載入的情況下執行)
這些字數是近似值,如果需要可以寫得更長。
關鍵模式:
- 將 SKILL.md 控制在 500 行以下;如果接近此限制,增加額外的層次結構以及關於模型使用技能後應該去哪裡跟進的清晰指引
- 從 SKILL.md 中清楚地引用檔案,並說明何時讀取它們
- 對於大型參考檔案(>300 行),包含目錄
領域組織:當技能支援多個領域/框架時,按變體組織:
cloud-deploy/
├── SKILL.md (工作流程 + 選擇)
└── references/
├── aws.md
├── gcp.md
└── azure.md
Claude 只會讀取相關的參考檔案。
無意外原則
這不用多說,但技能不得包含惡意軟體、漏洞利用程式碼或任何可能危及系統安全的內容。如果被描述,技能的內容不應在其意圖上讓使用者感到意外。不要配合建立誤導性技能或旨在促進未經授權存取、資料外洩或其他惡意活動的技能的請求。不過像「角色扮演為 XYZ」之類的是可以的。
撰寫模式
在指令中優先使用祈使語氣。
定義輸出格式 —— 可以這樣做:
## 報告結構
永遠使用這個確切的範本:
# [標題]
## 執行摘要
## 關鍵發現
## 建議
範例模式 —— 包含範例很有用。可以這樣格式化(但如果範例中有「Input」和「Output」,你可能想要稍微偏離):
## 提交訊息格式
**範例 1:**
Input: Added user authentication with JWT tokens
Output: feat(auth): implement JWT-based authentication
撰寫風格
嘗試向模型解釋事情為什麼重要,而不是使用沉重的「必須」。運用心智理論,嘗試讓技能通用化,而不是過度針對特定範例。先寫一個草稿,然後用新鮮的眼光審視並改進。
測試案例
撰寫技能草稿後,想出 2-3 個真實的測試提示詞 —— 真正的使用者會說的那種話。與使用者分享:「這裡有幾個我想要測試的案例。看起來對嗎,或者你想再加一些?」然後執行它們。
將測試案例儲存到 evals/evals.json。先不要寫斷言 —— 只要提示詞。你將在下一步中,在執行進行時撰寫斷言。
{
"skill_name": "example-skill",
"evals": [
{
"id": 1,
"prompt": "User's task prompt",
"expected_output": "Description of expected result",
"files": []
}
]
}
完整 schema 請參見 references/schemas.md(包括 assertions 欄位,你稍後會添加)。
執行和評估測試案例
此部分是一個連續序列 —— 不要中途停止。不要使用 /skill-test 或任何其他測試技能。
將結果放在 <skill-name>-workspace/ 中,作為技能目錄的同層目錄。在工作空間中,按迭代組織結果(iteration-1/、iteration-2/ 等),每個測試案例都有一個目錄(eval-0/、eval-1/ 等)。不要預先建立所有這些 —— 隨著進展建立目錄。
步驟 1:在同一回合中啟動所有執行(有技能 AND 基線)
對每個測試案例,在同一回合中啟動兩個子代理 —— 一個有技能,一個沒有。這很重要:不要先啟動有技能的執行,然後再回來做基線。同時啟動所有內容,這樣它們大約會同時完成。
有技能的執行:
Execute this task:
- Skill path: <path-to-skill>
- Task: <eval prompt>
- Input files: <eval files if any, or "none">
- Save outputs to: <workspace>/iteration-<N>/eval-<ID>/with_skill/outputs/
- Outputs to save: <what the user cares about — e.g., "the .docx file", "the final CSV">
基線執行(相同提示詞,但基線取決於情境):
- 建立新技能:完全沒有技能。相同提示詞,沒有技能路徑,儲存到
without_skill/outputs/。 - 改進現有技能:舊版本。編輯前先快照技能(
cp -r <skill-path> <workspace>/skill-snapshot/),然後將基線子代理指向快照。儲存到old_skill/outputs/。
為每個測試案例撰寫 eval_metadata.json(斷言現在可以為空)。給每個評估一個描述性名稱,基於它測試的內容 —— 不只是「eval-0」。也用這個名稱命名目錄。如果此迭代使用新的或修改過的評估提示詞,為每個新的評估目錄建立這些檔案 —— 不要假設它們會從先前的迭代延續。
{
"eval_id": 0,
"eval_name": "descriptive-name-here",
"prompt": "The user's task prompt",
"assertions": []
}
步驟 2:在執行進行時,撰寫斷言草稿
不要只是等待執行完成 —— 你可以利用這段時間。為每個測試案例撰寫量化斷言草稿並向使用者解釋。如果斷言已存在於 evals/evals.json 中,審查它們並解釋它們檢查什麼。
好的斷言是客觀可驗證的,並有描述性名稱 —— 它們應該在基準測試檢視器中清楚地閱讀,讓瀏覽結果的人立即理解每個斷言檢查什麼。主觀技能(寫作風格、設計品質)更適合質性評估 —— 不要強制將斷言套用在需要人類判斷的事物上。
更新 eval_metadata.json 檔案和 evals/evals.json 中的斷言。同時向使用者解釋他們將在檢視器中看到什麼 —— 質性輸出和量化基準測試。
步驟 3:當執行完成時,捕捉計時資料
當每個子代理任務完成時,你會收到包含 total_tokens 和 duration_ms 的通知。立即將此資料儲存到執行目錄中的 timing.json:
{
"total_tokens": 84852,
"duration_ms": 23332,
"total_duration_seconds": 23.3
}
這是捕捉此資料的唯一機會 —— 它來自任務通知,不會在其他地方持久化。收到每個通知時立即處理,而不是嘗試批次處理。
步驟 4:評分、彙總和啟動檢視器
所有執行完成後:
-
為每個執行評分 —— 啟動一個評分子代理(或行內評分),讀取
agents/grader.md並針對輸出評估每個斷言。將結果儲存到每個執行目錄中的grading.json。grading.json 期望值陣列必須使用text、passed和evidence欄位(不是name/met/details或其他變體)—— 檢視器依賴這些確切的欄位名稱。對於可以程式化檢查的斷言,撰寫並執行腳本而不是目測 —— 腳本更快、更可靠,且可在迭代間重複使用。 -
彙總為基準測試 —— 從 skill-creator 目錄執行彙總腳本:
python -m scripts.aggregate_benchmark <workspace>/iteration-N --skill-name <name>這會產生
benchmark.json和benchmark.md,包含每個配置的 pass_rate、時間和 token,以及平均值 ± 標準差和差異。如果手動生成 benchmark.json,請參見references/schemas.md了解檢視器期望的確切 schema。將每個 with_skill 版本放在其基線對應版本之前。 -
進行分析師檢查 —— 讀取基準測試資料並發現彙總統計可能隱藏的模式。參見
agents/analyzer.md(「分析基準測試結果」部分)了解要尋找什麼 —— 例如無論技能如何都會通過的斷言(無鑑別力)、高變異的評估(可能不穩定)以及時間/token 的權衡。 -
啟動檢視器,同時顯示質性輸出和量化資料:
nohup python <skill-creator-path>/eval-viewer/generate_review.py \ <workspace>/iteration-N \ --skill-name "my-skill" \ --benchmark <workspace>/iteration-N/benchmark.json \ > /dev/null 2>&1 & VIEWER_PID=$!對於第 2 次以上的迭代,同時傳入
--previous-workspace <workspace>/iteration-<N-1>。Cowork / 無頭環境: 如果
webbrowser.open()不可用或環境沒有顯示器,使用--static <output_path>將獨立 HTML 檔案寫出而不是啟動伺服器。當使用者點擊「Submit All Reviews」時,回饋會作為feedback.json檔案下載。下載後,將feedback.json複製到工作空間目錄以供下一次迭代使用。
注意:請使用 generate_review.py 建立檢視器;不需要撰寫自訂 HTML。
- 告訴使用者類似這樣的話:「我已經在你的瀏覽器中開啟了結果。有兩個分頁 —— 『Outputs』讓你點擊每個測試案例並留下回饋,『Benchmark』顯示量化比較。當你完成時,回來告訴我。」
使用者在檢視器中看到什麼
「Outputs」分頁一次顯示一個測試案例:
- Prompt:給予的任務
- Output:技能產生的檔案,盡可能內嵌渲染
- Previous Output(第 2 次以上迭代):折疊區塊顯示上次迭代的輸出
- Formal Grades(如果有評分):折疊區塊顯示斷言通過/失敗
- Feedback:一個文字方塊,輸入時自動儲存
- Previous Feedback(第 2 次以上迭代):上次的評論,顯示在文字方塊下方
「Benchmark」分頁顯示統計摘要:每個配置的通過率、計時和 token 使用量,以及每個評估的細分和分析師觀察。
導航透過上一個/下一個按鈕或方向鍵。完成後,點擊「Submit All Reviews」將所有回饋儲存到 feedback.json。
步驟 5:讀取回饋
當使用者告訴你他們完成了,讀取 feedback.json:
{
"reviews": [
{"run_id": "eval-0-with_skill", "feedback": "the chart is missing axis labels", "timestamp": "..."},
{"run_id": "eval-1-with_skill", "feedback": "", "timestamp": "..."},
{"run_id": "eval-2-with_skill", "feedback": "perfect, love this", "timestamp": "..."}
],
"status": "complete"
}
空回饋表示使用者認為沒問題。將改進重點放在使用者有具體抱怨的測試案例上。
完成後終止檢視器伺服器:
kill $VIEWER_PID 2>/dev/null
改進技能
這是循環的核心。你已經執行了測試案例,使用者已經審查了結果,現在你需要根據他們的回饋讓技能變得更好。
如何思考改進
-
從回饋中概括。 這裡發生的大局是我們正在嘗試建立可以被使用百萬次(也許真的,也許更多)跨許多不同提示詞的技能。這裡你和使用者只在少數幾個範例上反覆迭代,因為這有助於加快速度。使用者對這些範例瞭若指掌,評估新輸出很快。但如果你和使用者共同開發的技能只適用於那些範例,那就沒有用了。與其加入瑣碎的過擬合變更或壓迫性的限制性「必須」,如果有一些頑固的問題,你可以嘗試分支出去,使用不同的隱喻,或建議不同的工作模式。嘗試相對廉價,也許你會找到很棒的方法。
-
保持提示精簡。 移除沒有發揮作用的內容。確保閱讀執行記錄,而不只是最終輸出 —— 如果看起來技能讓模型浪費大量時間做沒有成效的事情,你可以嘗試去掉技能中導致這種行為的部分,看看會發生什麼。