第 11 章

代理技能(SKILL.md)

代理技能(Skills)是一種可重複使用的指令集,封裝在 SKILL.md 檔案中。本章說明如何建立、發現、載入技能,以及管理其權限與工具。

高級 Advanced

學習目標

什麼是代理技能?

代理技能(Skill)是一種以 SKILL.md 檔案封裝的指令集,定義了代理在特定任務中應遵循的行為模式。技能系統讓你可以將複雜的工作流程標準化,並在多個專案中重複使用。

技能與一般 AGENTS.md 的關鍵差異:

特性AGENTS.mdSKILL.md
範圍專案全域按需載入
命名無名稱有唯一名稱,可被代理引用
可重用性單一專案可跨專案、跨使用者分享
工具可定義關聯工具
觸發自動需代理明確載入

SKILL.md 放置位置與發現機制

opencode 會從以下位置掃描並發現 SKILL.md 檔案:

位置說明
~/.config/opencode/skills/<name>/SKILL.md全域技能目錄(所有專案共用)
.opencode/skills/<name>/SKILL.md專案技能目錄(僅限當前專案)

當代理需要載入技能時,它會依序搜尋上述兩個目錄。技能的名稱即為目錄的名稱,目錄內必須包含一個 SKILL.md 檔案。

搜尋順序:全域技能目錄優先於專案技能目錄。如果你在兩個位置定義了相同名稱的技能,全域版本會優先被使用。

YAML Frontmatter 欄位

SKILL.md 以 YAML frontmatter 定義技能的後設資料。以下是完整的可用欄位:

欄位型別必填說明
namestring技能的唯一名稱,必須符合命名規則
descriptionstring技能的簡短描述,用於觸發判斷
triggerstring 或 array觸發模式(always / on-topic),預設為 on-topic
toolsarray技能需要的工具描述清單
permissionsobject技能運作時需要的特定權限

名稱驗證規則

技能名稱必須遵守以下規則:

有效名稱範例:web-designcode-reviewerpython-test-runner

無效名稱範例:Web Design(含大寫和空格)、my_skill(含底線)、-skill(以連字號開頭)

完整範例

以下是一個完整的 SKILL.md 檔案,定義了一個程式碼審查技能:

---
name: code-reviewer
description: |
  專門進行程式碼審查的技能。能夠分析程式碼品質、
  找出潛在問題,並提供具體的改善建議。
trigger: on-topic
tools:
  - name: bash
    description: 用於執行 linter 或測試指令
  - name: read
    description: 讀取待審查的原始碼
  - name: grep
    description: 在專案中搜尋相關的程式碼模式
permissions:
  bash:
    allow:
      - "npm run lint"
      - "npx eslint"
      - "npm test"
    deny:
      - "npm install"
      - "rm"
  edit: deny
---

# Code Review 技能

當你需要進行程式碼審查時,我會按照以下流程進行:

## 審查流程

1. **理解上下文** — 先讀取相關檔案,了解功能與設計意圖
2. **執行程式碼分析** — 使用 linter 等工具進行靜態分析
3. **逐行審查** — 關注可讀性、效能、安全性與最佳實務
4. **提供具體建議** — 每個問題附上範例程式碼與說明

## 審查重點

- 安全性漏洞(SQL injection、XSS 等)
- 效能瓶頸(不必要的迴圈、過多的 DOM 操作)
- 程式碼重複(DRY 原則)
- 錯誤處理是否完善
- 型別與邊界情況

工具描述與載入方式

在 SKILL.md 的 tools 區塊中,你可以描述技能需要使用的工具。這些工具描述會影響代理的行為:

技能由代理透過 skill 工具載入。當代理認為你的請求與某個技能的 description 相符時,它會自動載入該技能。你也可以在對話中明確要求代理載入特定技能。

trigger 欄位說明

trigger 欄位控制技能何時被載入:

行為
on-topic(預設)當對話主題與技能描述相符時自動載入
always每次對話都會自動載入此技能

注意:使用 always 觸發模式會讓技能在每個對話中都自動載入,這可能影響效能。建議只在真正需要的技能上使用此模式。

權限設定

技能可以在 frontmatter 的 permissions 區塊中設定自己的權限規則。權限覆蓋層級如下(由低到高):

  1. 全域權限opencode.json 中的 permissions 設定
  2. 技能權限 — SKILL.md 中的 permissions 設定(覆蓋全域)
  3. 代理權限 — 自訂代理定義中的 permissions(覆蓋技能與全域)

範例:全域將 bash 設為 ask,但技能中將特定指令設為 allow

---
name: test-runner
description: 執行與維護測試
permissions:
  bash:
    allow:
      - "npm test"
      - "npx jest"
      - "npx vitest"
    deny:
      - "sudo"
---

停用技能工具

如果你不希望代理在特定技能中使用某個工具,可以在 permissions 中將它設為 deny,或直接在 tools 清單中省略它:

---
name: safe-analyzer
description: 安全的程式碼分析(不執行任何指令)
tools:
  - name: read
    description: 讀取原始碼
  - name: grep
    description: 搜尋程式碼模式
  - name: glob
    description: 尋找檔案
# 注意:沒有列出 bash、write、edit
# 這些工具在技能中無法使用
---

排查載入問題

如果你的技能沒有被正確載入,請檢查以下常見問題:

問題解決方法
SKILL.md 不在正確的目錄中確認放置在 ~/.config/opencode/skills/<name>/SKILL.md.opencode/skills/<name>/SKILL.md
YAML frontmatter 語法錯誤檢查 YAML 格式,注意縮排與冒號後的空格
名稱包含不合法字元確認名稱只使用小寫字母、數字和連字號
缺少必填欄位(name 或 description)確認 frontmatter 包含 name 和 description
目錄名稱與 name 不符確保目錄名稱與 frontmatter 中的 name 一致
技能未觸發確認 trigger 設定是否正確;或明確要求代理載入技能

除錯提示:啟動 opencode 時,注意終端機的輸出訊息。opencode 會顯示已載入的技能數量。如果技能數目不如預期,可檢查是否有錯誤提示。

實戰練習

練習 1:建立你的第一個技能

  1. ~/.config/opencode/skills/ 下建立 log-analyzer/SKILL.md
  2. 定義技能名稱為 log-analyzer
  3. 設定描述:專門分析應用程式日誌,找出錯誤模式與異常
  4. 列出需要的工具:bash(用 grep 分析日誌)、read(讀取日誌檔)
  5. 設定權限:允許 grep 相關指令,禁止寫入操作

練習 2:設定觸發模式

  1. 複製上一個技能,修改名稱為 always-helper
  2. trigger 設為 always
  3. 啟動 opencode 並確認技能在每個對話中自動載入
  4. trigger 改回 on-topic,觀察行為差異

練習 3:技能權限覆蓋測試

  1. 在全域 opencode.json 中將 websearch 設為 deny
  2. 建立一個技能 research-assistant,在其 permissions 中將 websearch 設為 ask
  3. 載入此技能,確認技能層級的權限覆蓋了全域設定
  4. 再建立一個自訂代理,在其 permissions 中將 websearch 設為 deny
  5. 使用該代理載入技能,確認代理層級最終覆蓋了技能層級