
事情是这样的。
我团队从今年3月开始全员切 Claude Code。一开始还好,大家往 CLAUDE.md 里塞项目规范,顺手写几个 /deploy、/review 的 Custom Commands,日子过得去。
一个月后噩梦开始。
前端同学用 Skill 封了一套「组件库使用规范」,后端同学用 MCP 接了个内部 API 做配置查询,DevOps 同学用 Hook 挂了 pre-tool 检查。三套东西各自跑得好好的,但互相不知道对方的存在。最离谱的是,有一天我发现同一个「数据库建表规范」的逻辑,在三个地方以三种形态存在:CLAUDE.md 里一堆 Markdown、一个 Skill 的 SKILL.md、一个 MCP Server 的 Python 脚本里又写了一份。
我当时就想:这四种东西到底该在什么场景用?它们之间是什么关系?
三周时间,我把官方文档翻了三遍,在生产环境踩了一堆坑,画了张图。今天把这张图展开讲。
坦白讲,这是我踩的最大的坑。
大多数人(包括三周前的我)面对 Skill、MCP、Hook、Plugin 时,心态是「四选一」,心里想的是:我这个需求,用哪个最合适?
这个思维模型本身就是错的。

四层金字塔模型:知识层→集成层→自动化层→分发层
它们解决的不是同一个层次的问题。 Skill 解决的是「Claude 知不知道怎么做」,MCP 解决的是「Claude 能不能跟外部系统对话」,Hook 解决的是「Claude 做事前后要不要自动触发点什么」,Plugin 解决的是「这些能力怎么分发给团队」。
这不是 Anthropic 发明的四个并列功能——这是软件开发中四个永恒问题在 AI 编程工具里的自然投影:知识管理、系统集成、流程自动化、能力分发。
我在团队里的真实体感是:80% 的场景用 Skill + MCP 就足够了,Hook 和 Plugin 解决的是规模化以后才暴露的治理问题。
码哥做了 10 年后端架构,见过太多「过度设计」的惨案。项目刚启动就上了消息队列和微服务,结果三个月后连业务逻辑都没跑通。Claude Code 的扩展机制也一样:Skill 起步,遇到真实瓶颈再加,别提前设计。
Skill 的本质是什么?
官方文档的定义很精确:Skill 是一组指令、工作流和工具配置,告诉 Claude「做这类任务时该按什么步骤来」。
但我觉得有个比喻更贴切。Skill 是给模型穿上的「知识铠甲」。没有 Skill,Claude 像一个聪明但对你项目一无所知的新同事;有了 Skill,它变成了一个带着 SOP 手册的老兵。
Skill 和 CLAUDE.md 的区别是最容易搞混的地方。
CLAUDE.md 是「项目宪法」,始终加载、定义全局规则。Skill 是「SOP 手册」,按需加载,只在做特定任务时激活。
举个例子。我们团队的 CLAUDE.md 里写了 7 条全局规则:「所有 API 接口必须返回 {code, data, message} 结构」「数据库字段用下划线命名」。这些是所有任务共享的底线。
但「前端如何接入埋点 SDK」这件事,只有做前端需求的 Claude 需要知道。把它塞进 CLAUDE.md 里,就变成了全局噪音。后端 Claude 每次处理 PR 都得浪费几百个 token 读一段跟自己无关的内容。
这就是 Skill 的存在意义:按需加载,不污染全局上下文。
---
name: frontend-tracking
description: 前端埋点 SDK 接入规范。当需要添加用户行为追踪时使用。
---
# 前端埋点规范
## 初始化方式
在 `app.tsx` 中引入 `@company/tracker`,调用 `initTracker({ appId: process.env.TRACKER_APP_ID })`。
## 事件命名规范
- 页面浏览:`page_view_{pageName}`
- 按钮点击:`btn_click_{buttonName}`
- 表单提交:`form_submit_{formName}`
## 禁止事项
- 禁止在 `useEffect` 中直接调用 `track()`,必须封装成自定义 Hook
- 禁止上报用户手机号、邮箱等 PII 数据
这个 Skill 写好之后,Claude 只有在前端任务中需要处理埋点逻辑时才会加载它。
从 Custom Commands 到 Skills 的演进,是一次范式转换。
Custom Commands 是人驱动,你说「执行这个」,Claude 照做。Skill 是模型驱动,Claude 自己判断「现在该用这个能力了」。这个转变的意义比功能本身大得多。Custom Commands 是给 Claude 加「按钮」,Skill 是给 Claude 加「直觉」。

