搞懂 AI Agent 中 Skill 和 MCP 的区别:用一个天气查询例子彻底理解

最近在使用 OpenCode、Browser Control 等 AI Agent 工具时,经常会同时看到几个概念:

  • Skill
  • MCP
  • MCP Server
  • Tool
  • Agent

刚开始接触的时候,很容易把 Skill 和 MCP 混为一谈。

例如安装 Browser Control 时,既需要安装 Skill,又需要配置 MCP:

Browser Control
├── Skill
├── MCP
├── Driver
└── Chrome Extension

那么问题来了:

Skill 和 MCP 到底有什么区别?为什么一个能力需要同时存在 Skill 和 MCP?

本文不从复杂的 MCP 协议规范讲起,而是自己做一个非常简单的“天气查询”例子,通过这个例子理解 Skill 和 MCP 的关系。


一、先给结论

如果只记住一句话,可以记住:

MCP 提供能力,Skill 告诉 AI 如何使用这个能力。

或者换一种更直观的说法:

MCP   = 工具
Skill = 工具使用说明
Agent = 使用工具的人

例如我们做一个天气查询能力。

MCP 提供:

get_weather(city)

Skill 告诉 AI:

用户询问天气时,
应该调用 get_weather。
不要自己猜测天气。
获取结果以后再回答用户。

最终关系:

                    AI Agent
                       │
             ┌─────────┴─────────┐
             │                   │
             ▼                   ▼
          Skill                MCP
             │                   │
       告诉 AI 怎么用        提供实际工具
             │                   │
             └─────────┬─────────┘
                       ▼
                  外部系统

下面我们自己实现一遍。


二、先认识 MCP

MCP 的全称是:

Model Context Protocol

它可以理解成一个让 AI Agent 使用外部工具和数据的标准化协议。

例如我们有一个天气服务:

天气服务
    │
    ├── 查询天气
    ├── 查询未来天气
    └── 查询空气质量

如果直接给每一个 AI Agent 单独开发接口:

OpenCode → 天气 API
Claude → 天气 API
自己的 Agent → 天气 API

每个 Agent 都需要单独适配。

MCP 的目标之一就是提供一个统一的工具接口:

              MCP
               │
       ┌───────┼────────┐
       ▼       ▼        ▼
    OpenCode  Claude   自定义 Agent
       │       │        │
       └───────┼────────┘
               ▼
          Weather MCP
               │
               ▼
           天气服务

所以 MCP 更关注:

“AI 有什么工具可以调用?”


三、创建一个最简单的 Weather MCP

下面做一个非常简化的 MCP Server。

创建目录:

mkdir ~/weather-demo
cd ~/weather-demo

创建:

weather-mcp.py

写入:

from mcp.server.fastmcp import FastMCP

mcp = FastMCP("weather-demo")


@mcp.tool()
def get_weather(city: str) -> str:
    """查询指定城市的天气。"""
    data = {
        "北京": "晴,25°C",
        "上海": "多云,27°C",
        "广州": "小雨,30°C",
    }

    return data.get(city, f"暂时没有 {city} 的天气数据")


if __name__ == "__main__":
    mcp.run()

这里最重要的是:

@mcp.tool()
def get_weather(city: str) -> str:

这段代码向 MCP 暴露了一个 Tool:

get_weather(city)

因此 MCP Server 可以告诉 Agent:

我有一个工具:

名称:
get_weather

参数:
city: string

功能:
查询指定城市的天气

四、MCP 到底提供了什么?

假设 Agent 连接了这个 MCP Server。

它就能够发现:

Tools
└── get_weather
      └── city: string

然后 Agent 可以调用:

get_weather("北京")

MCP Server 返回:

晴,25°C

整个过程:

AI Agent
   │
   │ get_weather("北京")
   ▼
Weather MCP
   │
   ▼
get_weather()
   │
   ▼
"晴,25°C"
   │
   ▼
AI Agent

注意一个非常重要的问题:

MCP 并没有告诉 AI 什么时候应该调用 get_weather。

它只是提供了这个工具。


五、这时候 Skill 出场了

现在我们创建一个 Skill。

创建目录:

mkdir -p ~/.config/opencode/skills/weather

创建:

~/.config/opencode/skills/weather/SKILL.md

内容:

---
name: weather
description: 查询天气时使用 weather MCP
---

# Weather Skill

当用户询问天气时:

1. 使用 `weather-demo` MCP 的 `get_weather` 工具。
2. 不要自己猜测天气。
3. 获取工具结果后,告诉用户城市和天气。
4. 如果 MCP 没有该城市的数据,明确告诉用户暂时无法查询。

## 示例

用户:

北京今天多少度?

操作:

调用:

get_weather("北京")

然后根据工具返回的结果回答用户。

这就是一个 Skill。

注意:

Skill 里面没有:

Python
HTTP API
数据库
天气数据
MCP Tool 实现

它本质上是一份:

给 AI Agent 阅读的使用说明。


