news 2026/9/2 2:05:48

Tool Calling、Skills与MCP:AI Agent工具调用的核心层次解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Tool Calling、Skills与MCP:AI Agent工具调用的核心层次解析

最近在给团队做 AI Agent 技术分享时,发现大家经常把三个名词混在一起聊:Tool Calling、Skills、MCP。有人以为 Skills 就是 MCP 的另一种叫法,有人把 Tool Calling 当成 MCP 的一个功能,还有人觉得只要接入了 MCP 就天然支持了 Tool Calling。

这些理解不能说完全错,但都没说到根上。如果概念边界不清晰,做架构选型和方案设计时就容易踩坑。这篇文章会把这三个概念拆开来讲,先说它们各自解决什么问题,再用对比表格梳理区别,最后给出一套最小可运行的示例代码,帮助你快速建立整体认知。

无论你是刚开始接触 AI Agent 开发的新手,还是已经在业务中落地过 Function Calling 的工程师,这篇文章都值得收藏备用。

1. 背景与核心概念

1.1 Tool Calling:让模型具备调用外部工具的“能力”

先看一个最简单的场景。你问大模型:“北京现在气温多少度?”

如果没有联网能力和工具调用能力,模型只能凭训练数据回答一个大致范围,甚至直接告诉你“我无法获取实时数据”。但如果你在请求中额外提供两个工具函数:一个负责查询天气,一个负责查询城市编码。模型会先输出一个结构化调用指令,比如:

{ "name": "get_weather", "arguments": "{\"city\": \"beijing\"}" }

你的程序收到这个指令后,去真实天气 API 查询数据,再把结果返回给模型,模型基于真实数据生成最终回答。

这就是 Tool Calling,本质上是大模型的一种“行为决策能力”。模型本身不会去执行真实 API 调用,它只是根据用户输入和工具描述,决定“接下来应该调用哪个工具、传入什么参数”。实际执行逻辑由你的代码完成,结果再回传给模型继续生成。

专业一点的叫法是 Function Calling 或 Tool Use。OpenAI 早期称之为 Function Calling,后来演进为 Tool Calling,Anthropic 也有类似的 Tool Use 机制。不同平台实现细节略有差异,但核心思想一致:把模型从“只会生成文本”扩展为“可以发起外部动作”。

1.2 Skills:把复杂能力打包成可复用的“技能”

Skills 的概念在 Claude 生态(如 Claude Code、Claude Desktop)中非常流行。它本质上是一组预定义好的指令、规则和示例,打包成一个可复用的文件夹或单一 Markdown 文件。当模型在对话或编码任务中触发对应的技能时,会自动加载这套指令,从而按照你期望的方式完成任务。

举个例子。你希望 AI 在帮你写代码时,必须遵循公司的 Git 提交规范。如果把规范写在每一次 Prompt 里,既冗长又容易遗漏。这时可以创建一个名为git-commit-skill的 Skills 文件,内容大致是:

--- name: git-commit-skill description: 用于生成符合团队规范的 Git 提交信息。 --- 当用户要求生成 Git 提交信息时,请严格遵守以下规则: 1. 提交类型使用固定前缀:feat / fix / docs / style / refactor / test / chore。 2. 首行不超过 50 个字符。 3. 正文必须说明修改动机,不能只写“更新代码”。 4. 如果涉及破坏性变更,必须以 BREAKING CHANGE 开头单独成段。

当模型识别到用户正在处理 Git 提交相关任务时,会主动加载并遵循这个技能文件里的约束,不需要你每次重复强调。

所以,Skills 的重点在于“封装经验和规则”。它有点像给 AI 写的“岗位 SOP”,把一套固定的工作方法沉淀下来,让 AI 在特定场景中稳定输出符合预期的结果。

1.3 MCP:统一工具接入的“协议标准”

MCP 全称是 Model Context Protocol,模型上下文协议。它由 Anthropic 在 2024 年底提出,目的是解决一个很实际的问题:每接入一个外部数据源或工具,开发者都要为不同模型平台写一套定制化集成代码。今天对接公司的内部数据库写一套,明天对接 Figma 又要写一套,重复劳动严重。