范式转换:从人驱动的 Custom Commands 到模型驱动的 Skills
上面说 Skill 解决的是「知不知道怎么做」,但有个场景 Skill 打死也解决不了。
你需要查数据库里某张表的实时字段。Skill 可以描述「字段 A 是什么类型、字段 B 的枚举值有哪些」,但这份描述是你写文章时人工录入的。两周后表结构变了,Skill 里的描述就过期了。
Skill 是静态知识。MCP 是实时连接。
MCP(Model Context Protocol)是 Anthropic 在 2024 年 11 月发布的协议,如今已经成了 AI 工具集成外部系统的事实标准。它的设计思路很直接:如果每个外部系统都要单独适配 Claude Code,Anthropic 得维护几百个 connector。不如定义一个标准协议,让系统自己暴露能力。
坦白讲,MCP 的 token 消耗确实比 Skill 高。每一次 MCP tool 调用都要经过「Claude 描述意图→MCP Server 解析→执行→返回结果」四个环节,光是一个简单的数据库查询就可能多消耗 500-1000 token。
但「省 token」不是拒绝 MCP 的理由。
你什么时候用 MCP?
一个硬判断标准:当你的需求涉及「实时数据」或者「外部系统状态变更」时,Skill 做不到。
查数据库当前状态、调用内部 API 创建工单、读取 Kubernetes 集群的 Pod 状态,这些都是 MCP 的主场。Skill 能给 Claude「知识」,但给不了「此刻的真实世界信息」。
# 一个简单的 MCP Server 示例:查询内部服务状态
from mcp.server import Server
from mcp.types import Tool, TextContent
server = Server("service-health")
@server.list_tools()
asyncdef list_tools():
return [
Tool(
name="check_service_status",
description="查询指定服务的健康状态",
inputSchema={
"type": "object",
"properties": {
"service_name": {"type": "string", "description": "服务名称"}
},
"required": ["service_name"]
}
)
]
@server.call_tool()
asyncdef call_tool(name: str, arguments: dict):
if name == "check_service_status":
service = arguments["service_name"]
# 实际调用内部健康检查 API
result = await internal_api.health_check(service)
return [TextContent(type="text", text=str(result))]
我们生产环境有一个典型的「Skill 不够用,上了 MCP」的案例:自动化部署流程。一开始用 Skill 写了部署步骤的 SOP,「先跑测试,再构建镜像,再滚动更新」。但实际部署时,Claude 需要知道「当前 K8s 集群里老 Pod 还在不在」「新镜像有没有成功拉取」。这些是 Skill 描述不出来的实时状态。Skill 能告诉你该怎么做,但 MCP 能告诉你现在是什么情况。

Skill vs MCP 核心差异对比
Hook 是四个机制里最容易被低估的一个。
很多人第一次看到 Hook 的反应是:「噢,跟 Git Hooks 差不多,就是自动化脚本。」
Claude Code Hooks 远比 Git Hooks 强大。 Git Hooks 只能做「提交前检查代码格式」这种 yes/no 判断。Claude Code Hooks 可以修改工具输入、阻止工具执行、注入额外上下文、甚至调用 MCP 工具。
这是官方 Hooks 文档里的一段配置片段:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "python3 .claude/hooks/pre-write-check.py",
"timeout": 10000
}
]
}
],
"PostToolUse": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "python3 .claude/hooks/log-tool-usage.py"
}
]
}
]
}
}
PreToolUse 可以在 Claude 写文件之前拦截,比如检查修改的文件是否包含敏感信息(密钥、内部域名),有就阻止写入。PostToolUse 可以在每次工具调用后自动记录日志,不侵入任何 Skill 或 MCP 的逻辑。
我们团队踩过一个坑:有位同事在调试时把测试环境的数据库连接串写进了一个 .env.example 文件,差点提交。后来我们用 Hook 挂了一个 PreToolUse 检查。任何 Write/Edit 操作写入包含「密码」「secret」「connectionString」等关键词的文件时,自动拦截并警告。
Hook 解决的是「什么时候」的问题。 Skill 和 MCP 回答「怎么做」,Hook 回答「什么情况下触发」。它们是正交的两个维度。
一个判断标准:如果你的需求是「每次做 X 之前/之后自动做 Y」,这就是 Hook 的活。 别把这种逻辑塞进 Skill 里。Skill 应该只描述「怎么做」,不应该关心「什么时候做」。

