Claude Code 扩展指南:Skills、Subagents、Hooks 与 MCP
Posted on Mon 28 September 2026 in AI 编程 • Sucre Liu
别一上来就配全家桶
见过太多人在第一周就把 skills、subagents、hooks、MCP 全配一遍,结果哪个都没用明白,还把上下文塞得又贵又乱。
扩展层的每个东西都解决一个具体问题。先有痛点,再加配置。 官方给了一张"信号 → 动作"的对照表,我按经验重排了一下:
| 你观察到的信号 | 该加的东西 |
|---|---|
| 同一个约定它错第二次 | 写进 CLAUDE.md |
| 同一段开场白你打第三次 | 存成一个 skill |
| 同一套多步流程你贴第三次 | 存成一个 skill |
| 你总在搬某个浏览器里的数据 | 接一个 MCP server |
| 一个侧任务刷屏、输出你也不会再看 | 丢给 subagent |
| 有件事必须每次发生、不能靠它自觉 | 写一个 hook |
| 第二个仓库要同一套配置 | 打包成 plugin |
五个机制,各管一段
- CLAUDE.md:常驻上下文,每次会话都加载。
- Skill:按需加载的知识或工作流,可以
/<name>手动触发,也可以由它自动匹配。 - Subagent:独立上下文里的工作者,干完只回一份摘要。
- Hook:生命周期事件触发的脚本,确定性执行。
- MCP:连接外部服务,给它目的明确的工具。
- Plugin:把上面这些打包分发。
它们的上下文成本差异巨大,这是选型时最该看的一栏:
| 机制 | 何时加载 | 成本 |
|---|---|---|
| CLAUDE.md | 会话开始 | 每次请求都占 |
| Skill | 开始时只加载描述,用到才加载全文 | 低(仅描述常驻) |
| MCP | 开始时只加载工具名,用到才拉 schema | 低 |
| Subagent | 被派生时 | 与主会话隔离 |
| Hook | 触发时 | 零(除非它返回内容) |
一句话总结选型:常驻的用 CLAUDE.md,按需的用 skill,隔离的用 subagent,必须发生的用 hook,连外部的用 MCP。
Skill:最灵活的一种
Skill 本质是一个带 frontmatter 的 markdown 文件,放在 .claude/skills/<name>/SKILL.md:
---
name: deploy
description: 把当前分支发布到预发环境。当用户要求部署或发布时使用。
---
# 部署流程
1. 运行 `npm run build`,失败即停止。
2. 运行 `npm test`,失败即停止。
3. 执行 `./deploy.sh --env staging`。
4. 输出发布版本号与访问地址。
两种用法:
- 知识型:像 API 规范、团队约定这种参考资料,它需要时会自己加载;
- 动作型:像
/deploy这种有副作用的流程,由你手动触发。
有个实用开关:给有副作用的 skill 设 disable-model-invocation: true,它就只在你手动打 /deploy 时才出现,不会被模型自作主张调用,平时也不占上下文。对"会改生产"的流程,这个开关建议默认打开。
Subagent:买的是上下文隔离
Subagent 和 skill 最容易搞混。区别在于:
- Skill 是加载进你当前上下文的可复用内容;
- Subagent 有自己独立的上下文窗口,干完只回一份摘要。
所以 subagent 的真正价值不是"更专业",而是把中间过程挡在主会话之外。一个"读几十个文件找结论"的研究任务,用 subagent 做,你的主会话只收到结论,不会被几十个文件读操作撑爆。
自定义 subagent 就是 .claude/agents/ 下的一个 markdown:
---
name: refactorer
description: 对大量文件做机械式重构
isolation: worktree
tools: Read, Edit, Bash
---
对每个受影响的文件应用指定重构,然后运行测试并汇报结果。
注意 isolation: worktree——这个 subagent 会在自己的 git worktree 里跑,并行改文件也不会和你冲突。适合"批量、互相独立"的改动。
另外两个内置 subagent 值得知道:Explore(快、只读、专门找代码)和 Plan(只读、出方案)。它们会跳过主会话的自动记忆和一些上下文,所以更轻。让它们去"找找 X 在哪",比你自己在主会话里翻要省得多。
Hook:唯一能说"必须"的机制
前面反复强调过:CLAUDE.md 里的"不要做 X"是请求,不是保证。要确定性,用 hook。
hook 定义在 settings.json 里,绑定到生命周期事件。常见事件:
| 事件 | 时机 |
|---|---|
SessionStart |
会话开始/恢复 |
UserPromptSubmit |
你提交提示、模型处理前 |
PreToolUse |
工具调用前,可拦截 |
PostToolUse |
工具调用成功后 |
Stop |
它结束这一轮回复时 |
PreCompact / PostCompact |
上下文压缩前后 |
一个"每次编辑后自动格式化"的例子,注册 PostToolUse、匹配 Edit|Write:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{ "type": "command", "command": "jq -r '.tool_input.file_path' | xargs npx prettier --write" }
]
}
]
}
}
hook 通过 stdin 收到 JSON 事件数据,用退出码和 stdout/stderr 回话:
exit 0:没意见,继续正常流程;exit 2:拦截,stderr 作为反馈给模型;exit 0+ stdout 输出 JSON:更精细的控制(放行/拒绝/转人工)。
还有两点值得注意:多个 hook 命中同一事件时会并行全部执行,一个 deny 不会阻止兄弟 hook 执行;以及 hook 默认不产生上下文成本,除非它把输出写回对话——一个 PostToolUse 跑 linter,结果会作为文本交给模型读,这既是有用,也是成本。
MCP:给它外部工具
MCP(Model Context Protocol)把外部系统变成它可调用的一组工具:查数据库、发消息、控浏览器都行。用 CLI 添加,比手改配置安全:
claude mcp add <name> --url <remote-url>
加完用 /mcp 看连接状态。几个经验:
- MCP 的工具定义默认延迟加载,未使用时只占很少上下文,所以"多接几个"没有想象中贵;
- MCP 负责连接和数据,skill 负责怎么用好这些工具——两者常常搭配:MCP 连上数据库,skill 记录表结构和查询范式;
- 凭证优先走服务本身的 OAuth,别把 key 写进配置。
组合起来长什么样
真实配置往往是叠加的:
CLAUDE.md写项目约定;- 一个
/deployskill 固化发布流程; - 一个数据库 MCP 提供查询能力;
- 一个
PostToolUsehook 每次编辑后跑 lint; - 研究类任务丢给 subagent。
按前面的"信号表"逐步长出来,比一次性设计更靠谱。每加一样,问一句:它解决的是常驻、按需、隔离还是确定性? 答不上来,就先别加。
小结
- 扩展层五件套:常驻用 CLAUDE.md,按需用 skill,隔离用 subagent,确定性用 hook,外部用 MCP。
- 上下文成本差异很大,选型先看"何时加载"。
- 有副作用的 skill 开
disable-model-invocation;subagent 的价值在隔离;hook 是唯一的硬保证。 - 按痛点增量配置,不要一次配齐。
下一篇讲并行与自动化:worktree 怎么隔离多个会话、后台代理和动态工作流什么时候用、以及如何用 headless 模式和 CI 把 Claude Code 接进流水线。