
上周有个做后端的哥们儿在群里问他想让手里的 agent 能查公司内部接口文档顺带按团队规范生成代码。有人让他写 MCP有人说写个 Skill 就够了还有人直接甩了篇 Plugin 开发教程过来。三份文档他都看了结果比看之前更懵——因为这三样东西压根不在同一个层面上打架。硬要比个高低相当于问螺丝刀、说明书和机器人手臂哪个更好用答案是看你要拧螺丝、要教人干活还是要造一条产线。这篇就把 MCP、Skill、Plugin 这三样东西按层拆开讲清楚它们各自解决什么问题、由谁来维护、什么时候会失效、以及在一个真实项目里怎么叠着用。刚接触 agent 开发不久的人可以拿它当选型清单已经踩过坑的人可以对照着检查自己的架构是不是把三层混成了一层。1. 别急着选型先看清这三种扩展分别长在哪一层很多人一上来就问MCP 和 Skill 哪个强这个问题本身问偏了。MCP 处理的是进程之间怎么对话Skill 处理的是这件事该怎么做Plugin 处理的是宿主程序怎么被改造。三者的作用位置完全不同一个是通信协议一个是自然语言资产一个是跑在宿主里的代码。我见过最典型的翻车是有人把一套我们公司的代码评审规范硬塞进 MCP server 里让 server 每次返回一大段规范文本。能跑但非常别扭规范会变改一次就要发一次版本、重启一次服务而且模型拿到这段文本的时机也不对——它不是工具它是一份知识。1.1 一句话判断法谁在跑代码谁在写文字谁必须待在宿主里判断该用哪个我自己习惯走这三步有没有一段必须由真实程序执行的逻辑比如查数据库、调内部 HTTP 接口、读本地文件、算一个复杂指标。有那核心就落在 MCP 或者 Plugin 上。有没有一套应该怎么做的判断标准比如什么情况该拆表、命名要遵循什么前缀、遇到冲突先改哪边。有那这部分就该写成 Skill。这件事是不是必须改动我正在用的那个软件本身比如加一个右键菜单、拦住保存动作、在侧边栏挂一个面板。是那只有 Plugin 能做到。三步走完你大概率会发现答案不是选一个而是分三段。1.2 用给 agent 装能力倒推一遍举个具体点的例子。你想让 agent 能读公司内网的接口文档站然后按规范生成调用代码。文档站在内网、需要鉴权、内容是分页的——这是数据获取问题交给 MCP server 最合适因为鉴权逻辑、分页逻辑都是代码写完就能复用。拿到文档之后怎么判断哪些字段必填、生成代码时用哪个 HTTP 客户端、异常怎么包——这是规范判断问题交给 Skill写成一份 Markdown 文档改起来不用发版。你还想让 agent 在你按下快捷键时自动读取当前光标所在的接口名——这是宿主行为问题必须写 Plugin因为 MCP server 根本感知不到你的光标在哪。你看一个需求自然裂成了三块。这也是为什么我常说讨论MCP 和 Skill 的区别时最好先讨论我的需求里有几块。1.3 三种扩展的维度对照维度MCPSkillPlugin本质通信协议写给模型看的文档资产宿主程序的扩展代码跑的进程独立进程通过 stdio 或 HTTP 通信不跑代码内容被加载进上下文跑在宿主进程内谁维护后端或平台工程师业务专家、技术负责人宿主生态的插件开发者改动成本中需要发版和重启极低改 Markdown 即可高依赖宿主 API 和版本跨模型通用性高协议层通用高纯文本低绑定宿主最容易出问题的点工具描述质量、上下文占用触发时机、内容过长版本漂移、宿主 API 变更注意这张表不是用来比高低的是用来判断我这块需求到底落在哪一格。落在同一格里的东西才值得比较跨格比较没有意义。2. MCP把外部世界翻译成模型能看懂的接口MCP 全称 Model Context Protocol直译过来就是模型上下文协议。名字里最关键的词是协议两个字。它不是插件系统不是工具库也不是某个厂商的私有格式而是一份约定一个外部程序用什么样的格式声明自己能干什么、用什么样的格式接收调用、用什么样的格式把结果还回去。这一点想通了很多困惑会自动消失。比如为什么我换了一个 agent 应用同一个 MCP server 还能用——因为它遵守的是同一份约定就像换了个浏览器还能打开同一个网站。2.1 Host、Client、Server 三个角色别搞混刚接触时最容易把这三个词弄反。按我的理解方式Host宿主你实际在用的那个 agent 应用本身它负责跟模型对话、管理会话、决定要不要调用工具。Client客户端Host 内部的一个连接器组件一个 Client 负责连一个 Server。你在配置里加一条 MCP 配置Host 就起一个 Client 去连它。Server服务端你自己写的那个进程里面注册了一堆工具、资源或者提示模板等着被调用。经常有人问我该在哪里写鉴权答案是在 Server 里。Host 和 Client 是别人的代码你改不了也不该改。你要做的就是把 Server 写好让它在收到调用时自己去处理 token、cookie、签名这些事。2.2 一次工具调用从提问到返回中间走了哪些路这条链路值得完整走一遍因为绝大多数agent 不调用我的工具的问题都能在这条链路上找到位置。Host 启动时拉起 ClientClient 通过 stdio 或 HTTP 连上 Server。双方握手做能力协商Server 把自己支持的原语报上去。Server 返回工具清单包括每个工具的名字、描述、参数结构。这些工具清单被拼进模型的上下文变成模型能看见的一批可选动作。用户提问模型判断是否需要调用工具需要的话输出一个结构化调用请求。Host 把这个请求交给对应的 ClientClient 转发给 Server。Server 真正执行逻辑把结果按协议格式返回。结果回填进上下文模型基于结果继续生成回答。第 4 步和第 5 步之间是最容易出问题的地方。很多人以为我把工具注册进去了模型就该会调实际上模型只能看到你写的名字和描述。描述写得含糊模型就选不准甚至干脆不选。2.3 MCP 提供的三类原语用途差别很大协议里主要暴露三类东西各自适合不同的场景Tools工具会产生副作用或者需要实时计算的动作比如写文件、发请求、跑查询。模型主动调用。Resources资源只读的数据内容比如一份文档、一条配置、一段日志。更偏向被动加载。Prompts提示模板预置好的提示词模板通常用于把某个固定流程一键触发。实际项目里Tools 用得最多Resources 经常被忽略但其实很有用——把一份经常要参考的规范文档挂成 Resource比每次让模型去读文件要省事得多。2.4 能连上和用得好之间隔着一段距离我自己总结MCP server 能不能被用好八成取决于三件事第一是工具粒度。一个工具干一件事名字要能自解释。我见过一个 server 只暴露了一个叫query的工具参数是一个自由文本字符串模型每次都要猜该往里写什么。后来拆成list_tables、describe_table、run_select三个调用成功率立刻上去了。第二是返回体大小。有的接口一返回就是几千行 JSON塞进上下文之后模型既读不完也读不准。正确做法是在 Server 里就做截断、做摘要、做分页只把必要字段吐出去。第三是错误信息的可读性。抛一个500 Internal Error回给模型模型完全不知道下一步该干嘛返回字段 user_id 缺失请先调用 list_users 获取这种描述模型就能自己纠偏。3. Skill把怎么做写成文档让 agent 自己去读如果 MCP 是把外部能力接进来那 Skill 就是把内部经验沉淀下来。它本质上是一份写给模型看的说明书通常是一个 Markdown 文件加上若干附属资源和可选的辅助脚本。模型在需要的时候把它读进上下文然后照着做。这件事听起来很朴素但威力不小。过去这些怎么做的经验大多藏在老员工脑子里或者散落在各种 wiki 里模型是看不到的。Skill 相当于把隐性经验显性化而且用一种模型最容易理解的格式——自然语言加结构化步骤。3.1 Skill 里到底装了什么一个写得好的 Skill内容大致分四类适用场景说明什么情况下该用这个 Skill什么情况下不该用。这一段直接决定模型会不会误触发。执行步骤分步骤的操作流程每一步说清楚输入是什么、输出是什么、遇到分支怎么走。判断标准那些没有标准答案但有经验倾向的决策点比如遇到循环依赖时优先拆哪一层。参考材料模板文件、字段清单、历史案例放在附属目录里需要时再加载。关键的一点是渐进式加载。Skill 主文件应该尽量短只写主干流程和需要的时候去看哪个附属文件。把几万字的规范全塞进主文件模型每次都要读完上下文成本高得离谱效果反而更差。3.2 Skill 和 Agent 的区别别混着用热词里经常出现skill 和 agent 的区别这个问题值得单独说清楚。我的理解是Agent 是一个执行主体。它有自己的循环——观察、思考、调用工具、看结果、再思考直到任务完成。它有目标、有状态、有工具集。Skill 是一个被调用的知识包。它没有循环没有状态不会自己去做事。它只是当 agent 决定做某件事时翻开的那本手册。打个比方agent 是员工Skill 是岗位操作手册MCP 是员工手上的工具箱Plugin 是办公桌本身。员工可以翻手册、可以拿工具、可以改桌子但手册本身不会自己干活。所以那种我写个 Skill 让它自己定时跑任务的想法是行不通的。Skill 不会自己醒过来必须有 agent 主动去读它。要走定时任务得靠宿主或者外部调度去触发 agent。3.3 什么情况下写 Skill 比写 MCP 划算判断标准很简单这块内容会不会频繁变变了之后要不要发版。会频繁变、而且变了不该发版的写成 Skill。比如代码风格和命名规范季度评审一次改一次。各类文档的写作模板业务侧随时会提调整。某类问题的排查思路随着经验积累不断补充。领域内的判断规则比如建模时该选哪类模型、参数怎么估。这些都是文字改一行 Markdown 就生效不用发版、不用重启、不用重新部署。相比之下如果把这些塞进 MCP server 的返回值里每次调整都得走一遍完整的发布流程运维成本白白翻倍。反过来说如果这块内容包含必须真实执行的计算或者访问那就别硬写成 Skill。我见过有人试图用 Skill 描述一个复杂的 SQL 查询逻辑让模型照着写结果每次都写得略有不同稳定性极差。这种就该封装成 MCP 工具让模型只管调用不管实现。4. Plugin宿主程序自己的扩展口Plugin 这个词比 agent 早出现至少二十年。浏览器有插件编辑器有插件各类桌面软件都有插件机制。它的核心特征是插件跑在宿主程序内部能直接访问宿主的界面、菜单、快捷键、事件和生命周期。这个跑在内部决定了插件的能力边界和 MCP 完全不同。MCP server 是个独立进程它永远只能被动接收调用插件是宿主的一部分它可以主动监听、主动弹窗、主动改界面。4.1 IDE 插件和 agent 插件经常是两回事这是很多人绕不明白的地方。假设你用一个带 agent 的编辑器装了某个语言的语法插件又配了一个查文档的 MCP server。这时候会出现三种扩展并存语法插件宿主生态的 Plugin负责高亮、补全、错误提示。文档 server你配的 MCP负责把文档内容提供给 agent。团队规范一份 Skill负责告诉 agent 写完代码之后该怎么自检。agent 能看到的只有后两者。语法插件做了什么agent 通常感知不到除非宿主主动把插件的某些信息暴露给模型。所以别指望我装了一个强大的插件agent 就自动会用它这是两套体系。4.2 什么时候非 Plugin 不可以下几种需求MCP 和 Skill 都做不到只能上 Plugin改界面要在侧边栏加一个面板、在编辑器里加装饰、在状态栏显示提示。接管宿主行为拦截保存事件、覆盖快捷键、在打开文件时自动执行某段逻辑。常驻监听持续监听文件变化、监听网络请求、监听剪贴板。深度集成宿主数据拿到当前打开的文件路径、当前选中的文本、当前光标位置。这些都是宿主内部的上下文独立进程拿不到。所以像在设计稿工具里读取当前选中图层的标注这类需求就得看宿主开放了什么能力——有的宿主直接提供了 MCP server比如设计稿工具自己出的 MCP那就用 MCP如果它只提供了插件 API那就只能写 Plugin然后由插件把数据转发出来。4.3 Plugin 的代价版本绑死和维护成本Plugin 最容易让人头痛的一点是它跟宿主版本强绑定。宿主升级插件接口变了你昨天还能用的功能今天就报错。这类报错通常长这样加载失败、找不到入口、版本不匹配。排查过程往往很折磨因为报错信息本身没什么信息量。我的经验是能用 MCP 解决的问题就不要写 Plugin。MCP 的协议边界清晰升级影响面小Plugin 拿到的能力更多但要承担宿主的升级风险。只有当需求真的必须触达宿主内部时才去写 Plugin。5. 选型表和三个真实场景的拆解前面把三层讲清楚了这一节把决策路径压缩成可以直接照着走的流程。5.1 一张表把决策路径框住你的需求长这样首选方案理由访问外部数据源、内部接口、数据库MCP有真实代码逻辑需要鉴权和连接管理沉淀判断标准、流程、模板、规范Skill纯文本资产改起来不用发版加界面、改快捷键、拦截宿主事件Plugin必须触达宿主内部上下文需要读写文件、跑命令MCP 或宿主自带工具取决于宿主是否已经内置需要先查数据再按规范处理MCP Skill数据获取和判断逻辑分层需要根据当前光标位置生成代码Plugin Skill宿主上下文由插件提供生成规范由 Skill 提供5.2 场景一让 agent 查内部业务数据需求是让 agent 能查内网的一套业务数据然后回答用户的问题。做法写一个 MCP server暴露三个工具——列可用数据集、描述数据集字段、按条件查询。查询工具的参数必须是结构化的比如dataset、filters、limit不要让模型自由拼 SQL那是给自己挖坑。然后是 Skill写一份很短的文档说明当用户问业务数据相关问题时先用列数据集工具确认有哪些数据可用再描述字段最后查询单次查询行数不要超过 200超过就分页。这份 Skill 解决的是调用顺序和约束MCP 解决的是怎么真的查到数据。提示查询类工具的limit参数一定要设默认值并在描述里写明上限。我吃过这个亏模型有一次让我拉了全表上下文直接被撑爆。5.3 场景二让 agent 按团队规范写文档需求是让 agent 生成接口文档、周报、技术方案时都符合团队格式。这种需求几乎百分之百应该写成 Skill。把模板、章节顺序、必填字段、语气要求、常见错误清单全写进去主文件控制在几百字以内把详细的模板放在附属文件里按需加载。为什么不写 MCP因为这里没有任何需要执行的逻辑。你写一个 MCP server 专门返回一段模板文本等于为了发一条消息去建一个邮局纯属多此一举而且改模板还要发版。5.4 场景三让 agent 读设计稿里的标注需求是让 agent 能拿到设计稿的图层信息、色值、间距然后生成对应的样式代码。这个场景的关键是看宿主提供了什么。不少设计工具已经出了自己的 MCP server能直接暴露图层数据那你只需要配一下就能用顺带写个 Skill 说明颜色值优先用变量、间距取 4 的倍数、字号走 tokens。如果工具只开放了插件 API那就要写 Plugin 把选中图层的数据导出来再由插件把数据交给 agent。这里有个很实际的经验先花半小时去翻宿主的官方文档确认它有没有现成的 MCP。很多时候答案是有的只是没被写进你看到的教程里。自己写一遍插件再发现官方早就提供了那种感觉相当难受。6. 我在这三种扩展上翻过的车前面讲的都是原理和方式这一节说点苦的。下面这些坑我自己逐个踩过写出来是为了让你少走一遍。6.1 工具描述写成产品说明书模型反而不调第一次写 MCP server 的时候我给每个工具写了一段很正式的功能描述什么本工具用于实现 XXX 功能支持多种参数组合。结果模型基本不调宁可自己瞎猜。后来我把描述改成口语化的短句直接说清楚什么时候用它、返回什么、不要用它做什么调用率立刻正常了。比如把本工具用于查询用户信息改成根据用户 ID 查单个用户的姓名和邮箱如果只有名字没有 ID先用 search_users。注意工具描述是写给模型看的不是写给同事看的。判断标准是模型读完能不能判断出该不该调而不是人读完觉得专不专业。6.2 一口气挂了三十个工具上下文直接爆有一阵我图省事把一个 server 的所有工具全挂上了二十多个。结果发现模型变笨了简单问题也开始乱调工具回答还经常跑偏。原因很直白——工具清单是常驻上下文的挂得越多模型每次要扫的候选就越多选择难度上升而且留给正文推理的空间被挤压。后来的做法是按场景拆 server需要哪组开哪组常驻工具控制在十个以内。6.3 权限没做隔离让 agent 摸到了不该摸的地方这个是事后冷汗最多的一个。早期我给查询工具的账号权限给大了本意是方便调试结果有一次 agent 在多轮对话里自己拼出了一个超出预期的查询。虽然没造成后果但从那之后我立了条规矩MCP server 的凭证必须是只读的、最小权限的、最好带白名单的。Skill 里也要写清楚禁止的部分。只用正面描述告诉模型该做什么模型在边缘情况下容易自由发挥把明确的禁止项写出来约束力会强很多。6.4 版本漂移昨天还好好的今天就报错Plugin 类扩展最容易碰到这个。宿主一升级插件要么加载失败要么行为变了。我现在的习惯是给 Plugin 的依赖版本做锁定能锁就锁。在配置里记录当前验证过的宿主版本升级前先在一个独立环境里跑一遍。把这套扩展的备用方案写进文档出问题的时候能快速降级。MCP 和 Skill 也有漂移问题但轻得多。Skill 是纯文本风险主要在内容过时MCP 的风险主要在协议版本和参数结构变化通常改几个字段就能修好不用重写。7. 把三者叠起来用一个我自己在用的分层思路走到这里选型其实已经不难了。我更想分享的是怎么把它们叠起来用因为真实项目里几乎不会只用一层。我的分层习惯是这样的最底层是宿主 Plugin只做一件不得不做的事——把宿主独有的上下文当前文件、选中内容、光标位置暴露出来。这一层我尽量写得薄代码量越少升级时越不容易坏。中间层是 MCP负责所有需要真实执行的动作查数据、调接口、读写文件、算指标。每个 server 只服务一个明确的场景域工具数量克制返回体做截断错误信息写清楚。最上层是 Skill负责把怎么做写明白什么时候用哪个工具、工具返回之后怎么判断、输出格式是什么、哪些是禁止的。这一层改得最频繁但改起来最安全因为它就是几个 Markdown 文件。搭好之后日常迭代基本都发生在上层。业务规范变了改 Skill数据源加了字段改 MCP需要新的宿主交互才动 Plugin。这种分层最大的好处是变更的影响面可控——你不会因为改了一句写作规范就要重新部署一遍服务。最后说一句我自己最真实的体会刚开始接触这三样东西时我总想找到一个最正确的那个结果越找越乱。后来才明白它们的关系不是替代而是分工。真正要问的问题从来不是该用哪个而是我这个需求拆开之后哪一块该落在哪一层。把这个问对了剩下的都是执行细节。