MCP、ToolFunction 与 Skill:从模型输入到工具执行

本文中的 ToolFunction 泛指"注册给 AI 应用使用的函数工具",不是某个框架的固定类名;Skill 指采用 SKILL.md 组织的 Agent Skills。

本文中的订单、日志、函数和编号均为虚构的通用示例,不涉及任何公司的真实代码、业务规则、内部接口或数据,也不代表任何实际系统的实现。

1. 先记住一句话

ToolFunction 提供动作,MCP 统一接入,Skill 提供方法;Harness 组织执行,模型提出下一步。

概念 主要解决什么问题 排查下单超时的例子
模型 LLM 理解问题、分析证据、生成回答或工具调用请求 判断还需要查哪段代码、哪份日志
Harness 组织上下文、调用模型、调度工具、落实运行限制 管理整段排查过程与工具调用循环
ToolFunction 把一项程序能力注册成可调用工具 搜索代码、读取文件、查询日志
MCP 约定应用如何发现和调用服务端能力 接入独立部署的日志查询服务
Skill 打包专业知识、操作步骤及配套资源 按"核对现象 → 查代码 → 查日志 → 给结论"排查

它们不是互相替代的三代技术。同一个函数可以通过 MCP 暴露,也可以被某个 Skill 指导使用。这里对 Harness 的描述是架构层面的概括,不表示所有产品都采用同一套内部实现。

2. 最核心的关系图

下面展示"应用侧负责工具执行"的常见结构。箭头旁标注的是传递的内容或执行路径。

模型产生工具调用请求,实际程序由应用或服务端执行,再把结果交回模型。这是 Function Calling 的基本交互方式。OpenAI Function Calling

3. ToolFunction:把程序能力交给模型选择

一个普通 Java 方法,并不会因为写好了就自动成为模型能用的工具。应用还需要完成注册和参数映射,让模型知道工具的名称、用途和参数格式。

例如下面的示意方法。logService 是虚构的服务依赖,代码省略了它的定义及框架注册部分,不来自实际项目:

java 复制代码
public String searchOrderLogs(String orderId) {
    // 校验模型提供的订单号,避免无条件执行无效查询。
    if (orderId == null || orderId.isBlank()) {
        // 将输入问题反馈给调用方,而不是继续访问日志服务。
        throw new IllegalArgumentException("orderId 不能为空");
    }
    // 使用应用已有的日志服务查询;真正执行 Java 的是运行环境。
    return logService.searchByOrderId(orderId);
}

这里需要区分三件事:

  • 工具实现:上面的 Java 代码,负责真正查询。
  • 工具定义:名称、描述、参数 Schema,帮助模型理解怎么使用。
  • 工具调用:模型生成的工具名和参数,由运行环境接收并处理。

模型通常不需要看到函数源码。名称也不必与 Java 方法完全一致,可以通过注册关系把 search_order_logs 映射到 searchOrderLogs函数工具定义与调用

"直接注册的函数"不等于"只能操作本地数据":函数内部完全可以访问远程日志 API。

4. MCP:给能力提供统一的接入方式

MCP 全称 Model Context Protocol。它定义应用与服务端交换能力和上下文的协议,而不是某个模型,也不是特指第三方服务。

它的三个参与者是:

  • Host:使用 MCP 的 AI 应用,组织一个或多个 Client。
  • Client:应用中负责与 MCP Server 通信的组件。
  • Server:提供工具、资源或提示模板的程序。

Server 可以是自己开发的,也可以来自第三方;可以运行在本机,也可以运行在远程。常见传输方式是本机进程间的 stdio 和基于 HTTP 的 Streamable HTTP。因此,MCP 与 HTTP 不是同一层面的替代关系。MCP 架构

对于工具,两个关键操作是:

MCP 方法 用途 核心内容
tools/list 发现服务端有哪些工具 名称、描述、inputSchema
tools/call 执行指定工具 工具名、arguments

一个调用可以概括为下面的协议片段。为便于阅读,省略了协议版本相关的必需元数据;这不是可直接发送的完整请求。

json 复制代码
{
  "jsonrpc": "2.0",
  "id": 7,
  "method": "tools/call",
  "params": {
    "name": "search_order_logs",
    "arguments": {
      "order_id": "ORDER-001"
    }
  }
}

