1. 从 Function Call 到 SKILLS:先把三者之间的关系摆清楚
如果你在去年年初开始做 AI Agent,大概率最早接触的是 Function Call;到了年底,身边全是 MCP 的声音;今年开春又被 SKILLS 刷屏。说实话,我一开始也有点懵——这三个名词到底谁替代谁?是同一件事换了马甲,还是真的在演进?
这篇文章我会结合自己做 Agent 项目的实际经历,把 Function Call、MCP、SKILLS 之间的真实关系、各自的边界,以及怎么在实际项目里组合使用,拆开来说清楚。适合正在从零搭 Agent、想给现有 Agent 加外部能力的开发者,也适合被各种新名词绕晕、想一次搞明白的朋友。
1.1 一个让我重新审视 Agent 的场景
我手头有一个自动化项目:让 Agent 根据需求文档自动生成前端页面。最开始我用 Function Call 给 Agent 挂了一个"读取设计稿标注"的接口,再挂一个"生成代码"的函数,写了大几百行 JSON schema,勉强跑通。后来我接了 MCP,把设计稿工具和浏览器自动化工具通过统一协议接进来,配置工作量一下少了很多。再往后,我发现真正让这个项目"稳定可用"的,不是又多接了什么工具,而是把整套流程沉淀成了一份 SKILLS 文件。
这个转变过程让我对"Agent 能力扩展"有了完全不一样的理解:能力扩展从来不只是"多接一个函数、多配一个服务"这么简单,它其实经历了从"给模型一双手"到"给模型一套标准接口",再到"给模型一份岗位操作手册"的演进。手里有工具不等于会干活,会干活还得有规范,这个逻辑在 Agent 身上一模一样。
1.2 三者的定位差异与协作关系
先说结论:Function Call 解决的是"模型能表达调用意图";MCP 解决的是"工具能统一接入";SKILLS 解决的是"Agent 能按一套成熟工序完成某一类任务"。三者不是互相替代,而是层层递进的关系。
| 层面 | 核心问题 | 粒度 | 维护者 |
|---|---|---|---|
| Function Call | 模型怎么表示"我要调用某个函数" | 单个动作 | 开发者逐函数定义 schema |
| MCP | 外部工具怎么接入主流 Agent | 整套工具服务 | 工具方提供 Server,客户端统一消费 |
| SKILLS | 某一类任务怎么稳定地做出来 | 任务工序 | 使用方沉淀,复用给多个项目 |
用流水线来类比:Function Call 是员工的手,单件取用工具;MCP 是统一规格的插座,什么工具插上就能用;SKILLS 是岗位操作手册,规定这单活按什么流程干、干到什么标准验收。很多人把 SKILLS 理解成"高级提示词",这没错,但只说对了一半——它能带脚本、带资源、带外部工具编排,本质上是一份可执行的作业指导书。
2. Function Call 实践笔记:Agent 有了工具,但接入方式很快见顶
2.1 最朴素的 Function Call 是怎么工作的
Function Call 的核心机制,是让模型在生成回答的同时,附带输出一段结构化 JSON,表示"我想调用某个函数"。开发者不替模型执行,而是拿到这段 JSON,在自己的服务端完成真实调用,把结果返回给模型,模型再基于结果继续生成。
标准做法是在请求里声明 tools 列表。下面是一个把 Python 函数包装成 tools 的最小示例:
tools = [ { "type": "function", "function": { "name": "get_weather", "description": "查询指定城市的实时天气", "parameters": { "type": "object", "properties": { "city": {"type": "string", "description": "城市名称"} }, "required": ["city"] } } } ]模型收到"北京今天适合穿什么"这样的问题时,会生成一句类似{"name": "get_weather", "arguments": {"city": "北京"}}的调用意图。开发者解析后执行请求,把天气数据回填给模型,模型再组织成自然语言回答。整个闭环并不复杂,这也是它能在 2023 年之后迅速普及的原因——理解成本低、门槛低,几乎任何 Agent 框架都能支持。
2.2 我在项目中遇到的三个现实问题
但真实项目很快会暴露问题。第一个是 schema 维护成本会失控。当工具从三五个涨到二三十个,每个函数都要写好 description 和 parameters,互相之间还有参数重叠,后端接口一改,JSON 定义就得同步改,特别容易漏。第二个是接入摩擦。每个工具服务的认证方式、调用协议、数据格式都不同,我为接一个浏览器自动化工具、一个设计稿标注工具和一个数据库查询工具,写出了三套完全不同的适配代码,每套都有各自的心跳检测和超时处理。
第三是上下文压力。每次对话都要把几十个函数定义全部塞给模型,一个函数定义平均 200 token,二十个就是几千 token。费用增加还是小事,关键模型会忽略冷门工具,明明有现成函数不用,反而靠想象编一个答案。这三个问题叠加,Agent 给我的感觉就是"会调用工具,但不好养"。尤其是你辛辛苦苦写完一套工具接入,换个 Agent 框架又得重来,这种点对点集成的成本,是每个做 Agent 的人都绕不开的坎。
2.3 Function Call 并没有退场
需要说明的是,Function Call 这套机制至今没有退场,也不会退场。MCP 里的工具最终往往还是要映射成某种 tool calling 形式交给模型;SKILLS 里写到的"调用工具"环节,底层大概率还是 function calling。它退场的是"作为唯一扩展方式"的地位——当扩展点越来越多,单靠它逐一定义和接入,效率就跟不上了。
我在后面的项目里,把 Function Call 当作原子能力,MCP 当作连接层,SKILLS 当作流程层。原子能力负责"表达意图",连接层负责"统一输入输出",流程层负责"保证交付质量"。这个分层思路,在后面两节里会越来越清楚。
3. MCP 破局的关键:统一协议带来的生态连锁反应
3.1 MCP 的组成:Host、Client、Server 一条链
MCP(Model Context Protocol)出现的本质,是把"工具方点对点接入 Agent"变成"工具方开发一次 Server,任何支持 MCP 的客户端都能用"。它定义了基于 JSON-RPC 2.0 的通信规范,既支持本地进程间通信(stdio),也支持远程 HTTP 通信(Streamable HTTP)。
整条链路里有三个角色:Host 是运行 Agent 的应用,比如 Claude Desktop、IDE,或者你自己写的业务平台;Client 在 Host 内部负责和 Server 建立连接;Server 则是暴露具体工具的进程,比如浏览器控制器、数据库查询器、设计稿标注读取器。
实际配置一个 MCP Server 很直接,比如在 claude_desktop_config.json 这类配置文件里加一段:
{ "mcpServers": { "playwright": { "command": "npx", "args": ["-y", "@playwright/mcp@latest"] } } }配置完成后,Agent 就能像调用一个普通函数那样,去调用这个 Server 暴露的所有工具。你不用关心对方内部是什么语言、什么协议、怎么认证,统一握手、统一传参,这些都由协议层处理干净。
3.2 生态扩张的真实案例:从浏览器到设计稿到建模
MCP 能快速铺开,我认为核心原因不是"协议设计多漂亮",而是它让工具方以极低成本接入大量 Agent 客户端。我实际接触过几个典型场景,感受都挺深:
| 场景 | 工具举例 | 解决什么问题 |
|---|---|---|
| 浏览器自动化 | Playwright MCP | 让 Agent 自己开页面、点击、截图、跑断言,非常轻量 |
| 设计协作 | 蓝湖 MCP / Figma MCP | 读取图层尺寸、颜色、标注,辅助设计稿转前端代码 |
| 持续集成 | Jenkins MCP | 查询流水线状态、触发构建,运维日常问答顺手解决 |
| 三维建模 | Blender MCP | 自然语言控制建模、调材质,创意生产流程自动化 |
| 安全测试 | BurpSuite MCP | 把流量、扫描结果交给 Agent 分析,提升漏洞研判效率 |
这些工具分布在不同领域,认证方式完全不同。如果没有 MCP,我至少要为每一个写一遍集成代码。现在只要工具方发布了自己的 Server,我在配置文件里加几行就完事。这种标准化带来的生态连锁效应,是 MCP 最大的价值。
3.3 MCP 并没有解决"什么时候该用什么工具"
但 MCP 也有明显的边界。你接的 Server 越多,Agent 手里的工具清单就越长。模型面对一大堆工具的时候,选择困难就出现了:该用哪个工具、调用顺序是什么、失败后重试策略是什么,MCP 协议本身完全不关心。
举一个很痛的例子:在"设计稿转页面"任务里,我同时接了蓝湖 MCP、Playwright MCP 和本地代码生成工具。正确的流程应该是"先读设计稿标注 -> 再生成代码 -> 最后用浏览器验证效果"。但最开始实现的 Agent 经常乱序,先打开浏览器,再读设计稿,输出驴唇不对马嘴。这提醒我:工具接入标准化是必要条件,但不是充分条件。要让 Agent 高效完成一类任务,还需要更高一层的编排能力,也就是接下来要说的 SKILLS。
4. SKILLS 的本质:把任务工序打包,而不是继续堆工具
4.1 SKILLS 到底是什么
我比较认可的一个定义是:SKILLS 是一种结构化的能力文件,把"完成某类任务所需的知识、提示词、工具调用规则、工作流步骤、质量标准和示例输出"打包成一个独立目录,Agent 根据任务描述动态加载并使用。
它的形态通常是这样:
my-skill/ ├── SKILL.md ├── scripts/ │ └── process_data.py └── resources/ └── template.htmlSKILL.md 是核心,开头用 YAML frontmatter 写清楚技能名称、描述和适用场景,正文则包含操作步骤、决策原则、避坑点、质量标准。用 markdown 写出来大概长这样:
--- name: design-to-page description: 根据设计稿链接或截图生成高质量前端页面时使用。 when_to_use: 当用户提供 Figma/蓝湖链接、设计稿截图,并希望得到可用页面代码时,优先使用本技能。 --- # 设计稿转页面 ## 步骤 1. 通过设计稿 MCP 读取图层标注,提取颜色、间距、字号、布局结构。 2. 按 HTML 语义化结构组织页面,使用 Tailwind 或 CSS 变量管理样式。 3. 输出完整页面代码,并在浏览器中用 Playwright MCP 自测关键交互。从性质上看,SKILLS 和"提示词模板"有一个关键差异:提示词模板只给模型一段话;SKILLS 则可以有脚本、资源文件、外部流程,甚至能指示模型去调用多个 MCP Server 完成一个完整工序。这等于把人的作业流程固化进了 Agent 的运行环境,而不只是"教它说一句话"。
4.2 与 Function Call、MCP 的边界与组合方式
要理解三者的关系,可以看一个我做过的实际组合。Function Call 负责"手":模型决定调用get_weather、generate_code这样的原子函数,Function Call 保证它能表达意图。MCP 负责"管线和插座":设计稿数据、浏览器操作、测试执行,都通过 MCP Server 暴露给 Agent。SKILLS 负责"操作手册":把"先读设计稿 -> 再生成页面 -> 再浏览器验证 -> 再输出交付说明"的整体流程写成 SKILL.md,成为可复用、可版本化、可分发的工作标准。
换句话说,SKILLS 的正文里可以写"使用 MCP Server 中的 xxx 工具做一步",但 SKILLS 本身不负责通信;它管的是"什么时候用哪个工具、用什么顺序、做到什么标准"。所以三者的正确姿势不是二选一,而是叠着用。
4.3 判断一个 SKILLS 是否合格
随着 skills 这个概念被讲得越来越多,网上的技能仓库也是一抓一大把,比如 superpower skills、opencode skills、codex skills,以及各类 GitHub 上的 skills 集合。质量参差不齐是肯定的,我判断一个 skill 能不能用,不看它功能名称多酷,只看三点。
第一,触发条件要窄。SKILL.md 里when_to_use写得越具体,Agent 误触发的概率越低。第二,步骤要明确到"可执行"的程度。每一步要有输入、有输出、有可判定的标准,不能让模型自由发挥。第三,质量标准要具体。不写"输出高质量代码",而要写"页面在 1280px 宽度下无溢出和错位""颜色必须使用设计稿原始色值"这类可验证的条款。
很多人问"如何学习 skills(技能)",我的答案一直很朴素:不要背文档,挑一个和你业务接近的 SKILL.md 通读一遍,看作者怎么设计步骤和标准,然后把它改造成自己的。读十篇教程,不如动手写一个。
5. 完整实操:安装 GitHub 上的 Skills,再手写一个自己的 Skill
5.1 Claude Code 手动安装 GitHub Skills 的具体步骤
这个问题我被问过很多次,很多人卡在"从 GitHub 下载了 skills 仓库,但 Claude Code 就是识别不到"。其实手动安装步骤并不复杂,关键是目录位置和结构要对。以 Claude Code 为例,完整流程是这样的:
第一步,把目标 skills 仓库 clone 到本地:
git clone https://github.com/xxx/awesome-skills.git第二步,找到你要的 skill 目录,把整个目录复制到 Claude Code 的技能目录里。全局目录一般在~/.claude/skills/,项目级目录是.claude/skills/:
mkdir -p ~/.claude/skills cp -r awesome-skills/frontend-page ~/.claude/skills/第三步,确认目录结构是"一个目录 + 里面直接放 SKILL.md",不要多包一层。正确的结构是~/.claude/skills/frontend-page/SKILL.md,不能是~/.claude/skills/frontend-page/xxx/SKILL.md。这个细节最容易出错。
第四步,重启 Claude Code,让它启动时重新扫描技能目录。之后用技能描述里覆盖的自然语言触发即可,比如"帮我把这个设计稿转成页面",它会自动加载对应 skill。
Codex 的安装逻辑类似,技能目录通常在~/.codex/skills/。有些 skills 仓库带了 README 或安装脚本,建议先看一眼说明,因为部分技能还依赖 npm 包或 Python 环境,需要先装好依赖才能跑。
5.2 手写一个"设计稿转前端页面" Skill
与其到处抄现成 skill,我更建议从手写开始。写的过程会让你真正理解技能需要拆成几层:先是触发信息,再是工序编排,然后是质量把关。
下面是我常用的一个"设计稿转前端页面"SKILL.md 骨架:
--- name: design-to-page description: 根据设计稿链接或截图生成高质量前端页面,适用于前端开发和视觉还原场景。 when_to_use: 用户提供蓝湖/Figma 链接、设计稿截图或标注图片,并希望得到可直接运行的页面代码时使用;其他场景不要使用本技能。 --- # 设计稿转前端页面 ## 输入 - 设计稿链接或截图文件路径 - 需要输出的页面类型说明(营销页 / 后台页 / 移动端页面等) ## 工序 1. 读取设计稿:调用蓝湖/Figma 对应的 MCP Server,提取页面整体尺寸、关键颜色、间距、字体层级。 2. 梳理布局结构:把页面拆分成 header、hero、section、footer 等区块,先用一段话描述结构再写代码。 3. 编写页面:使用语义化 HTML,样式优先用 Tailwind 或 CSS 变量,保证设计稿还原度达到 90% 以上。 4. 自测:用 Playwright MCP 打开本地页面文件,截图对比设计稿的关键区块差异,必要时迭代修正。 5. 输出:交付页面代码文件、运行方式说明、自测截图,并列出与设计稿不一致的地方。 ## 质量标准 - 颜色使用设计稿原始色值,不允许凭感觉修改。 - 交互状态(hover、active)至少覆盖按钮和链接。 - 页面在 1280px 宽度下无溢出和错位。这个 skill 的when_to_use写得很窄,就是为了降低误触发率。运行时,它会引导模型按步骤调用 MCP Server,最终输出就不是"随机生成一版页面",而是真正有设计稿依据的页面。我在团队里把它和蓝湖 MCP 组合使用,效果比我预期的还要好,还原度明显提升,返工率大幅下降。
5.3 手写一个"数学建模报告辅助" Skill 的思路
数学建模类 skill 这两年也很火,华为杯、美赛这种比赛里,很多同学开始给 Codex 或 Claude Code 配 skills。以"数学建模报告辅助"为例,我建议把工序设计成这样的节奏:
- 解析题目:提取约束条件、目标函数、数据样本类型,这一步不急着给方案。
- 建模选型:根据问题类型(优化、预测、评价)给出候选模型,并说明选择依据。数据量小的时候优先机理模型,数据量大再考虑统计或学习方法。
- 代码生成与验证:为所选模型生成可运行的 Python 代码,并跑通验证集,不允许给没有运行结果支撑的模型。
- 报告撰写:按照摘要 -> 问题重述 -> 模型假设 -> 模型建立 -> 求解 -> 灵敏度分析的标准结构输出。
这类 skill 真正的价值在于,它约束了模型不跳步。用通用对话式 AI 时,模型经常上来就给答案,步骤残缺;而 skill 把比赛报告的结构性要求固化进流程,让整个输出像模像样,摘要也有依据,不是空话套话。如果你正在备赛,强烈建议把这类工序自己写一遍。
5.4 最容易踩的四个坑
在实际跑通 SKILLS 的过程中,我至少踩过四类坑,在这里列出来供参考。
第一,目录层级不对。技能不生效大概率不是写错了,而是放错位置或目录多套了一层,Claude Code 默认只扫描技能目录的第一级子目录。第二,frontmatter 字段写错或没写。description 缺失时,Agent 不知道何时加载技能;when_to_use写得太宽,则会在不该触发时乱触发。第三,skill 依赖的 MCP Server 没配置。SKILL.md 里写了"调用蓝湖 MCP",但对应 Server 没在客户端配置里启用,技能会静默失败,表现就是 Agent 只聊不做。第四,脚本路径写死。scripts 里的脚本如果写死了开发机路径,换台机器就废,尽量用相对路径或环境变量。
这四个坑都很小,但任何一个都会让 skill 直接不可用。排查建议按顺序来:先看目录和 frontmatter,再看 MCP 配置,最后看脚本路径,基本能解决大多数问题。
6. 选型建议与演变方向:三层能力栈怎么组合
6.1 按任务复杂度选型
看完整个演进过程,很多人会问:那我做项目时到底用哪个?我的建议是按任务复杂度来选,而不是追时髦。
对于简单确定性任务,比如查天气、算加班费这种单函数调用,Function Call 直接搞定,不要为了用 MCP 而用 MCP。对于需要接外部系统的场景,比如查数据库、操作浏览器、读设计稿,优先用 MCP Server,避免自己维护 N 套对接代码。对于需要稳定复现的复杂工序,比如周报生成、设计稿转页面、建模报告辅助,一定要沉淀成 SKILLS,否则每次效果都不稳定。
一个成熟一点的 Agent 平台,三层其实都会用到。原子函数走 function calling,外部系统走 MCP,业务流程写成 skills 存放。这样的架构在维护成本、扩展成本、稳定性之间是相对平衡的。我也见过一些团队试图把业务逻辑全部塞进某个函数或某个 MCP Server,最后代码都变成一坨,明显是分层没做好。
6.2 未来观察:技能市场与 Agent 间协作
顺着 SKILLS 的思路往下看,未来的方向有几条线值得观察。第一是技能的标准化分发。现在的 skills 仓库靠 GitHub 分享,未来可能会演进成带评分、带评论的技能市场,你可以直接下载某个领域公认最佳实践的 skill,再局部调整。第二是 Agent 之间的技能复用。一个 Agent 掌握的 skills 能不能通过协议被另一个 Agent 调用,这会让能力像乐高积木一样组装。第三是安全和权限治理。skill 里的脚本具备执行能力,恶意 skills 可能成为新的供应链风险来源,所以安装未知来源技能时要谨慎,最好先在隔离环境里跑一遍再放到正式工作流里。
6.3 一些选型清单
如果你准备从零搭一个 Agent,我建议按这个顺序做选型:
- 列出你最常做的 3 类任务,分别判断它们属于"单动作"还是"多步骤工序"。
- 单动作任务优先用 Function Call,写好 schema 就够了。
- 涉及外部系统的动作,去查有没有现成 MCP Server,能接现成的就不要自己写。
- 多步骤工序直接写成 SKILL.md,把流程步骤、质量标准、输出格式一次定清楚。
- 每一次跑偏或返工,都回 SKILL.md 里补充一条"注意事项",让技能越用越准。
这样的路径,比"先选框架、再堆功能"稳得多。很多时候真正让 Agent 变得好用的,不是换一个更聪明的模型,而是你把工作标准写清楚了。
7. 写在最后:我的实践体会
最后说点个人体会。我从 Function Call 时代一路做过来,最大的感受是:AI Agent 能力的演进,本质上是把"人类如何用工具完成工作"这件事,一层一层做成了基础设施。Function Call 让模型表达出"我想用工具";MCP 让工具之间的连接成本降到最低;SKILLS 则把"一个熟练员工怎么干活"写成了可复制的文件。
我实际项目里最有价值的一次改动,不是接入了某个很牛的 MCP Server,而是花了一个下午把自己团队"从需求到页面"的工作流程写成了 SKILL.md。从那以后,Agent 的输出质量稳定了不止一个档次。所以说,与其追新名词,不如先把你手头最重复的那件事流程化,然后封装成一个 skill。技术名词会变,但"把工作标准沉淀下来"这件事永远有用,希望这篇内容能帮你少走点弯路。