六、现在 Skill 和 MCP 就联系起来了

到这里,我们有两个东西:

Weather Skill

告诉 AI:

什么时候使用天气能力?
怎么使用?
有什么注意事项?

以及:

Weather MCP

提供:

get_weather(city)

它们的关系:

                 AI Agent
                    │
          ┌─────────┴─────────┐
          │                   │
          ▼                   ▼
     Weather Skill       Weather MCP
          │                   │
          │                   │
     “应该怎么用”          “实际能做什么”
          │                   │
          └─────────┬─────────┘
                    ▼
              get_weather()

这就是 Skill 和 MCP 最核心的关系。


七、用户发出一个请求

现在用户对 AI 说:

北京今天多少度?

AI Agent 首先需要理解用户的意图。

Skill 告诉它:

这是一个天气问题。

应该使用:

get_weather(city)

然后 MCP 告诉它:

我有:

get_weather(city)

于是 AI 调用:

get_weather("北京")

MCP 返回:

晴,25°C

最后 AI 回答:

北京今天晴,25°C。

完整流程:

                         用户
                           │
                           ▼
                  “北京今天多少度?”
                           │
                           ▼
                       AI Agent
                           │
                ┌──────────┴──────────┐
                │                     │
                ▼                     ▼
             Skill                   MCP
                │                     │
       “这是天气问题,            “我提供
        应该调用天气工具”          get_weather”
                │                     │
                └──────────┬──────────┘
                           │
                           ▼
                 get_weather("北京")
                           │
                           ▼
                      MCP Server
                           │
                           ▼
                      “晴,25°C”
                           │
                           ▼
                       AI Agent
                           │
                           ▼
                  “北京今天晴,25°C”

八、如果没有 Skill,会发生什么?

这是理解 Skill 作用的一个好方法。

假设我们只有 MCP:

AI Agent
   │
   ▼
Weather MCP
   │
   └── get_weather()

AI 仍然能够发现:

get_weather(city)

所以它有能力查询天气。

但是它不知道项目作者希望它:

什么时候使用?
是否应该优先使用?
如何验证结果?
遇到错误怎么办?
应该怎么组织操作?

当然,强大的 LLM 很可能自己就能推断出来。

例如它看到:

get_weather(city)

大概率会理解:

“用户问天气的时候,我应该调用这个工具。”

但是这属于模型自己的推理,而不是明确的工作规范。


九、有了 Skill 以后

Skill 可以明确告诉 Agent:

天气问题
    ↓
必须调用 get_weather
    ↓
不要猜测
    ↓
拿到工具结果
    ↓
再回答用户

如果以后规则变复杂,例如:

用户问“今天北京天气”
    ↓
get_weather()

用户问“北京未来三天天气”
    ↓
get_forecast()

用户问“北京空气质量”
    ↓
get_air_quality()

用户问天气但没有城市
    ↓
先询问城市

那么 Skill 就非常有价值了。

MCP 负责提供:

get_weather()
get_forecast()
get_air_quality()

Skill 负责告诉 Agent:

什么情况下调用哪个工具。

十、所以 MCP 和 Skill 关注的问题不同

可以用下面这张表理解:

问题MCPSkill
有什么能力?✅❌
提供 Tool✅❌
定义 Tool 参数✅❌
实际执行代码✅❌
连接外部服务✅❌
告诉 AI 什么时候使用❌✅
告诉 AI 怎么使用❌✅
描述工作流程❌✅
提供最佳实践❌✅
约束 Agent 行为❌✅

因此:

MCP = Capability
Skill = Instructions

十一、Tool 又是什么?

这里还需要区分第三个概念:

Tool

例如:

@mcp.tool()
def get_weather(city: str):

这里的:

get_weather

就是一个 Tool。

所以关系可以进一步画成:

Skill
  │
  │ 告诉 Agent 如何使用
  ▼
Agent
  │
  │ 调用
  ▼
MCP
  │
  │ 暴露
  ▼
Tool
  │
  │ 执行
  ▼
外部系统

更加准确地说:

MCP 是工具与 Agent 之间的标准通信协议,Tool 是 MCP Server 暴露出来的具体能力,而 Skill 是指导 Agent 使用这些能力的说明。


十二、再联系 Browser Control

现在再回头看 Browser Control,就非常容易理解了。

之前我们安装 Browser Control 时同时接触到了:

browser-control
browser-control-mcp
Browser Control Skill
Chrome Extension
Relay

它们并不是重复的东西。

可以这样理解:

                         OpenCode
                            │
                 ┌──────────┴──────────┐
                 │                     │
                 ▼                     ▼
          Browser Control          Browser Control
             Skill                    MCP
                 │                     │
                 │                     │
        “如何操作浏览器”        “提供浏览器工具”
                 │                     │
                 └──────────┬──────────┘
                            ▼
                    Browser Control
                            │
                            ▼
                         Relay
                            │
                            ▼
                    Chrome Extension
                            │
                            ▼
                          Chrome

