Anthropic 和 OpenAI 最近不約而同地發了 Agent Skills 的深度指南。Anthropic 出了一份 32 頁 PDF 教你怎麼建 Skill,OpenAI 則發了一篇 eval 實戰文 教你怎麼系統性地評估 Skill。

兩家不約而同走向同一個方向,代表 Skills 作為 Agent 知識層的標準化已經是確定趨勢了。這篇把兩邊的精華整合起來,從建立到評估完整走一遍。

先講結論: Skill 就是一個資料夾,裡面放 Markdown 指令,教 AI agent 怎麼處理特定任務。你教一次,以後每次都自動套用。跟每次都在 prompt 裡重新解釋比起來,省事太多。但光是建好還不夠,你需要有系統地評估它,才能確定改動是真的改善,不是引入新 bug。


第一部分: 怎麼建 Skill (Anthropic 指南)

Skill 的結構

一個 Skill 就是一個資料夾:

  • SKILL.md (必要): Markdown 指令檔,帶 YAML frontmatter
  • scripts/ (選用): 可執行的程式碼
  • references/ (選用): 需要時才載入的參考文件
  • assets/ (選用): 模板、素材等

三層漸進式揭露

這是整個架構最漂亮的設計:

  1. YAML frontmatter: 永遠載入 system prompt,讓 agent 判斷「該不該用這個 Skill」
  2. SKILL.md 本文: agent 認為相關時才載入完整指令
  3. 連結檔案: 資料夾裡的其他檔案,需要時才讀

好處是最小化 token 消耗,同時保持專業知識隨時可用。這個設計在 Anthropic 和 OpenAI 的實作中是一致的——兩家都用 SKILL.md + YAML frontmatter 的格式,name 和 description 是 agent 決定要不要觸發 skill 的主要依據。

Skills + MCP

Anthropic 用了一個廚房比喻: MCP 是專業廚房 (提供工具和設備),Skill 是食譜 (教你怎麼用)。光有 MCP 連接器沒用,使用者接上了卻不知道下一步;有了 Skill,工作流自動啟動、結果一致。

YAML Frontmatter: 最重要的部分

最小格式:

---
name: your-skill-name
description: What it does. Use when user asks to [specific phrases].
---

name 必須 kebab-case,description 必須同時包含「做什麼」和「什麼時候用」。好的 description 長這樣:

# 好: 具體可操作
description: Analyzes Figma design files and generates developer handoff 
documentation. Use when user uploads .fig files, asks for "design specs", 
"component documentation", or "design-to-code handoff".
# 差: 太模糊
description: Helps with projects.

這不只是文件品質問題——description 寫得差,skill 就不會在該觸發的時候觸發。OpenAI 那邊也特別強調: name 和 description 是 agent 決定要不要載入 skill 的「唯一線索」,寫模糊等於白寫。

三大 Skill 類別

文件與素材生成: 產出一致、高品質的文件。技巧包括內嵌 style guide、模板結構、品質 checklist。

工作流自動化: 多步驟流程的一致化執行。包括逐步驗證、模板、審查建議、迭代精煉迴圈。

MCP 增強: 在 MCP 工具之上加入工作流知識。例如串接多個 MCP 呼叫、嵌入領域專業知識。

五大設計模式

  1. 循序工作流編排: 多步驟按特定順序執行,每階段驗證,失敗時 rollback
  2. 多 MCP 協調: 跨服務工作流,例如 Figma → Drive → Linear → Slack
  3. 迭代精煉: 初稿 → 品質檢查 → 修正迴圈 → 定稿
  4. 上下文感知的工具選擇: 同一目標不同情境用不同工具
  5. 領域專業知識: 加入工具之外的專業知識 (合規檢查、稽核紀錄等)

寫指令的最佳實踐

  • 要具體: 別寫「驗證資料」,要寫「執行 python scripts/validate.py --input {filename}
  • 包含錯誤處理: 列出常見問題和解法
  • 清楚引用資源: 「寫查詢前,先參考 references/api-patterns.md
  • 善用漸進式揭露: 核心指令放 SKILL.md,詳細文件移到 references/
  • SKILL.md 控制在 5,000 字以內
  • 對於關鍵驗證,打包腳本比靠語言指令更可靠 (程式碼是確定性的,語言解讀不是)

第二部分: 怎麼評估 Skill (OpenAI 指南)

建好 Skill 只是開始。OpenAI 這篇最核心的觀點是: 迭代 skill 的時候,你很難分辨「真的改善了」還是「只是改變了行為」。一個版本感覺比較快,另一個看起來更穩定,然後某天 regression 就悄悄溜進來了。

解法是 Evals (evaluations): 跑 agent → 記錄過程 → 用一組檢查規則打分 → 產出可比較的分數。

Step 1: 先定義成功,再寫 Skill

在寫 skill 之前,先寫下「成功」長什麼樣:

  • 結果目標: 任務完成了嗎?app 能跑嗎?
  • 過程目標: agent 有觸發 skill 嗎?有按預期步驟走嗎?
  • 風格目標: 輸出符合你要求的慣例嗎?
  • 效率目標: 有沒有不必要的 thrashing (多餘指令、浪費 token)?