tools/call 是应用侧 MCP Client 与 Server 的通信,不是必须交给模型阅读的提示词。模型看到的通常是应用为其整理的工具说明和执行结果。MCP Tools 规范

即使 Server 在本机,只要采用 MCP 接入,仍然要经过这一层协议;使用 stdio 时不必经过网络。协议交换本身不需要调用模型。

5. Skill:不仅是工具清单,更是操作说明

一个 Skill 可以包含专业知识、执行步骤、判断标准,也可以附带脚本和模板。Agent Skills 概述

例如下面的目录,仅用于展示组织方式:

text 复制代码
order-troubleshooting/
├── SKILL.md                  # 何时使用、排查步骤、输出要求
├── scripts/
│   └── summarize_logs.py     # 可选:整理日志
├── references/
│   └── order-flow.md         # 可选:下单业务说明
└── assets/
    └── report-template.md   # 可选:报告模板

其中 SKILL.md 的操作说明可以是:

先确认订单号、环境和时间范围;再定位下单代码与日志;区分已确认事实和待验证假设;只做只读诊断,不自行修改配置或重启服务。

Skill 的常见加载方式是:先提供名称和简介,选中后加载完整说明,再按需要读取参考资料或执行脚本。具体触发方式由宿主实现。Agent Skills 规范

需要注意:

  • 脚本放在 Skill 目录里,不会自动变成一个 Function Calling 工具。
  • 运行脚本需要已有的执行能力,例如经过授权的终端工具或专用执行器。
  • 脚本不一定只能由这个 Skill 使用,也可以复用公共代码;可移植性取决于依赖是否齐全。
  • 如果脚本内部主动调用模型 API,就会产生额外的模型调用;不是因为它叫 Skill 就自动发生。

因此,Toolkit 通常指一组可调用工具,并不等于一组 Skill;一个 Skill 可以指导使用多个 Toolkit 中的工具。

6. 最后到底给模型什么?

以 OpenAI Responses API 为例,最简单的请求可以这样组织。model 使用占位符,工具及订单号均为示例:

json 复制代码
{
  "model": "你的模型ID",
  "instructions": "你是只读排查助手。先核对证据,不修改数据。",
  "input": "请查一下 ORDER-001 的下单日志,解释超时原因。",
  "tools": [
    {
      "type": "function",
      "name": "search_order_logs",
      "description": "按订单号查询调用者有权访问的下单日志。",
      "parameters": {
        "type": "object",
        "properties": {
          "order_id": {
            "type": "string",
            "description": "待查询的订单号"
          }
        },
        "required": ["order_id"],
        "additionalProperties": false
      },
      "strict": true
    }
  ],
  "tool_choice": "auto"
}

这些字段分别表示:

内容 本例的承载位置
系统/开发者行为指令 instructions
用户问题 简单字符串形式的 input
工具名称、说明和参数格式 tools
是否允许模型自行选择工具 tool_choice
已加载的 Skill 内容 由 Harness 放进合适的指令或上下文,不是通用的独立 skill 参数

input 也可以使用带 role 的消息和其他输入项来承载历史对话、工具结果等。Chat Completions 则主要使用 messages 中的 systemdeveloperuser 消息;系统提示词和用户提示词没有消失,只是接口组织方式不同。消息角色与指令

如果日志工具来自 MCP,Harness 可以把 tools/list 中的 inputSchema 适配为上例的 parameters,并记录调用时应该路由到哪个 Server。这是一种接入设计,不是 MCP 强制要求的模型 API 格式。

也有平台原生支持 MCP。例如 Responses 支持 type: "mcp",由平台处理相应的服务接入;不能把"所有 MCP 都先转成 function"当成通则。OpenAI MCP 接入

是不是所有工具和 Skill 都一次性给模型?

不一定。要区分三个范围:

  1. 系统安装或配置了哪些能力。
  2. 当前 Agent 被允许使用哪些能力。
  3. 当前请求实际提供了哪些定义和上下文。

应用可以预先提供工具,也可以通过工具搜索等机制按需加载;Skill 也通常采用渐进加载。具体策略由 Harness、配置和所用平台能力共同决定,不是所有客户端都一样。工具搜索与延迟加载

API 层面,文本消息和工具定义可以分字段传递;它们都会影响模型生成,但这不等于把所有内容手工拼成一段用户提示词。

7. 一个完整案例:排查下单超时

假设用户说:"帮我排查 ORDER-001 下单超时,先不要修改代码。"下面是人为简化的串行执行例子,不是任何产品固定的调用次数。

