ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Tool Calling、Skills与MCP:搞清三者区别与组合用法

Tool Calling、Skills与MCP:搞清三者区别与组合用法 我接触过不少做 Agent 的开发者也看过很多技术社区里的讨论发现最近有两个现象非常典型一方面Claude、OpenAI、Google 都在快速迭代“函数调用”“工具调用”“技能”“MCP”这些能力官方文档越来越厚另一方面很多开发者面对“Tool Calling、Skills、MCP 之间的关系”时仍然是一头雾水。有人在面试里被问“Skill 和 MCP 有什么区别”有人在自己的项目里把 MCP 当成了 Tool Calling 的替代品还有人把 Claude Skills 理解成一组 Prompt结果写完根本没有生效。这篇文章想把这三件事讲透它们分别解决什么问题背后的运行机制是什么在同一个 Agent 项目里应该怎么组合使用。先说结论Tool Calling 是模型的一种“输出协议”它让模型能表达“我要调用某个函数参数是什么”Skills 是对模型技能的一种“封装形式”它把完成某类任务的说明、模板、可执行脚本打包成一个可复用的技能目录MCP 则是一套“工具接入标准”它让外部工具和数据源能够用统一的方式暴露给模型客户端。三者不在同一个平面上不能简单地说谁替代谁。如果你正在做 Agent 开发或者打算在自己的应用里接入 Claude、OpenAI 等模型的工具调用能力这篇文章可以帮你把这些概念理清并给出一套能直接照做的工程建议。1. 为什么这三个词最近总是同时出现在传统编程里函数调用是程序内部的事情代码调用代码数据在进程里流动。但在大模型时代“调用”的概念被扩展了模型本身不具备执行能力它只能生成文本。如果你希望模型在回答问题时能够查数据库、调用外部 API、操作浏览器就必须在“模型生成文本”和“外部系统执行动作”之间建一座桥。过去的桥大多是自己搭的。你用 Prompt 约定 JSON 格式让模型输出{action: get_weather, city: 北京}然后自己写代码解析这段 JSON再调用真实 API。这种方式能跑通但很脆弱模型可能输出不规范 JSON可能字段命名不统一也可能在你换了模型之后完全失效。于是出现了第一个层次的标准化Tool Calling。OpenAI 把它叫做 Function CallingAnthropic 叫做 Tool UseGoogle 也有类似能力。本质上是模型在训练和推理阶段被专门优化过能够稳定输出结构化的工具调用请求。你不用再靠 Prompt 硬逼模型输出 JSON而是把工具的描述和参数 Schema 告诉模型模型会在合适的时候“请求”调用。但这只是解决了“能不能调”的问题。当你开始做真正的 Agent 项目很快会发现另外两个痛点第一工具太多了。一个稍微完整的 Agent 可能要接入几十个工具比如 GitHub、数据库、内部文档搜索、浏览器自动化。如果每个工具都要写一套自定义接入代码工作量巨大而且每换一个客户端或者模型都要重新适配一遍。第二很多任务并不是简单“调一个函数”就能完成的。比如让模型帮你做一次完整的代码审查或者按照团队规范生成一份项目文档这类任务包含多步操作、固定的输出格式、领域知识甚至需要运行一段脚本来辅助完成。当时最普遍的做法是把这些写进一个巨大的 System Prompt结果 Prompt 越来越长模型越来越容易“忘”。对付这两个痛点就分别出现了 MCP 和 Skills。MCPModel Context Protocol模型上下文协议是由 Anthropic 于 2024 年底对外推广的一套开放协议目的是统一模型客户端与外部工具、数据源之间的接入方式。它的理念可以参考“USB-C 接口”无论你接的是显示器、硬盘还是读卡器只要接口标准一致插上就能用。MCP 把“工具”这个概念从单机函数变成了网络上可发现、可连接的资源。Skills 则是 Anthropic 在 2025 年推出的 Agent Skills 规范它把一个完整的工作流拆成可以独立发布的技能包。一个 Skill 通常由一个带有SKILL.md说明文件的目录构成里面可以包含步骤说明、参考文档、模板、Python 脚本等。模型在运行时可以读取这个技能包按照其中的指导完成复杂任务。它解决的是“经验沉淀”问题。所以你会看到这三个词经常同时出现是因为一个完整的 Agent 系统往往同时需要它们用 Tool Calling 作为模型与工具之间的调用契约用 MCP 统一工具接入方式用 Skills 沉淀和复用领域能力。2. Tool Calling让大模型拥有“操作权”2.1 Tool Calling 到底做了什么要理解 Tool Calling先要理解大模型本身是一个“文本生成器”。你问它“北京今天天气怎么样”它能回答但它并没有真的去查天气。它能告诉你如何写一段 Python 代码但它无法执行这段代码。Tool Calling 做的事情是在模型生成过程中允许它在合适的时机输出一个特殊结构这个结构不是普通聊天文本而是一个“工具调用请求”。这个请求会包含调用的工具名。调用时传入的参数。一个标识符用于区分多次调用。然后由你的应用程序负责执行这个调用并把执行结果返回给模型。模型拿到结果之后再继续生成最终回答。举个例子。你给模型配置了一个get_weather(city: string)工具用户问“北京和上海哪个冷”。模型可能不会直接回答而是先输出两次工具调用请求[ { id: call_1, type: function, function: { name: get_weather, arguments: {\city\: \北京\} } }, { id: call_2, type: function, function: { name: get_weather, arguments: {\city\: \上海\} } } ]你的代码收到这份请求后分别调用真实天气 API拿到两个城市的气温然后把结果追加到对话上下文中。模型看到结果后再生成“北京 10 度上海 16 度上海更暖和一些”这样的最终回答。2.2 Tool Calling 的核心流程一次完整的 Tool Calling 循环可以分为五步定义工具把每个函数的名称、描述、参数 Schema 提供给模型。这一步通常在 System Message 或请求参数中完成。模型决策模型根据用户的问题判断是否需要调用工具、调用哪个工具、传什么参数。应用执行应用程序收到模型返回的工具调用请求执行真实逻辑。结果返回把执行结果以消息形式追加到对话历史里。模型整合模型基于工具结果生成最终回复或发起下一轮工具调用。这个流程的核心特征是模型不直接执行工具它只负责“决策”和“参数生成”。真正的执行权在你的代码手里。这个设计很重要它意味着你可以在执行层加入权限校验、参数校验、日志、限流、人工审批等逻辑。2.3 常见误区新手最容易混淆的一点是以为模型“会使用工具”。实际上模型只是“请求”使用工具。如果工具本身有 bug或者参数传错模型无能为力。还有一层误区是把 Tool Calling 等同于模型“理解”了工具。模型对工具的理解仅局限于你提供给它的名称、描述和参数说明。如果描述写得含糊模型就会乱传参。因此在工程上工具描述的写作质量往往直接决定了 Tool Calling 的效果。下面是一个常见的问题描述写得差 获取天气信息。 描述写得好 获取某个城市当前的实时天气信息。用于回答天气查询、出行建议、穿衣建议等问题。传入城市名时请使用中文标准名称例如北京、上海不要使用拼音。描述越精确模型越不容易犯错。2.4 适合场景与不适合场景Tool Calling 适合那些“动作明确、参数明确”的场景例如查天气、查数据库、发邮件、创建工单、执行搜索。不适合的场景有两类任务链路很长、依赖复杂上下文的任务。Tool Calling 本身不带“流程意识”它只负责单轮调用。如果模型连续调了 5 个工具流程管理和错误恢复都要靠你自己的编排层去做。需要大量领域判断的任务。比如“按照公司规范撰写一份技术方案书”它本质上不是一个工具能解决的更适合用 Skills 来封装整套方法论。3. Skills把“做事的方法”打包给 Agent3.1 Skills 要解决的痛点假设你是一个前端团队的负责人。你想要让 Claude 或 Codex 帮助团队成员完成日常的代码审查、组件开发、构建配置。技术方案应该是告诉它公司技术栈。告诉它编码规范。告诉它审查清单。让它按照固定流程输出审查结果。如果把这些全部写进 System Prompt会有什么问题第一个问题System Prompt 会变得极其臃肿模型在长对话中容易忽略后面的内容第二个问题这些规范无法复用换一个项目或者换一个工具就要复制粘贴第三个问题静态文本没办法执行辅助脚本比如检查编译、跑测试。Skills 就是针对这个问题的解决方案。在 Claude 的机制里一个 Skill 是一个目录里面包含一个带 YAML frontmatter 的SKILL.md文件以及一些辅助文件。目录结构类似这样my-skill/ ├── SKILL.md └── scripts/ └── check_build.pySKILL.md的内容类似这样--- name: frontend-review description: 用于前端代码审查与规范检查。当用户要求审查前端代码、检查组件规范或优化构建配置时使用。 --- # 前端代码审查指南 ## 第一步阅读项目结构 先查看 package.json、src 目录结构确认识别项目类型。 ## 第二步检查规范 - 组件命名使用 PascalCase - 样式文件与组件同级 - 禁止在组件内直接使用 window 对象 ## 第三步运行构建检查 运行 python scripts/check_build.py收集错误信息。 ## 输出格式 按以下格式输出审查结果 - 问题列表 - 严重程度 - 修改建议当模型遇到适合该 Skill 的任务时它会通过description字段判断是否应该加载这个技能然后按照SKILL.md里的指引逐步完成任务。3.2 Skills 和普通 Prompt 的区别Skills 看起来像是“高级的 Prompt”其实差别很大。第一Skills 可以包含可执行脚本。模型可以直接在代码环境里运行这些脚本并把运行结果纳入自己的判断。这是纯文本 Prompt 做不到的。第二Skills 有主动加载机制。在 Claude Code 或 Codex 中Skills 是按需加载的。模型先读技能名和描述判断当前任务是否适用再决定是否完整读取技能内容。这样可以显著降低无关上下文对模型的干扰。第三Skills 是可发布的协作单元。你可以把某个技能打包上传团队成员直接安装使用不必复制 Prompt 到每个项目中。例如搜索热词里提到的“结构图 Skills”“分镜 Skills”本质上是有人把画框架图、写分镜脚本的方法打包成了 Skills 共享出来。3.3 Skills 和 MCP 的关系这是很多开发者问得最多的问题既然有了 MCP为什么还需要 Skills它们有什么区别简单来说MCP 解决的是“如何把外部工具接入模型”Skills 解决的是“如何把做事方法论沉淀进模型的工作流”。两者不是同一层的东西。MCP Server 对外暴露的是 tools、resources、prompts它是模型的“手和眼”Skills 提供的是指导模型“如何思考、如何行动”的说明、模板、流程它是模型的“操作手册”。举个例子。你可以通过 MCP 接入 Figma 的图层数据让 Agent 读取设计稿信息这是接入能力。但“如何根据设计稿生成规范的 React 组件代码”这种完整流程是 Skill 要管的事。实际项目中经常是两者配合使用用 MCP 获取数据用 Skill 约束处理方法和输出格式。3.4 Skills 的开发要点如果你打算自己写一个 Skill有几个要点值得注意Description 要写得谨慎。它决定了模型什么时候启用这个技能。写得太窄模型不会触发写得太宽模型会胡乱加载。步骤要可执行。SKILL.md里的每一步最好是具体动作比如“运行python scripts/check.py”而不是“检查构建是否正常”这种模糊描述。辅助脚本要健壮。如果脚本报错模型可能会被误导所以脚本最好有清晰的错误输出和结束状态例如返回非零退出码并打印错误原因。尽量保持技能目录独立。一个技能只做一件事避免技能之间互相依赖。4. MCP用一套协议连接所有工具与数据4.1 MCP 的背景与目标在 MCP 出现之前每个 Agent 应用接入外部工具时基本都是“点对点对接”。比如说应用 A 要接 GitHub应用 B 要接 GitHub两边写完全不同的代码。工具提供方要为一个工具写多个 SDK应用方也要为每个工具写多个适配器。这种局面非常像 USB 标准统一之前的电脑外设接口五花八门。MCP 的目标就是像 USB-C 一样把“客户端-工具”的连接方式标准化。只要工具方实现一个 MCP Server所有兼容 MCP 的客户端都可以直接使用只要客户端实现 MCP 客户端能力就能连接所有 MCP Server。通俗地说MCP 是一个“胶水层”它定义了一套 JSON-RPC 通信协议规范了连接、发现、调用等交互方式。它不关心你底层是 REST API、数据库还是本地文件它只关心如何把这些东西以统一的形式暴露给模型客户端。4.2 MCP 的核心角色MCP 架构中有三个核心角色MCP Host用户使用的程序例如 Claude Desktop、Claude Code、Cursor、自研应用。它是发起方负责与用户交互并调用 MCP 客户端。MCP Client在 Host 内部与 Server 建立一对一连接的组件。MCP Server提供工具、资源、提示的轻量级服务。每个 Server 对外暴露一组能力Client 连接后可以发现并调用这些能力。连接关系通常是这样用户 - MCP Host (Claude Code / 自研应用) - MCP Client A --JSON-RPC-- MCP Server A (GitHub) - MCP Client B --JSON-RPC-- MCP Server B (Database) - MCP Client C --JSON-RPC-- MCP Server C (本地文件)4.3 MCP 的三种核心能力MCP Server 可以暴露三种类型的能力Tools工具可被模型调用的函数式能力例如“查询 PR 列表”“创建 Issue”“搜索代码”。Tool Calling 在这里发挥作用模型决定调用工具MCP 负责传输调用请求和结果。Resources资源向客户端提供可读的数据例如文件内容、数据库记录。资源是数据来源不一定是可执行动作。Prompts提示模板预先定义好的可复用提示词用户或模型可以直接使用。一个 MCP Server 可以同时提供多种能力。例如一个“知识库 MCP”既可以提供文档资源也可以提供搜索工具。MCP 官方参考实现中还提供了 MCP Inspector 这类调试工具方便开发者验证 Server 是否工作正常。4.4 MCP 客户端配置示例在 Claude Desktop 或 Claude Code 中MCP Server 通常通过一个 JSON 配置文件登记。下面是一个典型配置{ mcpServers: { github: { command: npx, args: [-y, modelcontextprotocol/server-github], env: { GITHUB_PERSONAL_ACCESS_TOKEN: your_token_here } }, database: { command: python, args: [-m, my_mcp_server] } } }字段解释mcpServers配置多个 MCP Server 的入口。command启动 Server 的本地命令。args启动参数。示例里使用了npx -y拉取并运行 npm 包。env注入给 Server 进程的环境变量常用于放 API Token。要注意配置里的 Token 等敏感信息最好不要直接提交到代码仓库。更稳妥的做法是使用环境变量占位符或者在本地工具中通过特定配置方式注入。4.5 自己实现一个 MCP Server如果你需要在一个自研工具里暴露自己的业务能力可以用官方 SDK 快速实现。下面是 Python SDK 的一个最小示例代码仅供参考具体 API 以官方文档为准# server.py from mcp.server.fastmcp import FastMCP mcp FastMCP(demo-server) mcp.tool() def add(a: int, b: int) - int: 计算两个整数之和。 return a b mcp.tool() def get_user(id: str) - dict: 根据用户 ID 获取用户信息。这里用 mock 数据演示。 return {id: id, name: demo-user} if __name__ __main__: mcp.run()运行这个 Serverpython server.py然后你就可以在支持 MCP 的客户端中配置{ mcpServers: { demo: { command: python, args: [server.py] } } }这样一个最简单的 MCP Server 就跑起来了。它把add和get_user暴露给所有兼容 MCP 的客户端。5. 三者的核心区别与层次关系5.1 一句话概括Tool Calling是一种模型能力告诉模型“你可以申请调用某个函数”。Skills是一种能力封装规范告诉模型“完成这类任务时按这个流程、用这些工具、输出这种结果”。MCP是一种接入协议告诉客户端“外部工具和数据如何被安全、统一地暴露出来”。5.2 对比表格下面这张表总结了它们主要差异对比维度Tool CallingSkillsMCP本质模型的输出机制任务方法论的封装工具接入协议解决的核心问题模型如何表达调用意图模型如何按规范完成复杂任务外部工具如何统一接入主要执行者模型 应用代码模型 脚本/模板/说明文档MCP Server MCP Client是否必须联网不必须不必须Server 可以在本地运行是否包含可执行代码不包含可以包含可以包含复用范围单次对话或会话跨项目/跨团队复用跨客户端/服务端复用典型实现OpenAI Function Calling、Anthropic Tool UseClaude Agent Skills、Codex SkillsMCP SDK、MCP Server需要注意的是这个表格是从“定位”角度做的对比。实际使用中三者通常共存并非非此即彼。5.3 层级关系与组合方式从架构视角看三者的关系可以这么理解最底层是能力接入面用 MCP 统一接入所有外部工具和数据。中间层是工具调用面用 Tool Calling 让模型能够按需“点击”这些能力。最上层是流程编排面用 Skills 把解决某类任务的完整方法固化下来。在 Anthropic 的 Agent 套件中这个组合很常见Claude Code 作为一个 Host通过 MCP 连接 GitHub、文件系统、数据库等工具同时加载一个 Code Review Skill让模型按照技能说明先读取代码、再跑静态检查、最后按固定格式输出审查报告。Action 的触发基础就是 Tool Calling而执行链路被 Skill 组织起来。这种组合的好处是替换底层工具时只要换 MCP Server调整流程时只改 Skill模型升级时只要它还支持 Tool Calling上层几乎不用动。6. 完整示例在一个 Agent 项目中组合使用三者下面我们用一个尽可能简单的场景展示三者如何配合。假设我们要实现一个“项目体检助手”通过 MCP 连接一个本地代码仓库服务读取项目文件。通过 Tool Calling 让模型按需调用 MCP 暴露出的工具。通过一个project-reviewSkill 指导模型按固定流程完成项目体检。6.1 第一步定义 MCP Server我们先用 Python SDK 写一个简单的 MCP Server暴露两个工具read_file和list_files。# file_server.py from mcp.server.fastmcp import FastMCP mcp FastMCP(file-server) mcp.tool() def list_files(path: str) - list[str]: 列出指定目录下的文件与子目录名。 import os return os.listdir(path) mcp.tool() def read_file(path: str) - str: 读取指定文本文件的内容。 with open(path, r, encodingutf-8) as f: return f.read() if __name__ __main__: mcp.run()启动python file_server.py6.2 第二步注册 MCP Server在客户端配置文件中登记这个 Server{ mcpServers: { file-server: { command: python, args: [file_server.py] } } }这一步让模型所在的应用能找到这个工具服务。6.3 第三步编写一个 Skill创建一个project-reviewSkill 目录project-review/ ├── SKILL.md └── tips.mdSKILL.md内容--- name: project-review description: 用于对小型代码项目做健康体检包括文件结构检查、关键文件阅读、问题汇总输出。当用户要求“体检项目”“Review 项目”“检查代码结构”时使用。 --- # 项目体检指南 ## 第一步查看项目结构 调用 list_files 确认项目根目录。 ## 第二步阅读关键文件 通常需要阅读 README.md、package.json 或 requirements.txt了解项目类型。 ## 第三步输出体检报告 按以下格式输出 - 项目类型 - 主要文件结构 - 发现的问题 - 改进建议6.4 第四步运行效果与验证在支持 MCP 和 Skills 的客户端中运行用户请帮我看看这个项目做一次体检。模型触发project-reviewSkill按照技能说明发现需要读取文件列表因此通过 Tool Calling 请求调用 MCP 中的list_files工具拿到列表后再请求调用read_file读取关键文件最后按照 SKILL.md 规定的格式生成体检报告。实现这个流程的关键是模型既要有 Tool Calling 能力又要能理解技能文件。在 Claude Code 中这个链路是原生支持的在自研系统中你需要自己实现类似逻辑先让模型判断是否加载某个 Skill再加载 Skill 内容再允许模型进入 Tool Calling 循环。6.5 这个组合的意义这个例子虽然小但它展示了三个层面的分工MCP 负责“能拿到什么”文件服务通过 MCP 暴露出来。Tool Calling 负责“如何拿”模型按需调用工具。Skills 负责“怎么用这些拿到的信息”让模型知道先看结构、再看关键文件、最后按格式输出。如果将这套逻辑完全写在一个大 Prompt 里也能运行但维护成本完全不同。MCP Tool Calling Skills 的组合让每一层都可以独立演进。7. 常见问题与排查思路在实际开发里大多数人遇到的坑不是概念理解问题而是工具接入和运行时的配置问题。下面整理一些高频问题。问题现象可能原因排查方式解决方案模型总是调用同一个错误工具工具描述模糊或参数 Schema 设计不合理查看模型实际生成的调用参数对比描述文本重写工具描述增加明确的触发条件和示例模型没有调用工具直接编答案工具列表未传入模型请求检查请求参数中是否包含tools字段在 API 请求中显式传入工具列表MCP Server 启动失败环境变量缺失或依赖未安装在终端直接运行 MCP Server 启动命令查看报错安装缺失依赖配置环境变量后再试模型能发现 MCP 工具但调用时报错MCP Server 返回了异常结构查看 MCP Server 日志使用 MCP Inspector 调试工具验证工具参数格式Skill 始终没有生效SKILL.md 的 description 与任务不匹配检查技能描述与实际提示词是否搭边调整描述增加任务关键词使用 npx 启动 MCP Server 时下载缓慢网络原因或 npm 缓存问题查看日志中 npx 的下载进度改用本地安装依赖后运行node server.jsTool Calling 返回参数解析失败模型输出格式异常或 API 返回被截断检查返回对象的finish_reason和tool_calls字段增加异常捕获与重试逻辑在做 MCP 工具接入时我建议先孤立验证 MCP Server再把它接入具体客户端。单独跑起来一个 Server 不一定等于它能被客户端正常使用因为还牵扯到参数透传、JSON 序列化、权限配置等环节。8. 最佳实践与工程建议8.1 命名与描述规范无论是 Tool、MCP Server 还是 Skill命名都会直接影响模型的理解。工具名建议使用“动词 名词”的清晰结构例如get_user_by_id避免使用模糊的缩写。描述里要包含工具能做什么、什么场景触发它、参数怎么传。8.2 工具按需加载不要一把梭MCP Server 和 Skill 都不是越多越好。每加载一个工具模型在决策时就要多考虑一种可能这会增加误调用和性能开销。把工具按业务场景拆分成多个 Server例如file-service、git-service、database-service让客户端按需连接。8.3 安全与权限边界在大模型工具调用链路里安全边界尤其重要。最核心的一条原则是模型只拥有“请求权”应用拥有“执行权”。在实际工程里你可以在执行层做以下事情校验调用参数防止路径穿越、SQL 注入、命令注入。对高危动作设置二次确认例如删除、写库、发布。记录完整的调用链路日志方便回溯。使用最小权限原则给 MCP Server 分配专门的 Token而不是用个人最高权限账号。8.4 可观测性是第一位Agent 应用一旦进入多工具调用调试难度会明显上升。建议在每一个 Tool 调用前后都记录输入和输出保留结构化日志。对于 MCP Server最好统一日志格式并加入request_id关联上下文。否则一旦模型进入循环调用或误调用排查会非常痛苦。8.5 考虑降级方案Tool Calling 并不是 100% 可靠的MCP Server 也可能临时不可用。因此在正式产品里要设计降级路径。比如当模型调用工具失败时可以重试一次连续失败时让模型直接告诉用户“当前无法获取该信息”而不是臆造结果。不要让模型把工具模式的“失败”当成“结果为空”。8.6 把 Skill 像代码一样管理Skill 既然是技术资产就应该纳入版本管理。建议把每个 Skill 当作独立目录进行 Git 管理并写清楚版本变更说明。发布和更新流程也要有规范避免团队里出现多个版本的技能互相覆盖。9. 总结与下一步学习方向回到开头的问题Tool Calling、Skills、MCP 分别是什么有什么区别Tool Calling 是模型与外部动作之间的“调用契约”它回答“模型如何表达要调什么工具、传什么参数”。Skills 是复杂任务经验的“封装单元”它回答“如何引导模型按一套完整方法论完成任务”。MCP 是工具和数据源的“接入标准”它回答“外部能力如何统一地连接进 Agent”。三者相互配合但不互为替代。如果你正在做 Agent 应用我建议按这个顺序实践先跑通一个 Tool Calling 最小示例理解工具调用循环。再接入一个现成的 MCP Server体验统一接入协议。最后写一个属于自己的 Skill把某个重复性任务固化下来。接下来值得深入的方向包括MCP 的认证与授权机制、Skill 的自动发现与分数评测、如何设计高质量的工具参数 Schema以及如何在多 Agent 系统中共享 Skills。愿你少踩几个“工具没生效”的坑把 Agent 从“能聊天”真正推向“能干活”。
返回列表