# Claude Code Skills 與 Hooks 關係解析 ## 研究摘要 > 核心結論 > Skills 和 Hooks 是 Claude Code 中兩個互補的擴展機制:Skills 提供「知識和能力」(做什麼、怎麼做),Hooks 提供「控制和自動化」(確保做得對、做得安全)。兩者可在 Plugin 中整合,形成「能力層 + 控制層」的完整架構。 --- ## 核心概念定義 ### Skills(技能) Skills 是 Claude Code 的**能力擴展機制**,用於將專業知識打包成可重複使用的指導文件。 | 特性 | 說明 | |------|------| | 觸發方式 | **Model-invoked**(模型自主判斷調用) | | 文件格式 | Markdown(`SKILL.md`) | | 存放位置 | `~/.claude/skills/` 或 `.claude/skills/` | | 核心目的 | 教 Claude「如何做」特定任務 | ```markdown <!-- SKILL.md 範例結構 --> | Skill Name | Description and trigger conditions | ## 技能說明 詳細的執行指導... ## 最佳實踐 ... ``` ### Hooks(鉤子) Hooks 是 Claude Code 的**事件驅動自動化機制**,在特定時機自動執行 shell 命令。 | 特性 | 說明 | |------|------| | 觸發方式 | **Event-driven**(系統事件自動觸發) | | 配置格式 | JSON(`settings.json` 或 `hooks.json`) | | 存放位置 | `.claude/settings.json` 或 plugin 的 `hooks/` | | 核心目的 | 監控、驗證、自動化執行過程 | ```json { "hooks": { "PostToolUse": [ { "matcher": "Write|Edit", "hooks": [ { "type": "command", "command": "prettier --write \"$CLAUDE_FILE_PATHS\"" } ] } ] } } ``` --- ## 兩者的關鍵差異 | 面向 | Skills | Hooks | |------|--------|-------| | **觸發機制** | Claude 自主判斷使用 | 系統事件自動觸發 | | **主要目的** | 提供知識和指導 | 執行驗證和自動化 | | **執行控制** | 無法直接阻止操作 | 可透過 exit code 阻止工具執行 | | **配置格式** | Markdown 文件 | JSON + Shell 腳本 | | **用戶互動** | 被動(Claude 決定是否使用) | 確定性(事件發生必定執行) | --- ## 互動關係與生命週期 ### 執行流程圖 ```mermaid flowchart TD A[用戶請求] --> B{Claude 分析任務} B --> C[識別相關 Skill] C --> D[Skill 指導執行策略] D --> E[Claude 調用工具] E --> F[PreToolUse Hook] F -->|允許| G[工具執行] F -->|阻止| H[回饋給 Claude] G --> I[PostToolUse Hook] I --> J{任務完成?} J -->|否| E J -->|是| K[Stop Hook] K --> L[結束] H --> E ``` ### 層級架構 ``` ┌─────────────────────────────────────────────┐ │ 用戶請求(User Request) │ └─────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────┐ │ 能力層(Skills)- 提供知識和執行指導 │ │ • 定義「做什麼」和「怎麼做」 │ │ • Model-invoked,Claude 自主決定 │ └─────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────┐ │ 執行層(Tool Calls)- Claude 調用工具 │ │ • Write, Edit, Bash, Read 等 │ └─────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────┐ │ 控制層(Hooks)- 監控和干預執行 │ │ • 確保「做得對」和「做得安全」 │ │ • Event-driven,確定性執行 │ └─────────────────────────────────────────────┘ ``` --- ## Hook 事件類型一覽 | Hook 事件 | 觸發時機 | 常見用途 | |-----------|---------|---------| | `PreToolUse` | 工具執行**前** | 驗證、阻止危險操作 | | `PostToolUse` | 工具執行**後** | 格式化、測試、日誌 | | `UserPromptSubmit` | 用戶提交提示**前** | 添加上下文、過濾輸入 | | `SessionStart` | 會話**開始**時 | 載入項目配置 | | `SessionEnd` | 會話**結束**時 | 清理、保存狀態 | | `Stop` | Claude **完成回應**時 | 最終驗證、測試 | | `SubagentStop` | **子代理**完成時 | 子任務驗證 | | `PreCompact` | 上下文**壓縮前** | 保存重要資訊 | | `Notification` | 發送**通知**時 | 自訂通知處理 | | `PermissionRequest` | **權限請求**時 | 自動授權/拒絕 | > [!tip] Exit Code 行為 > - **Exit 0**:Hook 成功,繼續執行 > - **非零 Exit**:對於 `PreToolUse`,會阻止工具執行並將 stderr 回饋給 Claude --- ## 在 Plugin 中整合 Skills 和 Hooks ### Plugin 目錄結構 ``` my-plugin/ ├── .claude-plugin/ │ └── plugin.json # Plugin 元數據 ├── skills/ │ └── code-review/ │ └── SKILL.md # 代碼審查技能 ├── hooks/ │ └── hooks.json # Hook 配置 ├── scripts/ │ ├── pre-write-check.sh # 寫入前檢查 │ └── post-format.sh # 寫入後格式化 └── README.md ``` ### 整合範例:代碼審查 Plugin **skills/code-review/SKILL.md**: ```markdown | Code Review | Use when reviewing code, analyzing PRs, or checking code quality | ## 審查流程 1. 檢查代碼風格和一致性 2. 識別潛在的 bug 和安全問題 3. 評估可讀性和可維護性 4. 提供具體的改進建議 ## 注意事項 此專案使用 PreToolUse hook 阻止寫入 .env 文件, 並使用 PostToolUse hook 自動運行 linter。 ``` **hooks/hooks.json**: ```json { "description": "代碼審查安全和品質控制", "hooks": { "PreToolUse": [ { "matcher": "Write", "hooks": [ { "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/scripts/pre-write-check.sh" } ] } ], "PostToolUse": [ { "matcher": "Write|Edit", "hooks": [ { "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/scripts/post-format.sh" } ] } ] } } ``` > [!info] `${CLAUDE_PLUGIN_ROOT}` 變數 > 此變數會自動解析為 plugin 的根目錄路徑,讓 hooks 可以引用同一 plugin 中的腳本。 --- ## 實用組合模式 ### 1. 代碼質量保證 ```mermaid flowchart LR A[Skill: 編碼標準] --> B[Claude 編寫代碼] B --> C[PostToolUse: Linter] C --> D[PostToolUse: Formatter] D --> E[Stop: 運行測試] ``` | 組件 | 類型 | 職責 | |------|------|------| | 編碼標準指南 | Skill | 定義代碼風格和最佳實踐 | | 自動 Linting | PostToolUse Hook | 即時檢查語法問題 | | 自動格式化 | PostToolUse Hook | 確保代碼風格一致 | | 測試執行 | Stop Hook | 確保所有測試通過 | ### 2. 安全合規控制 | 組件 | 類型 | 職責 | |------|------|------| | 安全編碼指南 | Skill | 指導安全編碼實踐 | | 敏感文件保護 | PreToolUse Hook | 阻止寫入 `.env`、密鑰文件 | | 安全掃描 | PostToolUse Hook | 掃描新代碼的安全漏洞 | **PreToolUse 阻止敏感文件寫入範例**: ```bash #!/bin/bash # pre-write-check.sh input=$(cat) file_path=$(echo "$input" | jq -r '.tool_input.file_path // empty') # 檢查是否為敏感文件 if [[ "$file_path" =~ \.(env|pem|key)$ ]] || [[ "$file_path" =~ secrets ]]; then echo "❌ 禁止寫入敏感文件: $file_path" >&2 exit 1 fi exit 0 ``` ### 3. 文檔自動化 | 組件 | 類型 | 職責 | |------|------|------| | 文檔撰寫指南 | Skill | 定義文檔格式和內容標準 | | 項目上下文載入 | SessionStart Hook | 自動載入項目資訊 | | Markdown 驗證 | PostToolUse Hook | 確保格式正確 | ### 4. 機器學習實驗 | 組件 | 類型 | 職責 | |------|------|------| | 實驗流程指南 | Skill | 定義實驗設計和記錄標準 | | 參數驗證 | PreToolUse Hook | 確保超參數在合理範圍 | | 結果記錄 | Stop Hook | 自動保存實驗結果 | --- ## 最佳實踐 ### Skills 設計原則 > [!tip] DO - 建議做法 > - **保持專注**:一個 Skill 解決一個問題 > - **清晰描述**:讓 Claude 能準確判斷何時使用 > - **包含範例**:提供具體的輸入/輸出範例 > - **文檔化限制**:告知 Claude 相關的 Hook 行為 > [!warning] DON'T - 避免做法 > - 不要讓 Skill 範圍太廣泛 > - 不要在 Skill 中放置實際執行代碼 > - 不要假設 Claude 一定會遵循(使用 Hook 強制執行關鍵規則) ### Hooks 設計原則 > [!tip] DO - 建議做法 > - **保持快速**:Hook 會阻塞執行,保持輕量 > - **明確輸出**:使用 stderr 提供清晰的錯誤訊息 > - **冪等設計**:Hook 可能多次執行,確保結果一致 > - **使用 Matcher**:精確匹配需要的工具,避免過度觸發 > [!warning] DON'T - 避免做法 > - 不要在 Hook 中執行耗時操作 > - 不要忽略錯誤處理 > - 不要在 Hook 中做複雜的業務邏輯(保持簡單) ### 整合建議 1. **先定義 Skill,再設計 Hooks** - Skill 定義「應該怎麼做」 - Hooks 確保「必須這樣做」 2. **在 Skill 中記錄 Hook 行為** - 讓 Claude 了解哪些操作會被阻止 - 避免 Claude 重複嘗試被阻止的操作 3. **使用 Plugin 打包完整功能** - 一個 Plugin = 相關 Skills + 對應 Hooks + 輔助腳本 - 便於分享和版本控制 --- ## 常見問題 > [!faq]- Skill 執行時會觸發哪些 Hooks? > Skill 本身不直接觸發 Hooks。但當 Claude 根據 Skill 的指導調用工具(如 Write、Edit、Bash)時,這些工具調用會觸發相應的 `PreToolUse` 和 `PostToolUse` Hooks。 > [!faq]- 可以用 Hook 強制 Claude 使用特定 Skill 嗎? > 不能直接強制。但可以在 `UserPromptSubmit` Hook 中注入上下文或提示,引導 Claude 考慮使用特定 Skill。 > [!faq]- Hooks 失敗時 Skill 會如何反應? > 如果 `PreToolUse` Hook 返回非零 exit code,工具調用會被阻止,stderr 內容會回饋給 Claude。Claude 可能會根據回饋調整策略,但這取決於 Skill 中的指導和 Claude 的判斷。 > [!faq]- 如何調試 Skills 和 Hooks 的互動? > 使用 `claude --debug` 啟動 Claude Code,可以看到詳細的 Hook 執行日誌。也可以在 Hook 腳本中輸出調試資訊到日誌文件。 --- ## 參考資料 | 來源 | 標題 | 可信度 | |------|-----|--------| | [code.claude.com](https://code.claude.com/docs/en/skills) | Agent Skills - Claude Code Docs | ⭐⭐⭐⭐⭐ | | [code.claude.com](https://code.claude.com/docs/en/hooks) | Hooks reference - Claude Code Docs | ⭐⭐⭐⭐⭐ | | [code.claude.com](https://code.claude.com/docs/en/hooks-guide) | Get started with Claude Code hooks | ⭐⭐⭐⭐⭐ | | [code.claude.com](https://code.claude.com/docs/en/plugins) | Create plugins - Claude Code Docs | ⭐⭐⭐⭐⭐ | | [GitHub](https://github.com/anthropics/claude-code/blob/main/plugins/plugin-dev/skills/hook-development/SKILL.md) | Hook Development Skill | ⭐⭐⭐⭐⭐ | | [alexop.dev](https://alexop.dev/posts/claude-code-customization-guide-claudemd-skills-subagents/) | Claude Code customization guide | ⭐⭐⭐⭐ | | [eesel.ai](https://www.eesel.ai/blog/hooks-in-claude-code) | A complete guide to hooks in Claude Code | ⭐⭐⭐⭐ | | [youngleaders.tech](https://www.youngleaders.tech/p/claude-skills-commands-subagents-plugins) | Understanding Claude Code: Skills vs Commands vs Subagents | ⭐⭐⭐⭐ | ---