MCP 的思路是借鉴 USB 接口的设计:设备厂商按照 USB 标准生产设备,电脑系统按照 USB 标准识别设备,两者之间不需要互相知道对方的具体实现。MCP 把“AI 应用”(Host)和“外部工具/数据源”(MCP Server)解耦,定义一个标准化的通信协议。统一之后,同一个 MCP Server 可以在 Claude Desktop、Claude Code、Cursor 甚至自研 Agent 应用中复用。

一个典型的 MCP Server 会暴露三类能力:

能力类型作用类比
Tools可执行的函数,比如查询数据库、发 HTTP 请求接口函数
Resources可读取的数据资源,比如文件内容、数据库记录静态数据
Prompts预定义的可复用提示词模板脚本模板

可以看到,MCP 的范畴比单纯的工具调用更大,它试图成为整个 AI Agent 生态的“标准化接入层”。

1.4 为什么这三个概念容易混淆

容易混淆的根本原因是:它们出现在同一个技术链条上,但处于不同层次。

  • Tool Calling 是一种能力,回答的是“模型能不能调用工具”。
  • Skills 是一种内容封装,回答的是“怎么让模型按特定规范完成任务”。
  • MCP 是一种协议标准,回答的是“工具和模型之间用什么方式互通”。

打个比方:Tool Calling 相当于“人会使用螺丝刀”,Skills 相当于“一套标准化的修车流程手册”,MCP 相当于“全世界统一的螺丝刀接口规格”。三者职责不同,但实际使用中往往同时出现。

2. 三者本质区别与关系详解

2.1 核心定位对比

先把三者的核心定位放在一起看:

维度Tool CallingSkillsMCP
本质模型能力内容/指令封装通信协议
解决什么问题模型如何决定调用外部函数模型如何按固定规范完成任务工具/数据源如何标准化接入
实现层面模型推理层Prompt/上下文策略层应用架构层
典型载体API 参数中的 tools 字段Markdown 文件或 JSON 目录MCP Server 进程
是否依赖具体平台不依赖,各大模型基本支持多为 Claude 系生态跨平台、跨模型
开发者工作量写函数定义和调用逻辑写领域规则和示例写 Server 和 Client 适配层

2.2 三者的实现层次差异

从实现方式来看,三者完全不同。

Tool Calling 是模型平台内置的能力。你在请求里传入工具 Schema,模型在生成过程中自行决定是否调用以及如何调用。这个“决策”是模型推理的一部分,开发者无法直接干预模型内部的决策逻辑,只能通过工具描述写得是否清晰来间接影响。

Skills 是 Prompt 层面的增强。本质上它是把一段高质量的指令文本提前准备好,在恰当的时机注入上下文。它不需要模型额外支持什么特殊 API,只要模型具备足够长的上下文理解能力即可。这也是为什么 Skills 文件可以做成 Markdown 这种纯文本形式——因为它最终就是作为指令文本被模型读取。

MCP 是进程间的标准化通信。它需要客户端(MCP Client)和服务端(MCP Server)同时遵循协议规范。工具的真实执行逻辑在 MCP Server 中,Client 通过 JSON-RPC 格式的消息和服务端交互。两者通过标准输入输出或远程 HTTP 进行通信,实现进程解耦。

2.3 三者如何协同工作

这里用一个实际场景串联起来:你开发了一个 AI 编程助手,用户要求“帮我把项目里的 TODO 列表同步到飞书文档”。

  • MCP 负责打通“飞书文档”这个外部系统。你写好一个飞书 MCP Server,暴露一个create_doc的 Tool。
  • Tool Calling 负责让模型“看懂”应该调用create_doc。模型阅读用户请求,匹配到飞书文档相关的工具描述,输出一行调用指令。
  • Skills 负责约束“怎么调用才符合规范”。比如你预定义了一个feishu-doc-skill,规定标题格式、权限设置、内容排版要求,模型在调用工具前会先参考这套规则。

