深入解析四种扩展机制,用生动的比喻帮你理解何时使用什么。
🎭 核心比喻:一家 AI 软件外包公司
想象你经营一家软件外包公司,面对不同类型的需求,你需要决定:
-
派遣整个团队(Agent)
-
给现有团队配备专家手册(Skill)
-
使用现成工具(Tool)
-
调用外部服务商(MCP)
┌─────────────────────────────────────────────────────────────────┐ │ OpenCode 外包公司架构 │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ 👤 项目经理(主 Agent) │ │ ├── 手下有多支专业团队(Subagents) │ │ ├── 拥有各种工具(Tools) │ │ └── 可以随时请外部专家(Skills)或外包商(MCP) │ │ │ │ 🏢 内部专业团队(Agents) │ │ ├── 🔨 Build 施工队 - 全能开发 │ │ ├── 📝 Plan 规划组 - 只读规划 │ │ ├── 🔍 Explore 侦察组 - 代码探索专家 │ │ └── 🧰 General 特勤组 - 多任务并行 │ │ │ │ 🛠️ 工具库(Tools) │ │ ├── Read/Glob/Grep - 文件工具 │ │ ├── Edit/Write - 编辑工具 │ │ ├── Bash - 命令行工具 │ │ ├── Task - 团队派遣工具 │ │ └── Skill - 专家手册加载工具 │ │ │ │ 📚 专家手册库(Skills) │ │ ├── PPTX 专家 - 演示文稿制作 │ │ ├── XLSX 专家 - 电子表格处理 │ │ └── WebApp Testing 专家 - 网页测试 │ │ │ │ 🔌 外部服务商(MCP Servers) │ │ ├── 数据库服务商 │ │ ├── 搜索引擎服务商 │ │ └── 企业内网 API │ │ │ └─────────────────────────────────────────────────────────────────┘
1️⃣ Agent(专业团队)
定义
Agent = 完整的 AI 实体,拥有:
- 独立的 System Prompt(团队手册)
- 特定的权限配置(能做什么)
- 自己的工作模式(主代理/子代理)
- 独立的上下文(记忆隔离)
类比
Agent 就像公司里的完整团队:
- 有自己的团队手册(System Prompt)
- 有门禁权限(Permission Rules)
- 在独立办公室工作(Session 隔离)
- 通过派遣单联系(Task Tool)
OpenCode 的 Agent 类型
Agent
类型
权限特点
用途
build
Primary
全能(edit/bash/read 都允许)
默认开发代理
plan
Primary
只读(edit 禁止)
规划模式,不修改代码
explore
Subagent
只读(edit/write 禁止)
代码库探索专家
general
Subagent
无 todo(todowrite 禁止)
并行研究任务
title
Hidden
无工具权限
自动生成对话标题
summary
Hidden
无工具权限
生成对话摘要
compaction
Hidden
无工具权限
上下文压缩
何时使用 Agent
✅ 使用 Agent 的场景:
1. 需要完整独立的 AI 实例
"帮我探索这个大型代码库的架构"
→ 派遣 explore 子代理
2. 需要特定的权限约束
"只帮我规划,不要改代码"
→ 切换到 plan 代理
3. 任务复杂到需要独立的上下文
"同时分析前端和后端代码"
→ 并行派遣多个子代理
4. 需要后台自动处理
"给这个对话起个标题"
→ title 代理自动运行
代码示例
// agent.ts - 定义一个探索型子代理
explore: {
name: "explore",
mode: "subagent",
permission: PermissionNext.merge(defaults, PermissionNext.fromConfig({
"*": "deny", // 默认禁止所有
grep: "allow", // 只允许搜索
glob: "allow",
read: "allow",
bash: "allow",
// edit/write 被明确禁止!
})),
description: "Fast agent specialized for exploring codebases...",
prompt: PROMPT_EXPLORE, // 加载 explore.txt
}
2️⃣ Skill(专家手册)
定义
Skill = 专业化的指令集 + 资源包,包括:
SKILL.md:详细的专业指南- 附属资源:脚本、模板、参考文档
- 通过 Skill Tool 动态加载到当前 Agent
类比
Skill 就像专家手册:
- 项目经理(主 Agent)平时不带所有手册
- 遇到特定任务时(如"做 PPT"),临时加载对应手册
- 手册加载后,项目经理获得该领域专业知识
- 不会创建新团队,只是给现有团队增加能力
Skill 目录结构
~/.agents/skills/pptx/
├── SKILL.md # 核心指南(必须)
├── LICENSE.txt # 许可证
├── ooxml/
│ └── scripts/
│ ├── unpack.py # 解包脚本
│ └── pack.py # 打包脚本
└── templates/
└── template.pptx # 示例模板
SKILL.md 示例
---
name: pptx
description: "Presentation creation, editing, and analysis..."
license: Proprietary
---
# PPTX creation, editing, and analysis
## Overview
A user may ask you to create, edit, or analyze the contents of a .pptx file...
## Reading and analyzing content
### Text extraction
If you just need to read the text contents...
```bash
python -m markitdown path-to-file.pptx
Raw XML access
You need raw XML access for: comments, speaker notes...
### 何时使用 Skill
✅ 使用 Skill 的场景:
-
特定领域的专业知识 "帮我做一个 PPT" → 加载 pptx skill
-
需要配套资源(脚本、模板) "分析这个 Excel 数据" → 加载 xlsx skill(含处理脚本)
-
复杂任务的标准化流程 "测试这个网页应用" → 加载 webapp-testing skill
-
领域特定的最佳实践 "用 Python 做数据分析" → 加载 data-analysis skill
❌ 不使用 Skill 的场景:
-
通用编程任务(用主 Agent 即可)
-
单次简单操作(直接用 Tool)
-
需要完全隔离上下文(用 Agent)
Skill 加载流程
用户: "帮我做个 PPT" ↓ 主 Agent 识别到需要 pptx 专业知识 ↓ 调用 Skill Tool: skill({ name: "pptx" }) ↓ 系统查找 ~/.agents/skills/pptx/SKILL.md ↓ 加载 SKILL.md 内容 + 相关资源文件 ↓ 内容注入当前对话上下文 ↓ 主 Agent 现在拥有 PPT 制作能力
### 代码实现
```typescript
// skill.ts - Skill 加载工具
export const SkillTool = Tool.define("skill", async (ctx) => {
return {
description: "Load a specialized skill that provides domain-specific instructions...",
parameters: z.object({
name: z.string().describe("The name of the skill from available_skills"),
}),
async execute(params, ctx) {
const skill = await Skill.get(params.name)
return {
output: [
`<skill_content name="${skill.name}">`,
skill.content, // SKILL.md 内容
"<skill_files>",
files, // 相关资源文件
"</skill_files>",
"</skill_content>",
].join("\n"),
}
},
}
})
3️⃣ Tool(工具/能力)
定义
Tool = 可执行的函数/能力,包括:
- 明确的输入参数定义(Zod Schema)
- 执行逻辑
- 返回结果
- 权限检查
类比
Tool 就像工具/设备:
- Read Tool = 文件阅读器
- Edit Tool = 文本编辑器
- Bash Tool = 命令行终端
- Task Tool = 团队派遣系统
- Skill Tool = 手册加载器
关键:Tool 是 Agent 的能力延伸,不是独立实体。
Tool 类型
Tool
用途
参数示例
Read
读取文件
{ filePath: string }
Glob
文件匹配
{ pattern: string }
Grep
文本搜索
{ pattern: string, path?: string }
Edit
编辑文件
{ filePath: string, oldString: string, newString: string }
Write
写入文件
{ filePath: string, content: string }
Bash
执行命令
{ command: string, description?: string }
Task
派遣子代理
{ description: string, prompt: string, subagent_type: string }
TodoWrite
管理任务
{ todos: Array<{content, status, priority}> }
WebFetch
抓取网页
{ url: string }
Skill
加载技能
{ name: string }
何时创建新 Tool
✅ 创建新 Tool 的场景:
1. 需要执行特定代码逻辑
"需要与特定 API 交互"
→ 创建 API Tool
2. 需要封装复杂操作
"需要打包和解包 PPTX 文件"
→ 创建 Pack/Unpack Tool
3. 需要特定权限控制
"这个操作需要用户确认"
→ 创建带 ask() 的 Tool
4. 需要复用的功能
"多处需要读取配置文件"
→ 创建 ReadConfig Tool
❌ 不创建 Tool 的场景:
1. 只是给 AI 增加知识(用 Skill)
2. 需要完整独立上下文(用 Agent)
3. 调用外部已有服务(用 MCP)
Tool 结构
export const MyTool = Tool.define("mytool", {
description: "Clear description of what this tool does...",
parameters: z.object({
param1: z.string().describe("Description of param1"),
param2: z.number().optional(),
}),
async execute(params, ctx) {
// 1. 权限检查
await ctx.ask({ permission: "mytool", patterns: ["*"] })
// 2. 执行逻辑
const result = await doSomething(params)
// 3. 返回结果
return {
title: "操作标题",
output: "操作结果(会被截断 if 太长)",
metadata: { /* 元数据 */ },
}
},
})
4️⃣ MCP(外部服务协议)
定义
MCP = Model Context Protocol,是 Anthropic 提出的开放标准:
- 连接外部服务和数据源
- 标准化的工具/资源接口
- 支持 OAuth 认证
- 独立于 OpenCode 运行
类比
MCP 就像外部服务商 API:
- 数据库服务商(PostgreSQL MCP)
- 搜索服务商(Exa/Brave MCP)
- 企业内网服务(内部 API MCP)
- 不在公司内部,通过协议对接
MCP vs Tool 的核心区别
特性
Tool
MCP
位置
OpenCode 内部
外部服务
部署
随 OpenCode 一起
独立运行
通信
直接函数调用
HTTP/SSE/Stdio
认证
OpenCode 内部权限
OAuth/独立认证
发现
启动时加载
动态发现
示例
Read/Glob/Bash
数据库/搜索/内部 API
MCP 配置示例
{
"mcp": {
"my-database": {
"type": "remote",
"url": "https://mcp.example.com/database",
"oauth": {
"client_id": "xxx",
"authorization_url": "https://auth.example.com/authorize"
}
},
"local-search": {
"type": "stdio",
"command": "python -m search_mcp_server",
"env": { "API_KEY": "xxx" }
}
}
}
何时使用 MCP
✅ 使用 MCP 的场景:
1. 连接外部数据源
"查询公司销售数据库"
→ 使用 PostgreSQL MCP Server
2. 使用外部搜索服务
"搜索最新的技术文章"
→ 使用 Exa/Brave MCP Server
3. 访问企业内网服务
"查一下 JIRA 上的任务"
→ 使用内部 JIRA MCP Server
4. 需要独立部署维护的服务
"需要专门的图像识别服务"
→ 使用图像识别 MCP Server
❌ 不使用 MCP 的场景:
1. 功能简单可以直接写 Tool
2. 不需要外部网络访问
3. 需要紧密集成 OpenCode 内部状态
MCP 架构
┌─────────────────┐ HTTP/SSE/Stdio ┌─────────────────┐
│ │ ◄──────────────────────────────► │ │
│ OpenCode │ │ MCP Server │
│ (MCP Client) │ │ (外部服务) │
│ │ 1. 发现工具列表 │ │
│ │ 2. 调用工具 │ │
│ │ 3. 获取资源 │ │
│ │ │ │
└─────────────────┘ └─────────────────┘
│ │
│ │
▼ ▼
┌──────────────┐ ┌──────────────┐
│ Tools │ │ 数据库 │
│ Resources │ │ 搜索引擎 │
│ Prompts │ │ 内部 API │
└──────────────┘ └──────────────┘
🎯 决策树:我该用什么?
面对一个新需求,按以下流程决策:
┌──────────────────┐
│ 新需求来了! │
└────────┬─────────┘
│
┌────────▼─────────┐
│ 需要独立上下文? │
│ (隔离、并行、特殊权限)│
└────────┬─────────┘
│
┌──────────────┴──────────────┐
│ YES │ NO
▼ ▼
┌─────────────────┐ ┌─────────────────┐
│ 使用 AGENT │ │ 需要外部服务? │
│ (派遣子代理) │ │ (数据库/搜索/API)│
└─────────────────┘ └────────┬────────┘
│
┌──────────────┴──────────────┐
│ YES │ NO
▼ ▼
┌─────────────────┐ ┌─────────────────┐
│ 使用 MCP │ │ 只是增加知识? │
│ (外部服务协议) │ │ (无新执行能力) │
└─────────────────┘ └────────┬────────┘
│
┌──────────────┴──────────────┐
│ YES │ NO
▼ ▼
┌─────────────────┐ ┌─────────────────┐
│ 使用 SKILL │ │ 使用 TOOL │
│ (专家手册+资源) │ │ (新执行能力) │
└─────────────────┘ └─────────────────┘
📊 四者对比表
维度
Agent
Skill
Tool
MCP
本质
完整 AI 实体
专业知识包
执行函数
外部服务接口
上下文
完全独立
注入当前上下文
当前上下文
跨服务共享
System Prompt
✅ 有独立 Prompt
❌ 无
❌ 无
❌ 无
权限控制
✅ 完整权限系统
⚠️ 通过 Skill Tool
✅ 独立权限
✅ OAuth
资源文件
❌ 无
✅ 可以有脚本/模板
❌ 无
✅ 外部资源
启动成本
高(新 Session)
低(动态加载)
低(直接调用)
中(连接建立)
适用场景
复杂独立任务
领域专业知识
原子操作
外部系统集成
💡 实际案例
场景:开发一个支持 PPT 生成的 AI 助手
方案 A:只用 Tool(简陋版)
// 创建 GeneratePPT Tool
// 问题:AI 不懂 PPT 结构、设计原则、如何操作 XML
// 结果:生成的 PPT 质量差
方案 B:使用 Skill(推荐版)
1. 创建 pptx Skill
├── SKILL.md(PPT 制作指南)
├── scripts/unpack.py(解包脚本)
└── scripts/pack.py(打包脚本)
2. 用户说"做个 PPT"
→ 主 Agent 调用 skill({ name: "pptx" })
→ 加载专业知识
→ 使用 bash/edit 等现有工具操作文件
3. 结果:高质量 PPT,充分利用 AI 的通用能力 + 专业知识
方案 C:使用 Agent(过度设计版)
创建 pptx-agent
问题:
- 需要独立的 Session(启动慢)
- 仍然需要与主 Agent 通信
- 无法直接复用主 Agent 的文件操作能力
结果:复杂且低效
方案 D:使用 MCP(服务化版)
如果:
- PPT 生成需要专门的服务器(如高性能渲染)
- 需要连接 PPT 模板数据库
- 团队其他产品也需要 PPT 功能
则:创建 PPT MCP Server
好处:
- 服务独立部署维护
- 多客户端共享
- 专业的资源管理
🏆 最佳实践
1. 从 Tool 开始
"先做成 Tool,只有当 Tool 不够用时,才考虑 Skill 或 Agent"
大多数需求都可以先用 Tool 实现,只有当发现:
- 需要大量专业知识指导
- 需要配套资源(脚本、模板)
才升级为 Skill。
2. Skill 优于 Agent
"能用 Skill 解决的,不要用 Agent"
Skill 的优势:
- 加载快(不用创建新 Session)
- 资源省(复用主 Agent 上下文)
- 更灵活(可以和主 Agent 的工具组合)
3. Agent 用于真正的隔离
只有当需要:
- 权限隔离(如只读探索)
- 并行执行(同时处理多个独立任务)
- 上下文隔离(防止相互干扰)
才使用 Agent。
4. MCP 用于外部集成
MCP 是"最后一招":
- 连接已有外部服务
- 需要独立运维的服务
- 跨产品复用的能力
📝 一句话总结
Agent 是派团队,Skill 是请专家,Tool 是用工具,MCP 是叫外卖。选择合适的抽象层级,既不过度设计(什么都用 Agent),也不能力不足(该用 Skill 却用 Tool),是设计优秀 AI 系统的关键! 🎯