Skills 和 MCP 有什么区别,按上下文开销分工
Skills 和 MCP 的区别在加载时机。MCP 工具定义要占上下文,Skills 靠描述清单渐进披露,附官方文档里的 1536 字符与 1% 清单预算。

同一个需求,写个 skill 就行,还是得跑一个 MCP server?skills 和 mcp 有什么区别,答案主要落在加载时机和上下文开销上,跟谁功能更强关系不大。
MCP 管连接,Skills 管流程
MCP 官方规范把自己定义成一个开放协议:用 JSON-RPC 2.0 在 Host、Client、Server 三方之间建立有状态连接,还要做能力协商。Server 向模型侧暴露 Resources、Prompts、Tools 三类东西,Client 侧则可以提供 Sampling、Roots、Elicitation。它解决的是模型怎么合规地摸到外部系统。
Skills 是另一层。一个 skill 就是一个目录,入口 SKILL.md,YAML frontmatter 里写 description,正文写步骤,同目录可以放模板、示例和脚本。Claude Code 官方文档的原话是,skill 正文只在被用到时才加载,所以长参考材料在用到之前几乎不花 token。Anthropic 十月发布 Agent Skills 时给的四个词是可组合、可移植、按需加载、能带可执行代码,后来它被作为开放标准公开。
判断标准因此比较清楚。要拿到系统里活的数据、要带认证、要做写操作,那是连接问题,归 MCP。要固化一套你反复粘贴的流程和检查清单,那是流程问题,归 skill。
上下文开销差在加载时机
1% 和 2KB 这两个数字,解释了大部分开销差异。
Claude Code 会把所有 skill 的名字和描述做成一份清单常驻上下文,清单预算按模型上下文窗口的 1% 缩放,单条 description 与 when_to_use 合起来在清单里 截断到 1536 个字符。清单装不下时,官方文档说会从你调用得最少的 skill 开始丢描述。换句话说,一个没被触发的 skill 只花掉一行名字加一句描述。
MCP 这边的历史包袱更重。dev.to 那篇对比文章(第三方博客)吐槽的正是这点:为了几个根本用不上的工具,上百行工具定义先进了上下文。现在 Claude Code 默认开启 tool search,会话开始只加载工具名和 server instructions,工具定义推迟到需要时再取。把 ENABLE_TOOL_SEARCH 设成 auto 是阈值模式,schema 能塞进上下文窗口 10% 以内就先全量加载,超了才推迟。工具描述和 server instructions 各自截断在 2KB。
真正咬人的经常是返回值。MCP 工具输出超过 10000 token 会告警,默认上限 25000 token,要放宽得改 MAX_MCP_OUTPUT_TOKENS。
什么时候写 skill 就够了
你第三次把「发版前先跑 lint、再跑体检脚本、退出码非零就别提交」这段话粘进对话框的时候,就该写 skill 了。官方文档给的判据是两条:你在反复粘贴同一份指令或多步流程;CLAUDE.md 里某一段已经从事实长成了流程。
写的时候有几个硬约束。SKILL.md 建议控制在 500 行以内,细节挪到同目录的 reference.md、examples.md 按需读。skill 一旦被调用,渲染后的正文会作为一条消息留在上下文里直到会话结束,每一行都是重复成本。自动压缩之后 Claude Code 会把最近调用过的 skill 重新贴回来,每个保留前 5000 token,所有重贴的 skill 共享 25000 token 预算,从最近调用的开始填,一个会话里调太多,早期那些会被整个丢掉。
只想手动触发的流程,frontmatter 加 disable-model-invocation: true,它的描述就不进上下文了。
什么时候必须上 MCP
claude mcp add --transport http notion https://mcp.notion.com/mcp
这条命令做的事情 skill 做不到:让模型直接读写一个需要认证的外部系统,并拿回结构化结果。判据就一句话,你要的东西是不是活的。Issue 的当前状态、监控面板此刻的指标、数据库里的真实行数,没有协议连接就只能靠人粘贴。
能用 CLI 顶掉的就不必上 MCP。官方成本文档明确建议优先用 gh、aws、gcloud、sentry-cli 这类命令行工具,理由是它们不产生任何 per-tool 清单开销,模型直接跑命令即可。一个只包了一层 REST 的 MCP server,实际收益常常不如一条 curl。
安全那一层同样要算进来。MCP 规范写得很直白:工具行为注解这类描述在来源不可信时应当视为不可信内容,Host 必须先取得用户明确同意才能调用工具。给团队铺 MCP 之前,这条比功能列表重要。
混用时的优先级排法
---
name: release-check
description: 发版前的检查流程。用户说要发版、要提 PR 时使用。
allowed-tools: Bash(gh pr *)
---
这种形态在实际项目里最常见:skill 负责编排顺序和判据,MCP 工具负责真正取数据。dev.to 那篇文章的说法是 skill 可以教会 agent 怎么用你的 MCP 工具,两者不构成竞争关系。
排优先级可以按三步走。流程先写进 skill,它可读、可 review、能进版本库;能用 CLI 拿到的数据走 Bash,不占工具清单;只有需要认证、需要实时状态、CLI 又没覆盖的,才加一个 MCP server。
清单挤爆了就用 skillOverrides 降级。这个设置有四档:on 是名字加描述都给模型看,name-only 只给名字,user-invocable-only 对模型完全隐藏但你还能敲 /,off 全隐藏。共享仓库里别人写的 skill 不方便改 frontmatter 时,这是比较干净的办法。不同客户端的支持程度也有差别,装在哪一侧可以先对一下 Claude Code 与 Cursor 的 MCP 能力差异。
一份不打架的配置基线
三条命令就能看到自己现在的开销:/context 看各项占了多少,/mcp 看每个 server 的成本,/doctor 给出 skill 清单的上下文估算和最大贡献者。数字拿到手再动手改。
基线可以这样定。CLAUDE.md 压到 200 行以内,只放事实,流程全搬进 skill。手动触发的 skill 一律加 disable-model-invocation。MCP server 只留这个月真用过的那几个,/mcp 里把闲置的关掉。tool search 保持默认开启,但要注意它需要 Sonnet 4.5、Haiku 4.5、Opus 4.5 及之后的模型,且 ANTHROPIC_BASE_URL 指向非一方域名时会自动关闭,走第三方代理就得显式设 ENABLE_TOOL_SEARCH。
按这套跑一轮,再回头看那份 skill 清单和工具清单,通常能砍掉三分之一。
参考资料
- Skills vs MCP: How AI tools have evolved(dev.to,第三方博客) — 提出工具定义本身占上下文,以及 skill 可以教 agent 用 MCP 工具
- Model Context Protocol Specification(官方规范) — JSON-RPC 架构、Resources/Prompts/Tools 与工具安全原则
- Extend Claude with skills(Claude Code 官方文档) — frontmatter 字段、1536 字符截断、清单预算与压缩后重贴规则
- Introducing Agent Skills(Anthropic 官方公告) — Skills 的定位与跨产品可移植性
- Connect Claude Code to tools via MCP(官方文档) — tool search 默认行为、2KB 截断与输出上限