换句话说,MCP 把工具接入标准化,Tool Calling 让模型具备调用能力,Skills 让调用过程更可控、更贴近业务要求。它们不是替代关系,而是互补关系。

3. 环境准备与最小示例

3.1 环境准备

为了演示方便,本文使用 Python 3.10+ 作为示例环境,并假设你已经安装了openaianthropic两个 Python SDK。版本不需要完全一致,但建议尽量使用较新版本,以免缺少部分 API 参数。

pip install openai anthropic

同时,你可以准备一个虚拟环境,避免依赖冲突:

python -m venv .venv source .venv/bin/activate # Windows 下执行 .venv\Scripts\activate

由于不同模型的 API Key 获取方式不同,本文不会实际调用远程模型,而是以代码结构和配置示例为主,重点说明三者各自的实现形态。如果你需要真实运行,替换为自己的 API Key 即可。

3.2 Tool Calling 最小示例

下面这段代码演示了 OpenAI 风格下的 Tool Calling 实现。核心是:在请求中声明一个工具get_weather,模型在收到用户消息后,如果判断需要查询天气,会返回工具调用指令,而不是直接返回文本。

# 文件路径:examples/tool_calling_demo.py from openai import OpenAI client = OpenAI(api_key="YOUR_API_KEY") tools = [ { "type": "function", "function": { "name": "get_weather", "description": "查询指定城市的当前天气", "parameters": { "type": "object", "properties": { "city": { "type": "string", "description": "城市名称,如北京、上海" } }, "required": ["city"] } } } ] messages = [ {"role": "user", "content": "北京现在热不热?"} ] response = client.chat.completions.create( model="gpt-4o-mini", messages=messages, tools=tools, ) # 打印模型给出的工具调用指令 print(response.choices[0].message.tool_calls)

预期输出中会有一个tool_calls列表,里面包含函数名get_weather和参数{"city": "北京"}。你拿到这个结果后,可以执行真实的天气查询函数,再把结果以role="tool"的消息回传给模型,让模型完成最终回答。

这里的关键是:模型只负责“决定要调用哪个工具”,不负责“真的执行工具”。执行逻辑,如请求天气 API、解析响应、做数据转换,全部在你的代码中完成。

3.3 Skills 示例

Skills 的载体通常是文件夹或 Markdown 文件。以 Claude Code 的 Skills 为例,一个标准技能目录结构如下:

skills/ └── git-commit-skill/ ├── SKILL.md └── examples/ └── good_commit.md

SKILL.md是核心文件,带有 YAML 格式的 frontmatter,用于描述技能名称和触发条件:

--- name: git-commit-skill description: 当用户需要生成 Git 提交信息时使用此技能。 --- # Git Commit 技能 该技能用于生成符合团队规范的 Git 提交信息。 ## 规则 1. 提交类型必须使用 feat、fix、docs、style、refactor、test、chore 前缀。 2. 首行不超过 50 个字符。 3. 正文必须描述修改动机和影响范围。 4. 如有破坏性变更,必须使用 BREAKING CHANGE 开头。 ## 示例 用户输入:我修复了登录页面的按钮点击无响应问题 输出:fix: 修复登录页按钮点击无响应问题

当模型根据用户请求判断“这属于 Git 提交信息生成任务”时,它会自动加载这个技能文件,按里面的规则组织回答。这个过程中没有额外的 API 请求,也没有进程间通信,纯粹是通过注入更高质量的上下文指令来约束模型输出。

3.4 MCP 配置示例

MCP 的完整实现涉及 Server 和 Client 两端。这里以一个最小的服务端配置示例,展示 MCP Server 在 Claude Desktop 中的注册方式。配置文件位于claude_desktop_config.json

{ "mcpServers": { "weather-server": { "command": "python", "args": ["path/to/weather_server.py"], "env": { "WEATHER_API_KEY": "your_api_key_here" } } } }

