首页
/ Skills 并未杀死 MCP:Goose 中 Agent Skills 与 MCP 的能力分工与协作边界

Skills 并未杀死 MCP:Goose 中 Agent Skills 与 MCP 的能力分工与协作边界

2026-09-08 11:39:06作者:庞队千Virginia

导读:每当 AI 圈出现新概念,技术社区总喜欢宣布某个旧技术"已死"——这一次的标题党主角是 "Agent Skills 刚刚杀死了 MCP"。本文以 goose 开源项目为背景,从 MCP 的"能力层"与 Agent Skills 的"流程/知识层"入手,讲清楚两者为何是互补而非替代关系;同时结合 goose 仓库中 Skills 的文件发现机制、load_skill 工具的源码实现与 Developer MCP 扩展的真实配置,给出可落地的分层认知与配置方法。

Agent Skills 与 MCP 的分层协作示意图(文章封面图)

一、一个并不新鲜的"标题党"命题

"Skills 刚刚杀死了 MCP"——这句话听起来很大胆,也很笃定,但它是错的。

把它翻译成另一句话你就立刻明白了:说"GitHub Actions 杀死了 Bash"和它有差不多同等的准确性。Bash 至今活得很好,而且实际上正在干着真正的活。GitHub Actions 改变的是表达方式(expression),而不是执行方式(execution)——它给了我们一种更清晰、更易共享的方式来描述"我们如何构建、测试和部署",但底层跑的还是同一批 shell 命令。YAML 组织的是执行,不是取代执行。

这正是 Agent Skills 与 MCP 之间的关系。一旦你从这个视角看问题,"Skills 杀死 MCP"的说法自己就塌了。

在继续阅读之前,建议先对照 goose 官方对这两项能力的完整指南:Agent Skills 使用指南Developer MCP Server(Developer 扩展)

二、MCP 是"能力层":让 Agent 真正动手

MCP 承载的是能力(capability)。正是它让 AI Agent 真正"做成事",而不只是"讨论事"。当一个 Agent 能够执行 shell 命令、编辑文件、调用 API、查询数据库、读取磁盘、存取记忆、拉取实时数据时,背后基本都是 MCP 在工作。

MCP Server 是代码。它们以服务形式运行,对外暴露可调用的工具(tools)。只要 Agent 想以任何有意义的方式与现实世界交互,几乎必然有 MCP 参与。

举几个具体例子:Agent 需要查询 GitHub API、发送一条 Slack 消息、拉取生产环境指标——这些都要求真实的集成、真实的权限和真实的执行。光靠"指令"本身做不到这些。指令无法凭空获得网络访问权,也无法替你完成一次带认证的 API 调用。

在 goose 仓库中,这一点有非常清晰的落地形态:Developer 扩展(即内置的 Developer MCP Server)向 Agent 提供了 shellwriteedittreeread_image 等真实执行工具(见 documentation/docs/mcp/developer-mcp.md)。其中:

工具 作用 风险等级
shell 执行 shell 命令(跑测试、装包、git 操作) 高:可以以你的用户权限运行任意系统命令
write 创建或覆盖文件 高:可以修改任何可访问的文件
edit 精确替换文件中的文本 高:可以修改任何可访问的文件
tree 列出目录树与行数,帮助理解项目结构 低:只读
read_image 读取本地或远程图片供模型查看 低:只读

这正是"MCP 提供 runner"的仓库证据:真正的读写执行,落在这些由 MCP Server 暴露的工具上。

三、Agent Skills 是"流程与知识层":教 Agent 把事情做对

Skills 生活在另一个层级。Skills 关乎流程与知识(process and knowledge)。它们是 markdown 文件,编码了"工作应该怎么做":团队约定、工作流、领域经验。一个 Skill 可以描述部署应该如何进行、代码评审如何处理、事故如何分级响应——这是把制度性知识显性化(institutional knowledge made explicit)

goose 官方对 Skills 的定义是:"可复用的指令与资源集合,用于教会 goose 如何执行特定任务。一个 Skill 可以简单到一份清单,也可以复杂到一份包含领域专长的详细工作流,并且可以附带脚本或模板等支撑文件。"(见 using-skills.md)。典型使用场景包括部署流程、代码评审清单、API 集成指南。

原博客中给出了一个教 Agent 接入 Square 账户的示例 Skill,它完整展示了一个 Skill 的真实结构(YAML frontmatter + Markdown 正文):

---
name: square-integration
description: How to integrate with our Square account
---

# Square Integration

## Authentication
- Test key: Use `SQUARE_TEST_KEY` from `.env.test`
- Production key: In 1Password under "Square Production"

## Common Operations

### Create a customer
const customer = await squareup.customers.create({
  email: user.email,
  metadata: { userId: user.id }
});


