MCP 和 Agent Skills定义解析(AI 视频下载总结器实战)

MCP 和 Agent Skills 都能让 AI 调用外部能力,二者边界到底怎么划?产品逻辑不复杂:贴一个视频链接进去,程序先下载字幕,再交给大模型提炼要点,最后生成思维导图。难的是这些能力分散在多个服务里,我还想让 Claude 和 Cursor 都能直接调用。一开始我给每个助手各写一套自定义函数,结果换一个客户端就要重写一遍对接,维护成本直线上升,才决定把两套机制分开用:MCP 当”工具总线”,解决连接问题;Agent Skills 当”业务 SOP”,解决流程问题。下面把两者的本质、原理和我在项目里的落地取舍一次讲清楚。

一、什么是 MCP

MCP(Model Context Protocol)是 Anthropic 提出的”AI 工具调用标准化协议”,让 LLM 能与外部工具/数据源交互。我最初没用它,直接给大模型写函数调用定义,等接入第二个、第三个外部服务时才发现问题:每个服务都要单独维护一份调用规范,客户端一换全部失效。MCP 的价值在于把”接口协议”从具体的客户端和服务里抽出来,相当于给 AI 工具装了一个统一插口,接入新服务时不用再为每个助手单独适配。

┌─────────────────┐
│   LLM (Claude)   │
└─────────────────┘
        ↓ MCP 协议
┌─────────────────┐
│  MCP Server 1    │  ← 工具:yt-dlp 封装
│  MCP Server 2    │  ← 工具:DeepSeek 调用
│  MCP Server 3    │  ← 工具:Stripe API
└─────────────────┘

每个 MCP Server 暴露”工具(tools)”给 LLM,LLM 通过 MCP 协议发现并调用。这样任何支持 MCP 的客户端都能连上同一个服务端,下载、字幕、总结这些能力只写一份,换界面不用改核心逻辑。我接完第一个 MCP Server 后,第二个服务的接入时间从几天缩到几小时,这才是它真正省事的地方。

二、什么是 Agent Skills

Agent Skills 是”预定义的专家能力包”,让 Agent 快速具备某领域专长。它和 MCP 解决的是完全不同的问题:MCP 回答”我能连上什么”,Skills 回答”这件事按什么流程做”。我在给团队配开发助手时,把下载器的处理步骤、错误处理约定、代码规范都写进一个 Skill,助手加载后就按项目惯例工作,而不是每次凭训练数据里的通用经验瞎猜。

Agent + Skill 1 = "前端专家"
Agent + Skill 2 = "后端专家"
Agent + Skill 3 = "DevOps 专家"

Skills 是”指令集 + 工具集 + 知识库”的组合,Agent 加载 Skill 后就具备该能力。我踩过的坑是把 Skill 当 MCP 用,把工具调用细节也塞进 Skill 描述里,结果助手要么不会主动调工具,要么描述太长占上下文。后来才明白,工具接入交给 MCP,Skills 只负责把流程和标准说清楚,两者分开写才不乱。

三、MCP vs Skills 对比

选型的时候我对着这张表纠结了很久,最后定下的原则是:涉及外部系统接入走 MCP,涉及领域流程与项目惯例走 Skills。下面从七个维度对比两者差异。

维度 MCP Agent Skills
本质 工具调用协议 能力扩展包
提供方 协议 + Server 指令 + 知识 + 工具
触发 LLM 决定调用 显式/自动加载
协议 JSON-RPC over stdio/HTTP 纯 Prompt + 文件
跨平台 任何 LLM/工具 取决于 Agent 实现
状态 有状态(长连接) 通常无状态
适用 工具集成 领域专长

对比下来,差异落在”连接”和”流程”这两个词上:MCP 关心连接稳定与协议统一,Skills 关心流程标准与知识沉淀,两者不在同一层,可以叠加使用。项目里常见的组合是 MCP 提供工具,Skills 教 Agent 怎么组合这些工具完成任务。

四、MCP 的工作原理

1. MCP Server

MCP 的服务端就是一段普通程序,通过 stdio 或 HTTP 跑起来。下面这段是我总结器里 MCP Server 的核心代码,声明了两个工具:一个下载并总结视频,一个生成思维导图。

# mcp_server.py
from mcp.server import Server, stdio

app = Server("video-summarizer")