Hook 生命周期:Session / Turn / Tool 三级事件触发时机
Plugin 是四个概念里最「上层」的一个,也是误解最多的一个。
最常见的误解:「Plugin 不就是把 Skill 和 Hook 打个包?跟我直接放 .claude 目录有什么区别?」
技术上确实,Plugin 就是把 Skill、Hook、MCP 配置打包在一起。但 Plugin 解决的不是技术问题,是治理问题。
我团队的亲身教训:10 个人,每个人在 ~/.claude/skills/ 下维护自己的 Skill。三周后,出现了 3 个不同版本的「代码审查 Skill」,2 个版本的「部署脚本 Skill」,还有 1 个同事的 Skill 引用了已废弃的内部 API 地址。
Skill 是个人效率工具。Plugin 是团队能力标准。
当你把一组 Skill + Hook + MCP 配置封装成 Plugin、发布到内部源之后,团队所有人装的是同一个版本、同一份逻辑。更新也是集中升级,不存在「A 用的 v1.2,B 还在用 v1.0」的情况。
什么时候需要 Plugin?
当「多人协作」和「版本一致性」成为痛点时。 如果你是一个人用 Claude Code,Plugin 对你几乎没意义,直接维护 CLAUDE.md 和 ~/.claude/skills/ 就够了。但 3 人以上的团队,Plugin 是避免混乱的唯一方式。
目前 Claude Code 插件市场已有 9000+ 插件,这个生态的成熟度远超大部分人的想象。Claude Code 本身也在以惊人速度迭代,v2.1.0 一个版本的更新就有 1096 个 commits。这种迭代密度意味着扩展机制的设计还在快速演进中。
说了这么多,落地到一句话:我怎么判断自己的场景该用哪个?
我总结了一个三层决策框架。
三层决策框架:从问题本质到选型结论
第一层:你的问题属于哪个层次?
问自己:「我到底在解决什么问题?」
第二层:关键判断
如果落在「知识层」,再问自己:这份知识是所有任务都需要,还是只有特定任务需要?
如果落在「集成层」,再问自己:你连接的是静态文档(API 手册、数据库 schema 说明)还是实时系统(数据库本体、K8s 集群、内部 API)?
如果落在「自动化层」,再问自己:这个操作需要在 Claude「做某事前」触发,还是「做完后」触发?
第三层:选型结论
下面这张表是核心。建议存下来。

五机制全景对比矩阵:CLAUDE.md / Skill / MCP / Hook / Plugin
维度 | CLAUDE.md | Skill | MCP | Hook | Plugin |
|---|---|---|---|---|---|
层次 | 知识层(全局) | 知识层(按需) | 集成层 | 自动化层 | 分发层 |
触发方式 | 始终加载 | 模型判断加载 | 模型调用 | 生命周期事件 | 安装后生效 |
Token 消耗 | 始终消耗 | 按需消耗 | 单次高 | 按事件消耗 | 同所含组件 |
适用规模 | 个人/团队 | 个人/团队 | 个人/团队 | 个人/团队 | 3人以上团队 |
核心解决 | 全局底线规则 | 特定任务 SOP | 外部系统连接 | 时机自动化 | 能力标准化分发 |
不能做的事 | 访问外部API | 获取实时数据 | 做代码规范检查 | 给Claude知识 | 解决技术选型 |
聊一个实操问题:什么信号说明 Skill 不够用了,该升级到 MCP Server 了?
我总结了三个触发条件,缺一不可:
信号一:Skill 里的数据开始过期。 你在 Skill 里维护了一份「服务列表」或者「API 字段说明」,隔两周就要手动更新。这意味着这份知识本质上是「实时数据的快照」。Skill 不该承载快照,MCP 才该承载。
信号二:Claude 做决策时需要「验证事实」。 不是「我以为」而是「事实是什么」。比如「这个接口现在能不能调通」「这个配置项线上当前值是多少」。Skill 能给 Claude 信心,MCP 能给 Claude 事实。
信号三:你在 Skill 里写了「执行脚本」。 如果你发现自己写的 Skill 包含大量 bash 命令(查数据库、调 API、读文件),这就是 MCP 的典型领域。Skill 该描述的是流程和规范,不该是执行逻辑。
三个信号同时出现,就该动手拆 MCP Server 了。
但我要说一句实话:绝大多数情况下,信号一和信号二不会同时出现。大多数团队的需求就是「告诉 Claude 我们团队的代码规范」「给它一个部署的 SOP 步骤」。Skill 完全够用,别为了升级而升级。
我们在生产环境有一个反面案例。团队一开始用 MCP 接了一个内部文档搜索 API,token 消耗巨高,每次调用 3000+ token。后来发现这个文档三个月才更新一次。直接用 Skill 描述文档结构就够了,省了 60% 的 token。选型的第一原则永远不是「哪个更高级」,而是「哪个刚好解决我的问题」。
来投个票:你现在主要用什么方式扩展 Claude Code?
问:CLAUDE.md 和 Skill 到底怎么分?我现在 CLAUDE.md 已经 3000 行了。
删。
把 CLAUDE.md 精简到只放三类东西:(1) 项目技术栈声明(语言、框架版本);(2) 硬性编码规范(命名、目录结构);(3) 安全红线(禁止的操作)。
剩下的全部拆成 Skill。前端规范拆一个、数据库规范拆一个、部署流程拆一个。拆完之后,Claude 只在做对应任务时才加载对应 Skill,token 消耗立刻降下来。
问:Hook 能不能替代 Skill?比如我用 PreToolUse 在每次 Claude 写代码前自动注入代码规范?
技术上可以。但这是个坏设计。
Hook 的生命周期跟「事件」绑定,跟「任务语义」无关。用 Hook 注入代码规范,意味着「Claude 改 README 时」也会触发规范检查,它根本不需要。Hook 做任务无关的自动化,Skill 做任务相关的知识注入。 别混用。
问:我现在的场景是「一个人的项目,但以后可能团队用」,要不要直接上 Plugin?
不要。等到真的有多人协作的需求时再封装。过早的 Plugin 会带来额外的维护成本:版本号管理、发布流程、兼容性测试。一个人根本不需要这些。架构设计的黄金法则:别为还没出现的需求写代码。
问:9000+ 插件都是什么类型的?值得用吗?
目前插件市场的主流是三类:(1) 框架集成(Next.js、Nuxt、Spring Boot 的项目模板);(2) 工具增强(Git 工作流优化、代码审查规则包);(3) 平台对接(Vercel 部署、Supabase 数据库管理)。如果你的技术栈恰好匹配,第三类很值得,比自己写 MCP Server 省时间。
坦白讲,前两类谨慎安装。它们往往塞了很多你不需要的规则,反而增加 token 噪音。
如果你读到这里,脑子里应该有了一个清晰的图景:Skill 是模型的知识铠甲,MCP 是外部系统的连接器,Hook 是流程的守夜人,Plugin 是团队能力的分发包。 它们不是竞争关系,是一个工作流的不同零件。
我团队的结论是:90% 的日常场景 Skill + MCP 就够了。Hook 只在安全检查和自动化记录时用,Plugin 是给 10 人以上团队准备的。
写技术文章是真累,如果你觉得这篇对你有用,给个星标不过分吧。下次被 Claude Code 的扩展机制搞晕时,翻出这篇文章对着三层框架走一遍,大概率能自己判断。
对了,下一篇我准备聊聊 Claude Code 的上下文治理:CLAUDE.md 怎么写到刚好 200 行不冗余不遗漏、/compact 什么时候用、TOKENOFF 和 TODO 到底怎么配合。想看的评论区吱一声,人多就写。