# 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 | ⭐⭐⭐⭐ |
---