Skill vs MCP:OpenClaw 扩展能力的两条路径 给 AI "外挂"的正确方式:技能型还是协议型? 前言:AI 扩展的两种哲学 想象你在玩一个 RPG 游戏,想给角色增加新能力。你有两种选择: 方案 A:学习新技能 角色掌握"火球术"——这是角色内在的能力,随时可用,无需额外配置,但需要占用技能槽位。 方案 B:装备魔法道具 角色获得一根"火焰法杖"——这是外部工具,需要装备才能用,但可以随时切换,不占用技能槽。 在 OpenClaw 的世界里: Skill(技能) = 方案 A:AI 的内在能力,直接加载到上下文 MCP(模型上下文协议) = 方案 B:AI 的外部工具,通过协议连接 两者都能扩展 AI 的能力,但设计哲学、使用场景和实现方式完全不同。
给 AI "外挂"的正确方式:技能型还是协议型?
想象你在玩一个 RPG 游戏,想给角色增加新能力。你有两种选择:
方案 A:学习新技能
角色掌握"火球术"——这是角色内在的能力,随时可用,无需额外配置,但需要占用技能槽位。
方案 B:装备魔法道具
角色获得一根"火焰法杖"——这是外部工具,需要装备才能用,但可以随时切换,不占用技能槽。
在 OpenClaw 的世界里:
两者都能扩展 AI 的能力,但设计哲学、使用场景和实现方式完全不同。本文将深入解析这两种机制,帮你做出正确的技术选择。
Skill(技能)是 OpenClaw 的原生扩展机制,采用 AgentSkills 兼容格式。每个技能是一个包含 SKILL.md 指令文件和可选资源的文件夹。
核心特点:
my-skill/ ├── SKILL.md # 必需:元数据 + 指令 ├── scripts/ # 可选:可执行脚本 ├── references/ # 可选:参考文档 └── assets/ # 可选:输出资源
SKILL.md 示例:
--- name: pdf-processor description: PDF 文档处理,支持提取文本、旋转页面、合并文件。当用户需要处理 PDF 文档时使用此技能。 --- # PDF 处理技能 ## 提取文本 使用 pdfplumber 提取文本: \`\`\`python import pdfplumber with pdfplumber.open("file.pdf") as pdf: text = pdf.pages[0].extract_text() \`\`\` ## 旋转页面 参见 [ROTATE.md](references/ROTATE.md) 了解旋转方法。
OpenClaw 采用三层渐进式加载:
| 层级 | 内容 | 加载时机 | Token 成本 |
|---|---|---|---|
| 元数据 | name + description | 始终加载 | ~100 词 |
| SKILL.md | 核心指令 | 技能触发时 | <5k 词 |
| 资源 | scripts/references/assets | 按 AI 决定 | 无限制 |
关键特性:
✅ 适合用 Skill 的场景:
❌ 不适合用 Skill 的场景:
MCP(Model Context Protocol,模型上下文协议)是一个开放标准协议,用于连接 AI 应用与外部系统。可以把它理解为 AI 的 USB-C 接口。
核心特点:
┌─────────────────────────────────────────┐ │ MCP Host (OpenClaw) │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐│ │ │Client 1 │ │Client 2 │ │Client 3 ││ │ └────┬─────┘ └────┬─────┘ └────┬─────┘│ └───────┼────────────┼────────────┼────────┘ │ │ │ ┌───▼────┐ ┌───▼────┐ ┌───▼────┐ │Server A│ │Server B│ │Server C│ │(本地) │ │(远程) │ │(远程) │ └────────┘ └────────┘ └────────┘
MCP 服务器示例:
| 原语 | 用途 | 示例 |
|---|---|---|
| Tools | AI 可调用的函数 | query_database(), create_file() |
| Resources | 提供上下文的数据源 | 文件内容、数据库 Schema、API 响应 |
| Prompts | 可重用的交互模板 | 系统提示、Few-shot 示例 |
工具调用示例:
// 请求 { "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": "weather_current", "arguments": { "location": "San Francisco", "units": "imperial" } } } // 响应 { "jsonrpc": "2.0", "id": 1, "result": { "content": [ { "type": "text", "text": "Current weather in San Francisco: 68°F, partly cloudy" } ] } }
✅ 适合用 MCP 的场景:
❌ 不适合用 MCP 的场景:
| 维度 | Skill | MCP |
|---|---|---|
| 本质 | 知识载体 | 通信协议 |
| 部署位置 | 本地文件夹 | 独立进程(本地/远程) |
| 通信方式 | 直接读取上下文 | JSON-RPC 2.0 |
| 数据流向 | 静态指令 → AI | AI ↔ 服务器 ↔ 数据源 |
| Token 消耗 | 加载到上下文(消耗 token) | 仅传输结果(低 token 消耗) |
| 适用数据 | 静态知识、工作流程 | 动态数据、实时 API |
| 更新频率 | 手动更新 | 实时/按需更新 |
| 复杂度 | 简单(写 Markdown) | 中等(需实现服务器) |
| 扩展性 | 受限于上下文窗口 | 无限制(独立服务器) |
| 认证管理 | 配置文件注入 | 协议层支持 |
| 跨平台 | OpenClaw 专用 | 跨所有 MCP 客户端 |
Skill 的 Token 成本:
基础开销(≥1 技能时):195 字符 每个技能:97 字符 + len(name) + len(description) + len(location)
示例: 10 个技能,平均 name=15 字符,description=100 字符,location=50 字符
总成本 ≈ 195 + 10 × (97 + 15 + 100 + 50) = 195 + 2620 = 2815 字符 ≈ 700 tokens
MCP 的 Token 成本:
结论: MCP 对上下文窗口的影响远小于 Skill。
Skill 开发:
1. 创建文件夹 2. 编写 SKILL.md 3. (可选)添加脚本/资源 4. 完成
时间: 30 分钟 - 2 小时
MCP 服务器开发:
1. 选择 SDK(TypeScript/Python) 2. 实现服务器逻辑 3. 定义 tools/resources/prompts 4. 处理认证和错误 5. 部署服务器 6. 配置客户端连接
时间: 4 小时 - 数天(取决于复杂度)
需要扩展 AI 能力? │ ├─ 需要传递静态知识/工作流程? │ └─→ 使用 Skill │ ├─ 需要访问动态数据源? │ └─→ 使用 MCP │ ├─ 需要调用外部 API? │ ├─ API 简单且调用频率低? │ │ └─→ 可用 Skill(包含脚本) │ └─ API 复杂或需要认证? │ └─→ 使用 MCP │ └─ 需要实时数据或大规模数据访问? └─→ 使用 MCP
案例 1:PDF 处理
需求: AI 需要提取 PDF 文本、旋转页面、合并文件
选择: ✅ Skill
原因:
实现:
--- name: pdf-processor description: PDF 文档处理。提取文本、旋转页面、合并文件。 --- # PDF 处理 ## 提取文本 \`\`\`bash python scripts/extract_text.py input.pdf \`\`\` ## 旋转页面 \`\`\`bash python scripts/rotate.py input.pdf output.pdf 90 \`\`\`
案例 2:GitHub PR 管理
需求: AI 需要查询 PR、添加评论、合并代码
选择: ✅ MCP
原因:
实现:
// MCP 服务器 server.addTool({ name: "list_pull_requests", description: "List pull requests for a repository", inputSchema: { type: "object", properties: { owner: { type: "string" }, repo: { type: "string" }, state: { type: "string", enum: ["open", "closed", "all"] } } } }) // OpenClaw 配置 { "skills": { "load": { "extraDirs": ["./mcp-servers/github"] } } }
案例 3:企业知识库查询
需求: AI 需要搜索企业文档(Confluence/Notion)
选择: ✅ MCP
原因:
案例 4:代码规范指南
需求: AI 需要按照企业规范编写代码
选择: ✅ Skill
原因:
实现:
code-standards-skill/ ├── SKILL.md └── references/ ├── naming.md ├── architecture.md └── examples.md
最佳实践: Skill + MCP 组合使用
场景: 构建一个 DevOps 助手
| 能力 | 实现方式 | 原因 |
|---|---|---|
| CI/CD 流程指导 | Skill | 工作流程是静态知识 |
| Jenkins 任务查询 | MCP | 动态数据,需要认证 |
| 日志分析技巧 | Skill | 分析方法是静态知识 |
| 实时日志获取 | MCP | 动态数据,大数据量 |
| 部署规范 | Skill | 企业规范,静态知识 |
| Kubernetes 集群状态 | MCP | 实时数据,远程 API |
配置示例:
{ skills: { entries: { "cicd-workflow": { enabled: true }, // Skill "log-analysis": { enabled: true }, // Skill "deployment-guide": { enabled: true }, // Skill }, load: { extraDirs: [ "./mcp-servers/jenkins", // MCP Server "./mcp-servers/k8s", // MCP Server ] } } }
步骤 1:初始化
cd ~/.openclaw/workspace/skills scripts/init_skill.py my-skill --path . --resources scripts,references
步骤 2:编写 SKILL.md
--- name: my-skill description: 简洁描述技能功能和使用场景 --- # 技能名称 ## 核心功能 1. 功能一 2. 功能二 ## 使用方法 具体步骤...
步骤 3:添加资源
# 添加脚本 echo "print("Hello")" > scripts/hello.py # 添加参考文档 echo "# API 文档" > references/api.md
步骤 4:打包
scripts/package_skill.py ~/.openclaw/workspace/skills/my-skill
步骤 1:初始化项目
npm init -y npm install @modelcontextprotocol/sdk
步骤 2:实现服务器
import { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; const server = new Server({ name: "my-mcp-server", version: "1.0.0" }); // 添加工具 server.addTool({ name: "my_tool", description: "工具描述", inputSchema: { type: "object", properties: { param1: { type: "string" } } } }); // 启动服务器 const transport = new StdioServerTransport(); await server.connect(transport);
步骤 3:配置 OpenClaw
{ skills: { load: { extraDirs: ["./path/to/mcp-server"] } } }
渐进式披露:
# 主文档(SKILL.md) ## 快速开始 基础操作... ## 高级功能 - **功能 A**:参见 [ADVANCED_A.md](references/ADVANCED_A.md) - **功能 B**:参见 [ADVANCED_B.md](references/ADVANCED_B.md)
条件加载:
--- metadata: { "openclaw": { "requires": { "bins": ["python3"], "env": ["API_KEY"] } } } ---
资源缓存:
// 缓存频繁访问的资源 const cache = new Map(); server.addResource({ uri: "cache://data", name: "Cached Data", async handler() { if (!cache.has("data")) { cache.set("data", await fetchExpensiveData()); } return cache.get("data"); } });
流式响应:
server.addTool({ name: "stream_data", async handler(args) { const stream = await fetchDataStream(); return { content: [{ type: "text", text: stream }] }; } });
Skill 安全:
metadata.openclaw.requires 验证依赖skills.entries.*.apiKey 注入密钥MCP 安全:
Skill 和 MCP 是 OpenClaw 扩展 AI 能力的两条路径,它们并非相互排斥,而是互补关系。
记忆口诀:
选择原则:
下一步行动:
祝你构建出强大的 AI 扩展生态系统! 🦞