当前位置: 首页 > news >正文

【LLM进阶-Agent】13.function call vs mcp vs skills

function call vs mcp vs skills

在最底层的 LLM 模型层,这三者的原理没有任何区别。所有的魔法都只是一件事:指令遵从(Instruction Following) + 结构化输出(通常是 JSON)。模型本身不知道什么是 MCP,也不知道什么是 Skill,它只知道“Prompt 里提供了一堆工具的描述,我需要根据用户的意图,输出一个符合特定格式的字符串来表示我要用哪个工具”。

区别全部发生在这之上的应用架构层(Application/Engineering Layer)


1. Function Call:最基础的原子能力

Function Call 的本质就是“把所有工具的元数据信息(Schema)一股脑塞进 Prompt/API Payload 里”。它是所有 Agent 工具调用的基石。

特点:紧耦合。开发者需要手动维护 JSON Schema,手动解析模型的输出,再手动调用本地函数。

Code 演示 (Python / OpenAI 风格):

importjsonfromopenaiimportOpenAI client=OpenAI()# 1. 开发者手动硬编码的“元数据” (一股脑塞进请求中)tools=[{"type":"function","function":{"name":"get_weather","description":"获取指定城市的当前天气","parameters":{"type":"object","properties":{"city":{"type":"string","description":"城市名,如 北京"}},"required":["city"],},},}]# 2. LLM 层级:根据 prompt 和 tools 输出调用指令response=client.chat.completions.create(model="gpt-4o",messages=[{"role":"user","content":"北京天气怎样?"}],tools=tools,)# 3. 开发者手动拦截输出,执行本地代码message=response.choices[0].messageifmessage.tool_calls:fortool_callinmessage.tool_calls:iftool_call.function.name=="get_weather":args=json.loads(tool_call.function.arguments)# 真正执行本地函数print(f"Executing: get_weather({args['city']})")

2. MCP (Model Context Protocol):调用协议的标准化

MCP 与 function call 没有本质区别,只是标准化了调用协议。

痛点:以前每个应用(ChatGPT, Claude, 你的定制 Agent)要想用数据库、GitHub、Notion,都需要针对这些数据源单独写 Function Call 逻辑,形成了N x M 的集成灾难

MCP 的解法:引入了C/S 架构(客户端/服务端)。它不是一种新的模型能力,而是一种类似 HTTP/LSP 的标准协议。

  • MCP Server:负责实现具体的工具逻辑,并暴露标准的工具列表(类似于接口文档)。
  • MCP Client (Agent):动态连接 Server,自动发现(Discovery)有哪些工具,然后告诉 LLM。

MCP 协议规范了三大核心能力

  1. Tools(工具):让 Agent 执行的动作,通常是python代码。
  2. Resources(资源):标准化的数据读取方式。比如你的 Agent 需要读取本地文件、GitHub 仓库或某个 SaaS 里的文档,MCP 提供了一种类似URI的方式让 Agent 动态订阅和读取这些上下文,而不是让开发者每次都写专门的 API 去推数据。
  3. Prompts(提示词模板):MCP Server 可以直接向客户端暴露预设好的 Prompt 模板。

Code 演示 (使用 FastMCP 快速构建服务端):

Server 端 (提供能力,隔离逻辑):

# mcp_server.pyfrommcp.server.fastmcpimportFastMCP# 创建一个 MCP 服务器mcp=FastMCP("MyDataServer")# 开发者只需要用装饰器,不需要手写长串的 JSON Schema@mcp.tool()defquery_database(sql:str)->str:"""Execute SQL query on the company database."""# 复杂的数据库连接逻辑在这里...returnf"Result for{sql}"if__name__=="__main__":mcp.run_stdio()# 通过标准输入输出与 Client 通信协议

Client 端 (Agent 主体,无需硬编码 Schema):

# 伪代码:MCP Client 交互逻辑asyncdefrun_agent():# 1. 连接到 MCP ServerasyncwithMCPClient("python mcp_server.py")asserver:# 2. 动态获取工具列表!这里取代了 Function Call 中手动写的 tools 数组tools_metadata=awaitserver.list_tools()# 3. 把动态获取的 tools 交给 LLMresponse=call_llm(prompt="查一下昨天的新增用户",tools=tools_metadata)# 4. LLM 决定调用,Client 通过协议让 Server 执行,而不是自己在本地执行ifresponse.wants_to_call_tool:result=awaitserver.call_tool("query_database",{"sql":"SELECT count(*) FROM users"})print(result)

