AI Agent开发:Skills与MCP的区别、选型与组合实践 在 AI Agent 开发里Skills 和 MCP 是最近讨论频率最高的两个词。很多团队在规划能力扩展时会先问“要装 skills 还是接 mcp server”。答案往往不是二选一。Skills 解决的是“模型应该怎么做一件事”MCP 解决的是“模型怎么拿到外部能力和数据”。如果你只做了一个 skill 而没有数据访问能力agent 会按流程思考却拿不到现场信息如果你只接了一个 MCP server 而没有流程约束agent 可能知道能调用工具却不知道什么时候调、先调哪个、结果如何判断。这篇内容会从概念、最小实现、选型依据、排查路径和落地建议五个方面把 Skills 与 MCP 的关系讲清楚。1. 先定义两个容易混淆的概念Skills 与 MCP在日常沟通里有人把 Skills 理解成“提示词插件”有人把 MCP 理解成“工具插件”。这两种说法都不够准确。真正做 Agent 工程时需要区分它们所在层次。1.1 Skills 是一套可复用的操作手册和预制动作Skills 在中文语境里可以理解成“技能”或“工作流模板”。它把某类任务的执行步骤、判断规则、输出格式、注意事项提前整理成结构化内容让模型在遇到匹配任务时按这套内容执行。典型形态是 Markdown 文件文件中包含该技能的名称和用途描述。执行步骤例如先查什么、再判断什么、最后输出什么。检查清单例如提交代码前必须检查的 5 项内容。示例输入输出让模型理解期望结果。可选脚本例如一个 Python 脚本负责做确定性计算或文件处理。社区里也出现了一系列技能集例如 superpower skills、codex skills、claude code skills 等。它们的共同点是把重复性的专家经验从模型提示词里拆出来按需加载。这样一个 Agent 可以同时掌握很多领域的“做法”而不需要把所有说明都塞进 system prompt。1.2 MCP 是一套连接外部能力的标准协议MCP 全称 Model Context Protocol是一套让 AI 应用连接外部数据源和工具的标准协议。你可以把它理解成 USB-C 接口只要设备遵循同一套协议不同客户端都能接入同一个 MCP server。MCP 客户端负责和模型交互MCP server 负责暴露能力。二者通过 JSON-RPC 消息通信。MCP server 暴露的核心能力有三类Tools可被模型调用的函数比如查询订单、执行 SQL、打开浏览器。Resources可被读取的上下文比如配置文件、数据库记录、远程文档。Prompts服务端预定义的提示模板客户端可以按需拉取。实际项目里最常见的是 Tools。例如 Playwright MCP 让 Agent 能操作浏览器数据库 MCP 让 WorkBuddy、Dify 这类平台能直接访问数据库蓝湖、支付宝等平台也在逐步提供自己的 MCP 服务。这里的重点不是某个具体平台的实现而是协议本身让工具接入方式变得统一。1.3 两者不是替代关系而是不同轴上的能力Skills 偏“知识轴”MCP 偏“连接轴”。一个 skill 可以告诉模型“处理这个事件时先调用 k8s 事件查询工具再调用日志工具最后按模板输出报告。” 而 MCP server 提供的就是那些工具本身。没有 skill模型知道有工具但不知道何时该用没有 MCP模型知道处理流程却拿不到外部实时数据。两者也可以互相影响。MCP 的 Prompts 原语在形态上和 Skills 很接近都能给出一段预置提示。但 MCP Prompts 由服务端发布通常经过协议暴露Skills 更多是客户端侧或项目目录里的静态文件。理解这个差异后选型才不会机械。2. 从一次真实需求推导选型判断标准选型不能只看概念最好落在一个具体需求上。下面用一个常见的故障诊断场景说明如何判断。2.1 需求让 Agent 帮忙分析 Pod 反复重启假设团队希望 Agent 完成这个任务用户输入命名空间和 Pod 名。Agent 获取 Pod 状态、最近事件和日志。Agent 按固定流程判断根因。输出一份包含事件时间线、关键日志、可能原因、修复建议的报告。这个需求包含两段信息。前两段需要外部数据后两段需要“判断方法论”。如果把整套流程写成 instructions模型会知道流程但没有权限和能力去拿数据。如果只暴露一堆 MCP 工具模型知道可以查询很多信息却未必能按照团队的标准去组织结论。2.2 适合用 Skills 的信号如果需求本质上属于“知识规则 输出模板”并且外部依赖很弱优先用 Skills任务步骤比较固定例如代码评审、需求拆分、会议纪要整理。同一个流程需要覆盖多个输入场景输入来源可以靠用户后续补充。团队有强烈的提问规范、输出格式、边界约束需要统一。能力需要以纯文本形式跨系统复制不希望依赖特定服务端。实施路径是“写一份文档让模型按文档执行”。这种情况如果硬要做成 MCP server反而增加维护成本。一个很小的 skill 可能就是一个 Markdown 文件放在项目skills目录里即可。2.3 适合用 MCP 的信号如果需求核心是“访问一个已有系统”或者“提供一个可被任意客户端调用的能力”优先用 MCP数据源在远端例如数据库、对象存储、内部 API。需要统一鉴权不能让每个 skill 各自处理密钥。同样的能力要让多个客户端使用例如 Claude Code、Dify、Trae、Codex 都接入同一套工具。工具要返回实时结果而不是静态知识。团队希望把能力和提示词解耦由专门的服务维护。比如“通过 MCP 直接访问数据库”这类需求天然适合 MCP。数据库连接方式、表结构、SQL 执行逻辑都留在 server 端客户端只负责让模型按需调用。2.4 组合使用Skill 负责流程MCP 负责数据真正的故障诊断场景通常会同时使用两者。Skill 里定义排查顺序和处理规范MCP server 暴露pod_events、pod_logs这类工具。模型加载 skill 后在执行步骤中知道“步骤 1 调用 pod_events步骤 2 调用 pod_logs”最终输出按 skill 模板生成。这也是现在更推荐的工程方式把会变化的外部依赖放进 MCP把稳定流程放进 Skills。当接口变动时只改 MCP server当判断规范调整时只改 skill 文档。3. 动手实现一个最小可验证的组合案例下面用一个最小案例验证两种能力如何配合。环境不一定需要 GPU 或复杂平台本地命令行即可。3.1 Skills 目录和最小文件格式假设项目目录结构如下agent-project/ skills/ pod-restart-diag/ SKILL.md mcp_servers/ k8s_mcp_server.pySKILL.md是 Agent Skills 常见约定。下面是一个简化版--- name: pod-restart-diag description: 当用户报告 Pod 反复重启时调用 k8s MCP 工具收集事件和日志并按固定模板输出诊断报告。 --- # Pod 重启诊断 ## 输入 - namespace命名空间 - pod_namePod 名称 ## 执行步骤 1. 调用 MCP 工具 pod_events获取最近 30 条事件。 2. 调用 MCP 工具 pod_logs获取最近 100 行日志。 3. 分析事件中的 OOMKilled、BackOff、FailedMount 等关键字。 4. 输出诊断报告。 ## 输出模板 - 现象 - 事件时间线 - 关键日志 - 可能原因 - 下一步建议这里的关键点是description。模型不会无条件加载所有 skill它会根据用户问题的语义去匹配 skill 描述。描述越具体命中率越高。如果描述写得太泛比如“处理 Kubernetes 问题”模型可能在很多场景下误加载也可能在应该加载时不加载。3.2 MCP Server 的最小实现为了配合上面的 skill需要一个 MCP server 提供两个工具。以 Python 的 MCP SDK 为例先安装依赖pip install mcp然后创建k8s_mcp_server.pyfrom mcp.server.fastmcp import FastMCP mcp FastMCP(k8s-helper) mcp.tool() def pod_events(namespace: str, pod_name: str) - str: 获取 Pod 最近事件。实际项目里在这里调用 K8s API 或 kubectl。 return fevents for {namespace}/{pod_name}: ... mcp.tool() def pod_logs(namespace: str, pod_name: str) - str: 获取 Pod 最近日志。实际项目里在这里调用 K8s API 或 kubectl。 return flogs for {namespace}/{pod_name}: ... if __name__ __main__: mcp.run(transportstdio)这段代码只用于说明思路。不同版本的 MCP SDK 方法名可能有差异落地前要先确认你安装的版本。函数返回的内容可以直接是字符串也可以是 JSON。对真实项目来说建议返回结构化数据而不是一整段格式化好的文本这样模型更容易提取关键点。3.3 在客户端里注册本地 MCP 服务常见客户端的配置思路类似都是配置一组mcpServers每个 server 包含启动命令和参数。有的是界面配置有的是命令行配置Dify 添加本地 MCP 服务时通常也是输入命令和参数。以本地配置文件为例{ mcpServers: { k8s-helper: { command: python, args: [/absolute/path/to/agent-project/mcp_servers/k8s_mcp_server.py] } } }配置提醒command和args必须能直接从客户端所在环境启动 server。路径要写绝对路径相对路径受工作目录影响。如果脚本依赖虚拟环境command要改成虚拟环境里的 Python 绝对路径。如果 server 需要环境变量例如数据库密码记得先确认客户端是否支持注入环境变量不要把密钥写进配置文件。配置完成后在对话里让 Agent“使用 k8s-helper 查询某个命名空间的 Pod 事件”客户端会自动走 MCP 调用。如果配置失败对话里通常不会直接报错而是表现为模型说“我没有找到可用工具”。4. 参数、协议元素和选型速查理解参数和协议元素后排查才更有方向。下面把常见字段整理成速查表。4.1 SKILL.md 的关键字段不同生态对 SKILL.md 的字段定义不完全一致但以下几个字段是大多数实现都会关心的字段作用建议nameskill 唯一标识用短横线命名例如 pod-restart-diagdescription供模型匹配使用写清楚触发场景、输入、输出正文执行步骤和判断规则控制篇幅避免一次性加载过多内容附加脚本处理确定性计算或文件读写只保留必要脚本减少依赖正文内容不要写成人话贴士要写得像一份可以让另一个工程师接手执行的 SOP。每一条步骤都要有明确动作和检查点。4.2 MCP 的协议原语与调用环节MCP 客户端和 server 之间主要走这几类消息消息作用使用场景initialize握手协商协议版本连接建立时tools/list获取 server 暴露的全部工具客户端发现可用能力tools/call调用指定工具模型决定调用工具时resources/list获取可读资源列表客户端需要加载上下文prompts/get获取服务端提示模板客户端拉取预置 prompt实际排错时如果客户端一直说没有工具可以先看tools/list是否成功返回。如果返回了工具但调用时报错再去看tools/call的请求参数和错误信息。4.3 Skills 与 MCP 的对比表对比维度SkillsMCP核心作用给模型一套执行流程和规范给模型一个统一访问工具和数据的方式典型载体Markdown 文件可选脚本独立 serverJSON-RPC 通信是否需要外部服务不一定本地文件即可需要 server 进程或远程服务鉴权方式没有统一标准server 层统一处理鉴权跨客户端复用复制文件即可配置 mcpServers 即可适合场景方法论、模板、固定流程实时数据、API、数据库、系统操作容易出问题description 不准确、正文过长路径错误、环境变量缺失、协议不兼容这张表不是绝对规则。项目里经常会把两者组合使用因为 skill 负责告诉模型“做什么步骤”MCP 负责“如何拿到步骤需要的数据”。5. 常见误判与排查路径Skills 和 MCP 都有各自典型的“看起来能用但实际不好用”的问题。下面从现象倒推原因。5.1 症状加了 skillsAgent 还是不按预期执行现象skill 文件已经放在skills目录但模型完全没按里面步骤执行或者在某些不该触发的场景误触发了。可能原因description 写得过于宽泛模型无法匹配。description 和正文不一致模型根据描述加载后发现正文是别的内容。正文太长被上下文压缩后关键步骤被丢。客户端没有开启自动 skill 加载功能需要手动指定或通过命令触发。检查方式先问模型“你现在使用的 skill 是什么”再看客户端日志里是否出现 skill 加载记录最后检查 skill 文件路径是否在客户端读取范围内。处理建议把 description 改造成带触发条件的句子例如“当用户提到 Pod 重启、CrashLoopBackOff、OOMKilled 时使用”。正文尽量压缩到一屏以内复杂细节放到附加脚本或参考资源里。5.2 症状MCP server 注册成功但工具调用失败现象客户端能看到工具列表但一调用就报超时、找不到目标、权限不足或返回空结果。可能原因mcpServers 里的command路径错误。工作目录不对相对路径失效。脚本依赖未安装server 启动后立刻退出。server 需要的环境变量没有注入。返回数据格式不符合客户端解析要求。检查方式python /absolute/path/to/agent-project/mcp_servers/k8s_mcp_server.py先手动运行看是否报错。再查看客户端日志里有没有initialize失败记录。如果使用的是远程 MCP还要检查网络连通性和鉴权 token。处理建议优先使用绝对路径和虚拟环境 Python把密钥放在环境变量中在 server 里加日志函数记录每次tools/call的入参和异常堆栈。5.3 上下文过大自动总结后仍然超限很多 Agent 客户端会提示“上下文过大已进行多次自动总结但上下文大小仍超出限制”。这个现象往往不是单一工具导致的而是技能正文和 MCP 返回内容同时膨胀。可能原因skill 文件里塞了大量示例文本模型每次加载都要占用大量 token。MCP 工具返回了整张表或整个日志文件没有做摘要。客户端一次性加载了过多 MCP 工具的 schema工具描述太长。同一个 session 中反复调用返回大数据量的工具历史消息越来越长。处理建议把 MCP 工具返回值改成“摘要 抽样”例如只返回前 50 条事件而不是返回全部 JSON。如果有大文件通过 MCP 的 Resource 按需读取片段不要让模型一次性读完。对 skill 做“触发加载”设计只有相关任务才加载对应正文。关闭不用的 MCP server减少工具 schema 对上下文的占用。如果自动总结仍然不够考虑拆分 session把长任务的中间结果写到文件或数据库下一次任务重新读取。5.4 排查清单检查项检查方式处理动作skill 是否被正确加载查看客户端日志或让模型复述修正 description、路径、触发条件skill 正文是否过长估算 token 数精简正文抽到脚本或资源中MCP server 是否能启动手动运行脚本修复路径、依赖、虚拟环境MCP 工具是否出现在列表中tools/list检查 mcpServers 配置和协议握手MCP 工具返回是否过大查看日志中的返回内容增加摘要、分页、字段裁剪环境变量和密钥检查客户端注入方式不要把密钥写入仓库上下文是否持续膨胀观察多次调用后的 token 变化使用分区能力、独立 session、闭全文返回按照从“输入是否正确”到“日志是否报错”的顺序排查能省去大量试错时间。6. 落地建议与可复用的检查清单最后这部分不是“二选一”的结论而是给出一个可以在真实项目里直接使用的判断顺序。6.1 先问这 5 个问题开发新能力之前按顺序回答以下问题这项能力是“教模型按规范做事”还是“给模型一个原来没有的操作入口”数据源是不是跨系统、需要实时访问、需要中心化鉴权流程是否稳定预计多久调整一次同一能力是否需要多个客户端复用如果用 Skill 承载会不会让每个会话的提示词显著变大如果答案是“规范 稳定 不涉及外部系统”先考虑 Skills。如果答案是“实时数据 多客户端 需要鉴权”考虑 MCP。如果两个都有就组合使用。6.2 Skills 的生产维护建议把 skills 作为代码管理走 Git 评审。每个 skill 必须写清楚适用场景、输入、输出和步骤。不在 skill 正文里放密钥不写入可执行的高级权限命令。定期清点 skill 数量删除长期无触发的技能。在真实对话中对每个 skill 做回归测试确认描述命中率和执行效果。如果团队里有大量技能可以建立一个技能目录索引例如README.md里写清楚“哪个场景用哪个技能”方便新成员理解。6.3 MCP Server 的生产提醒固定依赖版本避免 SDK 升级导致协议行为变化。在 server 端做参数校验和错误返回不要直接把 stack trace 抛给模型。工具命名要语义化例如pod_logs好过get_data。为只读能力提供只读工具减少误操作风险。记录每个工具的调用次数、耗时、失败率便于判断哪些工具真的有用。对于需要长时间运行的查询设计异步任务或超时限制避免阻塞客户端。对于本地 MCP 服务还要注意进程生命周期。某些客户端会在会话结束时销毁 server 进程如果 server 有初始化成本这种模式会影响效率。更复杂的生产环境可以把 MCP server 做成独立服务通过远程传输方式接入。6.4 最小落地顺序无论最终选择 Skills、MCP 还是两者结合都建议按这个顺序落地先用纯文本把任务流程写出来确认流程本身是对的。把流程中涉及外部数据的部分标记出来确定数据源和操作。把流程写成 skill把数据操作拆成 MCP 工具。本地先跑通最小案例验证模型能正确加载 skill、调用工具、按模板输出。加入错误分支和权限控制再进入测试环境和生产环境。Skills 和 MCP 的关系并不是竞争。真正值得关注的是一套能力如何以更低的维护成本、更稳定的行为被 Agent 使用。先判断问题在哪一层再决定用哪种机制。这个判断顺序比记住任何一份技术清单都更重要。