Agent Skills、MCP、Function Calling 到底啥区别?一文讲透
一个把我绕晕的周末
上个月有个朋友找我,说他们团队在用 Claude Code 搭一套自动化测试流程,文档里满屏的 “MCP Server”“Function Calling”“Agent Skills”,他看到第三遍还是没搞明白:“这几个东西到底啥关系?我到底该用哪个?”
这还真不是他一个人困惑。
我去翻了下社区里的讨论,发现一个挺普遍的现象——有人把 MCP 当成 Function Calling 的升级版,觉得“有了 MCP 就不需要 Function Calling 了”;也有人觉得 Skills 就是“高级一点的 Prompt”。这些理解都不太对。
它们的层级关系其实是固定的:MCP(平台层)> Skill(业务层)> Function Calling(原子层) 。别急着记这个结论,先把每个东西搞明白,这句话自然就懂了。
用的讨论,都得从 Function Calling 说起。因为它是后面两个东西能够存在的前置条件。
2023 年 6 月,OpenAI 在 gpt-3.5-turbo 上首次引入了 Function Calling 能力。它的核心机制其实很简单:
你用 JSON Schema 描述一个函数的样子——叫什么名字、有哪些参数、参数是什么类型——然后把这份描述连同用户的问题一起发给模型。模型判断需要调用这个函数时,会返回一个结构化的 JSON,里面包含函数名和参数。
这里有一个特别容易被误解的地方:模型并不会真的去执行那个函数。 它只负责“点单”——告诉你它想调什么、传什么参数。真正的执行,是你写在代码里的逻辑。
整个流程走四步:
-
用 JSON Schema 把可用工具告诉模型 -
模型返回 tool_calls,包含函数名和参数 JSON -
你的代码解析参数,调用真实函数 -
把执行结果以 role: "tool"追加进对话,再请求一次,模型基于结果给出最终回答
我一直觉得 Function Calling 很像一个只会点菜不会做菜的食客。它知道菜单上有什么,知道自己想吃什么,但端菜上桌这件事跟它没关系。
Function Calling 的局限也很明确。工具定义跟模型强绑定,换一个模型就得重新适配;工具数量一多,描述就膨胀,模型选择工具的准确率会明显下降。
MCP:把插座标准化
Function Calling 解决了“模型怎么表达调用意图”的问题,但没解决“后端怎么执行工具”的问题。
以前的做法是:每个应用自己手写对接代码。A 模型要调天气工具,写一套;B 模型也要调同一个天气工具,再写一套。工具的实现方式五花八门,有 REST API 的,有本地脚本的,有 gRPC 的,每接一个都得单独适配。
Anthropic 提出的 MCP(Model Context Protocol) 就是为了统一这件事。它定义了一套标准化的客户端-服务器协议:工具提供方把能力封装成 MCP Server,AI 应用作为 MCP Client 连接上去,通过标准化的接口发现和调用工具。
有个特别贴切的比喻:MCP 就像 AI 界的“聚合支付” 。以前每个商户都得单独对接微信支付、支付宝、银联,现在统一成一个二维码,谁来扫都行。
MCP 在协议层面做了几件关键的事:
动态能力发现。 客户端发送 ListToolsRequest 就能拿到服务器当前提供的全部工具列表,不需要提前硬编码。服务器加了新工具,客户端自动就能看到。
标准化调用接口。 通过 CallToolRequest 发起调用,参数用 JSON Schema 校验,不同语言、不同框架写的工具只要遵循协议就能无缝对接。
安全边界。 MCP 工具代表任意代码执行,协议要求对工具调用做严格的权限控制。
用一句话概括:Function Calling 让模型“知道能做什么”,MCP 让模型“能连上做这件事的工具”。
但 MCP 也有它的代价。所有 MCP Server 的工具描述在会话启动时就加载进上下文,装多了之后 token 消耗非常可观。而且它解决的是“连接”问题,不解决“怎么做才对”的问题。
Agent Skills:把你的经验变成可调用的能力包
MCP 让 Agent 能连上工具了,但连上之后呢?
想象一个场景:Agent 要帮你跑一遍接口回归测试。它有 MCP 连接好的数据库工具、日志工具、接口文档工具。但工具是有了,它知道先做什么、后做什么吗?知道某个接口返回 500 时该重试还是该标记为 bug 吗?知道断言该校验哪些字段吗?
这些问题,MCP 回答不了。Function Calling 更回答不了。
Anthropic 在 2025 年 10 月推出的 Agent Skills 就是冲着这个问题来的。
形式上,Skill 就是一个文件夹。核心是 SKILL.md 文件,YAML 元数据里写技能名称和触发描述,正文用 Markdown 写执行指令。旁边可以放 scripts/ 目录存执行脚本,references/ 存领域知识文档。
但 Skill 真正解决的问题,不是“写一个文档”。它解决的问题是:把“怎么做一个任务”从一次性的对话,变成可复用、可版本控制、可被 Agent 自动调度的能力单元。
这里的关键设计是渐进式披露。Skill 启动时只加载名称和描述,大概 100 个 token,只有当 Agent 判断这个 Skill 跟当前任务相关时,才会展开完整内容。实测下来,初始上下文消耗可以从 16k token 压缩到 500 token 左右。
Skill 和 Function Calling 的本质区别在于:Function Calling 解决的是“能不能调”,Skill 解决的是“该不该这么调”。
Function Calling 是一个原子动作的调用契约。Skill 是一套完整的业务流程——包含多个步骤、多个工具调用、异常处理逻辑、输出格式规范。你写一个“接口测试用例生成”的 Skill,它内部可能调用了参数构造、依赖链分析、断言生成三个 Function Calling,每个都有明确的输入输出约束,但对外暴露的是一个完整的业务能力。
字节在 2026 年初推出 Agent Skills 功能,阿里发布了“悟空”工作平台,腾讯上线了 SkillHub,汇聚超过 28000 个 Skill。测试领域的信号更直接:字节 2026 年春招的测试开发 JD 里,多了一行硬性要求——“对 AI Agent 有深入理解和实践经验”。
一个场景串起三者
说了这么多概念,用一个具体的测试场景把它们串起来。
假设你要让 Agent 自动跑一遍支付接口的幂等性测试。
第一步,MCP 负责连接。 Agent 通过 MCP 协议连接上接口文档服务器,拉取支付接口的 OpenAPI 规范;连接上数据库服务器,准备好查询订单状态;连接上 Jira 服务器,准备在失败时创建 bug。
第二步,Skill 负责流程。 Agent 加载“支付幂等性测试” Skill。Skill 里面写清楚了:先调支付接口发起扣款,然后用同一个订单号再调一次,断言第二次返回的状态码是 200 但订单没有重复扣款。如果第二次返回 500,重试一次再判断。失败时收集 requestId 和响应体,写入 Jira 的指定项目。
第三步,Function Calling 负责执行。 Skill 执行过程中,Agent 通过 Function Calling 逐个调用具体工具:调 call_payment_api、调 query_order_status、调 create_jira_issue。每次调用,模型返回结构化参数,后端代码负责执行。
三者的分工非常清晰:Function Calling 是螺丝刀,MCP 是供电插座和标准接口,Skill 是施工手册加整套工具箱。
搞混它们的人,都在犯同一个错
写到这里,可以回答最初那个问题了。
Function Calling 是基础能力,没有它,后面两个都不存在。MCP 解决的是标准化连接问题——让工具和模型之间的对接有一个统一的协议,不用每换一个模型就重写一次适配代码。Skills 解决的是经验封装问题——让你的测试流程、领域知识、异常处理逻辑变成可复用、可版本控制的能力单元。
它们不是替代关系,是不同层次上的协作关系。Function Calling 让模型有了“嘴”,MCP 让模型有了“手”,Skills 让模型有了“经验”。
那个朋友后来在团队里搭了一套组合拳:用 Skill 封装了 30 多个测试场景的完整流程,用 MCP 连接了接口文档、数据库、CI 系统和 Jira,底层用 Function Calling 驱动每个原子操作。跑了一个月下来,回归测试的用例通过率没变,但用例失效排查的时间从平均 40 分钟降到了 5 分钟。因为 Skill 里封装了失败诊断的排查清单,Agent 自动收集日志、比对响应体、判断是环境问题还是代码问题,人只需要看结论。
他的原话是:“我以前觉得这些概念都是营销词汇,真正跑起来才发现,搞不清它们区别的时候,搭出来的东西就是一堆散装脚本。”
如果你也在搭 Agent 测试体系,建议从这三层去审视你的架构:底层有没有清晰的 Function Calling 定义,中间有没有 MCP 做连接标准化,上层有没有 Skill 做经验封装。三层都到位了,Agent 才算真正能干活。
- 点赞
- 收藏
- 关注作者
评论(0)