### Handle webhooks
Always verify webhook signatures. See `src/webhooks/square.js` for our handler pattern.

## Error Handling
- `card_declined`: Show user-friendly message, suggest different payment method
- `rate_limit`: Implement exponential backoff
- `invalid_request`: Log full error, likely a bug in our code

注意上例中的 frontmatter 只有两个必填字段:namedescription。goose 源码对这两个字段做了严格校验与解析——在 crates/goose/src/skills/mod.rs 中定义了 SkillFrontmatter 结构:name 可选(缺失时跳过该 Skill 并告警)、description 必填、额外的自由元数据放入 metadata 嵌套映射(遵循 agentskills.io 规范,避免与保留字段冲突)。而 validate_skill_namemod.rs)进一步约束了命名规则:

  • 名称不能为空;
  • 长度不超过 64 个字符;
  • 只允许小写字母、数字与连字符 -
  • 不能以连字符开头或结尾。

违反以上任何一条,该 Skill 都会在发现阶段被跳过或直接报错——这些约束从侧面说明:Skill 的 name 是运行时被精确索引与调用的标识符,而不只是给人看的标题。

四、为什么 Skill "看起来会执行"却不会?

Skills 可以包含看起来可执行的东西——这也是大量混淆的来源。一个 Skill 可能展示代码片段、引用脚本、甚至打包模板或脚本文件,这很容易让人觉得"是 Skill 自己在干活"。

但事实并非如此。

即使一个 Skill 文件夹里带着可运行的脚本,执行它们的也不是 Skill 本身。Agent 是靠调用"别处提供的工具"(例如通过 Developer MCP Server 暴露的 shell 工具)来执行这些文件的。Skill 打包的是指导与素材(guidance and assets),而运行代码、访问网络、修改系统的能力来自工具——这些工具通常正是通过 MCP 暴露的。

goose 中的一条关键证据:Skill 目录与支撑文件如何被"执行"

在 goose 中,Skills 功能由内置的 Skills 平台扩展提供(默认启用,扩展名 skills,常量定义见 crates/goose/src/skills/client.rs)。深挖实现会发现一个很有意思的事实:Skills 扩展本身也是以 MCP Client 的方式实现的——它向 Agent 暴露了一个名为 load_skill 的工具(工具定义与参数 schema 见 client.rs),参数只有两个:

  • name:要加载的 Skill 名称;支持用 "skill-name/路径" 的形式加载某个支撑文件;
  • args:加载 Skill 时可选的参数(会被注入正文中的 $ARGUMENTS 占位符,相关渲染逻辑见 mod.rs)。

也就是说:Skill 的正文内容通过 load_skill 注入 Agent 的上下文,让模型"学会怎么做";而 Skill 内引用的脚本、模板等支撑文件,要么同样通过 load_skill(name: "skill-name/relative/path") 读取内容,要么依赖 Developer 扩展的文件工具去读写。用源码注释里的话说:"shell 工具运行在会话工作目录中,因此相对路径会从 Skill 目录解析;如果要运行支撑脚本,请使用解析后的完整路径或先 cd 进 Skill 目录"(见 mod.rs 的 supporting files 拼接逻辑)。

这在代码层面再次印证了博客的核心论断:Skill 只负责"把指导送进上下文",真正的跑命令、改文件永远由工具完成。

五、GitHub Actions 类比:YAML 不执行任何东西

让我们回到 GitHub Actions 的类比,把话讲透:

一个 workflow 文件可以引用脚本、命令和可复用的 action,看上去威力十足。但 YAML 本身不执行任何东西——执行它的是 runner。没有 runner,workflow 只是一份计划。

对应到 Agent 世界:

  • Skills 描述工作流,MCP 提供 runner。
  • Skills 没有 MCP:只是一份写得不错的说明书。
  • MCP 没有 Skills:是没有任何指引的"裸能力"。
  • 一个告诉 Agent 应该发生什么;另一个让 任何事情都有可能发生

能力与指引必须双全

把两者放在一起,生态才算完整。举一个 goose 用户每天都在经历的对比:

  • 要让 Agent 在新会话中自主选择正确方法:需要 Skill 提供的名称与描述被自动注入系统指令。goose 在每次会话启动时,会把发现的 Skill 名称与描述加入指令(见 using-skills.mdclient.rs 附近的 get_instructions 逻辑)。当你的请求明确匹配某个 Skill 的用途、或你显式要求"用 code-review skill 评审这个 PR"时,goose 才会把完整指令加载进来。
  • 要让 Agent 真正把这些步骤跑完:需要 Developer MCP 提供的 shellwriteedit 工具来安装依赖、创建文件、执行测试。

只给 Agent 一把刀(MCP 工具)而没有任何操作手册,它会乱砍;只给手册(Skill)而没有任何工具,它什么都做不了。

