MCP 进化:让静态 Tool 进化为具备“上下文感知”的远程 Skills
在 AI Agent 的工程实践中,Model Context Protocol (MCP) 已成为连接大模型与外部世界的标准桥梁。然而,随着应用场景从“个人助手”向“企业级复杂业务”迈进,传统的 MCP 交互模式开始显露其 “静态化” 的瓶颈。
Solon AI 支持将 MCP 封装为 Skill,实现了从“冷冰冰的 API 集合”到“具备感知能力的智能技能”的跨越。
一、静态 Tools 的三大痛点
传统的 MCP 交互类似于一个“无法关闭的工具箱”,无论场景如何,所有工具一涌而上:
- 上下文噪音(Context Noise): 即使是一个简单的问候,模型也会被注入成百上千行的工具 Schema 定义,白白浪费 Token,更干扰模型的推理专注度。
- 权限真空(Security Risks): 模型对工具的可见性是“全量”的。难以根据当前登录用户的角色(如普通用户 vs 管理员)动态隐藏敏感操作(如:删除订单)。
- 行为失控(Instruction Gap): 工具只提供了“能做什么”,却无法告诉模型“在当前背景下该怎么做”。模型缺乏针对特定业务场景的即时指令约束。
二、核心解决方式:感知、挂载与动态分发
Solon AI 通过引入 Skill(Solon AI Skills) 生命周期 来包裹 MCP 协议,实现以下机制解决上述痛点:
A. 智能准入 (isSupported):
只有当 Prompt 上下文(意图、租户信息、环境变量)满足条件时,技能才会被激活。
B. 指令注入 (getInstruction):
在技能挂载时,自动为模型注入针对当前上下文的“行为准则”(System Message)。
C. 三态路由 (getToolsName):
服务端根据 Prompt 属性,动态决定给模型展示哪些工具。支持三种形态的路由方式:
- 全量使用:未定义过滤逻辑时,显示所有业务工具。
- 精准授权:仅展示当前用户权限范围内的工具。
- 完全拒绝:即便技能激活,也可能因安全策略在此时封锁所有工具调用。
三、实战示例
1. 客户端:像本地技能一样调用
开发者只需关注业务属性的注入,无需操心工具的过滤逻辑,一切由 MCP Skill 代理与远程服务端约定与协商。
import org.noear.solon.ai.chat.ChatModel;
import org.noear.solon.ai.chat.prompt.Prompt;
import org.noear.solon.ai.mcp.McpChannel;
import org.noear.solon.ai.mcp.client.McpClientProvider;
import org.noear.solon.ai.mcp.client.McpSkillClient;
//构建 mcp 客户端
McpClientProvider mcpClient = McpClientProvider.builder()
.channel(McpChannel.STREAMABLE)
.url("http://localhost:8081//skill/order")
.build();
// 构建带有业务属性的提示词
Prompt prompt = Prompt.of("帮我取消订单 A001")
.attrPut("tenant_id", "solon_001")
.attrPut("user_role", "ADMIN"); // 模拟管理员身份
// 注入技能,模型将只看到“管理员”权限下的工具
chatModel.prompt(prompt)
.options(o -> o.skillAdd(new McpSkillClient(mcpClient))) //将 mcp 客户端 包装为 Solon AI Skills
.call();
2. 服务端:实现具备“感知力”的技能
服务端不再是盲目响应,而是通过解析 Prompt 决定自己的表现。
import org.noear.solon.ai.annotation.ToolMapping;
import org.noear.solon.ai.chat.prompt.Prompt;
import org.noear.solon.ai.mcp.McpChannel;
import org.noear.solon.ai.mcp.server.McpSkillServer;
import org.noear.solon.ai.mcp.server.annotation.McpServerEndpoint;
import java.util.ArrayList;
import java.util.List;
@McpServerEndpoint(channel = McpChannel.STREAMABLE_STATELESS, mcpEndpoint = "/skill/order")
public class OrderSkillServer extends McpSkillServer {
@Override
public boolean isSupported(Prompt prompt) {
// 感知意图:只有涉及“订单”且租户合规时才激活
return prompt.getUserContent().contains("订单")
&& prompt.attr("tenant_id") != null;
}
@Override
public String getInstruction(Prompt prompt) {
// 动态指令:注入租户特定的业务规则
return "你现在是租户[" + prompt.attr("tenant_id") + "]的订单助手。";
}
@Override
public List<String> getToolsName(Prompt prompt) {
// 权限隔离:根据用户角色动态下发工具名
List<String> tools = new ArrayList<>();
tools.add("OrderQuery"); // 基础权限
if ("ADMIN".equals(prompt.attr("user_role"))) {
tools.add("OrderCancel"); // 仅管理员可见
}
return tools;
}
@ToolMapping(description = "查询订单")
public String OrderQuery(String id) { ... }
@ToolMapping(description = "取消订单")
public String OrderCancel(String id) { ... }
}
四、Skills 架构反思与局限性补充
尽管将 MCP 进化为 Skills 带来了显著的工程优势,但开发者仍需理清其技术边界:
- 非标准化的架构增强:
LLM 的底层标准仅包含 Prompt 和 Tool-Call。Skills 并非模型原生标准,也不属于 MCP 的公共协议规范,而是一种 架构设计模式(模式,是通用的)。它通常由 AI 开发框架(如 Solon AI)在消费侧实现,用于解决复杂业务下的能力调度问题。
- 消费侧驱动的定制:
MCP 向 Skills 的进化本质上是“业务驱动”或“领域驱动”的。在设计远程 MCP Skill 时,必须参考消费侧(即 Agent 执行引擎)的具体规范进行深度定制。
- 适用场景的选择:
Tool:适用于原子化、无状态、全量公开的简单功能插件。
Skill:适用于需要上下文感知、多租户隔离、动态指令约束的复杂业务逻辑块。
五、 好处总结
将 MCP 进化为 Skills 之后,您的 AI Agent 架构将获得:
- 极致的上下文纯净度:
模型只看到此时此刻该看的工具(通过 getToolsName 实现按需加载,或权限控制)。
- 天然的权限安全:
通过服务端感知的动态分发,实现真正的跨进程角色权限控制(RBAC for Tools)。
- 低耦合的业务演进:
业务逻辑和规则变更集中在服务端,客户端 “无需” 任何代码改动即可获得最新能力。

浙公网安备 33010602011771号