Fuction calling
定义
Function Calling(工具调用) :是大模型的一种能力协议,让 LLM 可以输出结构化 JSON ,而不是纯自然语言,用来告诉外部程序:
"我现在需要调用一个函数(工具),参数是 xxx,请你执行,然后把执行结果返回给我,我继续思考。"
本质:LLM 只负责决策什么时候调用、调用哪个函数、填什么参数;函数执行逻辑完全在模型外部,由宿主程序运行。
完整一轮流程(通用)
-
开发者向模型传入工具定义列表(多个 function 的 schema)
-
用户提问 + 历史消息一起发给 LLM
-
LLM 判断:
-
不需要工具:直接输出自然语言回答
-
需要工具:输出结构化
tool_call,包含工具名和参数
-
-
宿主程序解析这个 JSON ,执行对应函数(模型不能自己执行代码)
-
宿主把工具执行结果包装成一条消息,塞回对话上下文
-
再次把完整消息传给 LLM,继续循环(ReAct)
例子:读取指定路径文本文件(OpenAI 官方标准 Function Calling 结构)
-
Function Definition(发给模型,告诉模型有哪些工具可用)
-
模型输出 ToolCall(模型返回)
-
Tool Result 消息(框架执行完,回传给模型)
工具调用出错了怎么处理?
答:分类处理------参数错误返回明确信息让模型修正重试;业务错误返回语义描述让模型换策略;瞬时错误(网络/限流)自动重试+指数退避;系统错误返回友好提示。
MCP
定义
Model Context Protocol(MCP,模型上下文协议)是一套开放、标准化的 JSON‑RPC 2.0 协议。它定义了 AI Agent 和外部程序 / 服务之间,如何安全地发现、访问外部工具、资源和提示词模板。
MCP 解决的问题:给 Agent 提供一套统一的方式去对接外部能力,不用为每一个外部软件、每一个 Agent 单独写定制胶水代码。这里和上面function calling的区别在于,function calling是agent和llm之间的交接层,而这里的MCP是agent和外部工具的交接层。
两大核心角色
-
MCP Server(服务端) 提供能力的一方(独立进程 / 服务,可以嵌入外部软件)。 对外暴露三类核心实体:
-
tools:可调用函数(工具),包含名称、描述、JSON Schema 参数、执行逻辑;支持tools/list(列出全部工具)、tools/call(执行工具) -
resources:可读资源(文件、图片、日志等) -
prompts:预制提示词模板
-
工具的业务执行逻辑全部写在 MCP Server
- MCP Client(客户端) 接入 Agent 侧。 职责:连接 MCP Server,调用协议方法,拿到工具定义,再把工具转换成 LLM 可用的 Function Calling Schema;收到模型 tool_call 请求后,转发给 MCP Server 执行。
每生成一个新的MCP插件,这里的MCP Server都需要重新写一遍,而MCP Client不需要。
特性:跨 Agent 复用 一份 MCP Server 实现,可以同时给所有支持 MCP 的 Agent(Pi、Claude Desktop 等)使用,不需要为每个 Agent 重写对接代码。
MCP 和 Function Calling 的边界
-
Function Calling: LLM ↔ Agent 。规定大模型怎么输出结构化 tool_call 请求,让模型选择调用工具。不规定工具在哪执行、怎么发现工具。
-
MCP :Agent ↔ 外部服务 。规定 Agent 怎么发现远端工具、远程执行工具。MCP 本身不涉及 大模型 , LLM 完全不知道 MCP 存在。
MCP 暴露出来的工具,会被 Agent 转换成 Function Calling schema,交给 LLM 使用;MCP 底层经常搭配 Function Calling 一起工作,但二者不属于同一层协议。
存在意义
MCP可以让只要支持它的agent共用一个MCP Server,避免了要为每一个agent写一个各自的MCP Server的麻烦。
流程
阶段 1:初始化连接(仅建立连接时执行一次)
-
Agent 启动 MCP Client,启动并建立与 MCP Server 的连接(stdio / HTTP 等传输方式)。
-
MCP Client 发送 MCP 请求:
tools/list,向 MCP Server 查询它暴露的全部工具。 -
MCP Server 返回工具列表:每个工具包含名称、描述、入参 JSON Schema。
-
MCP Client 将所有工具定义存入 Agent 本地内存中的工具注册表 ToolRegistry。
至此:远端工具元信息全部缓存完成,等待后续使用。
阶段 2:Agent 循环,每一轮用户交互都会走这个循环
-
工具子集筛选(可选优化,Agent 框架层逻辑,不属于 MCP 协议) Agent 读取当前对话上下文,从本地 ToolRegistry 全部工具里,筛选出当前任务相关的工具子集。不筛选的话,直接取全部工具。
-
转换为 Function Calling Schema 把筛选后的工具子集,转换成 LLM API 要求的 Function Calling 工具格式。
-
调用 LLM 把对话历史消息 + 转换后的工具列表,一起发给 LLM。
-
LLM 推理,返回结果 LLM 基于当前上下文判断:
-
如果不需要调用工具:直接返回文本回答,本轮循环结束;
-
如果需要调用工具:返回结构化
tool_call,包含工具名称与参数。
- Agent 收到 tool_call,识别工具来源 Agent 检查这个工具是否来自 MCP 注册表:
-
✅ 属于 MCP 工具:Agent 使用 MCP 协议,发送
tools/call请求,携带工具名与参数,转发给 MCP Server; -
❌ 本地工具:Agent 直接在本地执行 handler 函数(不走 MCP)。
-
MCP Server 执行工具逻辑并返回结果: MCP Server 收到
tools/call,在自己进程内部执行业务逻辑,执行完成后,把结果返回给 MCP Client(Agent)。 -
包装 tool_result,追加到对话上下文: Agent 把 MCP 返回的结果封装成 Function Calling 规范的
tool_result消息,追加进对话消息列表。 -
回到本轮循环第 3 步,再次调用 LLM,把工具返回结果交给模型,继续思考,循环往复。
例子:简单例子:本地文件 MCP Server,Agent 读取文件
阶段 1:初始化
-
Pi 启动 MCP Client,拉起文件 MCP Server 进程。
-
Client 发送
tools/list。 -
文件 MCP Server 返回两个工具:
read_file(读取文件)、write_file(写入文件)。 -
Pi 把这两个工具存入本地 ToolRegistry 内存。
阶段 2:用户提问:读取 test.txt 的内容
-
工具筛选:Pi 分析上下文,挑选
read_file,本次只把这个工具的 schema 准备好。 -
转成 Function Calling 格式。
-
Pi 调用 LLM,消息带上用户问题 +
read_file工具定义。 -
LLM 思考,输出 tool_call:调用
read_file,参数:文件路径test.txt。 -
Pi 识别
read_file是 MCP 工具,发送 MCPtools/call请求,参数为 test.txt。 -
文件 MCP Server 收到请求,读取本地 test.txt,把文本内容返回 Pi。
-
Pi 将读取到的文本包装成
tool_result消息,添加到对话历史。 -
Pi 再次调用 LLM,把文件内容交给模型;LLM 整理内容,输出回答给用户。
如果用户后续说:把这段文字写入 result.txt,下一轮筛选器会选出
write_file,重复上述循环。
Skill
定义
Skill 是一个面向业务目标、可被大模型触发的、封装完整任务能力的高层单元。它内部包含预定义的流程逻辑、状态管理、输入校验、异常处理,并可以编排调用多个原子 Tool;模型只需要决定是否唤起该 Skill,任务内部的步骤调度不由模型负责。
组成:
Skill = 静态元配置 + 业务编排代码 + 运行时 SkillContext 实例
区分清楚:前两者是代码仓库里定义 Skill 的模板(一次性写死) ;SkillContext 是运行时实例,每次被唤起才动态生成,一个 Skill 实例一份独立上下文。
静态 yaml 元配置:描述 Skill 对外是什么,给 Skill 管理器做渐进披露;
业务编排代码:定义 Skill 内部怎么跑、状态怎么流转;
SkillContext:单次 Skill 任务实例的私有状态容器,每个唤起的 Skill 单独一份。
SkillContext 和 Session Session:全局对话消息流水,所有 Skill 共享,LLM 可见; SkillContext:单个 Skill 私有任务状态,LLM 完全看不到。
渐进式披露
渐进式披露就是在每一轮 LLM 请求之前,Skill 管理层读取「当前会话信息」,动态筛选出本轮允许暴露给 LLM 的 Skill 集合,把筛选后的 Skill 元数据转成 tool schema,作为 tools 参数传给 LLM;不在集合里的 Skill,完全不会给到模型。如果是一个简单agent就是直接一个静态表读取skill元数据,然后选择完成后读取描述,接着开始使用。
skill意义
Skill 是面向业务的、带状态的多步骤任务封装单元。把一堆零散原子 Tool/ API ,包装成一个对 Agent(LLM)友好的、可分步执行的业务能力;同时方便系统做可见性管控(渐进披露)、权限、风险隔离。
对比基准:直接用原生 Function Calling 只能调用无状态原子工具;Skill 解决原生 Tool Calling 做复杂业务任务时的痛点。