总结 MCP:底层还是 Function Call,但工程上实现了解耦。Agent 不需要懂数据库怎么连,只需要懂怎么和 MCP Server 聊天。


3. Skills:软件工程的“封装”思想在 Agent 中的应用

为了减小 prompt 中的工具信息长度,通过将复杂的 sub job 封装到 skill 文件夹中,提供给主 agent 的只是 skill 的元数据信息,具体逻辑内部实现。skills的理念,结合了MCP与初级的AutoGen理念,skill由sub agent负责执行,主agent作为调度器决定什么时候调度哪个skill来解决问题,同时也能做到 human in the loop,自主向人工求助。

Function Call 和 MCP 暴露的往往是“原子操作”(如:搜索网页、读文件)。如果你的主 Agent 有 50 个原子工具,Prompt 会撑爆,而且 LLM 极容易选错。

Skill 是一种高层抽象。它可能本身就是一个完整的 Sub-Agent 或一套复杂的 RAG 工作流。对于主 Agent 来说,它看起来就像一个普通的 Function,但内部别有洞天。

skill 与 mcp 的本质区别

如果单纯把多个代码步骤写死成一个大函数,那把它暴露为 MCP Tool 还是暴露为 Skill,在架构上与skill确实没有任何本质区别。从纯技术的角度来说,在 MCP Server 内部写一行os.system("ls -la")也能执行 shell 指令,但skill文件夹shell 指令,真正触及了现代 Agent 框架(比如 AutoGen、LangGraph 以及各类 Coding Agents)中,Skill 与 MCP/普通 Function Call 的三个核心分水岭

1. 运行边界:上下文与生命周期的耦合度

这是最大的工程区别。

MCP 强调的是服务的标准化解耦,无论它是跑在本地子进程还是远程服务器,Agent 与 MCP 工具之间是通过标准协议通信的,互不关心对方的运行环境。而 Skill(尤其在原生代码中)通常与主 Agent 共享同一个运行时上下文(Runtime Context)或内存空间,这使得 Skill 可以更方便地直接操作 Agent 的内部状态、全局变量或共享对象。这使得skill的自主性大大提高,比如skill可以做到:

  • 自我管理上下文,构建动态分层记忆
  • 自我进化 (Code-as-Tool)
2. 动态进化:Agent 的“可生长性” (Code-as-Tool)

如果说 MCP 强调的是“全球开发者共享写好的工具”,那么 Skill 在前沿研究(比如著名的 Voyager 玩我的世界,或者 Devin 这类程序员 Agent)中,强调的是Agent 的自我学习与能力积累

  • MCP / Function Call 通常是静态的:开发者写好 API,定义好 Schema,Agent 只能用这些预设的能力。
  • Skill 可以是动态生成的:Agent 在遇到一个新问题时,它可以自己写一段 Python 代码或 Shell 脚本(比如写一个专门清洗某类特殊日志的脚本),测试运行成功后,把这段代码保存到skills/文件夹下
  • 下一次,主 Agent 扫描skills/文件夹,自动读取刚才那个脚本的 Docstring(文档注释)作为 Schema。Agent 就这样自己教会了自己一个新的 Skill。这是 MCP 协议本身不关心的范畴。
3. 框架层的编排抽象 (Workflow / Graph)

在更复杂的 Agent 应用开发中,Skill 已经超越了纯代码的范畴。

如果你自己用代码构建底层的指令遵从,那一切都是 Function Call。但当你在更高维度的框架里构建 Agent 时,Skill 往往指代的是一个编排好的工作流(Workflow)或子图(Sub-graph)

例如,你可以将一个由多个节点组成的 RAG 流程(包含了意图识别、向量检索、重排、总结)打包发布。在这个框架内,它被称为一个 Skill。主 Agent 调用它时,并不像调用普通的本地代码那样走标准输出,而是触发了框架底层的另一个 DAG(有向无环图)引擎去流转数据。

