Solon v3.9.0

mcp - McpSkill(Solon AI Remote Skills)

</> markdown
2026年1月26日 上午9:11:00

在 AI Agent 的工程实践中,Model Context Protocol (MCP) 已成为连接大模型与外部世界的标准桥梁。然而,随着应用场景从“个人助手”向“企业级复杂业务”迈进,传统的 MCP 交互模式开始显露其 “静态化” 的瓶颈。

Solon AI 支持将 MCP 封装为 Skill,实现了从“冷冰冰的 API 集合”到“具备感知能力的智能技能”的跨越。

1、静态 Tools 的三大痛点

传统的 MCP 交互类似于一个“无法关闭的工具箱”,无论场景如何,所有工具一涌而上:

  • 上下文噪音(Context Noise): 即使是一个简单的问候,模型也会被注入成百上千行的工具 Schema 定义,白白浪费 Token,更干扰模型的推理专注度。
  • 权限真空(Security Risks): 模型对工具的可见性是“全量”的。难以根据当前登录用户的角色(如普通用户 vs 管理员)动态隐藏敏感操作(如:删除订单)。
  • 行为失控(Instruction Gap): 工具只提供了“能做什么”,却无法告诉模型“在当前背景下该怎么做”。模型缺乏针对特定业务场景的即时指令约束。

2、核心解决方式:感知、挂载与动态分发

Solon AI 通过引入 Skill(Solon AI Skills) 生命周期 来包裹 MCP 协议,实现以下机制解决上述痛点:

A. 智能准入 (isSupported):

只有当 Prompt 上下文(意图、租户信息、环境变量)满足条件时,技能才会被激活。

B. 指令注入 (getInstruction):

在技能挂载时,自动为模型注入针对当前上下文的“行为准则”(System Message)。

C. 三态路由 (getToolsName):

服务端根据 Prompt 属性,动态决定给模型展示哪些工具。支持三种形态的路由方式:

  • 全量使用:未定义过滤逻辑时,显示所有业务工具。
  • 精准授权:仅展示当前用户权限范围内的工具。
  • 完全拒绝:即便技能激活,也可能因安全策略在此时封锁所有工具调用。

3、实战示例:McpSkillClient:远程技能的本地代理

McpSkillClient 将一个远程 MCP 服务包装成一个本地 Skill。它(通过与 McpSkillServer 约定)能够自动同步远程元数据,并根据当前对话的 Prompt 动态决定如何表现。

// 1. 构建 MCP 客户端提供者(负责协议通信与 Schema 缓存)
McpClientProvider mcpClient = McpClientProvider.builder()
                .channel(McpChannel.STREAMABLE)
                .url("http://localhost:8081/skill/order")
                .build();
                
// 2. 将 MCP 客户端进化为 Skill 代理
McpSkillClient skillClient = new McpSkillClient(mcpClient);

// 3. 构建带有业务上下文的 Prompt
Prompt prompt = Prompt.of("这个订单:A001,请查询订单详情。")
                .attrPut("tenant_id", "1")       // 注入租户上下文
                .attrPut("user_role", "admin");  // 注入角色权限

// 4. 调用大模型,技能将根据 Prompt 自动完成:远程准入、指令获取、工具过滤
chatModel.prompt(prompt)
          .options(o -> o.skillAdd(skillClient))
          .call();

4、实战示例:McpSkillServer:具备“智能感知”的技能服务端

通过继承 McpSkillServer,你可以将本地业务逻辑导出为远程技能。其核心优势在于:服务端可以感知用户的 Prompt 状态。

/**
 * 订单管理远程技能服务端实现
 */
@McpServerEndpoint(channel = McpChannel.STREAMABLE_STATELESS, mcpEndpoint = "/skill/order")
public class OrderManagerSkillServer extends McpSkillServer {
    
    @Override
    public String description() {
        return "提供订单查询与取消的专业技能";
    }

    /**
     * 智能准入:根据 Prompt 内容与属性决定是否响应
     */
    @Override
    public boolean isSupported(Prompt prompt) {
        // 语义检查:意图是否相关
        boolean isOrderTask = prompt.getUserContent().contains("订单");
        // 安全检查:必须有租户 ID
        boolean hasTenant = prompt.attr("tenant_id") != null;

        return isOrderTask && hasTenant;
    }

    /**
     * 动态指令:根据上下文为大模型注入实时“行为准则”
     */
    @Override
    public String getInstruction(Prompt prompt) {
        String tenantName = prompt.attrOrDefault("tenant_name", "未知租户");
        return "你现在是[" + tenantName + "]的订单主管。请只处理该租户下的订单数据,禁止跨租户查询。";
    }

    /**
     * 挂载钩子:技能被激活时触发,可用于注入初始化消息或记录日志
     */
    @Override
    public void onAttach(Prompt prompt) {
        // 可以在此处通过 prompt.addMessage() 注入 Few-shot 或背景知识
        System.out.println("订单技能已挂载,当前租户:" + prompt.attr("tenant_id"));
    }

    /**
     * 动态能力发现:根据用户权限决定暴露哪些工具
     * @return null 表示暴露所有业务工具;Empty 表示禁用所有工具;List 表示精准暴露。
     */
    @Override
    public List<String> getToolsName(Prompt prompt) {
        List<String> tools = new ArrayList<>();

        // 基础权限:所有合规用户可见
        tools.add("OrderQueryTool");

        // 细粒度权限:仅 ADMIN 角色可见“取消订单”工具
        if ("ADMIN".equals(prompt.attr("user_role"))) {
            tools.add("OrderCancelTool");
        }

        return tools;
    }

    @ToolMapping(description = "根据订单号查询详情")
    public String OrderQueryTool(String orderId) {
        return "订单 " + orderId + " 状态:已发货";
    }

    @ToolMapping(description = "取消指定订单")
    public String OrderCancelTool(String orderId) {
        return "订单 " + orderId + " 已成功取消";
    }
}

5、Skills 架构反思与局限性补充

尽管将 MCP 进化为 Skills 带来了显著的工程优势,但开发者仍需理清其技术边界:

  • 非标准化的架构增强:

LLM 的底层标准仅包含 Prompt 和 Tool-Call。Skills 并非模型原生标准,也不属于 MCP 的公共协议规范,而是一种 架构设计模式(模式,是通用的)。它通常由 AI 开发框架(如 Solon AI)在消费侧实现,用于解决复杂业务下的能力调度问题。

  • 消费侧驱动的定制:

MCP 向 Skills 的进化本质上是“业务驱动”或“领域驱动”的。在设计远程 MCP Skill 时,必须参考消费侧(即 Agent 执行引擎)的具体规范进行深度定制。

  • 适用场景的选择:

Tool:适用于原子化、无状态、全量公开的简单功能插件。

Skill:适用于需要上下文感知、多租户隔离、动态指令约束的复杂业务逻辑块。

6、 好处总结

将 MCP 进化为 Skills 之后,您的 AI Agent 架构将获得:

  • 极致的上下文纯净度:

模型只看到此时此刻该看的工具(通过 getToolsName 实现按需加载,或权限控制)。

  • 天然的权限安全:

通过服务端感知的动态分发,实现真正的跨进程角色权限控制(RBAC for Tools)。

  • 低耦合的业务演进:

业务逻辑和规则变更集中在服务端,客户端 “无需” 任何代码改动即可获得最新能力。