上面的配置告诉 Claude Desktop:启动一个名为weather-server的 MCP Server,通过 Python 脚本运行,并注入环境变量。

如果使用 MCP 官方 Python SDK 搭建一个最简单的 Server,核心代码大致如下:

# 文件路径:examples/weather_server.py from mcp.server import Server from mcp.server.stdio import stdio_server app = Server("weather-server") @app.list_tools() async def list_tools(): return [ { "name": "get_weather", "description": "查询指定城市的当前天气", "inputSchema": { "type": "object", "properties": { "city": {"type": "string"} }, "required": ["city"] } } ] @app.call_tool() async def call_tool(name: str, arguments: dict): if name == "get_weather": city = arguments["city"] # 这里可以替换为真实的天气 API 调用 return {"city": city, "temperature": "26℃", "condition": "晴"} raise ValueError(f"未知工具: {name}") async def main(): async with stdio_server() as (read_stream, write_stream): await app.run(read_stream, write_stream, app.create_initialization_options()) if __name__ == "__main__": import asyncio asyncio.run(main())

这段代码实现了一个标准的 MCP Server:list_tools向客户端声明可用的工具列表,call_tool处理真实的工具调用逻辑。客户端(如 Claude Desktop、自研 Agent)通过标准输入输出流与 Server 通信,实现进程间的能力复用。

4. 实际场景选择指南

4.1 什么时候只需要 Tool Calling

如果你的业务逻辑相对简单,外部依赖较少,只需要调用两三个固定 API,那么直接用 Tool Calling 就够了。

典型场景包括:

  • 让 AI 根据用户问题决定调用计算器、翻译接口或短链接生成接口。
  • 在已有业务系统中增加一个“AI 助手”,只需要查询订单状态、用户信息等少量接口。
  • 快速原型验证阶段,不想引入额外协议层。

用 Tool Calling 的优势是简单直接。你不需要搭建额外服务,只需要在请求参数里写好工具 Schema。缺点是每个接入方都要写一套定制化代码,复用性差。

4.2 什么时候应该用 Skills

当你发现同一个领域的 AI 任务反复出现,且每次都需要强调同样的规则时,就该考虑用 Skills。

典型场景包括:

  • 团队内部要求 AI 生成代码时必须遵守固定的代码风格和提交规范。
  • 需要让 AI 按固定格式输出测试报告、周报、复盘文档。
  • 面向特定岗位,比如前端、测试、运维,沉淀专属的 AI 工作流。

Skills 的价值在于“一次编写,处处生效”。它把经验沉淀为可复用的资产。尤其适合团队协作,因为技能文件可以进入 Git 仓库,接受版本管理和评审。

4.3 什么时候必须引入 MCP

MCP 的引入成本相对更高,但收益也更明显。当你的应用需要对接多种外部系统,或者希望同一个接入能力被多个 AI 应用复用时,MCP 是更合适的方案。

典型场景包括:

  • 需要同时对接数据库、文件系统、第三方 SaaS 平台等多个数据源。
  • 同一套工具能力需要被 Claude Desktop、Claude Code、Cursor、自研应用等多端复用。
  • 希望团队内部沉淀一套标准化的“工具接入层”,不同业务线共用。
  • 涉及复杂的长生命周期连接,比如数据库连接、浏览器自动化会话、设计稿读取等。

4.4 综合选型矩阵

场景特征推荐方案理由
接口少、逻辑简单、快速验证Tool Calling成本最低,开发速度快
需要固定输出规范、积累团队经验Skills以内容驱动模型行为,收敛效果好
多工具、多端复用、系统间解耦MCP标准化接入,避免重复开发
三者混合、复杂 Agent 应用三者结合MCP 接入工具,Tool Calling 驱动调用,Skills 规范过程

5. 常见问题与排查思路

5.1 常见问题排查表

