扩展 Claude Code 的四种机制解决的是完全不同的问题。技能教会 Claude 你希望如何完成某事。钩子保证某件事会发生,无论 Claude 决定什么。子代理通过将重点工作委托给干净的边线过程来保护主对话的上下文。MCP 服务器让 Claude 能够访问它没有该服务器就完全无法到达的系统。选错了,你最后要么得到一条模型可以悄悄忽视的"规则",要么把 MCP 依赖硬塞在本来只需要简单指令的地方。
按任务选择机制
从一个诊断问题开始:实际缺失什么?
如果答案是"Claude 不知道我希望如何完成这件事",那就是一项技能。提交消息格式、拉取请求描述模板、lint 策略、审查清单。所有这些都是打包的知识,在相关时按需加载,在你现有的会话中运行,没有外部依赖。
如果答案是"某件事必须在固定点发生,而我无法相信模型会记住",那就是一个钩子。钩子在 PreToolUse 或 PostToolUse 等生命周期事件上触发,完全在 Claude 的上下文之外运行。模型无法覆盖它们。CodingNomads 对此描述得很好:钩子以零 LLM 参与和零上下文成本确定性运行。
如果答案是"这个子任务会把 40 个文件读取拖入我的主线程",那就是一个子代理。独立的上下文窗口、自己的令牌预算、返回摘要。安静而专注。
如果答案是"Claude 需要实际接触一个它无法到达的系统",那就是一个 MCP 服务器。数据库读取、Slack 发帖、内部 API、Notion 页面。这些不是知识问题,它们是连接问题,只有 MCP 能解决。
CLAUDE.md 位于所有这些之上,作为常启层。每个会话自动读取它。根据 Anthropic 的指导,将其保持在 200 行以下,否则重要的约束会被埋没并被忽视。
指令、工具访问、事件和隔离上下文
每种机制实际控制什么:

- 技能:指令和上下文,按需加载到当前对话中。无外部调用。无事件触发。模型根据前言中的描述决定何时相关技能相关。
- MCP 服务器:工具访问。Claude 调用 MCP 工具的方式与调用任何工具相同,但执行通过 JSON-RPC 发生在单独的进程中。MCP 服务器将 Claude 连接到外部系统;技能告诉它连接后如何很好地使用它们。
- 钩子:生命周期事件。SessionStart、PreToolUse、PostToolUse、PreCompact。它们确定性运行。阻止破坏性命令的钩子每次都会阻止它,无论 Claude 是否认为这是个好主意。
- 子代理:隔离上下文。你给子代理一个简报;它独立工作;它返回结果。测试编写子代理不需要了解你的部署管道。文档编写子代理不需要你的数据库架构。那种分离就是整个要点。
技能和命令值得在这里简要说明,因为它们容易混淆。根据官方技能文档,自定义命令被折叠到技能中,不是单独的第六个系统。它们共享相同的 SKILL.md 编写模型。更多内容请见下一节。
Inventive HQ 的分析表述清楚:"技能改变行为,子代理保护上下文,MCP 服务器增加能力,钩子保证操作确定性地在事件上运行,无论模型决定做什么。"
斜杠命令在技能中的位置
自定义斜杠命令不是与技能并行的独立机制。它们是技能的调用界面。当你输入 /deploy 或 /review 时,你是按名称触发一个技能。该技能承载指令、任何链接的参考文件,以及 Claude 应该如何处理该任务的上下文。
创作任务(使用良好的 frontmatter 描述编写 SKILL.md)、命令查找任务(决定公开哪个命令名称)和机制对比任务(在技能和钩子之间选择)是三个不同的读者关注点。它们碰巧共享一个文件格式,这是持续混淆的部分原因。
如果你在决定是否使用技能,问题总是:这是我否则会重新输入的知识,还是需要无论输入如何都在事件触发时执行的东西?前者是技能,可能表现为一个命令。后者是钩子。
要更深入了解 CLAUDE.md 如何将项目上下文注入每个会话,代理机构的 CLAUDE.md 指南详细介绍了范围划定和文件结构。
为单个存储库任务组合机制
大多数实际设置不会选择一个机制就完事。它们会组合两个或三个。以下是说明 PR 工作流程如何实现的一个示例场景:
| 任务 | 机制 | 原因 |
|---|---|---|
| 强制 PR 描述格式 | 技能 | 打包的知识;当 Claude 编写 PR 时加载 |
| 从 Linear 获取工单上下文 | MCP 服务器 | Claude 无法本地访问的外部系统 |
| 扫描 >20 个文件进行影响分析 | 子代理 | 保持主线程清洁;返回一个聚焦摘要 |
| 如果测试失败则阻止提交 | 钩子 | 确定性保证;不能被模型辩论掉 |
| 始终启用分支命名规则 | CLAUDE.md | 永不条件化;每个会话都需要 |
| 文件写入前自动运行代码检查工具 | 在 PreToolUse 上挂钩 | 需要在事件触发时运行,而不是由 Claude 决定 |
代码检查工具这个例子值得停下来仔细看。Moeed 的分析总结得很好:"'运行代码检查工具'这部分是技能,Claude 可以做,你只是想要一致性。'只有通过检查才提交'这部分是钩子,那是保证,不是指导。它们相互配合。"
这就是实际的思维模型。技能和钩子经常从不同角度处理同一个任务。
常见的错误选择及纠正方法
几种模式反复出现:
- 用 MCP 服务器来处理本应只需知识的问题。如果你发现自己在启动 MCP 服务器让 Claude"访问"你的风格指南,停下来。那是技能。MCP 是用来连接实时系统的,不是用来加载 markdown 文档的。
- CLAUDE.md 中实际上是钩子的规则。把"从不运行 rm -rf"写在 CLAUDE.md 里,模型在技术上可以绕过。PreToolUse 钩子在该模式上阻止 Bash 工具是硬停止。如果规则需要被保证执行,它应该在钩子中,而不是在上下文中。
- 某个任务需要自己的上下文预算时使用的技能。如果工作涉及读取数十个文件,令牌溢出到你的主会话会快速累积。启动一个子代理。它得到一个专注的提示,完成工作,然后返回摘要。你的主上下文保持清晰。
- 用子代理处理只需要指令的任务。子代理有开销。如果 Claude 只需要知道你的迁移约定,写个技能。不要为了一个知识问题而启动一个隔离的工作进程。
- 过载的 CLAUDE.md。超过 200 行时,Anthropic 自己的指导说关键约束会被遗漏。将参考内容移到技能中,或按路径匹配条件加载分割到
.claude/rules/文件中。
如果你从零开始构建 Claude Code 工作流,并想要一个结构化的起点,Claude Code 工作流指南会讲解如何为真实的仓库设置序列化这些层。
遵循相关的实施指南
一旦你确定了正确的机制,实施路径就会清晰地分开。这篇文章是一个导航和比较层,不是设置教程。下面是按机制去的地方:
- 钩子设置:Claude Code 钩子指南涵盖生命周期事件、处理程序类型,以及如何编写确定性运行的 shell 和 HTTP 处理程序。
- 子代理:Claude Code 子代理指南解释如何向子代理下达任务、限定其工具权限,以及在父会话中处理结果。
- MCP 服务器:如果你为生产栈构建或集成 MCP 服务器,MCP 服务器生产指南涵盖服务器类型、传输和可靠性模式。
- 技能:从官方技能文档开始,它涵盖 SKILL.md 结构、前置元数据描述,以及自定义命令如何映射到技能文件。
在你决定了哪种机制适用之前,不要试图同时阅读这四个。那是你最终花三小时深入钩子配置的方式,而你本来只需要两行技能。
FAQ
CLAUDE.md应该被纳入这个决策考虑吗?
是的,但这是另一种类型的决策。CLAUDE.md不在任务时选择。它每个会话都会自动加载。CLAUDE.md的问题是:"Claude每次都无条件地需要这些信息吗?"如果是,就放在那里。如果指令只在特定任务中重要,它应该属于具有特定frontmatter描述的技能。
技能可以触发MCP服务器调用吗?
可以。技能可以指示Claude作为工作流的一部分使用可用的MCP工具。技能提供方法(要求什么、按什么顺序、期望什么格式),MCP服务器提供访问权限。它们是互补的,而不是竞争的。
子代理和代理团队有什么区别?
子代理是你从主会话分派来处理特定子任务的工作者。代理团队是一组对等会话,可以彼此直接通信,适合真正的并行协作工作。对于大多数仓库任务,子代理是正确的选择。当多个独立工作流需要协调而不是一个会话向下委派时,代理团队才有意义。
钩子可以访问Claude的上下文吗?
不能。这正是关键。钩子在Claude的上下文之外运行,模型无法覆盖它们。这使它们成为硬性保证的正确工具:安全检查、强制性linting检查、被屏蔽的文件模式。权衡是钩子无法根据Claude对任务的理解做出微妙的决策。它在事件时触发并运行其处理程序。
何时应该同时使用全部四个机制?
当你有一个具有多种不同故障模式的工作流时:知识缺口(技能)、连接要求(MCP)、上下文泄漏风险(子代理)以及至少一个必须保证的操作,无论模型判断如何(钩子)。大多数简单任务只需要一到两个机制。每项任务都用全部四个机制会增加开销,没有收益。
这整个比较中最尖锐的区别:技能是Claude读取并遵循的建议;钩子是挽具执行的规则,无论Claude是否同意。如果搞错了,你的"安全规则"就只是一个礼貌的请求。