@app.list_tools()
async def list_tools():
    return [
        {
            "name": "summarize_video",
            "description": "总结视频字幕",
            "inputSchema": {
                "type": "object",
                "properties": {
                    "url": {"type": "string"},
                    "language": {"type": "string", "default": "zh"}
                },
                "required": ["url"]
            }
        },
        {
            "name": "generate_mindmap",
            "description": "生成思维导图",
            "inputSchema": {
                "type": "object",
                "properties": {
                    "summary": {"type": "string"}
                },
                "required": ["summary"]
            }
        }
    ]

@app.call_tool()
async def call_tool(name, arguments):
    if name == "summarize_video":
        info = await downloader.get_info(arguments["url"])
        summary = await ai_service.summarize(info.subtitle)
        return {"content": [{"type": "text", "text": summary}]}
    
    elif name == "generate_mindmap":
        mindmap = await ai_service.generate_mindmap(arguments["summary"])
        return {"content": [{"type": "text", "text": mindmap}]}

这段最容易出错的是 inputSchema 里的 required 字段,漏写会让 LLM 自己猜参数,调用时反复报缺参。我第一次就把 url 的 required 写漏了,助手调工具十次里三次失败。把 schema 写完整后,调用成功率明显提升,这个细节值得一开始就注意。

2. LLM 调用 MCP

客户端这边不用手写每个工具的调用逻辑,服务端启动后工具定义会自动注入。下面这个示例是 Claude 客户端的写法,模型收到用户指令后自行决定调哪个工具、传什么参数。

# 客户端(Claude/Cursor)
import anthropic

client = anthropic.Anthropic()

response = client.messages.create(
    model="claude-3-5-sonnet-20241022",
    tools=[
        # MCP server 自动注入的工具定义
    ],
    messages=[
        {
            "role": "user",
            "content": "总结这个视频 https://..."
        }
    ]
)

LLM 看到工具定义后,决定调用哪个、传什么参数。实际跑下来,模型对”描述清晰、参数明确”的工具判断更准,描述含糊的工具常常被忽略。所以工具描述值得多花点字数,这直接影响调用准确率。

五、Agent Skills 的工作原理

1. Skill 结构

Skills 本质是项目里的几个文件,加载成本比 MCP 低得多。我按照下面的目录组织,把说明、脚本、示例分开,改一处不影响其他部分。

skills/
├── video-downloader/
│   ├── SKILL.md          # Skill 描述
│   ├── instructions.md   # 详细指令
│   ├── scripts/          # 辅助脚本
│   └── examples/         # 示例

2. SKILL.md 示例

SKILL.md 是 Skill 的入口,先写清楚能干什么、按什么流程做,再给出代码样例和约束。

# Video Downloader Skill

## 能力
- 多平台视频信息获取
- 视频/音频/字幕下载
- 元数据提取

## 工作流
1. 接收 URL
2. 识别平台
3. 调用对应下载器
4. 返回元信息

## 代码示例
```python
from app.services.downloader import VideoDownloader
downloader = VideoDownloader()
info = await downloader.get_info(url)

约束

  • 30s 超时
  • 失败重试 2 次
  • 不下载付费内容

约束部分很重要。我把"不下载付费内容""失败重试 2 次"写进去后,助手遇到异常不再盲目重试,行为稳定了不少。如果漏掉约束,模型会按自己的理解处理边界情况,结果不可控。

### 3. 加载 Skill

加载 Skill 就是把它读进上下文,我封装了一个 VideoAgent 类,启动时把 Skill 的指令拼进提示词。

```python
# Agent 启动时加载 Skill
class VideoAgent:
    def __init__(self):
        self.skill = self.load_skill('video-downloader')
    
    async def run(self, url: str):
        # Skill 提供指令 + 工具
        prompt = f"""
        {self.skill.instructions}
        
        用户任务:总结视频 {url}
        """
        return await llm.generate(prompt)

这段的注意点是 Skill 不要全量塞进上下文,指令文件越大越占 token。我后来改成按任务只加载相关 Skill,上下文占用降了不少,长会话里明显更从容。

六、平台对 MCP 的使用

平台用 MCP 把核心功能暴露给 Claude/Cursor,让开发助手在聊天里直接操作业务能力,不用来回切工具。

1. MCP Server 工具列表

我把总结器的五个核心能力统一成工具暴露出去,下载、总结、导图、问答、搜索各一个,名字一眼能看出用途。