例如 MCP 提供:

browser_snapshot
browser_click
browser_type
browser_navigate
browser_tabs

而 Skill 可以告诉 AI:

操作网页时:

1. 先获取页面结构
2. 找到目标元素
3. 执行操作
4. 检查操作结果
5. 不要猜测页面元素

所以:

MCP:
“你可以点击按钮。”

Skill:
“遇到这种情况,你应该先找到按钮,再点击,
点击以后检查页面是否发生预期变化。”

两者结合起来,Agent 才不仅拥有浏览器能力,而且知道如何更可靠地使用这个能力。


十三、一个非常重要的认识:Skill 本身通常不能“执行”

这是很多初学者容易产生的误解。

例如 Skill 里面写:

调用 get_weather("北京")

它并不会真的执行:

get_weather()

因为 Skill 本身没有这个工具。

它只是告诉 Agent:

你应该这么做。

真正执行:

get_weather("北京")

的是 MCP Tool。

所以:

Skill
  ↓
告诉 Agent “调用 get_weather”
  ↓
Agent 决定调用
  ↓
MCP
  ↓
执行 Tool

十四、一个更形象的类比

可以把整个系统想象成一家餐厅。

MCP = 厨房

厨房里面有:

炒菜
煮面
做咖啡
做甜点

它真正具备生产能力。


Tool = 厨房里的具体设备/工位

例如:

炒菜 → 炒锅
咖啡 → 咖啡机
甜点 → 烤箱

这些是具体能力。


Skill = 厨师手册

告诉厨师:

做牛排:
    先煎
    再烤
    最后静置

做咖啡:
    根据客人的要求选择不同参数

它告诉你:

怎么组合和使用现有能力。


Agent = 厨师

用户说:

我要一杯咖啡。

厨师根据 Skill:

这是咖啡需求
    ↓
按照咖啡流程
    ↓
使用咖啡机

厨房提供实际能力。

所以:

用户
 ↓
Agent
 ↓
Skill:告诉怎么做
 ↓
MCP:提供工具
 ↓
Tool:实际执行

这个类比基本可以覆盖大多数 Agent + Skill + MCP 的使用场景。


十五、最终把四个概念放在一起

到这里可以建立一个完整的认知模型:

┌────────────────────────────────────┐
│              AI Agent              │
│                                    │
│       LLM + Planning + Reasoning   │
└───────────────┬────────────────────┘
                │
        ┌───────┴────────┐
        │                │
        ▼                ▼
     Skill              MCP
        │                │
        │                │
   使用说明/流程       工具协议
        │                │
        │                ▼
        │              Tools
        │                │
        │                ▼
        │           外部系统/API
        │
        └──────→ 指导 Agent 如何
                 使用这些能力

一句话总结:

LLM
负责思考

Agent
负责执行任务循环

Skill
负责告诉 Agent 怎么做

MCP
负责提供标准化工具接口

Tool
负责执行具体操作

外部系统
负责真正的数据和业务能力

十六、为什么现代 AI Agent 经常同时使用 Skill + MCP?

因为两者解决的是不同的问题。

假设没有 MCP:

Skill
 ↓
“请查询天气”
 ↓
但是没有天气工具

AI 知道应该做什么,却没有执行能力。

假设没有 Skill:

MCP
 ↓
get_weather()
 ↓
AI 可以调用

AI 有工具,但是复杂任务下需要自己推断最佳工作流程。

两者结合:

Skill
  ↓
告诉 Agent 如何完成任务
  ↓
MCP
  ↓
提供完成任务所需的工具
  ↓
Tool
  ↓
真正执行

这就是现代 Agent 架构中经常看到:

Agent
 + Skills
 + MCP
 + Tools

的原因。


十七、总结

如果你第一次接触 Skill 和 MCP,不需要一开始就研究 MCP 协议的所有细节。

先记住下面这四句话:

Skill 告诉 AI 怎么做。

MCP 告诉 AI 有什么工具可以用。

Tool 是具体可以执行的能力。

Agent/LLM 决定什么时候调用这些能力。

以本文的天气例子来说:

用户:
北京今天多少度?

        ↓

Skill:
这是天气问题,
应该使用天气工具。

        ↓

MCP:
我提供 get_weather(city)。

        ↓

Agent:
调用 get_weather("北京")。

        ↓

Tool:
返回“晴,25°C”。

        ↓

Agent:
告诉用户北京今天晴,25°C。

而到了 Browser Control:

Skill:
告诉 AI 如何可靠地操作浏览器

MCP:
提供浏览器操作工具

Tool:
click / type / navigate / snapshot ...

Browser Control:
真正执行浏览器控制

Chrome Extension:
连接现有 Chrome

这样再回头看 OpenCode 的 Browser Control,就不会再觉得:

“为什么一个 Browser Control 要同时安装 Skill 和 MCP?”

因为它们本来就是两个不同层次的东西:

一个负责“怎么用”,一个负责“提供能力”。