问题现象常见原因解决思路
模型输出了工具名,但没有参数工具 Schema 中缺少required字段,或者描述不够明确为必填参数添加required;在参数描述中给出示例值
模型一直不调用工具工具描述与用户问题的关联度不够强优化工具描述的措辞,显式说明“当用户询问 XXX 时使用此工具”
Skills 没有生效技能文件命名不符合规范,或触发条件描述不清晰检查 frontmatter 中namedescription;确保技能目录结构正确
MCP Server 启动失败Python 依赖缺失或路径配置错误使用python -m mcp.server手动启动调试,检查环境变量和依赖
MCP 工具能注册但调用报错参数格式与 Server 端预期不一致在 Server 端添加参数校验和日志输出,对比客户端传入的参数结构
同一个工具在 Codex 中注册不上客户端对 MCP Server 的启动方式或参数类型有限制查看客户端日志确认具体报错;尝试用本地 stdio 模式和远程模式分别验证

5.2 排查思路示例

以“模型一直不调用工具”为例,推荐按以下顺序排查:

  1. 打开调试日志,确认模型返回的完整响应中是否包含tool_calls字段。
  2. 检查工具描述是否清晰。很多时候,模型不调用是因为描述里没有说明“什么时候该用”。
  3. 尝试把工具数量减少到一个,排除多个工具间的选择干扰。
  4. 检查上下文长度。如果用户问题前后信息量过大,模型可能丢失工具信息。
  5. 如果使用 OpenAI 系模型,可以尝试在工具定义中增加"strict": true来约束 JSON Schema 严格模式,减少参数匹配失败的概率。

MCP 相关的问题则要优先看日志。MCP 是进程间通信,任何一端发生异常都会导致整体失败。建议在 Server 的关键路径添加日志输出,确认是否收到客户端的初始化请求、工具列表请求和调用请求。

6. 最佳实践与工程建议

6.1 工具命名与描述规范化

无论采用哪种方案,工具命名和描述都值得认真打磨。工具名使用小写字母和下划线,如get_weather,避免使用空格和特殊字符。描述中明确说明“在什么情况下使用”,必要时给出示例参数,让模型更容易理解调用边界。

一个反例和一个正例对比:

反例:查询天气 正例:当用户询问某个城市的当前气温、天气状况或出行建议时,查询该城市的实时天气数据。参数 city 为城市中文名,例如“北京”“上海”。

6.2 配置隔离与环境管理

Skills 文件建议纳入版本管理,按团队或项目维度拆分。不要把所有规则写进一个巨型文件,应该按领域拆分,比如frontend-skillbackend-skilltest-skill,让模型按需加载。

MCP Server 的配置信息,如 API Key、数据库连接串,应该通过环境变量注入,不能硬编码在配置文件中。不同环境(开发、测试、生产)使用不同的配置文件,避免把生产环境的密钥带到本地。

6.3 安全边界与最小权限原则

工具调用和 MCP 接入都意味着模型获得了触发外部动作的能力。权限控制是必须考虑的问题。

建议遵循最小权限原则:给模型暴露的工具,只授予完成任务所需的最小权限。比如,查询订单状态的工具不应该具备删除订单的能力。如果 MCP Server 需要访问数据库,建议使用只读账号,并限制可访问的表和字段范围。

对于涉及用户数据、支付、删除类操作的调用,应该在调用链路上增加人工确认环节,不能完全由模型自动决定。

6.4 异常处理与可观测性

无论使用 Tool Calling 还是 MCP,建议在工具执行层统一封装错误处理逻辑:

  • 工具执行失败时,返回结构化错误信息,而不要抛出原始异常给模型。
  • 记录完整的调用流水,包括用户输入、模型决策、工具参数、执行结果、耗时。
  • 对耗时较高的工具调用做超时控制,防止模型长时间等待外部服务响应。
  • 为关键工具调用增加日志级别区分,便于线上问题回溯。

6.5 性能优化建议

MCP 的进程间通信有一定开销,如果是本地 stdio 模式,单次调用的延迟增加并不明显。但如果是远程 HTTP 模式,网络延迟会成为瓶颈。在设计 MCP Server 时,尽量把频繁调用的逻辑做成无状态接口,方便水平扩展。

