1. 项目概述:一次面试引发的深度技术辨析
前几天和一位在阿里做AI应用架构的朋友聊天,他提到最近面试候选人时,发现很多人对“Agent Skills”、“MCP”和“Function Call”这几个概念的理解是模糊的、甚至是混淆的。这其实挺有意思的,因为这三个词恰好代表了当前AI应用开发,特别是智能体(Agent)构建领域,三种不同层级、不同思路的能力扩展方案。它们不是简单的并列关系,而是从微观到宏观,从封闭到开放的一套技术演进图谱。
简单来说,你可以把它们想象成给一个聪明的“大脑”(大语言模型)配备不同工具和技能的方式。Function Call是最基础、最直接的“手把手”教学,告诉模型现在可以调用某个具体函数了。Agent Skills则更像是一个“技能工具箱”的管理理念,它关注如何组织、描述和让模型理解一整套能力。而MCP则是一个雄心勃勃的“行业标准协议”,它试图定义一套统一的语言和流程,让任何工具都能以标准化的方式接入任何模型或智能体,实现真正的“即插即用”。
这次讨论,我们就来彻底厘清这三者的区别、联系以及各自的适用场景。无论你是正在准备面试的开发者,还是希望构建更强大AI应用的工程师,理解这些概念背后的设计哲学和实现差异,都能帮你更好地进行技术选型和架构设计。
2. 核心概念拆解:从Function Call到MCP协议
要理解区别,我们必须先回到原点,看看每个概念究竟解决了什么问题。它们诞生的背景和要应对的挑战是不同的,这直接决定了它们的设计形态和应用范围。
2.1 Function Call:模型与外部世界的“基础连接器”
Function Call,通常被称为“函数调用”,是伴随GPT-3.5/4等模型API一同成熟起来的基础能力。它的核心逻辑非常简单直接:开发者定义好一个函数(包括名称、描述、参数结构),然后将这个定义“告知”大语言模型。模型在对话过程中,如果判断需要调用这个函数来获取信息或执行操作,就会在回复中结构化地输出一个包含函数名和参数的JSON对象。随后,开发者的应用程序解析这个JSON,真正执行本地或远程的函数,并将执行结果返回给模型,模型再基于结果生成最终的自然语言回复给用户。
它的工作流程是一个清晰的闭环:用户提问 -> 模型思考是否需要调用函数 -> 是则输出结构化调用请求 -> 应用端执行函数 -> 返回结果给模型 -> 模型整合结果生成回答。例如,你问“北京今天天气怎么样?”,模型可能会输出一个调用get_weather(location="北京")的请求,你的代码执行这个函数调用气象API,把“晴,25℃”的结果塞回给模型,模型再组织成“北京今天天气晴朗,气温25摄氏度……”这样的句子回复你。
Function Call的本质,是给模型开了一个非常具体、预设好的“后门”。这个后门是什么样、能通向哪里,完全由开发者定义。它的优势在于极度简单和可控,几乎无额外开销,与模型API集成紧密。但它的缺点也同样明显:它是静态和封闭的。函数列表需要在对话开始前就定义好并注入模型的上下文,中途难以动态增删。每个函数都需要手动编写描述和参数格式,当工具数量庞大时,管理和维护成本很高。更重要的是,它缺乏统一的发现和描述标准,每个项目、每个模型平台可能都有自己的实现方式。
2.2 Agent Skills:面向任务规划的“能力抽象层”
当我们需要构建一个能处理复杂任务的智能体(Agent)时,仅仅有一堆零散的Function Call就不够用了。这就是Agent Skills概念登场的时候。Skill不是一个具体的技术协议,而是一个更高层次的设计范式或架构理念。它关注的是如何对“能力”进行抽象、封装和组织,以便智能体能够更好地理解、选择和组合这些能力来完成复杂目标。
一个Skill通常包含以下几个要素:
- 能力描述:用自然语言清晰说明这个技能能做什么、适用于什么场景。
- 输入/输出规范:定义执行该技能需要哪些参数,以及会返回什么格式的结果。
- 执行逻辑:背后具体的代码实现,可能对应一个或多个Function Call,也可能是一段复杂的业务流程。
- 元信息:如技能类别、权限要求、依赖条件、成功概率估计等,用于帮助智能体进行决策。
例如,一个“订机票Skill”可能内部封装了查询航班、比价、填写乘机人信息、支付等多个底层函数调用。但对智能体来说,它只需要知道“我有一个订机票的技能,需要提供目的地、时间和乘客信息”,而不必关心里面具体调用了哪个航空公司的API、支付流程如何衔接。
Agent Skills的核心价值在于“管理”和“规划”。它让智能体以更接近人类“技能”的维度去思考,而不是面对一堆冰冷的函数签名。在基于LLM的智能体框架(如LangChain、AutoGPT、Dify等)中,Skills的管理系统负责技能的注册、发现、描述和调用。智能体的“大脑”(通常是规划模块)根据用户目标和当前状态,从技能库中选择最合适的一个或一系列技能来执行。
与Function Call相比,Skill是更上层的抽象。一个Skill内部可能会调用多个Function Call,而一个Function Call也可能被多个不同的Skill复用。你可以把Function Call看作是“汇编指令”,而Skill则是“高级函数”或“模块”。Skill的设计更注重与智能体规划、推理流程的配合。
2.3 MCP:打破生态壁垒的“通用工具协议”
如果说Function Call是“私有后门”,Agent Skills是“内部管理规范”,那么MCP的目标就是建立一条“公共高速公路”。MCP,全称Model Context Protocol,是由Anthropic公司牵头提出并开源的一套协议标准。它要解决的核心痛点是:AI模型/智能体与外部工具、数据源之间连接的高度碎片化和定制化问题。
在MCP出现之前,如果你想让你Claude、ChatGPT或自己部署的模型能使用某个特定工具(比如查询公司内部数据库、操作Figma设计稿、控制智能家居),你需要为每个“模型-工具”组合编写特定的适配器代码。这产生了大量的重复劳动,并且工具生态难以共享。
MCP协议定义了一套标准化的通信方式,主要包括:
- 标准化接口:规定了工具(称为MCP Server)如何向模型(MCP Client)宣告自己提供了哪些“资源”和“工具”。
- 统一描述格式:工具的能力通过统一的模式(Schema)进行描述,包括名称、描述、参数等,类似于OpenAPI规范,但更简洁,为AI交互优化。
- 安全的执行通道:模型可以通过标准请求调用工具,工具执行后通过标准响应返回结果。这个过程通常是远程过程调用。
- 动态发现与连接:MCP Client可以在运行时动态发现并连接到MCP Server,无需在应用启动前就将所有工具定义硬编码进去。
MCP的核心思想是“关注点分离”和“标准化”。工具开发者只需关注实现一个符合MCP协议的Server,就可以让所有支持MCP协议的AI模型或智能体框架(如Claude Desktop、Cursor、Continue.dev等)直接使用。而AI应用开发者则无需关心每个工具的具体集成细节,只需让他的智能体客户端支持MCP协议,就能接入整个MCP工具生态。
举个例子,社区有人开发了一个figma-mcp-server,这个服务器程序运行后,任何支持MCP的AI助手(如配置好的Claude)就能直接获取Figma文件列表、读取设计稿内容甚至进行简单编辑,而不需要Figma官方为每个AI助手单独开发插件。
3. 三维对比:设计哲学、应用场景与实操差异
理解了各自是什么,我们可以从多个维度进行一场深入的“同台竞技”,这能帮你更清晰地把握何时该用什么。
3.1 设计哲学与定位对比
Function Call:模型原生扩展机制
- 定位:是大语言模型API的一部分,是模型能力的直接延伸。它的设计首要目标是简单、高效、低延迟地让模型获得执行简单、离散操作的能力。
- 哲学:“告诉模型它能做什么具体事”。它是一种指令式的扩展,强调控制和精确性。
Agent Skills:智能体架构中的能力单元
- 定位:是构建复杂智能体(Agent)应用时的架构设计概念。它不属于某个特定模型,而是属于智能体系统本身。
- 哲学:“为智能体规划提供模块化能力”。它是一种任务导向的抽象,强调能力的封装、描述和可规划性。
MCP:跨平台工具集成开放标准
- 定位:是一个中立的、开放的网络协议。它独立于任何特定的模型或智能体框架,旨在成为连接AI模型与外部工具世界的“通用总线”。
- 哲学:“让任何工具都能被任何AI使用”。它是一种协议化、标准化的解决方案,强调互操作性和生态建设。
3.2 技术实现与依赖关系
Function Call
- 实现:深度依赖特定模型提供商(如OpenAI、Anthropic)的API规范。你需要按照它们的格式定义JSON Schema。
- 依赖:强绑定于你所使用的模型API。不同厂商的格式可能有细微差别。
- 通信:通常作为模型API请求/响应的一部分,在同一次HTTP请求/响应周期内完成,是同步的。
Agent Skills
- 实现:没有统一标准,由各个智能体框架(LangChain, AutoGen, Dify等)自行定义其Skill的接口和注册方式。通常需要在框架的代码中定义。
- 依赖:绑定于你选择的智能体框架。从一个框架迁移到另一个,可能需要重写Skill定义。
- 通信:在智能体框架内部进行,可能是内存函数调用,也可能是内部消息传递。
MCP
- 实现:基于标准的、与模型无关的协议(通常使用JSON-RPC over stdio/HTTP/SSE)。工具端实现MCP Server,AI端实现MCP Client。
- 依赖:不依赖任何特定模型或框架,只依赖MCP协议本身。只要双方都遵循协议,即可通信。
- 通信:通常是进程间或网络间的通信。Server可以独立部署和运行,Client动态连接。支持异步和流式响应。
3.3 动态性与生态对比
这是三者区别最显著的地方之一。
- Function Call:静态。函数列表必须在会话开始前确定并注入系统提示词或通过API参数传入。对话中途无法动态添加新的函数。生态上,每个应用都是孤岛。
- Agent Skills:半静态。取决于框架实现,有些框架支持运行时注册Skill,但通常仍需要在代码层面预定义或通过配置文件加载。生态局限于该框架的内部社区。
- MCP:高度动态。MCP Client可以在任何时候发现并连接到新的MCP Server,立即获取其提供的工具列表并开始使用。这带来了真正的“即插即用”体验。它正在形成一个共享的生态,开发者可以将自己写的MCP Server开源,供所有MCP用户使用,比如搜索、数据库、浏览器自动化等通用工具正在涌现。
3.4 复杂度与适用场景
Function Call
- 复杂度:低。适合快速原型验证、功能简单的聊天机器人、需要紧密耦合模型响应的场景。
- 场景:天气查询、简单计算、知识库问答(调用检索函数)等。当你的工具数量很少(<10个),且变动不频繁时,它是最高效的选择。
- 口诀:“简单、直接、快,但别想太多。”
Agent Skills
- 复杂度:中到高。引入了架构设计,需要你思考能力的抽象和智能体的规划逻辑。
- 场景:构建需要自主规划、分解和执行多步骤任务的智能体。例如,一个“旅行规划Agent”可能需要组合“查询航班”、“预订酒店”、“生成日程”等多个Skills。或者企业内部的自动化流程助手,需要调用多个内部系统API。
- 口诀:“我要造一个能自己思考、组合技能完成复杂任务的‘大脑’。”
MCP
- 复杂度:中(使用)/ 高(开发Server)。使用现成的MCP Server很简单(如下载一个二进制文件运行)。开发一个新的MCP Server需要理解协议细节。
- 场景:
- 希望AI助手拥有广泛、可扩展的工具能力:比如让Claude Desktop能直接操作我的本地文件、查询数据库、控制智能家居。
- 开发通用工具,希望被多种AI使用:你写了一个优秀的代码仓库分析工具,通过封装成MCP Server,可以让Claude、Cursor、以及任何支持MCP的智能体都使用它。
- 在安全隔离环境中运行工具:工具运行在独立的Server进程中,与AI主进程隔离,更安全。
- 口诀:“我想要一个开放的工具生态,让我的AI能像安装插件一样使用各种能力。”
4. 实战推演:从零构建一个智能体看三者如何协作
光讲理论有点干,我们通过一个虚构但具体的例子,来看看这三者在实际项目中可能扮演的角色。假设我们要构建一个“智能研发助手Agent”,它能帮程序员分析需求、检索相关代码、生成新代码并提交到Git。
4.1 技术选型与架构设计
我们选择使用一个开源的智能体框架(比如LangGraph)作为我们Agent的“大脑”和协调中枢。这个框架本身提供了Agent Skills的管理能力。我们的大模型选用支持Function Call的API(例如GPT-4)。同时,我们希望代码检索、Git操作等工具能力是标准化、可复用的,因此考虑采用MCP协议。
于是,架构雏形如下:
- 核心:智能体框架(管理Skills和规划流程)。
- 思维引擎:大模型API(通过Function Call接收框架的指令)。
- 工具生态:多个MCP Server(提供代码检索、Git操作、文件浏览等标准化工具)。
- 粘合剂:框架内会有一个“MCP Client Skill”,专门负责与各类MCP Server通信。
4.2 具体实现步骤与代码示意
第一步:搭建MCP工具层(标准化基础设施)我们不会为这个项目单独写Git操作函数,而是启动一个现成的git-mcp-server。同样,启动一个code-search-mcp-server来连接我们的代码仓库索引。
# 假设通过npm或cargo安装后,运行MCP Server git-mcp-server --repo-path /path/to/our/code & code-search-mcp-server --index-path /path/to/index &这些Server启动后,会在本地某个端口或通过stdio提供MCP服务,宣告它们拥有的“工具”,比如git_commit,git_diff,search_code等。
第二步:在智能体框架中创建“MCP Client Skill”(适配层)我们在LangGraph中定义一个Skill,它的核心是一个MCP客户端。这个Skill的职责是:
- 动态发现并连接上述MCP Server。
- 将Server提供的工具,转换并注册为框架内部可理解的Skill。
- 当Agent决定执行某个工具时(例如“执行Git提交”),这个Skill负责将请求转换为MCP协议格式,发送给对应的Server,并将结果返回。
# 伪代码示意 MCP Client Skill 的核心 class MCPClientSkill(Skill): def __init__(self): self.client = MCPClient() # 一个MCP协议客户端库 self.client.connect_to_server("http://localhost:8080") # 连接git-mcp-server self.client.connect_to_server("http://localhost:8081") # 连接code-search-server def get_skills(self): skills = [] for tool in self.client.list_all_tools(): # 从所有Server获取工具列表 # 将MCP工具描述,封装成框架所需的Skill格式 skill = Skill( name=tool.name, description=tool.description, execute=self._make_executor(tool) # 执行器会调用MCP协议 ) skills.append(skill) return skills def _make_executor(self, tool): def executor(**kwargs): # 调用MCP Server result = self.client.call_tool(tool.name, arguments=kwargs) return result.content return executor第三步:定义核心Agent Skills(业务流程抽象)除了工具类Skill,我们还需要定义一些更高阶的、负责业务流程的Skill,这些Skill内部会调用底层的工具Skill。
AnalyzeRequirementSkill: 分析用户需求,拆分子任务。它主要与大模型交互(通过Function Call),可能不需要调用外部工具。ImplementCodeSkill: 实施编码。它内部可能先调用code-search-skill(背后是MCP)查找类似代码,然后调用大模型(Function Call)生成新代码,最后调用file-write-skill(可能是另一个MCP工具)保存文件。ReviewAndCommitSkill: 审查并提交。调用代码检查工具,最后调用git-commit-skill(背后是MCP)提交更改。
第四步:配置大模型与Function Call(思维驱动)在智能体框架中,当我们的大模型需要执行某个Skill时(比如AnalyzeRequirementSkill),框架会将这个Skill的描述、参数格式等信息,动态地转换为一次大模型API调用中的Function Call定义。模型在思考后,如果决定调用,就会输出结构化的调用请求。框架捕获这个请求,找到对应的Skill(可能是MCP Client Skill封装的,也可能是纯业务的)并执行。
# 伪代码示意框架如何将Skill转化为对LLM的Function Call def step_think(state): # 获取当前所有可用Skills的描述 available_functions = [] for skill in all_skills: available_functions.append({ "name": skill.name, "description": skill.description, "parameters": skill.parameters_schema # 转换为OpenAI Function Call格式 }) # 调用LLM,传入这些function定义 llm_response = openai.chat.completions.create( model="gpt-4", messages=state.messages, functions=available_functions, # 动态注入当前可用的技能作为Function Call function_call="auto", ) # ... 解析llm_response,执行对应的skill4.3 流程梳理与价值体现
在这个架构中:
- MCP提供了标准化、可插拔的工具底座。Git操作、代码搜索等能力被封装成独立的服务,不仅本项目能用,其他任何支持MCP的AI应用都能用。未来要新增一个Jira操作能力,只需要找一个或写一个
jira-mcp-server启动即可,我们的Agent几乎无需修改代码就能获得新能力。 - Agent Skills提供了业务逻辑的抽象和编排能力。它将“提交代码”这个业务概念,与底层的
git commit命令解耦。Skills层负责管理哪些工具在什么情况下可用,以及如何将复杂任务(如“实现一个登录功能”)分解为调用搜索、生成、写入、提交等多个步骤。 - Function Call是驱动整个智能体思考和执行的具体机制。它是大模型与Skills之间的“翻译官”和“触发器”。模型通过Function Call来表达“我现在要使用那个叫‘搜索代码’的技能,参数是‘用户登录’”。
这个例子清晰地展示了一个趋势:Function Call作为基础的执行机制,Agent Skills作为能力的组织和管理范式,而MCP则致力于成为连接能力和模型的开放生态标准。在现代AI应用开发中,它们常常是协同工作的,而不是非此即彼的选择。
5. 常见困惑、陷阱与选型指南
在实际学习和应用中,大家会对这几个概念产生不少困惑,也容易踩坑。
5.1 典型误区澄清
误区一:MCP是来取代Function Call的。不对。MCP和Function Call解决的是不同层面的问题。Function Call是模型如何调用一个已定义功能的具体机制。MCP是工具功能如何被描述和发现的协议。一个MCP Server提供的工具,最终被AI模型使用时,很可能在模型那一侧,还是通过一次Function Call请求来触发的。MCP让Function Call里的“函数定义”可以动态地从Server获取,而不是写死在代码里。
误区二:有了MCP,就不需要设计Agent Skills了。不完全对。对于简单场景,直接让模型使用MCP工具也许足够。但对于复杂Agent,Skills这层抽象依然重要。Skills负责的是战略层面的“为什么要用这个工具”、“用了之后下一步做什么”,而MCP解决的是战术层面的“这个工具怎么连接和调用”。Skills是智能体的“大脑皮层”,负责规划和决策;MCP工具是“脊髓和末梢神经”,负责执行标准动作。
误区三:Function Call的性能一定比MCP好。在简单、封闭的场景下,是的。因为Function Call是内存内或同进程的调用,而MCP通常涉及进程间通信(IPC)或网络调用(HTTP),有额外的序列化/反序列化和传输开销。但是,MCP带来的动态性、安全隔离和生态价值,往往远大于这点性能损耗。对于大多数AI交互场景(响应时间在秒级),这点开销是可接受的。在需要极致性能且工具固定的场景,Function Call仍是优选。
5.2 实操中的关键陷阱
陷阱一:MCP工具描述的模糊性。MCP Server提供的工具描述(name, description, parameters)的质量,直接决定了模型能否正确使用它。描述过于简略,模型可能无法理解或错误调用。例如,一个“搜索”工具,如果描述只是“搜索信息”,模型可能用它来搜网页,而实际上它是搜本地文件的。最佳实践是像写API文档一样,清晰、具体、举例说明工具用途和每个参数的意义。
陷阱二:忽视Function Call结果的上下文管理。这是一个经典且容易导致对话“死机”的问题。当模型通过Function Call调用工具后,工具返回的结果必须被完整、准确地追加到对话上下文中,供模型在生成下一步回复时参考。如果遗漏或截断,模型就会基于不完整的记忆做出错误判断。在一些流式响应或复杂编排中,这个环节容易出错。务必在代码中确认,每次工具调用的输出,都成为了后续模型输入的一部分。
陷阱三:Skill爆炸与规划迷失。当你的Agent Skills或MCP工具数量非常多(比如几十上百个)时,一股脑儿全部提供给模型,反而会降低模型的规划和调用准确性。模型可能会陷入“选择困难”,或者产生幻觉调用不相关的工具。解决方案是分层或动态过滤:设计一个“路由器”Skill,先根据用户意图判断大类,再动态加载该类下的具体工具;或者利用Embedding计算工具描述与用户查询的相似度,只返回最相关的几个工具。
5.3 技术选型决策树
面对一个新项目,你可以通过回答下面几个问题来做选择:
你的工具/能力是否需要被多种不同的AI模型或应用使用?
- 是-> 强烈考虑MCP。标准化一次,处处可用。
- 否-> 进入下一题。
你的应用核心是处理需要多步骤规划、复杂决策的链式或图式任务吗?
- 是-> 你需要一个Agent框架,并采用Agent Skills的思想来设计你的能力模块。然后考虑这些Skill底层用什么实现。
- 否-> 你的应用可能更接近一个“增强型聊天机器人”,进入下一题。
你需要的能力是否简单、固定且数量少(<10个)?
- 是-> 直接使用模型原生的Function Call是最快、最直接的方案。
- 否-> 即使不用MCP,你也应该考虑在代码层面对“能力”进行良好的封装和管理(这其实就是简单的Skill思想),底层调用可以混合使用Function Call和其他API。
你是否非常关注工具运行的安全隔离(例如,工具代码不可信)?
- 是->MCP的Server-Client隔离架构是天然优势。
- 否-> 安全性不是首要决定因素。
一个简单的总结公式:
- 快速原型/简单功能:直接用Function Call。
- 构建复杂自主智能体:用Agent框架 + Skills抽象。
- 希望能力标准化、可复用、即插即用:用MCP。
- 现代复杂生产级Agent应用:很可能是三者结合:用MCP构建开放工具生态,用Skills管理业务能力抽象,用Function Call作为模型与Skills间的执行桥梁。
6. 未来展望与个人洞见
聊了这么多区别,其实我们能看到一个清晰的演进脉络:从封闭的、点对点的集成(Function Call),到系统化的内部管理(Agent Skills),再到开放的、标准化的生态共建(MCP)。这背后是AI应用从“玩具”到“工具”再到“平台”的必然路径。
MCP协议虽然由Anthropic推动,但其开源和协议中立的特性,让它有潜力成为AI时代的“USB标准”或“驱动模型”。目前,Claude Desktop、Cursor、Continue.dev等客户端已原生支持,社区也涌现了大量实用的MCP Server。它的挑战在于协议本身的完善度(如更复杂的权限控制、流式工具响应等)以及生态的进一步繁荣。
对于开发者而言,我的建议是:
- 掌握Function Call:这是基本功,理解它如何工作,是理解一切上层建筑的基础。
- 理解Skill设计模式:无论你用不用某个具体的Agent框架,学会将能力模块化、描述化、可规划化,是构建健壮AI应用的关键思维。
- 密切关注MCP生态:即使你现在不直接使用,也值得了解。尝试为你的内部工具写一个MCP Server适配器,或者在你的项目中试验性地接入一个MCP工具(比如文件浏览器),感受一下“即插即用”的威力。这很可能代表了未来工具集成的主流方向。
最后,回到那个面试题。如果被问到,一个清晰的回答层次应该是:先说明Function Call是模型调用的基础机制,再阐述Agent Skills是智能体内部管理能力的架构思想,最后点明MCP是连接AI与工具、旨在建立开放生态的通信协议。它们分别作用于执行层、组织层和生态层,在复杂的AI应用中可以协同工作,共同构成智能体能力扩展的完整图景。