步骤 谁在处理 发生什么 对应概念
1 Harness 按已有配置选定排查 Skill,准备相关说明与工具 Skill、上下文装配
2 模型,第 1 次 请求搜索下单超时相关代码 选择 ToolFunction
3 工具执行器 校验后执行代码搜索,将代码片段返回 ToolFunction 执行
4 模型,第 2 次 结合代码,请求查询订单日志 选择 MCP 暴露的工具
5 MCP Client/Server 查询日志,返回"等待数据库连接超时"的记录 MCP 调用及服务端执行
6 模型,第 3 次 汇总证据,给出结论和仍需验证的部分 分析与最终回答

这条示例链路调用了 3 次模型、执行了 2 次业务工具。不能据此认为"一个工具固定对应一次模型调用":一次模型响应可能请求多个工具,工具也可能内部调用模型。

同样,应用发出了几次 API 请求,也不一定等于平台内部推理了几轮;托管工具流程可能在一次外部请求中完成多步处理。

本例应输出"日志显示等待数据库连接超时",而不能只凭这一条日志断言"数据库已经宕机"。工具提供证据,模型负责分析,最终结论仍需要足够证据支撑。

8. 工具失败了,谁决定下一步?

可以分成两层:

  • 预设策略:Harness 或工具执行器按代码规则处理,例如对幂等的只读查询有限重试、到达超时后返回错误。
  • 模型决策:错误进入上下文后,模型可能提出更换查询条件、使用其他已获准工具,或说明无法继续。

更换工具不是必然发生,也不能因为工具名称相似就认定能力等价。MCP 负责传递调用和结果,不会自动提供完整的排查与恢复策略。

尤其是写操作,失败响应不一定意味着操作没有生效。重试前需要检查执行结果和幂等条件,不能无限重试。

9. 权限控制不能只靠提示词

"只读排查,不允许修改"可以写进系统指令和 Skill,但工程上还应在执行层落实:

  • 只暴露任务所需的工具,并使用最小权限凭证。
  • 校验工具名、参数、目标资源和当前用户权限。
  • 对写入、删除、发布等动作设置明确的授权规则。
  • 限制执行时间、重试次数与总调用预算。
  • 记录工具调用与结果摘要,但不要记录凭证或无关敏感数据。
  • 把外部日志、文档和工具返回中的指令性文字当作待判断的数据,不能让它们自行扩大权限。

这些是执行层的设计要求,不能由"工具描述说它只读"或"模型承诺不修改"代替。MCP 规范同样强调输入校验、访问控制及对工具元数据的信任边界。MCP 安全要求

10. 怎么选?

作为工程选型的简化判断:

  • 只在一个应用里使用某项能力:直接注册 ToolFunction 往往最简单。
  • 希望多个兼容客户端复用服务:可以考虑通过 MCP 暴露能力。
  • 希望沉淀团队的专业做法:使用 Skill 打包流程、知识和配套资源。
  • 希望管理多轮执行、上下文与权限:由已有或自建的 Harness 承担。

它们可以组合,也可以只采用其中一部分。有工具,不代表有操作方法;有操作方法,不代表有执行权限;有协议,不代表有完整的 Agent 运行循环。

相关推荐
ClouGence20 分钟前
2026 数据库 CI/CD 工具大盘点:4 款热门工具怎么选?
数据库·后端·ci/cd
码事漫谈1 小时前
项目探测:把老项目的知识变成 AI 的外部记忆
后端
PragmaticWorks1 小时前
从"遍地 try-catch"到分层治理:用 pragmatic-ddd 的异常体系治好代码洁癖
后端·领域驱动设计
苍何1 小时前
我的开源项目登顶 GitHub 趋势榜 No1 了!
后端
AI发掘2 小时前
论文 AI 率超标,如何低成本降低至合格标准?快降重 VS PaperPass 实测,选出省钱又达标的方案
人工智能·aigc
苍何2 小时前
原来 Agent 量大管饱,真不是吹的
后端
MetaLite2 小时前
SpringBoot分页接口怎么设计-pageSize不设上限会发生什么
java·spring boot·后端
元界metalite2 小时前
SpringBoot整合Redis分布式锁-为什么不能直接DEL
后端
0end12 小时前
AI Agent 学习笔记(五):工具设计(上)——分类与设计原则
aigc