ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Tool Calling、Skills、MCP 怎么选?LLM Agent 开发的核心概念辨析

2026/9/1 10:47:20 拓冰建站 浏览量
Tool Calling、Skills、MCP 怎么选?LLM Agent 开发的核心概念辨析 在 LLM Agent 开发中Tool Calling、Skills、MCP 是三个经常被放在一起对比的概念。不少同学刚接触时会有一种困惑它们听起来都像“让模型能调用外部能力”那为什么要分成三个词实际项目里到底应该用哪个这篇文章会从概念定义、协作关系、最小示例、落地配置、选型标准和排查路径几个角度把三者的差异讲清楚目标是让你看完之后能在具体场景里做出判断当前需要的是 Tool Calling 的能力还是 Skills 的知识封装还是 MCP 的连接协议。需要说明的是这三个概念所在的生态还在快速演进不同平台的命名和实现会略有差异。文章里的代码和配置用于说明通用思路落地前请先确认你使用的模型服务、Agent 框架和客户端版本。1. 先区分三个概念Tool Calling、Skills、MCP 分别解决什么问题1.1 Tool Calling让模型按约定生成函数调用意图Tool Calling 通常也被称为 Function Calling它解决的是“模型如何把用户意图转成对某个外部函数的一次调用请求”。这里的重点在于“模型本身不真正执行函数”。模型在收到用户问题时会根据系统说明和工具描述生成一个结构化的调用意图例如“调用 get_weathercity 参数为 Beijing”然后由你的应用代码去真正调用天气接口并返回结果。Tool Calling 是一种模型 API 的能力。常见的 OpenAI 风格函数调用、Claude 的 tool use、国产大模型中类似功能本质都属于这一类。它需要你预先以结构化的方式描述每个工具的名字、功能、参数格式模型才能知道什么情况下选择哪个工具、应该填什么参数。工具描述写得越清楚模型的选择通常越准。需要特别注意的是Tool Calling 不等于“工具已经接通了”。它只完成了“模型觉得该调某个函数”这一步。函数是否真的存在、参数是否真的合法、调用失败后如何反馈仍然是应用层要解决的问题。1.2 Skills把完成特定任务的完整方法打包给模型Skills 在 Claude 生态和部分 Agent 工具中开始流行它的核心目标不是“定义一次函数调用”而是“把完成某一类任务的过程、注意事项、参考脚本和模板打包成可发现、可加载的知识包”。你可以把它理解为当模型遇到的任务与某个 Skill 匹配时模型会先读取 Skill 里的说明再按照说明去组织回答或执行步骤。一个典型的 Skills 目录通常会包含一个描述文件例如 SKILL.md、配套脚本、参考文档、示例数据。描述文件里会写清楚这个 Skill 解决什么问题、在什么场景下使用、执行步骤是什么、有哪些注意事项。和普通的提示词模板相比Skills 更像一个小型工具包它不只是给模型一段提示还可能附带可运行的脚本和结构化资源。Skills 解决的是“每次任务都从零引导模型”的问题。没有 Skills 时你需要在每轮对话里反复粘贴任务背景和规则有了 Skills 后模型能按任务描述自动发现并加载对应技能让重复性任务的输出更稳定、更容易维护。1.3 MCP用统一协议连接外部工具和数据MCPModel Context Protocol模型上下文协议是一种应用层协议目标是解决“模型应用如何标准化接入外部工具、数据源和上下文信息”的问题。过去一个模型应用要接入某个数据库查询工具可能需要写一套自己的集成代码换一个模型应用后接入逻辑可能又要重写。MCP 的做法是把这些外部能力封装成统一的 Server模型应用侧实现统一的 Client两边通过标准协议交互。MCP Server 可以暴露三类能力Tools工具调用、Resources资源读取、Prompts提示模板。Tools 是执行类操作Resources 是数据读取Prompts 是面向特定场景的提示复用。MCP 规范定义了客户端如何发现 Server 支持哪些能力、如何调用这些能力、如何传输结果。从抽象层级来看MCP 并不和 Tool Calling 对立。MCP Server 暴露的 Tools 最终往往还是要通过模型客户端的 Tool Calling 能力来被模型使用。MCP 解决的是“工具方如何以统一方式暴露能力客户端如何以统一方式发现和调用能力”的问题它处在集成协议层。2. 三者不是替代关系一条调用链路里它们如何配合2.1 从四个维度看它们的差异很多同学容易把三者当作同一个层次的概念去做“谁替代谁”的对比。实际上它们解决的问题层次差异很大可以通过下面的维度来区分。维度Tool CallingSkillsMCP定位模型生成函数调用意图的能力面向模型的任务知识和方法封装模型应用与外部工具之间的连接协议抽象层级模型 API 能力应用层任务封装应用层协议核心产物结构化工具描述和调用参数Skills 目录、说明文件和附带脚本MCP Server 暴露的 tools、resources、prompts解决的核心问题模型“想”调用哪个函数模型“知道”该怎么完成复杂任务应用“怎么”连接多个外部系统人工投入重点编写工具描述和参数校验沉淀任务步骤、经验、模板编写服务端能力、部署、权限和版本管理从表格可以看出Tool Calling 最贴近模型本身Skills 偏向任务经验和知识的组织MCP 偏向系统集成。三者并不冲突而是在一条链路里各管一段。2.2 一条完整链路里三者的协作方式实际 Agent 的一次任务执行往往是这样串联的用户输入问题后Agent 先做规划和路由根据问题语义判断该用哪个技能命中某个 Skill 后把 Skill 里的步骤、脚本和规则注入上下文作为后续决策的指导在执行具体操作时模型通过 Tool Calling 能力选择外部函数并生成参数最终执行函数时函数本身可以直接写在应用代码中也可以由 MCP Server 暴露给 Agent。举一个实际场景假设你要让 Agent 完成“分析某产品最近一周的销量趋势并生成报告”。Agent 可以先加载一个“周报分析”SkillSkill 里告诉模型应该先查询数据、再做统计、最后按固定格式输出模型在“查询数据”这一步通过 Tool Calling 调用 get_sales_data这个工具如果已经做成了 MCP Server那么调用请求会通过 MCP 协议发给 ServerServer 负责查库并返回结果。整条链路中三个概念同时存在但各自承担的职责完全不同。正因如此不要问“Tool Calling 和 MCP 哪个好”。更合理的问题是当前项目缺少的是模型调用能力还是任务知识沉淀还是外部系统的统一接入方式。缺少哪一层就补哪一层。3. 用最小示例还原三条落地链路下面用三组最小示例分别展示 Tool Calling、Skills、MCP 在实际开发中的样子。这些示例用于说明思路不代表你已经可以直接复制到生产环境。3.1 Tool Calling 的最小示例以 OpenAI 风格的 Chat Completions 为例第一步是向模型声明有哪些工具可用。工具描述使用 JSON Schema 描述参数结构。[ { type: function, function: { name: get_weather, description: 查询指定城市当前天气, parameters: { type: object, properties: { city: { type: string, description: 城市名称例如 Beijing、Shanghai } }, required: [city] } } } ]当用户问“北京今天天气怎么样”时模型返回的内容里会出现类似下面的结构{ tool_calls: [ { id: call_001, type: function, function: { name: get_weather, arguments: {\city\: \Beijing\} } } ] }应用侧拿到tool_calls后需要自己完成这些事根据function.name找到对应函数把arguments解析成对象调用函数再把结果作为新的消息交回给模型。这里最容易出错的是arguments是字符串而不是对象直接拿到 JSON 字符串就做类型转换会导致运行时报错。3.2 Skills 的最小目录结构Skills 在不同平台的存放位置和加载方式不完全一样但结构化的思路是通用的。一个最小 Skills 项目通常长这样weekly-report-skill/ SKILL.md scripts/ build_report.py assets/ report_template.mdSKILL.md是核心描述文件内容类似这样--- name: weekly-report description: 用于生成产品销量周报。当用户需要按周分析销量趋势、生成数据图表或输出周报文案时使用。 --- # 周报生成技能 ## 适用场景 - 用户提供产品销量数据或数据查询入口 - 用户需要输出结构化周报 ## 执行步骤 1. 获取最近 7 天产品销量数据 2. 计算环比增长率和主要波动原因 3. 输出 markdown 格式周报包含标题、总览表、趋势分析、结论 ## 注意事项 - 所有数据必须标注来源 - 数据缺失时不猜测数值需明确提示模型在判断“这个任务可以交给 weekly-report 技能处理”之后会读取 SKILL.md 并按照其中的步骤执行。描述文件里的description非常重要它决定了模型能不能在合适时机发现这个技能。描述写得太泛模型会在不相关的任务里误用写得太窄模型又发现不了。3.3 MCP Server 的最小示例MCP Server 可以使用官方 SDK也可以用社区封装的类库。下面以 Python 生态的 fastmcp 风格为例演示一个最小服务。实际使用前请先确认当前依赖版本和接口名称不同版本可能有差异。from fastmcp import FastMCP # 创建一个 MCP Server名称为 demo-server mcp FastMCP(demo-server) # 暴露一个工具模型可以通过协议调用它 mcp.tool() def get_weather(city: str) - str: 查询指定城市当前天气 # 这里可以接入真实天气 API return f{city} 当前天气晴25 度 # 暴露一个资源客户端可以按 URI 读取 mcp.resource(config://app) def get_app_config() - str: 返回应用全局配置 return {\timezone\: \Asia/Shanghai\} if __name__ __main__: # stdio 模式适合本地命令行客户端启动 mcp.run()要让一个支持 MCP 的客户端连接这个 Server通常需要在客户端配置里声明启动命令。以 Claude 桌面端或类似工具常见配置为例{ mcpServers: { demo-server: { command: python, args: [path/to/server.py], env: {} } } }这里最关键的是command和args。客户端启动时如果找不到这个命令MCP Server 会启动失败后续所有工具都注册不上。后面排错部分会专门展开讲这个问题。4. 真正落地时这些配置细节决定成败4.1 工具描述字段会影响模型调用准确率Tool Calling 环境下工具能不能被正确调用很大程度取决于name、description、parameters三个字段写得好不好。字段含义常见问题name工具唯一标识命名含糊多个工具语义重叠时模型容易选错description模型判断何时调用该工具的依据写得太空例如“处理数据”模型无法判断具体场景parameters参数结构推荐使用 JSON Schema缺少 required模型可能漏传必填项枚举值未声明模型可能传非法值建议在参数类型上用枚举约束取值范围例如城市固定集合时用enum对于数字参数明确写单位避免模型传入歧义值。工具数量达到十几个之后description 的区分度比数量更重要。4.2 Skills 的命名和描述要服务于“自动发现”Skills 的加载机制大多依赖模型根据任务文本去匹配技能描述。想让匹配更稳定建议注意三点。第一name使用同一个项目中一眼能对齐的命名例如周报类技能统一用*-report后缀。第二description用“当用户需要……时使用”这种句式把触发场景写全。第三Skills 内部不要只写几行文字最好包含可执行脚本或模板让模型不只是在上下文里读到规则还能实际运行辅助程序。Skills 里的脚本同样要有明确的输入输出约定。例如build_report.py接收什么路径的 CSV、输出什么格式的 Markdown必须在 SKILL.md 里写清楚。否则模型加载 Skill 后仍然不知道脚本该怎么用技能封装就失去了意义。4.3 MCP 的传输方式、权限和版本要提前确定MCP 的交互模式从早期到现在一直在演进不同客户端支持的传输方式不完全一致。常见方式包括 stdio、SSEServer-Sent Events和 streamable HTTP。传输方式使用场景需要注意的问题stdio本地命令行工具、桌面客户端客户端需要知道启动命令Server 日志不能打到 stdout否则会污染协议通道SSE远程服务早期 Web 场景需要服务端可访问地址复杂重连需要额外处理streamable HTTP当前趋势更倾向于 HTTP 方式需要确认服务端和客户端实现的 MCP 规范版本是否兼容权限问题上MCP Server 暴露的工具不要默认拥有全部系统权限。比如一个查数据库的 Server最好只使用只读账号一个文件操作 Server最好限制其可访问目录范围。MCP 让工具接入变得方便但也让攻击面更容易隐藏生产中必须对每个暴露能力做最小权限设计。5. 选型不是“谁更强”而是“先接入哪个”5.1 用这几个问题判断当前项目缺什么选型之前先用一组问题确认现状。当前模型能不能稳定返回工具调用意图如果不能优先补齐 Tool Calling 的工具描述和参数定义。是不是每次让模型完成同一个任务都要在提示词里解释大量背景如果是说明缺 Skills 沉淀。外部工具数量是否越来越多每个应用都要单独写一套集成代码如果是考虑将工具改造成 MCP Server。是否需要多人、多客户端共用同一套工具能力如果是MCP 的标准化价值会非常明显。团队有没有能力维护一套独立服务如果没有先不要为了“用 MCP”而引入 MCP直接在应用代码里写函数也能跑通业务。5.2 决策清单可以按这个顺序走可以直接把下面的清单当作选型参考场景优先方案理由模型需要调用一个或少数几个本地函数直接使用 Tool Calling改动最小调试直接同一任务需要多步骤且要输出固定结构在应用代码中保证基础调用再用 Skills 固化任务步骤Skills 降低每次提示词的重复成本一个工具要被桌面端、Web 端、命令行等多个客户端使用做 MCP Server一次接入多处复用外部系统很多但团队没有专职运维先用轻量 MCP Server逐步增加监控和权限控制避免一次性引入过重架构建议不要在一开始同时引入三套能力。许多项目最终失败不是因为某个概念选择错而是因为复杂度一次性堆得太大。先跑通 Tool Calling再沉淀 Skills最后根据需要上 MCP是最稳妥的路径。5.3 学习环境与生产环境的差异要提前想清楚在本地学习和生产落地之间需要补上的工作量差异巨大。这里列一个最小对照表。关注点学习环境生产环境工具执行本地函数直接返回固定数据记录请求和响应支持链路追踪工具权限不做限制最小权限账号、目录白名单、敏感操作审批Skills 版本手工拷贝目录版本管理、目录服务、更新策略MCP Server本机 stdio 启动即可部署、健康检查、多实例、超时重试、日志告警密钥写本地环境变量密钥管理系统集中管理许多问题在本地不会出现。比如本地用 stdio 启动 MCP Server 很容易但一到生产就会发现进程被系统回收、日志把协议通道撑爆、服务重启后工具注册失败。这类问题不在模型侧而在工程侧。6. 常见误区、报错与排查顺序6.1 四个常见误区第一个误区是把 Tool Calling 当成整个 Agent 能力。Tool Calling 只解决“模型输出调用意图”真正的环境执行、结果处理、异常回传还需要应用层完成。第二个误区是把 Skills 与 MCP 放在同一个选型维度。Skills 面向任务MCP 面向工具连接二者职责不同。第三个误区是在 MCP Server 的工具里写太多业务逻辑。MCP Server 更适合做能力暴露和协议适配复杂业务应该拆到独立服务中否则单个 Server 会变成不可维护的“大杂烩”。第四个误区是不约束工具参数。模型不是数据库它也可能传不符合预期的参数工具函数必须先做参数校验再执行业务逻辑。6.2 高频报错和排查思路下面几个现象在 Tool Calling、Skills、MCP 的实际落地中很常见。问题现象常见原因检查方向模型返回的工具名不在预期集合中工具描述语义重叠或模型版本不支持检查 tools 名称是否唯一、description 是否足够清晰arguments 解析失败模型返回的是 JSON 字符串直接当作对象处理先JSON.parse再校验必填字段Skill 总是匹配不上SKILL.md 的 description 与用户问题语义偏差太大修改 description用真实问题做匹配测试MCP 工具注册不上Server 进程启动失败、路径错误、协议版本不兼容先用命令行直接运行 Server 命令再看客户端日志MCP 能连接但调用超时Server 内请求外部接口太慢或网络不可达在 Server 内部加日志测量每步耗时6.3 排查需要按照链路顺序来不管是哪一层出问题排查顺序都建议按照“发现、调用、执行”三个阶段推进。先确认为什么没有发现工具工具是否真的传入模型请求、Skill 是否真的被加载、MCP Server 是否真的注册成功。检查方式是一次只去掉一个变量例如把 MCP Server 地址换成本地路径把 Skill description 换成更简单的关键词。再确认调用阶段模型选择了哪个工具、参数是什么、返回的调用结构是否合法。最后确认执行阶段函数真跑了吗、外部接口返回什么、错误有没有被正确回传给模型。跳过前半段直接看执行日志容易在“工具压根没被发现”的情况下白查很久。7. 从零到生产的渐进路径与检查清单7.1 第一阶段先跑通 Tool Calling这个阶段的目标是用最简单的本地函数把“模型选择工具、应用执行函数、结果回传”这条链路走通。不需要引入 MCP也不需要建 Skills 目录。只需要定义两三个工具例如查天气、算时间差、查配置然后在本地调试模型返回的tool_calls。通过这个阶段你要能回答模型什么时候会选这个工具参数结构什么时候会解析失败结果回传后模型能否基于结果继续回答。跑通后你会对 Agent 的调用链条有一个真实感知而不是停留在概念层面。7.2 第二阶段用 Skills 沉淀高频任务当你发现某个任务每周都要做且每次都要写一大段提示词时就可以把它固化成 Skills。先整理任务步骤再写 SKILL.md接着配一个辅助脚本最后用至少 10 个真实问题测试自动匹配。这个阶段重点关注 description 的质量和匹配稳定性。不要觉得写 SKILL.md 只是在写文档它本身就是 Agent 系统的一部分和代码一样需要版本管理。7.3 第三阶段按需引入 MCP当同一个工具要被多个客户端使用或者外部系统越来越多时再把工具改造成 MCP Server。先从一个只读工具开始例如查询数据库状态、读取远程配置用客户端配置连接调试。确认注册和调用都稳定后再逐步加入有写入操作的工具。MCP 的价值在于一次实现、多处复用所以优先级应该给复用频率高、接入价值大的工具。7.4 发布前检查清单下面这份清单可以保存为团队内部的发布模板每次接入新工具时都过一遍。工具是否声明了清晰的名称、描述、参数约束和必填项。工具函数是否做了参数校验非法请求是否返回人类可读错误。Skill 的 description 是否经过真实问题匹配测试是否存在误触发。Skill 目录是否纳入版本管理脚本依赖是否写清。MCP Server 是否在干净环境中验证过启动命令避免依赖本机特殊路径。MCP Server 是否使用最小权限账号是否限制可访问目录和命令。日志中是否隐藏密钥和敏感字段。是否有超时、重试、熔断机制外部系统不可用时不拖死主进程。是否记录了完整的请求、响应和耗时便于链路追踪。这三个概念会继续演化今天的标准和配置也可能在半年后发生变化。但底层思路是稳定的Tool Calling 是模型调用外部函数的基础能力Skills 是任务方法的结构化沉淀MCP 是工具接入的标准化协议。上手时建议沿着这条路径小步走先让模型能稳定调用一个本地函数再把重复任务封装成技能最后把高频工具通过 MCP 开放给多个客户端使用。复杂系统的稳定性从来不是靠某一个概念“一次到位”而是靠每一层边界清晰、职责明确、可观测。