TOOLS = [
    {
        "name": "get_video_info",
        "description": "获取视频元信息(标题、时长、缩略图)"
    },
    {
        "name": "summarize_video",
        "description": "AI 总结视频"
    },
    {
        "name": "generate_mindmap",
        "description": "生成思维导图"
    },
    {
        "name": "answer_question",
        "description": "基于视频内容回答用户问题"
    },
    {
        "name": "search_videos",
        "description": "搜索用户的视频历史"
    }
]

工具命名保持”动词 + 对象”的模式,模型识别起来最快。我之前起过 video_stuff 这种含糊名字,助手根本不知道什么时候该用它,改成 get/summarize/generate 开头后,命中率明显上来了。

2. Cursor 中使用

Cursor 通过 .cursor/mcp.json 发现服务端,配好就能在聊天里直接用。

{
    "mcpServers": {
        "video-summarizer": {
            "command": "python",
            "args": ["-m", "app.mcp_server"]
        }
    }
}

Cursor 自动发现 MCP server,用户在聊天中就能用:

总结 https://www.youtube.com/watch?v=xxx

这里有个容易忽略的细节:json 里的 command 要指向实际可执行的入口。我第一次配成模块路径却漏了 -m,服务端一直起不来,报错也看不太懂;改成 python -m app.mcp_server 后一次通过,排错花了不少时间。

七、平台对 Agent Skills 的使用

平台写代码时加载技能,让助手一进来就懂项目的规范和惯例:

skills/
├── backend-dev/
│   ├── SKILL.md
│   └── instructions.md
├── frontend-dev/
├── ai-prompt/
└── video-downloader/

Skill 示例

下面这个 Skill 定义的是”修改下载器”这件事的流程,从读代码到写测试都约定好,避免每次改动靠人肉叮嘱。

# video-downloader Skill

## 适用场景
- 添加新平台支持
- 修改下载器逻辑
- 修复下载 bug

## 工作流
1. 阅读现有 downloader.py
2. 添加新平台:
   - URL 识别规则
   - 平台特定配置(UA/Referer)
   - 错误处理
3. 写测试
4. 验证成功下载

## 代码风格
- 异步函数
- 异常用具体类型
- 日志用结构化
- 不要修改 base 类

主 Agent 加载此 Skill 后,就能”以视频下载器专家”的视角工作。我的实际体会是,加载 Skill 后助手写出的代码风格统一多了,提交的改动也更能直接合并,省掉了反复 review 改风格的环节。

八、什么场景用 MCP

适合

  • AI 编程助手(Cursor/Claude Code)调用工具;
  • LLM 与外部数据源对接;
  • 跨平台工具标准化。

不适合

  • 一次性脚本(直接调函数);
  • 高频内部调用(协议开销);
  • 实时性要求极高(毫秒级)。

选 MCP 前先问一句:这个能力要不要跨客户端复用。只在单个项目里用一次的脚本,直接调函数更省事。我早期为了图整齐,把内部函数也包成 MCP,结果协议开销让每次调用多出几百毫秒,得不偿失,后来才把这一层拆掉。

九、什么场景用 Skills

适合

  • 领域专长(”我是视频下载专家”);
  • 工作流模板(”按这个流程开发”);
  • 知识沉淀(”这些是项目惯例”)。

不适合

  • 工具调用(用 MCP);
  • 简单提示(直接写 prompt);
  • 频繁变动的逻辑(写代码更直接)。

Skills 适合内容变化慢、需要反复复用的部分。如果某段逻辑天天改,把它固化进 Skill 反而要频繁更新文件,不如直接写在代码里。我做了一次”哪些知识值得沉淀成 Skill”的筛选,最终只保留三四个稳定的,其余一律不碰。

十、平台完整架构

把两者合在一起,就是总结器的完整调用链:

用户 → Web 端
       ↓
Claude/Cursor(开发时)
       ↓ MCP
MCP Server(暴露 5 个工具)
       ↓ 调用
业务服务(下载、AI、支付)
       ↓
Database / External API

主 Agent 加载 Skills 后,有”项目惯例”知识 + 能调 MCP 工具 = 高效开发。到这里,MCP 和 Skills 在项目里的分工链路就完整了:Skills 教方法,MCP 给通路,业务服务负责落地。

十一、MCP 实战细节

1. 工具描述要清晰

工具描述直接影响模型何时调用、怎么传参。下面正反两个例子对比很明显。

# 好的描述
{
    "name": "summarize_video",
    "description": "总结指定 URL 的视频。返回内容包括:"
                   "1) 一句话总结 2) 核心要点 3) 关键时间点。"
                   "需要 10-30 秒。"
}