六、在 goose 中实际使用 Skills:位置、命令与发现机制

存放位置与发现优先级

goose 会从多个位置递归发现 SKILL.md。推荐位置有三类:

  1. ~/.agents/skills/ —— 全局 Skill,所有会话可用;
  2. .agents/skills/ —— 项目级 Skill,仅当前项目可见;
  3. ~/.agents/plugins/<plugin-name>/ —— 由已安装插件提供的 Skill。

同时为向后兼容,goose 也会扫描 .goose/skills/.claude/skills/~/.claude/skills/ 以及平台相关的配置目录,但官方推荐统一使用 agents/skills/ 标准。

源码 mod.rs 中的 all_skill_dirs_with_config 精确描述了发现顺序与优先级:项目目录在前(.agents/skills.goose/skills.claude/skills → 项目插件 Skill 目录),全局目录在后(~/.agents/skills → 配置目录 skills → ~/.claude/skills → 用户插件 Skill 目录)。递归遍历时会跳过 .git/.hg/.svn 等目录,并在遇到同名 Skill 时只保留优先级更高(先被扫描到)的那一个——测试用例 project_plugin_skill_precedes_global_skill_with_same_name 对此有专门验证。实际目录结构如下:

~/.agents/skills/
└── code-review/
    └── SKILL.md

会话内的操作命令

你可以直接向 goose 询问有哪些 Skill 可用,也可以运行 goose skills list,或在 CLI 中用 /skills 命令一次性按名称加载多个 Skill:

/skills code-review edge-case-finder

需要支持文件的 Skill(例如附带脚本、模板的 api-setup)建议把素材放进 Skill 目录中与 SKILL.md 并列:

~/.agents/skills/
└── api-setup/
    ├── SKILL.md
    ├── setup.sh
    └── templates/
        └── config.template.json

内置 Skill 示例:web-search

goose 自带一个无需安装即可用的内置 Skill web-search(内容见 crates/goose/src/skills/builtins/web_search.md)。注意它的实现方式非常能说明问题:这个 Skill 描述的是"用哪些命令行去搜索",而真正联网抓取靠的是 shell 工具与 uvx/curl 这些程序在运行。它内部按优先级选择后端:

  • 默认 DuckDuckGo:uvx ddgs text -q "your query here" -m 5(无需 API key,仅需安装 uv);
  • 设置 TAVILY_API_KEY 时改用 Tavily(结果更丰富);
  • 设置 SEARXNG_URL 时改用自托管 SearXNG。

它甚至写明了"若返回登录墙或 CAPTCHA,报告 URL 并停止,不要尝试绕过"这样的使用规则——规则属于 Skill,执行仍属于工具。这就是"流程层"与"能力层"同框工作的最小示例。

七、为什么"两者并存"恰恰是生态成熟的表现

如果非要说 Skills 取代了 MCP,那逻辑就变成了"说明书取代了执行引擎",这本身就不成立。反过来说:

  • MCP 给 Agent 以能力(abilities)。
  • Skills 教 Agent 如何用好这些能力(how to use them well)。
  • Bash 仍在运行命令;GitHub Actions 仍在定义工作流。同一套系统、不同的层级,没有谁被谋杀。

更进一步,两者的并存是一个积极的信号:它意味着 Agent 生态正在走向成熟——我们不再争论"Agent 该有工具还是该有指令",而是在构建默认"两者都需要"的系统。工具负责让"做"成为可能,指令负责让"做对"成为大概率事件。

这正是进步,而不是替代。

给读者的分层实践建议

  1. 凡是涉及真实副作用的操作(联网、写文件、执行命令、访问外部系统),优先以 MCP Server 的形式提供工具能力,参考 Developer MCP Server 的配置方式与权限控制;
  2. 凡是涉及"怎么做的知识"(部署流程、评审规范、事故响应、API 集成手册),写成带 name/description frontmatter 的 SKILL.md,放入 ~/.agents/skills/ 或项目 .agents/skills/,参考 using-skills.md 中的部署工作流、测试策略等完整范例;
  3. Skill 需要引用脚本或模板时,把文件放进 Skill 目录,正文用相对路径指引,Agent 会通过 load_skill(name: "skill-name/文件路径") 或 Developer 扩展的文件工具访问它们;
  4. 命名遵守 goose 约束:小写字母、数字与连字符,不超过 64 字符,且不以连字符开头结尾,否则 Skill 会被跳过。

把握好"Skills 描述工作流、MCP 提供 runner"这条分界线,你就不会再被"X 杀死 Y"的标题党带走节奏——你会更关心如何让两者在自己的工程里各司其职。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
898
5.82 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
921
1.84 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.8 K
1.02 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
531
596
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.02 K
519
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.36 K
1.46 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
391