Code 演示 (以 Semantic Kernel / 自定义封装风格为例):

# --- 1. 定义一个复杂的 Skill (内部可能有多个步骤、甚至自己的 LLM 调用) ---classDeepResearchSkill:def__init__(self):# 暴露给主 Agent 的极简元数据self.name="perform_deep_research"self.description="当用户需要关于某个主题的深度、多源信息的综合报告时调用此技能。"self.parameters={"topic":"string"}defexecute(self,topic:str):print(f"Skill 内部开始执行复杂工作流: 搜索 [{topic}]...")# Step 1: 内部调用搜索引擎 (原子 Function)search_results=self._internal_search(topic)# Step 2: 内部调用网页爬虫 (原子 Function)scraped_data=self._internal_scrape(search_results)# Step 3: 内部甚至调用一个小的 LLM 进行总结summary=self._internal_llm_summarize(scraped_data)returnsummary# --- 2. 主 Agent 的视角 ---research_skill=DeepResearchSkill()# 主 Agent 的 prompt 里只需要放入这一个 Skill 的描述tools=[{"type":"function","function":{"name":research_skill.name,"description":research_skill.description,# 描述很短,概括了宏观意图"parameters":...}}]# 主 Agent 调用:# User: "给我一份关于 2024 年固态电池进展的深度报告"# LLM 输出: {"name": "perform_deep_research", "arguments": {"topic": "2024固态电池进展"}}# 主 Agent 只需要调用 skill.execute(),内部的脏活累活主 Agent 一概不知。

一张表总结

概念层面核心解决的问题
LLM 底层模型层文本生成,指令遵从
Function Call接口层让 LLM 能够输出结构化的动作意图
MCP协议层解决 Agent 与工具的标准化连接与动态发现
Skills架构层封装复杂逻辑,降低主脑上下文负担,提高执行稳定性
http://www.jsqmd.com/news/490776/

相关文章:

  • 2025_NIPS_EgoExoBench: A Benchmark for First- and Third-person View Video Understanding in MLLMs
  • 告别绘图软件!Paperxie AI 科研绘图:10 次免费额度,让理工科论文可视化一步到位
  • Tower I3C Host Adapter 使用范例 (20)
  • 【C++】左值引用、右值引用
  • CS二开之睡眠混淆(五)BeaconGate,UDRL,Sleepmask组合拳
  • AI新范式 02|拆解世界模型:它是如何理解物理规律的?
  • WebRTC QoS方法之NetEQ在流量卡弱网应用下失效
  • Java基础-1
  • 2025_NIPS_Scaling RL to Long Videos
  • 【Dv3Admin】FastCRUD MD编辑器操作
  • open claw安装在windows wsl中教程
  • HDOJ 课程例题记录
  • 第三方 API 调用 OpenClaw 出现 LLM request timed out 的解决方案
  • openclaw+qwen(笔记,非教程)
  • 讲讲普通小轿车驾驶证报考流程及费用,西安哪家驾校好? - mypinpai
  • UE5C++Part2--几种常见的变量类型
  • 企业级RustDesk私有化部署:Docker Swarm集群方案与安全加固指南
  • (85页PPT)某著名企业贝因美IT规划咨询报告(附下载方式)
  • Simulink仿真漂移机理分析(二):相图分析
  • R轻松玩转Excel数据
  • 课程记录:Windows2
  • 高德地图混合部署实战:离线瓦片与在线API的智能切换策略
  • 西安国文驾校二轮摩托车考驾照口碑如何,值得推荐吗 - 工业品牌热点
  • 探讨专业的精密锻造公司,三邑锻造在全国排名第几? - 工业推荐榜
  • 【一篇即毕业系列】C++的引用从基础到通天
  • 仅剩72小时!生态环境部新发布的《污染预测模型R实现规范》(HJ 1308-2024)强制适配倒计时(含兼容性迁移速查表)
  • 2026 本科生论文工具盘点:9 款 AI 工具搞定初稿 / 绘图 / 排版 / AI 率
  • leetcode 1389. Create Target Array in the Given Order 按既定顺序创建目标数组-耗时100
  • 国内免费AI聊天网站大全:稳定直连与高效响应指南
  • 从零开始了解数据采集——制造业数字孪生