资讯动态

AI Agent开发:Skills与MCP如何选择?差异对比与最佳实践

发布时间:2026/8/30 23:20:42 来源:尧图企业网站定制
最近在开发 AI Agent 功能时我频繁遇到一个来自团队内部的疑问我们到底应该把能力写在 Skills 里还是封装成 MCP Server 暴露给 Agent一开始我也觉得这两个东西差不多反正都是“给模型加能力”。但真正在项目中落地过一笔后你会发现它俩的设计目标、使用方式、更新节奏完全不同。如果选错了轻则功能无法触发重则维护成本指数上涨甚至出现上下文爆炸或者工具调用失败。这篇文章就把我的实践和理解整理成一份对比型教程围绕“Skills vs. MCP: when to use which”展开。我会从概念讲起逐步拆解它们的本质差异再结合代码示例说明各自典型的实现方式最后给出一个可落地的选择清单。无论你是刚接触 Agent 开发还是已经在用 Claude Code、Codex、Dify 等工具这篇文章都能帮你少走弯路。1. 先搞清楚 Skills 和 MCP 分别是什么很多人第一次接触这两个名词是在使用 AI 编程助手或者 Agent 框架时有的配置项叫.claude/skills里面放了一堆 Markdown 文件。有的配置项叫mcpServers里面填了 command、url、headers 之类的内容。看起来都是“给 Agent 加能力”但它们解决的问题层次并不一样。1.1 Skills教模型“怎么把一件事做好”Skills 通常翻译成“技能”或“Agent 技能”。它本质上是一份结构化的说明文档里面包含任务描述、执行步骤、示例、注意事项、输出格式等内容。模型在开始处理某个任务前会先读取这份说明然后按照说明里的方式去执行。用一个不太严谨但很好理解的比喻MCP 就像给 Agent 接上了外部系统的 USB 接口让 Agent 能调用真实世界的服务。 Skills 就像给 Agent 发了一本操作手册告诉它面对某类任务时正确的工作流是什么。Skills 不直接替 Agent 执行外部操作它更多地是“提升模型在特定任务上的表现”。比如一个“SQL 编写 Skill”告诉模型应该遵循什么样的 SQL 风格、如何处理空值、如何分页。一个“代码审查 Skill”告诉模型应该从哪几个维度审查代码、发现问题后用什么格式输出。一个“PPT 结构设计 Skill”告诉模型如何根据主题生成一份有逻辑的 PPT 大纲。这些能力模型本身也有一定的底子但通过 Skills我们可以把团队沉淀下来的经验、规范、最佳实践固化到配置里让每次生成都更稳定。1.2 MCP让 Agent 能“触达外部世界”MCP 的全称是 Model Context Protocol中文叫“模型上下文协议”。它是一种开放协议目标是统一 AI 应用与外部工具、数据源之间的通信方式。在 MCP 架构下通常有三方MCP Client运行在 AI 应用内部负责与模型交互并发起工具调用。MCP Server独立进程或远程服务暴露出一组“工具Tools”供模型调用。MCP 协议定义了客户端和服务端之间的消息格式、生命周期、安全机制等。模型通过 MCP 调用外部工具时本质上是一个函数调用过程。比如访问数据库模型生成一个调用参数MCP Server 执行查询并返回结果。读取文件模型调用文件系统工具MCP Server 负责文件读写。打开浏览器模型调用浏览器自动化工具MCP Server 驱动浏览器操作。所以 MCP 解决的是“Agent 如何标准化地与外部能力对接”的问题。1.3 关键区别一个是“会做”一个是“够得着”用一句话概括Skills 负责让 Agent会做某件复杂任务它改变的是模型的思考方式和输出质量。MCP 负责让 Agent够得着外部资源它改变的是 Agent 的能力边界。这两者并不互斥在真实项目中往往组合使用。但在具体落地时我们需要先判断当前需求更偏哪一边。2. 环境准备与版本说明在开始对比实现之前先说明我的实验环境。由于 Skills 和 MCP 都属于高速演进的领域版本更新非常快我这里不写死具体的工具链版本只给一个通用的参考项目推荐环境操作系统macOS / Linux / Windows部分命令有差异编程语言Python 3.10 或 Node.js 18AI 应用Claude Code / Codex / Dify / OpenCode 等支持 Skills 或 MCP 的 AgentMCP SDKPython 版mcp或fastmcpNode.js 版modelcontextprotocol/sdkSkills 目录不同 Agent 有各自约定例如 Claude Code 的.claude/skills实际使用哪种 Agent以你当前项目接入的产品文档为准。本文重点是讲解设计思路和通用模式你可以把示例迁移到你自己的框架中。3. Skills 与 MCP 的核心原理拆解3.1 Skills 的工作方式以 Claude Code 的 Skills 为例一个 Skill 通常是一个包含SKILL.md的目录也可以附带示例文件、模板、脚本等资源。SKILL.md 的内容大致包括技能名称和对齐方式触发场景描述执行步骤具体规范或约束示例代码或输出模板示例结构如下skills/ review-code/ SKILL.md examples/ good-example.py bad-example.pySKILL.md简化版--- name: review-code description: 用于代码审查当用户要求审查代码或检查提交质量时使用。 --- # Code Review Skill ## 审查维度 1. 正确性是否存在明显的逻辑错误、边界问题。 2. 安全性是否有注入、越权、敏感信息泄露风险。 3. 可维护性命名是否清晰函数是否过长是否存在重复代码。 4. 性能是否有 N1 查询、无索引查询、大对象加载等问题。 ## 输出格式 按「文件路径:行号 - 问题等级 - 问题说明 - 修改建议」的格式输出。当模型遇到代码审查需求时会读取该 Skill在推理过程中遵循以上规范。这个过程不依赖外部服务内容直接注入上下文或按需加载到上下文。需要注意的是Skills 的核心是指令 示例。它能不能被触发取决于 Agent 对 Skill 描述的理解能力。所以 Skill 的description写得好不好直接影响触发率。3.2 MCP 的工作方式MCP 的工作方式比 Skills 更工程化。我们来拆分一下MCP Server 启动后会向 Client 暴露一个工具列表。每个工具都有名字、描述、输入参数结构JSON Schema。模型根据用户问题在可用工具中选择合适的工具并生成参数。Client 将模型生成的工具调用请求转发给 MCP Server。MCP Server 执行操作返回结果给 ClientClient 再把结果交回模型。下面用 Python 的fastmcp写一个最简数据库查询 MCP Server# 文件路径mcp_server.py from fastmcp import FastMCP import sqlite3 # 创建 MCP Server 实例 mcp FastMCP(db-server) # 定义一个工具查询本地 SQLite 数据库 mcp.tool() def query_db(sql: str) - str: 执行一条 SELECT 查询返回结果字符串。 参数必须是合法的 SELECT 查询禁止包含写操作。 # 示例仅用于本地开发生产环境务必做更严格的权限校验 conn sqlite3.connect(test.db) try: cursor conn.execute(sql) rows cursor.fetchall() return \n.join([str(row) for row in rows]) except Exception as e: return f查询失败: {e} finally: conn.close() if __name__ __main__: mcp.run()在客户端的配置中我们把这个 Server 注册到 Agent{ mcpServers: { db-server: { command: python, args: [mcp_server.py] } } }模型如果发现用户问“最近一个月有多少订单”会调用query_db参数可能是SELECT COUNT(*) FROM orders WHERE created_at datetime(now, -1 month);MCP Server 执行查询把结果返回给模型模型再整理成自然语言回复。这个流程里真正干活的是 MCP Server而不是模型本身。3.3 两者在上下文层面的差异还有一个很容易被忽略的差异上下文资源占用。Skills 通常会在“需要时”把相关文档加载到上下文。如果 Skill 写得太长会挤占上下文空间。有些 Agent 做了 Skill 动态加载模型只有在任务匹配时才读取详情但即便如此技能描述本身依然会参与模型决策。MCP 工具列表也会占用上下文空间。每个工具的名称和描述都在上下文中有一定 token 成本。如果暴露了几十个工具模型选择工具的准确性也会下降。最近很多人反馈“上下文过大已进行多次自动总结但上下文大小仍超出限制”其中很大一部分原因就是 Skills 和 MCP 工具配置太多或者单个 Skill 里的内容过于臃肿。这不是模型不行而是 Agent 的“外部配置”超出了上下文承载能力。4. 完整实战对比实现同一个“读取数据库”需求为了更直观地回答“Skills vs. MCP: when to use which”我们用一个具体场景来做两版实现。场景用户希望 Agent 能够查询项目本地数据库中的数据并将查询结果整理成报表。4.1 基于 MCP 的实现方式这种方式最符合“工具化”的思路。我们把“数据库查询能力”封装成一个独立服务Agent 通过标准协议调用。步骤一准备数据库文件sqlite3 test.db CREATE TABLE orders ( id INTEGER PRIMARY KEY, product_name TEXT, amount REAL, created_at TEXT ); INSERT INTO orders (product_name, amount, created_at) VALUES (键盘, 299, 2025-01-10); INSERT INTO orders (product_name, amount, created_at) VALUES (鼠标, 199, 2025-01-11);步骤二编写 MCP Server上面已经给了fastmcp简版。这里补充一个更严谨的版本加上参数校验# 文件路径mcp_server.py from fastmcp import FastMCP import sqlite3 mcp FastMCP(db-server) mcp.tool() def query_orders(where_sql: str) - str: 查询订单表 orderswhere_sql 是合法的 WHERE 条件不包含 WHERE 关键字。 示例where_sqlamount 200 # 安全校验只允许 SELECT 场景示例简化生产建议使用查询构建器 blacklist [insert, update, delete, drop, alter, ;, --] lowered where_sql.lower() for word in blacklist: if word in lowered: return 非法的查询条件 conn sqlite3.connect(test.db) try: cursor conn.execute(fSELECT * FROM orders WHERE {where_sql}) rows cursor.fetchall() return \n.join([str(row) for row in rows]) except Exception as e: return f查询失败: {e} finally: conn.close() if __name__ __main__: mcp.run()步骤三在 Agent 配置中注册{ mcpServers: { db-server: { command: python, args: [mcp_server.py] } } }步骤四运行验证在支持 MCP 的 Agent 中直接输入帮我查一下订单表里金额大于 200 的订单有哪些模型会生成工具调用{ tool: query_orders, arguments: { where_sql: amount 200 } }MCP Server 返回(1, 键盘, 299.0, 2025-01-10)模型基于这个结果整理输出让用户得到一条完整的回答。4.2 基于 Skills 的实现方式如果不用 MCP我们也可以写一个 Skill让模型“学会”如何查询数据库。但这里有个前提查询动作本身还是需要某种执行通道。可能是命令行工具可能是内置的 Shell 工具也可能是其他 Agent 内置能力。所以更合理的 Skills 场景是模型已经具备执行 SQL 的能力但缺少规范和约束。我们通过 Skill 来统一查询风格、避免写操作、规范结果输出。假设 Agent 内置了run_sql_command这样的工具我们写一个 Skill 来教它正确使用--- name: sql-query-guide description: 当用户要求查询本地数据库时使用。用于规范 SQL 查询行为确保只读操作并格式化输出结果。 --- # SQL 查询规范 ## 触发条件 - 用户请求查询订单、用户、商品等数据库数据。 - 用户希望基于数据做汇总分析。 ## 执行步骤 1. 先明确要查询的数据表名和字段。 2. 只用 SELECT 查询禁止任何写操作。 3. 如果没有明确条件先展示全表数据但加上 LIMIT 20。 4. 查询结果需要转成 Markdown 表格输出。 ## 输出示例 | id | product_name | amount | created_at | |----|--------------|--------|-----------| | 1 | 键盘 | 299 | 2025-01-10 |在这个方案中模型读取 Skill 后就会按照规范生成 SQL 并格式化结果。Skill 本身不负责执行数据库读取它负责的是“把查询这件事做得更规范、更稳定”。4.3 对比结论从上面两种实现可以看出场景维度MCP 方案Skills 方案核心目的提供数据库能力规范查询行为依赖外部服务是需要运行 MCP Server否依赖已有工具安全边界可在服务端做权限隔离只能靠模型自律开发成本中等需要编写服务端代码较低编写文档即可更新速度需要重启或热更新服务改文档即可适合团队有后端开发能力业务/算法/文档团队如果你需要的是一项“Agent 目前根本没有的能力”优先考虑 MCP。如果你需要的只是“让 Agent 把已有能力执行得更符合团队规范”优先考虑 Skills。5. 常见误区与排查思路在实际使用中我经常看到有人把这两个概念混用或者配置之后怎么都不生效。这里整理一份高频问题清单。5.1 问题配置了 Skills但 Agent 不按 Skill 执行可能原因解决思路Skill 的 description 描述不清晰模型没有识别到触发场景重写 description加入典型用户问题和触发条件示例Skill 文件路径放错检查 Agent 约定的 Skills 目录例如.claude/skillsSkill 内容过长上下文未完整加载精简 Skill把核心步骤放前面Agent 版本不支持 Skills升级 Agent 到支持 Skills 的版本5.2 问题MCP Server 启动成功但工具调用一直失败可能原因解决思路MCP Server 返回参数格式不符合协议查看 Client 日志确认工具返回类型是否为字符串或结构化数据工具描述不清晰模型生成的参数不符合预期在工具描述中写清楚参数格式、边界条件网络不通检查本地进程是否启动、端口是否监听上下文过大导致工具列表被截断减少注册的工具数量精简工具描述5.3 问题不知道能力应该放 Skills 还是 MCP这里给一个通用判断方式如果你的能力需要“连接外部系统、实时获取数据”选 MCP。如果你的能力是“让模型更擅长某项任务的输出”选 Skills。如果两者都要先做 MCP 提供基础能力再做 Skills 规范调用方式。5.4 问题上下文总是过大这个在热词里也有相关反馈。当配置了许多 Skills 和 MCP Server 时Agent 在每次对话中都会感知到这些配置的存在。尤其是一些描述很长的工具、很长的 Skill 文档占用大量 token。建议Skill 的description控制在 2-3 行内。MCP 工具的描述控制在 50-100 个字符让模型快速理解用途。定期清理不再使用的 Skills 和 MCP Server。优先使用“按需加载”型的 Skills而不是全部塞进系统提示词。6. 实际工程中的最佳实践结合我自己的项目经验这里总结几条 Skills 与 MCP 组合使用的工程建议。6.1 Skills 保持“小而专”一个 Skill 只解决一个问题。不要在同一个 Skill 里既写代码审查规范又写数据库查询规范。正确做法是拆分成多个 Skill 目录skills/ code-review/ sql-query/ ppt-outline/每个 Skill 都是一个独立的可复用模块。这样不仅方便维护也方便模型在需要时精准触发。6.2 MCP 工具按域划分MCP Server 不要做成一个“万能服务”。建议按照业务域拆分一个 Server 负责数据库访问。一个 Server 负责文件系统操作。一个 Server 负责浏览器自动化。一个 Server 负责外部 API 集成。这样每个 Server 的工具列表更清晰模型选择工具的准确率更高。6.3 用 Skills 封装 MCP 的调用习惯这是两个能力组合使用的最佳姿势。比如团队里有一个 MCP Server 暴露了数据库查询工具但模型不一定知道“哪些查询允许执行、哪些不允许”。这时候可以写一个 Skill专门教它如何安全地使用这个 MCP 工具先读取表结构再生成查询。所有查询必须加 LIMIT。禁止联表删除。查询结果输出为 Markdown。这样模型既有能力MCP又有规范Skills组合起来效果最好。6.4 权限与安全隔离MCP 工具可能直接操作数据库、文件系统、SSH 等敏感资源必须做最小权限设计数据库连接使用只读账号。文件系统工具限制可访问目录。SSH 工具禁止交互式登录仅允许执行白名单命令。涉及生产环境变更时先走审批流程在测试环境验证后再执行。Skills 虽然只是文档但它会引导模型生成代码或命令同样存在风险。不要把敏感信息直接写在 Skill 文件里。6.5 配置纳入版本管理Skills 目录和 MCP 配置文件都应该纳入 Git 管理。这样每次变更都有记录团队成员可以通过 Code Review 来审查。建议目录结构agent-config/ skills/ review-code/ SKILL.md sql-query/ SKILL.md mcp/ db-server/ src/ config.json file-server/ src/ config.json README.md6.6 可测试性每个 Skill 和 MCP 工具都应该有对应的测试用例。MCP 工具的测试相对容易直接调用函数验证返回值def test_query_orders(): result query_orders(amount 200) assert 键盘 in resultSkills 的测试稍微复杂可以准备一组标准输入让 Agent 在不同 Skill 配置下执行对比输出质量。这是目前团队里常用的回归测试方式。6.7 注意命名规范无论是 Skill 还是 MCP 工具命名都要清晰一致。Skill 名称使用 kebab-casecode-review、sql-query。MCP 工具名称使用 snake_casequery_orders、list_files。描述中写明用途避免使用含糊词汇。7. 如何根据项目阶段做选择项目阶段不同选择策略也有差异。7.1 原型验证阶段优先用 Skills。因为这个阶段你还不确定 Agent 需要哪些外部能力最好的办法是先写一个 Skill让模型按照流程生成一个模拟结果。这样可以快速验证任务流程是否合理。例如你想让 Agent 做“根据订单数据生成周报”可以先用 Skill 定义清楚周报的维度、指标、输出格式让模型基于已有的示例数据生成一版周报看看效果如何。如果确认需要实时数据再引入 MCP。7.2 功能落地阶段在确认需要接入真实数据源后再开发 MCP Server。这个阶段重点关注接口定义是否稳定。参数校验是否完整。权限和安全是否可靠。错误返回是否可读。7.3 生产维护阶段此时应该形成稳定的配置管理流程Skills 和 MCP 配置变更走评审。每个新工具上线前先跑回归测试。记录模型在真实场景中的调用成功率。定期检查上下文占用优化工具描述和 Skill 文档长度。8. 从“二选一”到“组合使用”如果只记住一个结论那就是Skills 和 MCP 不是竞争关系而是互补关系。MCP 解决的是“Agent 有什么能力”的问题Skills 解决的是“Agent 怎么用这些能力”的问题。没有 MCPAgent 就像一台没有外接设备的电脑没有 SkillsAgent 即使接了很多设备也可能用得很粗糙。在实际项目中比较理想的架构是先用 MCP 把高频外部能力标准化接入比如数据库、文件、网关 API。再针对特定业务场景编写 Skills把团队的领域知识和操作规范固化下来。保持每个 Skill 和 MCP Server 轻量化避免上下文膨胀。把配置纳入版本管理用测试保证每次修改不破坏已有能力。如果你刚开始接触建议先从一个最简单的场景入手选一个你平时重复做的任务写一个 Skill 试试再选一个需要外部数据的能力用 MCP 接入试试。两种方式各跑一遍你对它们的理解会透彻很多。最后想说的是这类技术演进非常快。今天的最佳实践可能在半年后就过时了。但底层逻辑不变Agent 需要既“会做”又“够得着”Skills 让“会做”更规范MCP 让“够得着”更标准。理解了这层关系无论工具怎么变你都能快速上手。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价