# 不好的描述
{
    "name": "summarize",
    "description": "总结"  # 太模糊
}

改完描述后我专门跑了一组对比:模糊描述的调用准确率不到一半,写清楚触发条件和返回结构后,模型几乎每次都选对工具。描述里带上耗时、返回结构这类信息,能让模型判断得更准。

2. 错误信息要友好

工具报错时,把可操作的建议一并返回,模型能自己纠正。

try:
    result = await call_tool(name, args)
except ToolError as e:
    return {
        "content": [{
            "type": "text",
            "text": f"工具调用失败: {e}\n"
                    f"建议:检查 URL 是否正确,或换其他视频"
        }],
        "isError": True
    }

这个改动带来的变化是,失败后模型会主动换思路而不是原地重试,用户感知到的失败率低了很多。

3. 长操作要异步

视频下载动辄几十秒,不能阻塞等待,改为先返回任务编号,再轮询结果。

@app.call_tool()
async def call_tool(name, args):
    if name == "summarize_video":
        # 启动后台任务,立即返回 task_id
        task_id = await task_service.start(args)
        return {
            "content": [{
                "type": "text",
                "text": f"任务已启动,task_id={task_id}\n"
                        f"用 get_task_result 查询进度"
            }]
        }

十二、Skills 实战细节

1. SKILL.md 模板

给团队建 Skill 时,我固定用这套模板,字段齐全,别人接手也能看懂。

# [Skill Name]

## 适用场景
- ...

## 工作流
1. ...
2. ...

## 关键文件
- `path/to/file.py`:功能说明
- `path/to/other.py`:功能说明

## 代码示例
[具体代码]

## 约束
- 不要...
- 必须...
- 性能要求...

2. Skill 版本管理

Skill 也是要迭代的,我在目录里按版本归档,旧版本留作回退。

skills/
├── video-downloader/
│   ├── v1/
│   │   └── SKILL.md
│   └── v2/
│       └── SKILL.md

3. Skill 自动发现

加载所有 Skill 时按目录扫描就行,不需要手动逐个注册。

def load_all_skills():
    skills = {}
    for skill_dir in glob('skills/*/'):
        skills[skill_dir.name] = parse_skill(skill_dir)
    return skills

十三、对比其他方案

除了 MCP 和 Skills,还有几种常见的扩展方式,选型时按这张表对号入座。

方案 何时选
MCP 跨平台工具集成、协议标准化
Skills 领域专长、项目惯例
Function Calling 简单工具调用
Plugins(IDE) 编辑器集成
Webhooks 服务间异步通知

结论是别迷信单一方案:同个项目里 MCP、Skills、Function Calling 经常共存,各自负责擅长的层。选型的关键是看”连接””流程””单次调用”哪个是主要矛盾。

十四、未来趋势

  1. MCP 标准化:可能成为行业标准协议;
  2. Skills 市场:类似 npm 的 Skills 共享生态;
  3. 多 Agent 协作:MCP + Skills + 多 Agent 框架融合。

十五、踩坑

1. MCP Server 启动慢

服务端启动时加载了太多大文件,工具列表迟迟出不来。改成静态工具列表后,启动明显加快。

# 启动时不要加载大文件
@app.list_tools()
async def list_tools():
    return TOOLS  # 静态

2. Skills 太多

20+ Skills 让 Agent 困惑。控制在 5-10 个核心 Skills,多了反而互相干扰。

3. MCP 协议开销

每个工具调用 100-300ms 协议开销。频繁调用合并成一次批量请求更划算。

4. Skills 上下文爆

Skills 全部塞进 prompt 占用 token。按需加载,用哪个加载哪个。

十六、最佳实践

  1. MCP 工具描述详细,LLM 才知道何时调用;
  2. Skills 简明扼要,聚焦核心工作流;
  3. 错误信息友好,LLM 能自我纠正;
  4. 异步长任务用 task_id 模式;
  5. 关键操作加人工确认。

常见问题(FAQ)

Q1:MCP 与 Function Calling 区别?

MCP 是协议标准,跨平台;Function Calling 是 LLM 提供商的能力。

Q2:MCP 必须用 Claude 吗?

不,Anthropic 提的协议,理论任何 LLM 都能用。

Q3:Skills 越多越好吗?

不是,5-10 个最佳,超过反而干扰。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 qiqicto@qq.com 举报,一经查实,本站将立刻删除。
赞 (0)
其AI的头像其AI普通用户

相关推荐

返回顶部