重點: 清單要小、聚焦在 must-pass 的檢查。不是要一次編碼所有偏好,而是抓住你最在意的行為。

Step 2: 手動跑一遍,找出隱藏假設

先手動觸發 skill,觀察哪裡會壞。你在找的是:

  • 觸發假設: 某些 prompt 應該觸發但沒有?不該觸發但觸發了?
  • 環境假設: skill 假設跑在空目錄?假設 npm 可用?
  • 執行假設: agent 跳過 npm install 因為假設依賴已裝好?

每次手動修正都是未來 eval 的候選——鎖定預期行為後才能大規模評估。

Step 3: 用小型 prompt set 抓 regression

不需要大型 benchmark。10-20 個 prompt 就夠了。用 CSV 管理:

id,should_trigger,prompt
test-01,true,"Create a demo app using the $setup-demo-app skill"
test-02,true,"Set up a minimal React demo app with Tailwind"
test-03,true,"Create a small demo app to showcase the API"
test-04,false,"Add Tailwind styling to my existing React app"

四種測試角度:

  • 明確呼叫 (test-01): 直接指名 skill,確認基本功能
  • 隱式呼叫 (test-02): 描述場景但不提 skill 名稱,測試 description 是否夠強
  • 帶脈絡的呼叫 (test-03): 加入領域脈絡,測試在 noisy prompt 下是否正常觸發
  • 負面控制 (test-04): 不該觸發的情境,抓 false positive

隨著遇到新的失敗案例,持續加新 row。這份 CSV 會變成 skill 必須持續通過的活文件。

Step 4: 確定性檢查 (Deterministic Graders)

用結構化輸出 (JSONL trace) 來打分,而不是看最終結果「感覺」對不對:

  • agent 有沒有跑 npm install
  • package.json 有沒有被建立?
  • 預期的指令有沒有按順序執行?

這些檢查刻意做得很輕量。快速、可解釋的信號,在加入任何 model-based 評分之前先有基本保障。

OpenAI 的做法是用 codex exec --json 產出 JSONL event stream,每個指令執行都是一個 item.* event,可以直接寫程式檢查。如果某個 check 失敗,打開 JSONL 就能看到完整過程,不用猜。

Step 5: 定性檢查 (Rubric-based Grading)

確定性檢查回答「有沒有做到基本的」,但不回答「有沒有照你要的方式做」。

很多需求是定性的: 元件結構、styling 慣例、設定方式。這些很難用檔案存在與否來檢查。

解法是加一個 model-assisted 的步驟:

  1. 跑 skill (產出程式碼)
  2. 用另一個 agent 做 read-only 的風格檢查
  3. 要求結構化 JSON 回應,你的 harness 可以穩定地打分

定義一個 rubric schema:

{
  "type": "object",
  "properties": {
    "overall_pass": { "type": "boolean" },
    "score": { "type": "integer", "minimum": 0, "maximum": 100 },
    "checks": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": { "type": "string" },
          "pass": { "type": "boolean" },
          "notes": { "type": "string" }
        },
        "required": ["id", "pass", "notes"]
      }
    }
  },
  "required": ["overall_pass", "score", "checks"]
}

穩定的欄位 (overall_pass、score、per-check results) 讓你可以跨版本比較、追蹤趨勢。

Step 6: 持續擴展

核心迴圈跑起來之後,可以逐步加深:

  • 指令計數: 抓 thrashing,agent 有沒有在 loop 或重複跑指令
  • Token 預算: 追蹤 input/output tokens,抓 prompt bloat
  • Build 檢查: skill 跑完後執行 npm run build,抓壞掉的 import
  • Runtime 煙霧測試: 啟動 dev server,用 curl 或 Playwright 驗證
  • Repo 乾淨度: 確認沒有產生多餘檔案
  • 權限回歸: 確認 skill 沒有升級到不該有的權限

原則: 從快速、可解釋的檢查開始,只在能降低風險的地方加重量級檢查。


兩家的共識與啟示

把 Anthropic 和 OpenAI 的方法論放在一起看,幾個共識很明顯:

格式趨同: 兩家都用 SKILL.md + YAML frontmatter,都強調 name 和 description 的重要性,都支援 scripts 和 references 的漸進式載入。這不是巧合,而是實踐中收斂出來的最佳結構。

觸發機制是關鍵: 兩邊都花很多篇幅在講「skill 什麼時候該觸發、什麼時候不該」。Description 寫得好不好,直接決定 skill 的實用性。

評估不能靠 vibes: Anthropic 在指南裡承認「有一定程度的 vibes-based assessment」,但建議追蹤量化指標。OpenAI 更直接: 把 eval 做成一個正式流程,確定性檢查 + rubric-based 評分,讓「感覺比較好」變成「可證明比較好」。

實用建議: 先在單一困難任務上反覆迭代直到成功,再萃取成 Skill。每次手動修正都是一個未來 eval 的候選。SKILL.md 控制在 5,000 字以內。同時啟用的 skill 數量控制在 20-50 個。

如果你在用 AI agent 做重複性工作流,花時間建一個 skill 是值得的投資。但記得: 建好之後要有系統地評估,不然你永遠不知道改動是改善還是 regression。


參考資料: