用 Claude Code 久了,你会发现一个问题:它原生能力虽强,但总有些事需要"外挂"来补。

查数据库、发 Slack 消息,需要用到MCP。自动格式化代码、拦截危险操作,需要用到Hooks。让 Claude 遵循一套写作规范,需要用到Skills。
三种机制各管一摊,单独看都好理解。但一到实际场景,选择困难就来了:我这个需求到底该用哪个?混着用会不会互相冲突?token 消耗差多少?
- 这个功能该写 Skill 还是 Hook?
- MCP 会不会太重?
- 三个一起用会不会冲突?
- 为什么挂几个 MCP 后 token 消耗突然暴涨?
这篇文章就来解决这个问题。我们不重复介绍每种机制的基础用法(之前的 Hooks 篇、MCP 篇、Skills 篇 已经讲过了),而是聚焦在三个实战问题上:
- 它们的本质区别是什么
- Token 消耗差多少:通过数据,而不是主观感觉
- 什么场景用什么:可以通过一张决策表,对号入座
一、三种机制介绍
先给结论,后面展开:
| 机制 | 一句话 | 类比 |
|---|---|---|
| MCP | 给 Claude 接外设 | USB 接口:连数据库、GitHub、Slack 等外部服务 |
| Skills | 给 Claude 发手册 | 员工入职手册:需要的时候翻,不看的时候不占桌面 |
| Hooks | 给 Claude 装护栏 | 高速公路护栏:不靠 Claude 自觉,物理隔离危险操作 |
1.1 区别
三者的根本区别在于谁做决策:
- MCP:Claude 决定调用哪个工具( “我需要查一下数据库”)
- Skills:Claude 或用户决定加载哪份知识(“这个场景需要参考 API 规范”)
- Hooks:没人做决策,规则自动触发(“只要编辑了文件,就跑格式化”)。其实Hooks是系统行为,不是 AI 行为。
这意味着:MCP 和 Skills 是概率性的,Claude 大多数时候会正确使用,但不保证每次都用。Hooks 是确定性的,每次都执行,无一例外。

上图展示了三种机制与 Claude Code 的交互方式。注意 MCP 和 Skills 的数据流都穿过了"LLM 上下文"区域,它们会占用 context window;而 Hooks 的执行路径完全在 LLM 之外,这就是它几乎不消耗 token 的原因。
二、一个很多人忽略的问题:Token 成本模型完全不同
大多数人只关注“功能”,但在 Claude Code 里,真正决定体验的是:上下文预算(context budget)。三种机制的 token 模型几乎属于三个世界。
2.1 MCP:最贵,而且是"持续都贵"
MCP 的 token 消耗来自一个机制:工具定义注入。
Claude Code 需要"知道"有哪些 MCP 工具可用,才能决定什么时候调用它们。所以在每一轮对话中,所有已注册的 MCP 工具的 JSON Schema(包括工具名、参数类型、描述文字)都会被注入到请求中。
(1) 算一笔真实的账
一个典型的 MCP Server(比如 GitHub)约 15 个工具,每个工具的 Schema约 200~300 tokens,单个Server的开销:
15
×
250
≈
3
,
750
tokens/turn
15 \times 250 \approx 3,750 \text{ tokens/turn}
15×250≈3,750 tokens/turn
注意这是"每轮"的开销。 不管你这轮有没有用到 MCP 工具,只要 Server 连着,Schema 就在。聊 20 轮下来,光 MCP 工具定义就消耗了$3,750 \times 20 = 75,000 $ tokens,可能已经超过了你对话的有效内容。哪怕你一轮都没调用工具,也照样付费。
(2) 估算消耗的token
怎么估算自己的 MCP token 开销?一个 Server 注册了多少工具,不看配置文件(配置文件只有启动参数),而是看 Server 实际暴露了多少。最直接的办法是问 Claude:“帮我数一下当前有多少 MCP 工具”,或者去对应 MCP Server 的 GitHub 文档查工具列表。比如 chrome-devtools-mcp 注册了 29个工具,按每个约 250 tokens 算,单这一个 Server 每轮就要吃掉
250
×
29
=
7250
250 \times 29 = 7250
250×29=7250 tokens。
(3) Tool Search:MCP 的省钱模式
Claude Code 提供了一个缓解机制叫 Tool Search。当 MCP 工具定义超过 context window 的 10% 时,它会自动开启:不再一次性加载所有工具的完整 Schema,而是只加载工具的简要描述。Claude 需要用某个工具时,先"搜索"一下,再按需加载完整定义。
不开 Tool Search:每轮 11,000 tokens(所有工具全量加载)
开了 Tool Search:每轮 ~1,000 tokens(只加载描述)+ 按需加载
-
效果很明显,但有两个限制:
- 需要 Sonnet 4 或 Opus 4 以上的模型,Haiku 不支持
- 使用代理(proxy)时默认关闭,需要手动开启
-
可以通过环境变量控制:
# 自动模式(推荐):超过 10% 时自动开启
export ENABLE_TOOL_SEARCH=auto
# 手动指定阈值:超过 5% 就开启
export ENABLE_TOOL_SEARCH=auto:5
# 强制开启
export ENABLE_TOOL_SEARCH=true
2.2 Skills:轻量级,按需加载
Skills 的 token 消耗分两部分:

上图展示了 Skills 的两阶段 token 消耗模型。左边是启动时的"轻量描述加载",右边是调用时的"完整内容加载"。注意两者的视觉体量差异,描述加载非常轻,完整加载也只在需要时才发生。
(1) 会话启动时:加载描述
Claude Code 启动时,会读取所有已注册 Skill 的描述信息(frontmatter 里的 description 字段),让 Claude 知道"有哪些技能可用"。这部分开销很小:
每个 Skill 的描述:约 100~500 tokens
5 个 Skill 的总开销:约 1,000~2,500 tokens(一次性)
而且这个开销有上限,Claude Code 会把 Skill 描述控制在 context window 的 2% 以内。
(2) 被调用时:加载完整内容
只有当你手动输入 /skill-name 或 Claude 判断需要使用时,完整的 Skill 内容才会被加载到上下文中。一个中等大小的 Skill(比如一份 API 风格指南)大约 1,000~3,000 tokens。
-
关键区别:不用的 Skill 不花钱。 这跟 MCP 形成鲜明对比,MCP 是"挂着就收费",Skills 是"用了才收费"。
-
还有一个省钱技巧:如果某个 Skill 你只想手动触发、不希望 Claude 自动调用,可以在 frontmatter 里加一行:
--- disable-model-invocation: true ---
这样连描述都不会被加载,彻底零开销,直到你主动 /skill-name 调用它。
2.3 Hooks:几乎免费
Hooks 的 token 消耗取决于类型:
| Hook 类型 | Token 开销 | 说明 |
|---|---|---|
command | 0 | Shell 命令在 LLM 上下文之外运行 |
http | 0 | HTTP 请求发到外部,不经过 LLM |
prompt | 500~1,000 | 单轮 LLM 评估(默认用 Haiku,便宜) |
agent | 1,000~5,000 | 多轮子代理验证(有 60 秒超时) |
大多数常用 Hook(自动格式化、拦截危险操作、发通知)都是 command 类型,token 开销为零。
它们在 LLM 的世界之外运行:Claude 看不到 Hook 的存在,Hook 也不会占用 Claude 的上下文。唯一的例外是 Hook 向 stdout 写了输出,这些输出会被注入到上下文中,但通常也就几行文字。
-
为什么很多高手优先用 Hooks?
可以总结成一句工程经验:**不要让 AI 决定规则。**如果事情可以确定执行:格式化、校验、权限控制、CI Gate等那就不该交给概率模型。
-
Hooks ≈ CI Pipeline 思维。
2.4 放在一起看
上图直观展示了三种机制的 token 消耗量级差异。MCP 是"常驻成本",只要 Server 连着每轮都要付出;Skills 和 Hooks 是"按需成本",不用不花钱。这也是为什么很多人觉得"挂了几个 MCP 后 Claude Code 变慢了",不是网络慢了,是每轮可用的有效 context 被工具定义挤占了。
三、三种机制怎么选:决策指南
3.1 场景对照表
| 你想做什么 | 用什么 | 为什么 |
|---|---|---|
| 连接 GitHub/数据库/Slack 等外部服务 | MCP | 只有 MCP 能桥接外部 API |
| 让 Claude 遵循一套编码规范 | Skills | 按需加载,Claude 需要时自动参考 |
封装可复用的工作流(如 /deploy、/review-pr) | Skills + disable-model-invocation | 手动触发,零常驻开销 |
| 每次编辑后自动跑格式化 | Hooks(PostToolUse) | 确定性执行,零 token 开销 |
| 禁止 Claude 修改某些文件 | Hooks(PreToolUse) | 物理拦截,不靠 Claude “自觉” |
| 任务完成前必须通过测试 | Hooks(Stop + agent) | 质量门禁,Claude 无法绕过 |
| Claude 停下来时发桌面通知 | Hooks(Notification) | 外部通知,不需要 LLM 参与 |
| 项目的基础约定(构建命令、目录结构) | CLAUDE.md | 每次会话都加载,比 Skill 更简单直接 |
3.2 三个经验法则
(1) 法则一:能用 Hooks 就不用 Skills,能用 Skills 就不用 MCP
这不是说 MCP 不好,而是从 token 效率角度排优先级。如果一个需求可以用确定性规则解决(Hooks),就不需要让 Claude 来"判断"(Skills/MCP)。如果只需要注入知识(Skills),就不需要挂一个常驻服务(MCP)。
(2) 法则二:MCP 用完就断
不要同时挂一堆 MCP Server “以备不时之需”。做数据库调查时连 database server,查完就断。写代码时连 GitHub server,提完 PR 就断。/mcp 命令可以随时查看和管理连接状态。
(3) 法则三:混合使用效果最好
实际项目中,三种机制往往组合使用。MCP 负责前期调研(拉 Issue、看 PR),Skill 在编码时提供规范参考,两个 Hook 分别在编辑后自动格式化、完成前强制跑测试。四种机制各司其职,没有冲突。
四、技术细节:三种机制的加载机制对比
如果你想更深入理解 token 消耗差异的根源,需要看看它们各自的加载机制。
4.1 MCP:全量注入 vs Tool Search
MCP 工具的加载有两种模式:全量注入和Tool Search
(1) 默认模式:全量注入
每轮对话请求发送给 Claude 时,所有已注册 MCP 工具的完整 JSON Schema 都会被包含在请求中。Claude 需要这些信息来决定"要不要调用某个工具"。
// 一个典型的 MCP 工具 Schema(简化版)
{
"name": "mcp__github__create_issue",
"description": "Create a new issue in a GitHub repository",
"input_schema": {
"type": "object",
"properties": {
"owner": { "type": "string", "description": "Repository owner" },
"repo": { "type": "string", "description": "Repository name" },
"title": { "type": "string", "description": "Issue title" },
"body": { "type": "string", "description": "Issue body (markdown)" },
"labels": { "type": "array", "items": { "type": "string" } }
},
"required": ["owner", "repo", "title"]
}
}
这只是一个工具。一个 GitHub MCP Server 可能注册了 create_issue、list_issues、create_pr、merge_pr、add_comment 等十几个工具,每个都有类似的 Schema。全部加起来,轻松几千 tokens。
(2) Tool Search 模式:按需发现
开启 Tool Search 后,Claude 的请求中不再包含完整 Schema,而是包含一个特殊的"搜索工具"。当 Claude 判断需要使用某类功能时,先用搜索工具查找匹配的 MCP 工具,再加载该工具的完整定义。
这就像是从"把整本工具手册塞进口袋"变成了"带一个搜索引擎,需要时再查"。
4.2 Skills:天生就是按需加载
Skills 采用 deferred tool(延迟工具) 机制,天生就是按需的。启动时只加载"目录"(名称+描述),需要时才展开完整内容,用完还能收回释放空间。这就是它和 MCP 的本质差异,MCP 是"全套搬进来常驻",Skills 是"按需借阅,用完归还"。
你在对话开头看到的 <available-deferred-tools> 列表就是这个机制的体现。只有名字,没有 Schema,按需拉取。
4.3 Hooks:根本不进 LLM 上下文
Hooks 的执行流程完全绕过了 LLM:
整个过程中,Claude 甚至不知道 Hook 的存在。它只知道"我的编辑请求被拒绝了,原因是 xxx"或者"编辑成功了"。Hooks 的配置信息、执行逻辑都不会出现在 LLM 的上下文中。
五、常见误区
5.1 “Hooks 能替代 CLAUDE.md 里的规则”
不完全对。Hooks 能强制执行的规则是有限的——它只能在工具调用层面做拦截和后处理。“代码要写注释”、"变量名用驼峰"这类语义级别的要求,Hooks 管不了,还是得靠 CLAUDE.md 或 Skills。
5.2 “MCP 越多越好”
恰恰相反。每多挂一个 MCP Server,就多一份常驻 token 开销。更重要的是,工具太多会让 Claude 的"选择空间"变大,反而可能选错工具或在不需要时调用工具。少即是多,只挂当前任务需要的 Server。
5.3 “Skills 和 CLAUDE.md 功能重复”
有重叠,但定位不同。CLAUDE.md 是每次会话都加载的基础指令,适合放不变的、通用的规则。Skills 是按需加载的专项知识,适合放特定场景的详细指南。
一个经验:如果内容不超过 10 行,放 CLAUDE.md;如果是一整套规范或工作流,封装成 Skill。
六、总结
三种机制的核心差异,归结为三个维度:
| MCP | Skills | Hooks | |
|---|---|---|---|
| 本质 | 连接外部服务 | 注入领域知识 | 确定性自动化 |
| 决策者 | Claude 判断 | Claude 或用户 | 规则自动触发 |
| Token 模式 | 常驻开销(每轮) | 按需开销(调用时) | 几乎为零 |
| 适合 | 需要外部数据/操作 | 需要参考知识/流程 | 需要强制执行的规则 |
选择的优先级很简单:确定性规则 → Hooks,领域知识 → Skills,外部连接 → MCP。 能用轻量的就不用重量的,能按需加载的就不要常驻。
最后一个建议:定期用 /mcp 检查你的 MCP Server 列表。那些"装了就没用过"的 Server,每一轮都在默默消耗你的 token 预算。断开它们,把 context window 还给真正有用的对话内容。


1702

被折叠的 条评论
为什么被折叠?