Tool Calling 的性能优化重点在减少不必要的工具调用。通过更精确的工具描述和更严格的参数约束,可以让模型一次就调用正确的工具,避免多轮试探带来的 Token 浪费和延迟。

7. 总结与学习路线

本文梳理了 Tool Calling、Skills、MCP 三者的核心概念和区别。简单回顾一下重点:

  • Tool Calling 是模型决策层的“能力开关”,负责决定是否调用工具以及传什么参数。
  • Skills 是内容层的“知识沉淀”,用预定义指令约束模型输出质量。
  • MCP 是架构层的“协议标准”,解决工具接入的标准化和跨应用复用问题。

三者不是竞争关系,而是层层叠加的配合关系。MCP 负责接入,Tool Calling 负责决策,Skills 负责规范。

如果你想继续深入学习,建议按以下路线推进:

  1. 先熟练掌握一种模型的 Tool Calling 用法,理解工具 Schema 如何影响模型决策。
  2. 接着研究 Skills 的编写规范,把你日常工作流沉淀成可复用的技能文件。
  3. 最后学习 MCP 协议,尝试用官方 SDK 搭建一个自己的 MCP Server,接入 Claude Desktop 或自研应用。
  4. 等基础概念清晰之后,再接触 LangChain、LlamaIndex 这类 Agent 框架,你会发现框架里的很多抽象,本质上就是在封装 Tool Calling、Skills、MCP 的这些基础能力。

如果在实际项目中遇到这三个概念混用、选择困难的问题,建议回到业务场景本身:你当前最需要解决的是“模型不会调用工具”“输出不稳定”还是“工具接入太重复”?定位清楚问题,再选对应的技术方案,就不会被概念绕晕了。

如果这篇文章对你有帮助,欢迎收藏备用,后续会继续更新 Agent 工程化的实战内容。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/2 2:04:29

Elasticsearch Carrot2插件实现搜索结果聚类实战指南

简介:面向 Elasticsearch 7.6.0 的 Carrot2 聚类查询插件,专为大规模搜索场景设计,可自动将返回文档组织为结构化主题簇,解决结果冗杂、用户难以快速定位信息的问题。开发者或数据分析人员部署后,可在查询请求中指定多…

作者头像 李华
网站建设 2026/9/2 2:04:19

自研TCP调试助手源码解析:客户端/服务端双模式与Hex收发实现

简介:这是一份基于C#的TCP调试助手源码包,面向网络开发与嵌入式调试人员,提供可运行的TCP客户端与服务端实现。源码包含Form1.cs、myConfing.cs等核心模块,覆盖连接建立、数据发送接收、参数配置等关键逻辑,同时包含Fo…

作者头像 李华
网站建设 2026/9/2 2:03:13

SQLite版本管理痛点与Rust Cargo机制对比及迁移方案

这次我们不聊某一个新项目,而是聊一个很有意思的结构性问题:为什么 SQLite 到现在还在靠PRAGMA user_version 手工迁移脚本管理数据库版本,而不是像 Rust 的 Cargo 那样,有一套从依赖声明到锁文件、再到自动更新策略的完整版本机制…

作者头像 李华
网站建设 2026/9/2 2:01:14

UI动画+高级光影风:让产品价值在30秒内被看懂

判断一个产品页面是否成功的标准,通常不是单张截图有多惊艳,而是用户在前 30 秒内能否读清楚产品核心价值。在这 30 秒里,UI 动画负责引导视线,高级光影风负责建立质感和空间感,两者配合才能把视觉注意力转换成真正的信…

作者头像 李华
网站建设 2026/9/2 2:01:10

Claude Code与Pi的Agent安全:Bash工具权限最小化实战

过去一年,AI 编程助手的形态发生了一个明显变化:从“聊天窗口里贴代码”进化到“直接在终端里替你干活”。Claude Code、Pi 这类 coding agent,能自己读目录、跑测试、提交 Git、清理文件,看起来像一个坐在你电脑前的实习生。但如…

作者头像 李华