本文以我的开源项目 OpsMind 为例,探讨 AI 应用开发中三种常见的技术模式:预设代码、Skill 和 MCP,分析它们的本质区别与适用场景。
最近在开发 OpsMind —— 一个智能运营决策中枢,核心功能是通过自然语言对话进行数据分析和文件生成。在研究 AI 应用架构时,我接触到了 Skill 和 MCP 两个概念。
起初我有些困惑:我的项目也能通过对话生成文件,这和 MCP 有什么区别?预设代码算不算 Skill 技术?这些技术和提示词工程又是什么关系?
我的现状:预设代码模式
项目架构
OpsMind 目前的核心是一个 DataAnalysisEngine 类,所有功能都硬编码在类方法中:
class DataAnalysisEngine: """数据分析引擎类""" def generate_charts(self, df, chart_types): """生成图表""" if "histogram" in chart_types: plt.hist(...) if "scatter" in chart_types: plt.scatter(...) if "heatmap" in chart_types: sns.heatmap(...) def generate_tables(self, df, table_types): """生成表格""" if "basic_stats" in table_types: df.describe().to_excel(...) if "pivot" in table_types: df.pivot_table(...).to_excel(...)
|
执行流程
用户说”帮我分析销售数据并生成图表”,整个流程如下:
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ 用户输入 │ ──→ │ LLM 判断 │ ──→ │ 调用预设 │ ──→ │ 生成文件 │ │ │ │ 意图 │ │ 函数 │ │ │ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘
|
LLM 的作用是判断用户想要什么类型的图表/表格,然后调用对应的 Python 函数执行。
这种模式的特点
| 优点 |
缺点 |
| 开发简单,逻辑清晰 |
功能固定,扩展需改代码 |
| 性能好,无额外开销 |
无法被其他 AI 应用复用 |
| 功能可控,调试方便 |
所有功能耦合在一起 |
我把这种模式称为预设代码模式——功能写死在代码里,调用时直接执行。
Skill 技术:动态能力注入
什么是 Skill
Skill 是一种运行时动态加载能力的模式。与预设代码不同,Skill 不是把所有功能都写死在启动时加载,而是根据用户需求,按需激活对应的能力模块。
如果用 Skill 重构 OpsMind
skills/ ├── data_analysis/ │ └── skill.md # 数据分析能力 ├── chart_generation/ │ └── skill.md # 图表生成能力 └── table_export/ └── skill.md # 表格导出能力
|
每个 Skill 文件包含:
# 图表生成 Skill
## 触发条件 用户要求生成图表、可视化数据时激活
## Prompt 模板 你是一个数据可视化专家,可以生成以下图表: - 直方图:调用 generate_histogram(data, column) - 散点图:调用 generate_scatter(data, x_col, y_col) - 热力图:调用 generate_heatmap(data, columns)
## 工具定义 - generate_histogram(data, column): 生成指定列的直方图 - generate_scatter(data, x_col, y_col): 生成散点图 - generate_heatmap(data, columns): 生成相关性热力图
|
执行流程对比
预设代码模式:
启动时加载所有功能 → 用户提问 → LLM 选择函数 → 执行
|
Skill 模式:
启动时加载基础能力 → 用户提问 → 识别需要哪个 Skill → 动态注入 Skill → LLM 使用 Skill 中的工具 → 执行
|
与预设代码的对比
| 维度 |
预设代码 |
Skill |
| 加载时机 |
启动时全部加载 |
运行时按需加载 |
| Prompt 位置 |
固定在代码里 |
动态注入上下文 |
| 扩展方式 |
修改源代码 |
添加 Skill 文件 |
| 隔离性 |
功能耦合 |
模块独立 |
| 复用性 |
仅限本项目 |
可跨项目复用 |
我的理解:Skill 本质上是把”能力”抽象成可插拔的模块,让 AI Agent 能够根据任务动态组装自己的能力集。
MCP:跨应用工具共享协议
什么是 MCP
MCP(Model Context Protocol)是 Anthropic 推出的开放协议,让 AI 应用能够调用外部工具。与 Skill 不同,MCP 关注的是跨应用的能力共享。
如果用 MCP 重构 OpsMind
我可以把数据分析能力封装成 MCP Server:
from mcp import Server
server = Server("opsmind-data-analysis")
@server.tool("analyze_excel") def analyze_excel(file_path: str, query: str) -> dict: """ 分析 Excel 文件并返回结果 Args: file_path: Excel 文件路径 query: 分析需求描述 Returns: 包含分析结果的字典 """ df = pd.read_excel(file_path) return {"result": analysis_result}
@server.tool("generate_chart") def generate_chart(data_path: str, chart_type: str, columns: list) -> str: """ 生成图表并返回文件路径 Args: data_path: 数据文件路径 chart_type: 图表类型 (histogram/scatter/heatmap) columns: 要分析的列名 Returns: 生成的图表文件路径 """ return chart_path
|
MCP 的核心价值
┌─────────────────────────────────────────────────────────────┐ │ MCP 生态 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │ Claude │ │ Cursor │ │ Trae │ │ │ │ (Client) │ │ (Client) │ │ (Client) │ │ │ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │ │ │ │ │ │ │ └─────────────────┼─────────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────┐ │ │ │ MCP Protocol │ │ │ └────────┬────────┘ │ │ │ │ │ ┌─────────────────┼─────────────────┐ │ │ │ │ │ │ │ ▼ ▼ ▼ │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │ OpsMind │ │ 文件系统 │ │ 数据库 │ │ │ │ (Server) │ │ (Server) │ │ (Server) │ │ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │ │ └─────────────────────────────────────────────────────────────┘
|
这样,任何支持 MCP 的 AI 应用都能直接使用 OpsMind 的数据分析工具,无需重复开发。
与 Skill 的对比
| 维度 |
Skill |
MCP |
| 作用范围 |
单个 AI 应用内部 |
跨应用共享 |
| 工具位置 |
应用内 |
独立进程 |
| 协议标准 |
无统一标准 |
统一开放协议 |
| 适用场景 |
能力模块化 |
工具生态化 |
| 开发成本 |
较低 |
需要实现协议 |
我的理解:MCP 解决的是”工具孤岛”问题——让不同 AI 应用能够共享同一套工具,而不是每个应用都重复开发。
三者的本质区别
架构对比图
┌─────────────────────────────────────────────────────────────────┐ │ │ │ 【预设代码】 │ │ │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ AI 应用 │ │ │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ │ │ 功能 A │ │ 功能 B │ │ 功能 C │ ← 全部硬编码 │ │ │ │ └─────────┘ └─────────┘ └─────────┘ │ │ │ └─────────────────────────────────────────────────────────┘ │ │ │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ 【Skill】 │ │ │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ AI 应用 │ │ │ │ ┌─────────┐ │ │ │ │ │ 基础能力 │ ←── 动态加载 ───┐ │ │ │ │ └─────────┘ │ │ │ │ └───────────────────────────────┼─────────────────────────┘ │ │ │ │ │ ┌───────────────┬───────────────┴───────────────┐ │ │ │ Skill A │ Skill B │ Skill C │ │ │ │ (按需加载) │ (按需加载) │ (按需加载) │ │ │ └───────────────┴───────────────┴───────────────┘ │ │ │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ 【MCP】 │ │ │ │ ┌─────────────────┐ ┌─────────────────┐ │ │ │ AI 应用 A │ │ AI 应用 B │ │ │ │ (MCP Client) │ │ (MCP Client) │ │ │ └────────┬────────┘ └────────┬────────┘ │ │ │ │ │ │ └───────────┬───────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────────┐ │ │ │ MCP Protocol │ │ │ └──────────┬──────────┘ │ │ │ │ │ ┌─────────────┼─────────────┐ │ │ │ │ │ │ │ ▼ ▼ ▼ │ │ ┌───────────┐ ┌───────────┐ ┌───────────┐ │ │ │MCP Server │ │MCP Server │ │MCP Server │ │ │ │ (工具1) │ │ (工具2) │ │ (工具3) │ │ │ └───────────┘ └───────────┘ └───────────┘ │ │ │ └─────────────────────────────────────────────────────────────────┘
|
核心差异总结
| 维度 |
预设代码 |
Skill |
MCP |
| 设计目标 |
快速实现功能 |
模块化能力管理 |
跨应用工具共享 |
| 工具位置 |
应用内部 |
应用内部 |
独立进程 |
| 加载方式 |
启动时全部加载 |
运行时按需加载 |
通过协议调用 |
| 扩展方式 |
修改源代码 |
添加 Skill 文件 |
连接新 Server |
| 共享能力 |
无法共享 |
应用内共享 |
跨应用共享 |
| 开发成本 |
低 |
中 |
高 |
| 适用规模 |
小型项目 |
中型项目 |
大型生态 |
提示词与执行层的关系
一个关键问题
在研究这些技术时,我曾有一个疑问:这些技术都可以算是集成的提示词吗?
答案是:不完全是,但都和提示词相关。
分层理解
┌─────────────────────────────────────────────────────────┐ │ │ │ ┌─────────────────────────────────────────────────┐ │ │ │ LLM(大语言模型) │ │ │ └─────────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────────────────────────────────────┐ │ │ │ 【提示词层】决定 LLM 知道什么 │ │ │ │ │ │ │ │ - 告诉 LLM 有哪些能力可用 │ │ │ │ - 告诉 LLM 如何调用这些能力 │ │ │ │ - 告诉 LLM 参数格式和返回格式 │ │ │ └─────────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────────────────────────────────────┐ │ │ │ 【执行层】决定实际做什么 │ │ │ │ │ │ │ │ - 预设代码:应用内的 Python 函数 │ │ │ │ - Skill:应用内的模块化函数 │ │ │ │ - MCP:外部独立进程 │ │ │ └─────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────┘
|
以 OpsMind 为例
预设代码模式:
prompt = """ 【可选图表类型】 - histogram: 直方图 - 查看数值分布 - scatter: 散点图 - 查看变量关系 - heatmap: 热力图 - 查看特征相关性 """
if "histogram" in chart_types: plt.hist(...)
|
Skill 模式:
<!-- skill.md - 这部分会转换成提示词注入给 LLM --> # 图表生成 Skill
你是一个数据可视化专家,可以生成以下图表: - 直方图:调用 generate_histogram(data, column) - 散点图:调用 generate_scatter(data, x_col, y_col)
<!-- 实际执行的函数定义在别处 -->
|
MCP 模式:
@server.tool("generate_chart") def generate_chart(data_path: str, chart_type: str) -> str: """生成图表并返回文件路径""" return chart_path
|
形象比喻
| 概念 |
比喻 |
作用 |
| 提示词 |
菜单 |
告诉客人(LLM)有什么菜 |
| 预设代码/Skill/MCP |
厨房 |
真正做菜的地方 |
关键理解:
- 提示词是 LLM 的”说明书”——告诉它能做什么
- 预设代码/Skill/MCP 是执行层——真正干活的代码
- 这三种技术都依赖提示词让 LLM 知道有什么能力可用,但不是提示词本身
技术选型建议
场景匹配
| 场景 |
推荐模式 |
理由 |
| 快速开发 MVP |
预设代码 |
开发成本低,迭代快 |
| 功能相对固定 |
预设代码 |
无需复杂架构 |
| 需要模块化扩展 |
Skill |
能力可插拔,易维护 |
| 多团队协作开发 |
Skill |
模块独立,职责清晰 |
| 需要跨应用共享工具 |
MCP |
一次开发,多处使用 |
| 构建工具生态 |
MCP |
开放协议,生态共赢 |
OpsMind 的演进方向
目前 OpsMind 使用预设代码模式,对于单一应用来说已经足够。但未来可以考虑:
┌─────────────────────────────────────────────────────────────┐ │ OpsMind 架构演进 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ 第一阶段:预设代码(当前) │ │ ├── 快速实现核心功能 │ │ ├── 验证产品价值 │ │ └── 积累用户反馈 │ │ │ │ 第二阶段:引入 Skill │ │ ├── 模块化现有功能 │ │ ├── 支持第三方 Skill 扩展 │ │ └── 提升可维护性 │ │ │ │ 第三阶段:MCP Server │ │ ├── 开放数据分析能力给其他 AI 应用 │ │ ├── 接入 MCP 生态 │ │ └── 构建工具生态 │ │ │ └─────────────────────────────────────────────────────────────┘
|
组合使用
三者并非互斥,可以组合使用:
AI 应用 → Skill(动态加载能力)→ MCP Client → MCP Server(调用外部工具)
|
例如:
- OpsMind 作为 AI 应用
- 使用 Skill 管理内部能力模块
- 通过 MCP Client 连接外部工具(如数据库、文件系统)
- 同时作为 MCP Server 对外提供服务
总结
核心观点
预设代码:功能写死在代码里,简单直接,适合快速开发和功能固定的场景。
Skill:动态能力注入,按需加载,适合模块化设计和需要扩展的场景。
MCP:跨应用工具共享,开放协议,适合构建工具生态和跨应用复用。
提示词与执行层:提示词是 LLM 的”说明书”,预设代码/Skill/MCP 是真正干活的”执行层”,两者配合才能让 AI 应用具备实际能力。
架构演进路径
预设代码 → Skill → MCP ↓ ↓ ↓ 功能固定 能力模块化 工具生态化 ↓ ↓ ↓ 单应用内 单应用内 跨应用共享 ↓ ↓ ↓ 改代码扩展 加文件扩展 连接新Server
|
最后的话
没有最好的架构,只有最适合的架构。理解每种模式的适用场景,才能做出正确的技术选型。
对于 OpsMind 这样的项目,从预设代码开始是正确的选择——先验证价值,再考虑架构演进。当功能逐渐丰富、用户需求多样化时,再引入 Skill 和 MCP,逐步构建更开放、更可扩展的架构。