第 17 章:扩展点不是一堆名词,而是平台的能力接口
本章目标:把命令、Hook、Agent、Skill、MCP 这些常见扩展点拆清楚,讲明白它们各自负责什么、不负责什么,以及为什么把这些概念混写会直接把平台设计搞乱。
本章对应总纲:docs/ebook-outline.md中“第 17 章正文写作提纲(2026-03-31 归档)”。
17.1 为什么平台一长扩展点,名词就会先乱掉
平台化一开始,最常见的毛病不是代码炸,而是概念先炸。
大家会开始同时说这些词:
- 命令
- Hook
- Agent
- Skill
- MCP
- 插件
然后很快就会出现这种烂场面:
- 把入口当能力源
- 把能力源当执行角色
- 把执行角色当知识封装
- 把生命周期挂点当功能模块
最后系统虽然“看起来很多扩展点”,实际却没人说得清每层到底在干什么。
所以平台成熟不成熟,一个很硬的标准就是:
它有没有把不同扩展点的职责边界说清楚。
17.2 命令:它解决的是入口问题
命令最适合解决的问题是:
- 用户怎么显式触发一段能力
- 一段常见任务如何被包装成清晰入口
- 某类操作怎样被快速复用
所以命令的价值不在于“能力更强”,而在于:
它给系统提供了一个明确、可发现、可复用的触发入口。
命令不该承载什么?
- 不该假装自己是完整治理层
- 不该偷偷承担复杂生命周期管理
- 不该把大量运行时策略硬塞进入口定义里
入口就是入口,别让它背太多锅。
17.3 Hook:它解决的是时机问题
Hook 和命令完全不是一类东西。
命令回答的是“从哪开始”;Hook 回答的是“在什么时候插手”。
Hook 最适合挂的地方通常是生命周期节点:
- 动作之前
- 动作之后
- 停止之前
- 子任务结束之后
- 会话启动或结束时
所以 Hook 的核心价值不是增加新功能,而是:
- 拦截
- 检查
- 补充治理
- 插入额外约束
- 在不改主流程的前提下影响流程
如果把 Hook 当成功能模块乱用,系统很快就会长成一堆隐式行为,最后谁都调不明白。
17.4 Agent:它解决的是执行单元问题
Agent 这个词前面已经讲过很多次了。
到了平台里,它更应该被理解成:
一个带有相对独立目标、上下文边界和工具边界的执行单元。
所以 Agent 扩展点的价值在于:
- 允许系统把复杂任务拆给不同执行角色
- 给不同子任务分配不同能力和上下文
- 让执行策略能分层组织
它不该被混成:
- 单纯的知识文档
- 单纯的入口命令
- 单纯的工具集合
否则你会把一个执行角色设计成四不像。
17.5 Skill:它解决的是知识封装问题
Skill 最容易被误解。
很多人会把它当成:
- 小命令
- 小 Agent
- 小插件
这都不准。
Skill 更像是在回答:
- 某类任务所需的方法、模式和参考资料,怎样被打包复用
- 某种专业能力,怎样在需要时被按需加载
也就是说,Skill 的核心价值不在于替系统“执行”,而在于替系统“补方法和知识”。
它更偏:
- 能力说明书
- 任务方法包
- 渐进披露的知识封装
把 Skill 当执行单元用,或者把它当 Hook 用,都会把边界搞脏。
17.6 MCP:它解决的是外部能力标准接入问题
MCP 前面已经单独讲过协议层;这里不再重复“为什么需要协议层”,只从平台扩展点分层这个角度看它。也就是说,第 11 章讲的是“为什么要有统一协议”,这一节讲的是“这层统一协议在平台结构里到底挂在哪”。
放到扩展点视角里再看一次,它最关键的定位是:
- 不是命令
- 不是 Hook
- 不是 Agent
- 不是 Skill
它解决的是另一层问题:
外部工具与资源如何以统一协议进入平台。
所以 MCP 更像平台的外部能力接口层。
它让平台可以:
- 发现外部工具
- 暴露外部资源
- 用统一方式治理接入
- 把外部能力纳入同一执行世界
如果把 MCP 和命令、Hook 这些层混成一锅,平台很快就会失去结构感。
17.6.1 为什么这里没把“策略型扩展点”单列成一层
第 16 章提过“策略型扩展点”。这里没有把它和命令、Hook、Agent、Skill、MCP 并列展开,不是漏了,而是因为它更多不是一种独立执行实体,而是通过 settings、规则文件、Hook 管理和权限样板落地。也就是说,策略扩展更像是在给其他扩展点加治理壳层。
17.7 为什么这些扩展点不能互相替代
很多烂设计都有一个共同味道:
- 本来该用命令的地方,硬塞进 Hook
- 本来该用 Hook 的地方,硬做成 Agent
- 本来该用 Skill 承载知识的地方,硬做成命令正文
- 本来该用 MCP 接外部能力的地方,硬编码进核心流程
短期看,这些都“能用”。
长期看,后果很直接:
- 入口变脏
- 生命周期变乱
- 外部能力接入失控
- 知识和执行混成一锅
- 治理边界越来越模糊
所以好品味不是把扩展点越做越多,而是让每类扩展点都只解决自己那一层问题。
17.8 一个更务实的判断表:到底该挂在哪一层
可以把它压成一张表:
| 你要解决的问题 | 更像哪类扩展点 |
|---|---|
| 给用户一个明确触发入口 | 命令 |
| 在生命周期节点插入检查/约束 | Hook |
| 给系统增加一个相对独立的执行角色 | Agent |
| 封装方法、经验和参考资料 | Skill |
| 接入外部工具与资源 | MCP |
这张表不神圣,但比“看着差不多就塞进去”强得多。
17.9 用 Claude Code 看一个现实中的扩展点分层样本
Claude Code 的现实价值就在这里:它没有把这些东西混成一个大杂烩。
从当前仓库就能直接看到这种分层不是抽象概念,而是目录和文件层面的现实:
.claude/commands/CLAUDE.md明确把/commit-push-pr、/dedupe、/triage-issue归为自定义命令,说明命令是入口层examples/hooks/和examples/settings/这类样板说明 Hook 和策略配置不是正文附录,而是生命周期和治理层的独立挂点plugins/下面的多个模块说明 Agent / Skill / Hook 已经按执行角色和能力包拆开组织plugins/README.md里的标准结构把commands/、agents/、skills/、hooks/、.mcp.json明确拆开,说明平台不是靠约定俗成,而是靠目录契约和接口位置来维持分层.vitepress/config.ts的srcExclude又反过来说明:并不是所有扩展点都应该直接暴露成站点内容,呈现层和扩展层也有边界.github/workflows/deploy-docs.yml则说明工作流自动化属于另一套运行入口,不该和命令、Hook、Agent 混写成一层
你能明显看到:
- 命令是入口层
- Hook 是生命周期拦截层
- Agent 是执行单元层
- Skill 是知识与方法封装层
- MCP 是外部能力接入层
更重要的是,这里背后还有一条设计规则:同一种变化,应该只落在一种扩展点上。
也就是说:
- 要加显式触发入口,就进命令层
- 要加前后置拦截,就进 Hook 层
- 要加独立执行角色,就进 Agent 层
- 要加方法论与知识包,就进 Skill 层
- 要接外部工具和资源,就进 MCP 层
这不只是目录组织好看,而是系统结构清楚。
因为一旦这几层分清,很多架构问题都会跟着变简单:
- 某个需求应该放哪
- 某种风险应该在哪一层拦
- 某种能力到底是内部实现还是外部接入
- 哪些东西该复用知识,哪些东西该复用执行角色
这就是分层真正带来的价值。
17.10 扩展点设计得好不好,最终看的是系统有没有少长特殊情况
最后还是回到最硬的标准:好品味。
一个好的扩展点体系,不是名字取得多漂亮,而是它能不能减少特殊情况。
如果设计得对,系统会越来越像这样:
- 新入口就进命令层
- 新拦截就进 Hook 层
- 新执行角色就进 Agent 层
- 新方法包就进 Skill 层
- 新外部能力就进 MCP 层
如果设计得烂,系统就会变成:
- 每来一个需求都得先争论塞哪
- 每层都能做一点别层的事
- 结果每层都越来越脏
所以扩展点体系的最终价值,不是“开放”,而是“让结构长期保持清楚”。
17.11 本章小结
这一章真正想讲清的是:命令、Hook、Agent、Skill、MCP 不是一堆并列名词,而是平台里的不同能力接口。它们分别解决入口、时机、执行单元、知识封装和外部接入这五类问题。
你现在应该记住六件事:
- 平台一长扩展点,最先要治理的就是概念边界。
- 命令解决入口问题,Hook 解决时机问题。
- Agent 解决执行单元问题,Skill 解决知识封装问题。
- MCP 解决的是外部工具与资源的标准接入问题。
- 这些扩展点不能互相乱替代,否则系统结构会迅速变脏。
- 好的扩展点体系,本质上是在减少特殊情况。
下一章我们继续往下走,回到多 Agent,但这次不再讲“值不值得上”,而是讲一旦真的上了,多 Agent 之间到底该如何编排,主 Agent、子 Agent、Hook 和工具扩展又是怎么串起来的。