Spring AI 对 Skill/MCP 的支持全景整理

Spring AI 对 Skill/MCP 的支持全景整理

整理时间:2026 年 6 月 9 日 | 基于 Spring AI 1.1 GA(2025年11月发布)

图示:Spring AI 作为中枢,将 Agent、Tool、Resource、Prompt 与多模型生态连接起来,体现 MCP 带来的互操作能力。

一、背景:Spring AI 1.1 里程碑

2025 年 11 月 12 日,Spring AI 发布 1.1.0 GA 版本,引入超过 850 项改进,其中最重大的功能集改进即 Model Context Protocol(MCP) 的原生支持。这也标志着 Spring AI 正式将 Skill/工具抽象层纳入核心框架能力。

二、Spring AI Skill/MCP 核心能力

图示:左侧为 Tool、Resource、Prompt 三类能力入口,中间为 Spring AI,右侧为三种传输通道,其中 Streamable HTTP 为当前推荐路径。

2.1 注解式编程模型(Annotation-Based)

Spring AI 提供三个核心注解,开发者通过注解即可声明式地暴露工具(Tool)、资源(Resource)和提示模板(Prompt):

注解 对应 MCP 概念 示例
@McpTool MCP Tool 暴露为 AI 可调用的函数工具
@McpResource MCP Resource 提供结构化数据资源(如数据库 schema)
@McpPrompt MCP Prompt Template 参数化提示模板,供 AI 复用
java 复制代码
@McpTool
public String getCurrentWeather(String location) {
    // Tool implementation
}

@McpResource
public String getDatabaseSchema() {
    // Resource implementation
}

@McpPrompt
public String generateSqlQuery(String userIntent) {
    // Prompt template implementation
}

2.2 多种传输协议(Transport)

Spring AI MCP 支持三种传输方式,适应不同部署场景:

  • STDIO:适用于本地进程通信,适合本地 AI 工具链集成
  • HTTP SSE(Server-Sent Events):基于 Web 的推送集成(⚠️ 已标记为deprecated)
  • Streamable HTTP(推荐):支持有状态会话管理和可恢复请求,是当前首选传输层

自 Spring AI 1.1 起,Streamable HTTP 已取代 SSE 成为推荐传输方式。SSE 传输已被标记为 deprecated。

2.3 Spring Boot 自动配置

Spring AI 提供完整的 Spring Boot Starter 自动配置能力,支持:

  • 多环境适配:WebFlux(响应式)、WebMVC(同步)、Servlet 环境均有对应 Starter
  • 客户端/服务端双向:可快速构建 MCP 客户端消费外部 MCP 服务,也可作为 MCP 服务端对外暴露自身工具
  • Docker / Testcontainers 集成:支持容器化 MCP Gateway 部署

2.4 安全集成

MCP 服务端安全由 OAuth2 集成模式保障,详情参考:Securing MCP Servers with Spring AI

三、Spring AI Agents 与 Skill 生态

图示:Spring AI 不只是单点工具调用,而是围绕 Agent、Skill、评测与顾问机制形成一个可编排、可扩展的协作生态。

3.1 Spring AI Agents

Spring AI 社区(Spring AI Community GitHub Organization)孵化了专门的 Agent 框架项目:

  • Spring AI Agents:用于构建 Agentic 编码工具和 AI Agent 的框架
  • Spring AI Bench:AI Agent 基准测试和评估工具包

3.2 Skill 的另一层含义:ChatClient Skill API

在 Spring AI 的 ChatClient 体系中,Skill 也指通过 @Tool 注解包装现有工具为可注入的能力,支持:

  • 包装现有 @Tool 注解方法为增强版工具
  • 包装现有 ToolCallbackProvider
  • 从 classpath 以 Spring Resources 方式加载 Skill(适用于 JAR/WAR 打包分发)
  • 通过 SkillAugmentedArguments 在 ChatClient 中直接使用

3.3 Recursive Advisors(递归顾问)

Spring AI 1.1 新增递归顾问功能,支持顾问链式调用其他顾问,形成多步骤 AI 工作流,可构建"自我改进"的 AI Agent,实现 LLM-as-a-Judge 评估系统。

四、与传统 @Tool 注解的关系

维度 @Tool(传统) @McpTool(MCP)
协议层 Spring AI 内部 Tool Calling MCP 标准协议,跨框架互操作
暴露范围 仅限 Spring AI 内部调用 可被任何 MCP 兼容客户端消费
生态集成 Spring 生态内 Java MCP SDK(v0.10→v0.15)+ 跨生态
适用场景 内部 AI 应用 AI 工具互联互通(Agent间通信)

图示:内部调用用 @Tool,跨生态互通用 @McpTool------两者在协议层、暴露范围、生态集成与适用场景上的核心差异一目了然。

五、供应商生态(Skill 调用的模型端)

Spring AI 1.1 扩展了大量模型提供商支持,使 Skill 调用覆盖更广的模型端:

  • OpenAI:GPT-5 系列(gpt-5 / gpt-5-mini / gpt-5-nano)、File API、推理内容访问
  • Anthropic Claude:Claude 4.5 / Opus 4.1、Citations API、Tool Choice 控制
  • Google Gemini:Gemini Pro / 1.5 Pro / 2.0 Flash(通过 Google GenAI SDK 集成)
  • ZhipuAI(智谱):GLM-4.6 / GLM-4.5 / GLM-Z1,支持 Thinking 模式
  • Mistral AI:OCR API、Codestral Embed 模型
  • AWS Bedrock:Prompt Caching 支持 Claude / Nova 模型

图示:以 Spring AI 为中枢,一套 Skill 调用即可覆盖 OpenAI、Anthropic、Google、智谱、Mistral、AWS Bedrock 六大模型供应商。

六、快速上手路线

  1. MCP 入门 :Spring AI MCP Getting Started Guide
  2. Spring AI 入门博客 :Connect Your AI to Everything: Spring AI MCP Boot Starters
  3. 安全配置 :Securing MCP Servers with Spring AI
  4. 深度技术分享 :Beyond Local Tools: Deep Dive into MCP(James Ward & Maximilian Schellhorn)
  5. 官方示例仓库 :spring-projects/spring-ai-examples(37 个模块,含 MCP 集成示例)

七、版本演进与未来

  • Spring AI 当前主分支为 1.1.1-SNAPSHOT,后续将切换至 2.0.0-SNAPSHOT
  • 2.0 版本将开始支持 Spring Framework 7 和 Spring Boot 4.0
  • MCP Java SDK 在 1.1 开发周期内从 v0.10 演进至 v0.15,成熟度显著提升

📌 小结: Spring AI 1.1 带来的 MCP 支持,本质上是将 Spring 生态的 AI 工具(Tool/Resource/Prompt)通过标准化的 MCP 协议暴露为可互操作的 Skill,无论是构建内部 AI Agent 还是接入更大的 AI 工具生态,这套注解驱动的方案都大幅降低了集成门槛。


八、Skill 调用集成案例

图示:用户请求先进入 ChatClient/Agent,再由 ToolCallingAdvisor 自动编排本地 @Tool Skill、ToolSearch 与远端 MCP Skill 的多步调用,最后汇总为自然语言结果。
以下案例基于 Spring AI 2.0.0-RC1(Spring Boot 4.0 / JDK 21+)编写,关键差异处标注了与 1.x 的对比。

8.1 依赖配置

通过 Spring AI BOM 统一管理依赖版本,按需引入模型和 MCP 相关 Starter:

xml 复制代码
<!-- Spring AI BOM -->
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-bom</artifactId>
            <version>2.0.0-RC1</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<!-- OpenAI 模型(按需替换为 anthropic / gemini 等) -->
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-model-openai</artifactId>
</dependency>

<!-- MCP 服务端(WebMVC 同步环境;响应式用 webflux 变体) -->
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-mcp-server-webmvc</artifactId>
</dependency>

<!-- MCP 客户端 -->
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-mcp-client</artifactId>
</dependency>

8.2 定义与注册 Skill(Tool)

用 @Tool 注解将普通方法声明为 Skill,@ToolParam 描述参数,帮助 LLM 理解调用语义:

java 复制代码
@Component
public class WeatherSkill {

    private final WeatherApiClient apiClient;

    public WeatherSkill(WeatherApiClient apiClient) {
        this.apiClient = apiClient;
    }

    @Tool(description = "查询指定城市的实时天气信息")
    public WeatherInfo getCurrentWeather(
            @ToolParam(description = "城市名称,如:北京、上海") String city) {
        return apiClient.query(city);
    }

    @Tool(description = "获取某城市未来若干天的天气预报")
    public List<WeatherForecast> getForecast(
            @ToolParam(description = "城市名称") String city,
            @ToolParam(description = "预报天数,取值 1-7") int days) {
        return apiClient.forecast(city, days);
    }
}

在 Spring AI 2.0 中,工具不再按 Bean 名称自动解析,需显式注册为 ToolCallback/ToolCallbackProvider:

java 复制代码
@Configuration
public class SkillConfig {

    @Bean
    public ToolCallbackProvider weatherTools(WeatherSkill weatherSkill) {
        return MethodToolCallbackProvider.builder()
                .toolObjects(weatherSkill)   // 扫描对象上所有 @Tool 方法
                .build();
    }
}

8.3 ChatClient 调用 Skill

这是 1.x 与 2.0 差异最大的环节。2.0 移除了 ChatModel 内置的工具执行循环 ,必须经由 ToolCallingAdvisor 驱动调用循环,并通过 .tools() 显式传入 Skill:

java 复制代码
@Service
public class WeatherAgent {

    private final ChatClient chatClient;
    private final ToolCallbackProvider weatherTools;

    public WeatherAgent(ChatClient.Builder builder,
                        ToolCallbackProvider weatherTools) {
        this.chatClient = builder
                // 2.0:工具执行循环由 Advisor 接管(取代 ChatModel 内置循环)
                .defaultAdvisors(new ToolCallingAdvisor())
                .build();
        this.weatherTools = weatherTools;
    }

    public String ask(String userMessage) {
        return chatClient.prompt()
                .user(userMessage)
                .tools(weatherTools)   // ✅ 2.0 显式传递 Skill
                .call()
                .content();
    }
}

调用 agent.ask("北京今天天气怎么样,适合穿什么?"),LLM 会自动识别意图、调用 getCurrentWeather("北京"),再基于返回数据生成自然语言答复。

与 1.x 写法对比:

java 复制代码
// ❌ 1.x:依赖 toolNames() 按 Bean 名解析,且 ChatModel 内置执行循环
// 该写法在 2.0 已不可用
chatClient.prompt()
    .user("北京今天天气怎么样?")
    .toolNames("getCurrentWeather")   // toolNames() 已移除
    .call()
    .content();

8.4 大工具集场景:ToolSearchToolCallingAdvisor

当 Skill 数量庞大时,将所有工具定义一次性注入 LLM 会造成巨大 Token 开销。 ToolSearchToolCallingAdvisor 利用向量检索在运行时按需发现并注入相关工具:

java 复制代码
@Configuration
public class SearchAdvisorConfig {

    @Bean
    public ToolSearchToolCallingAdvisor toolSearchAdvisor(
            VectorStore vectorStore,
            ToolCallbackProvider allSkills) {
        return ToolSearchToolCallingAdvisor.builder()
                .toolCallbackProvider(allSkills)
                .vectorStore(vectorStore)   // 工具描述预先向量化存入此 Store
                .topK(5)                    // 每次对话最多检索 5 个相关工具
                .build();
    }
}

// 使用方式:将 Advisor 注入 ChatClient,不再需要手动 .tools()
@Service
public class SmartAgent {

    private final ChatClient chatClient;

    public SmartAgent(ChatClient.Builder builder,
                      ToolSearchToolCallingAdvisor searchAdvisor) {
        this.chatClient = builder
                .defaultAdvisors(searchAdvisor)   // 自动检索 + 执行,合二为一
                .build();
    }

    public String ask(String userMessage) {
        return chatClient.prompt().user(userMessage).call().content();
    }
}

8.5 MCP 服务端:将 Skill 暴露为标准 MCP 工具

在 application.yml 中配置 MCP 服务端,选择 Streamable HTTP 传输(当前推荐):

yaml 复制代码
# application.yml
spring:
  ai:
    mcp:
      server:
        name: weather-mcp-server
        version: 1.0.0
        transport: STREAMABLE_HTTP   # 推荐;SSE 已废弃

用 @McpTool 将 @Tool 方法注册到 MCP 协议层:

java 复制代码
@Component
public class WeatherMcpSkill {

    @McpTool                                      // 对外暴露为 MCP Tool
    @Tool(description = "查询指定城市的实时天气")
    public String getCurrentWeather(
            @ToolParam(description = "城市名称") String city) {
        // 返回 JSON 字符串,MCP 客户端可直接反序列化
        return weatherApiClient.query(city).toJson();
    }
}

8.6 MCP 客户端:消费外部 MCP Skill

客户端配置远端 MCP 服务地址,Starter 会自动将远端工具注册为 ToolCallbackProvider Bean:

yaml 复制代码
# application.yml
spring:
  ai:
    mcp:
      client:
        streamable-http:
          connections:
            weather-server:
              url: http://weather-mcp-service:8080/mcp

注入自动装配的 MCP 工具,与本地 Skill 用法完全一致:

java 复制代码
@Service
public class McpConsumerAgent {

    private final ChatClient chatClient;
    private final ToolCallbackProvider mcpTools;   // 由 MCP 客户端 Starter 自动注入

    public McpConsumerAgent(ChatClient.Builder builder,
                            ToolCallbackProvider mcpTools) {
        this.chatClient = builder
                .defaultAdvisors(new ToolCallingAdvisor())
                .build();
        this.mcpTools = mcpTools;
    }

    public String ask(String question) {
        return chatClient.prompt()
                .user(question)
                .tools(mcpTools)        // 远端 MCP Skill 与本地工具一视同仁
                .call()
                .content();
    }
}

关键价值:MCP 服务端的 Skill 一次定义,可被任意 MCP 兼容客户端(Spring AI、Claude Desktop、其他 Agent 框架)跨语言、跨进程复用,这正是 @McpTool 相比内部 @Tool 的核心优势。

8.7 完整案例:多 Skill 协作的差旅助手 Agent

下面把本地 Skill 与远端 MCP Skill 组合成一个差旅助手,由 LLM 自动编排多步调用:

java 复制代码
@Service
public class TravelAssistant {

    private final ChatClient chatClient;
    private final List<ToolCallbackProvider> allSkills;

    public TravelAssistant(ChatClient.Builder builder,
                           ToolCallbackProvider weatherTools,   // 本地:天气 Skill
                           ToolCallbackProvider flightMcpTools,  // 远端 MCP:航班 Skill
                           ChatMemory chatMemory) {
        this.chatClient = builder
                .defaultSystem("你是差旅助手,可调用天气与航班工具,规划用户行程。")
                .defaultAdvisors(
                        // Memory Advisor 默认包裹在工具循环外层,
                        // 中间结果不会污染对话记忆
                        MessageChatMemoryAdvisor.builder(chatMemory).build(),
                        new ToolCallingAdvisor())
                .build();
        this.allSkills = List.of(weatherTools, flightMcpTools);
    }

    public String plan(String userMessage) {
        return chatClient.prompt()
                .user(userMessage)
                .tools(allSkills.toArray())   // 同时挂载多组 Skill
                .call()
                .content();
    }
}

调用示例与 LLM 自动编排流程:

text 复制代码
用户:下周三从上海飞北京,帮我看下两地天气,再推荐航班。

LLM 自动编排:
  1. getCurrentWeather("上海")     → 本地 Skill
  2. getForecast("北京", 7)        → 本地 Skill
  3. searchFlights("SHA","BJS",...) → 远端 MCP Skill
  4. 汇总三次结果,生成自然语言行程建议

整个多步调用由 ToolCallingAdvisor 在一次 call() 内自动循环完成,开发者无需手写编排逻辑------这正是注解式 Skill + Advisor 模型降低集成门槛的体现。

附:Spring AI 2.0.0-RC1 重大更新(2026年6月6日发布)

**里程碑意义:**RC1(Release Candidate 1)是 2.0.0 GA 之前的 API 稳定化里程碑,标志着 Spring AI 2.0 进入最终冲刺阶段。

一、Tool Calling 大重构

这是 2.0 RC1 最核心的变化,Tool Calling 机制发生了根本性改变:

1.1 统一 Tool 执行机制

内置的 call/stream 工具执行循环和 ToolExecutionEligibilityChecker 从所有 ChatModel 中移除(OpenAI、Ollama、Anthropic、MistralAI、DeepSeek、Bedrock Proxy、MiniMax 全部)。工具执行必须通过外部的 ChatClient + ToolCallingAdvisor 处理(或用户自行控制的 DefaultToolCallingManager 循环)。internalToolExecutionEnabled 配置项同步移除。

1.2 移除 toolNames() API 和 SpringBeanToolCallbackResolver

工具不再按 Bean 名称自动解析,必须显式注册为 ToolCallback Bean,并通过 .tools() 显式传递。

java 复制代码
// ❌ 1.x 方式(不再支持)
chatClient.prompt()
    .user("查询天气")
    .toolNames("getWeather")  // 已移除
    .call();

// ✅ 2.0 显式方式
@Bean
public ToolCallback weatherTool(GetCurrentWeather getCurrentWeather) {
    return ToolCallbackAdapter.builder(getCurrentWeather).build();
}

chatClient.prompt()
    .user("查询天气")
    .tools(weatherTool)  // 显式传递 ToolCallback
    .call();
1.3 ToolCallAdvisor → ToolCallingAdvisor(重命名)

原 ToolCallAdvisor 已重命名为 ToolCallingAdvisor(旧名称保留为已废弃子类,编译时不报错,只给警告)。

新增 ToolSearchToolCallingAdvisor,支持三种工具索引实现(向量数据库、Lucene、Regex),LLM 可在运行时按需发现并调用工具,而非预先加载所有工具定义------大幅降低大工具集下的 Token 开销。

1.5 Memory Advisor 位置调整

Memory Advisor 默认包裹在 Tool Calling 循环外层,不再参与每次工具调用的迭代,防止工具调用中间结果被错误地写入对话记忆。

图示:1.x 依赖 ChatModel 内置循环与 toolNames() 按名解析,2.0 全部交由 ToolCallingAdvisor 接管并要求显式 .tools() 注册------这是升级时最需要关注的破坏性变化。

二、Chat Memory 改进

  • Turn-Boundary Snapping: MessageWindowChatMemory 在消息窗口溢出时,驱逐边界自动对齐到最近的 USER 消息,避免一个对话轮次被截断到两个窗口中
  • **避免工具提示中的重复记忆:**工具调用延续提示不再重复之前的消息,同时保留最新工具响应
  • timestamp 字段可编程访问: JdbcChatMemoryRepository 的 timestamp 列现在可直接编程访问

三、Structured Output 增强

新增 EntityParamSpec,支持在 ChatClient.entity() 调用点直接配置结构化输出(Provider 原生模式或 Schema 验证),无需再单独配置 Advisor 或手动接线。

四、API 与代码清理

变更项 说明
移除模型默认选项值 未设置的选项现在回退到模型自身的默认值,修复了 Spring AI 默认值静默覆盖模型默认值的问题
N() → n() Options Builder 中的 N() 方法重命名为 n(),符合 Java 命名规范
ChatClientCustomizer 废弃 已废弃,推荐使用新的 ChatClientBuilderCustomizer
JSON 工具重构 SchemaGenerator 实例在结构化输出和工具 Schema 路径下现受并发访问保护
SLF4J → Commons Logging 日志框架切换为 org.apache.commons.logging.LogFactory,对齐 Spring 全系列项目
OkHttp 可观测性 为 OpenAI 和 Anthropic 模型恢复基于 Micrometer 的可观测性支持

五、模型更新

  • **DeepSeek V4:**新增 DeepSeek V4 聊天模型常量(不再需要硬编码字符串),修复了 DeepSeek V4 Function Calling 400 Bad Request 的问题
  • **Mistral AI 更新:**移除已废弃模型,重命名 devstral 系列模型
  • **MiniMax:**移除专用集成,官方推荐通过 Anthropic 兼容接口(text-anthropic API)接入
  • **Pixtral Large:**2026年5月31日 Mistral 官方下线,已同步移除

六、依赖升级

  • **MCP Java SDK:**从 v0.15 升级到 2.0.0-RC1,随 Spring AI 2.0 同步进入 MCP 2.0 时代
  • **其他依赖:**随 Spring Boot 4.0 / Spring Framework 7 的整体升级同步更新

七、从 1.x 升级到 2.0 注意事项

Breaking Changes 清单:

  • 工具必须改为显式 .tools(toolCallback) 注册,Bean 名称自动解析已移除
  • ToolCallAdvisor 已重命名(旧名保留但已废弃)
  • N() → n(),检查代码中的 Options Builder 调用
  • ChatClientCustomizer → ChatClientBuilderCustomizer
  • 依赖 Spring Framework 7 和 Spring Boot 4.0(需 JDK 21+)

八、版本演进路线图

版本 时间 状态
1.0 GA 2024年 ✅ 已发布
1.1 GA 2025年11月 ✅ 已发布(引入 MCP 支持)
2.0.0-RC1 2026年6月6日 🔄 RC阶段(最新)
2.0.0 GA 待定 ⏳ 目标里程碑

图示:从 1.0 GA 到 2.0 GA 的演进路线------MCP 支持始于 1.1,2.0 系列开始迈向 Spring Framework 7 / Spring Boot 4。

参考资料

相关推荐
弈栈录12 分钟前
Java AI 应用的异步化与高并发设计
java·后端·架构
凤山老林1 小时前
Spring Boot 集成 iText 7 实现动态 PDF 生成与电子签章:合同、报表场景实战
spring boot·后端·pdf·itext7·电子签章
孙启超1 小时前
【AI开发之Rust】第 19 课:UniFFI 导出核心能力
开发语言·后端·rust
ServBay1 小时前
基于Jev的浏览器Agent插件狂揽 21k star,3分钟教你解放双手
后端·aigc·ai编程
Json____1 小时前
家居装修 AI 智能咨询助手:让装修咨询从“大海捞针“变成“一问即答“
java·后端·vue3·it学习·wwwoop.com
Apifox2 小时前
Apifox 9 月更新|CLI 能力升级、GitLab 私有化部署接入与产品体验优化
前端·后端·测试
鱼弦2 小时前
Agent智能体 vs 传统运维:职业天花板的3倍差距?
后端
暗夜行者之光2 小时前
LangGraph 实战:用 LangSmith 可视化追踪 AI 智能体执行轨迹
后端
鱼弦3 小时前
Agent 的工具选择策略:从硬编码到动态决策
后端
Lost of 程序猿3 小时前
建造者模式实战:告别“十参数构造函数“的数据导出任务
后端·设计模式·c#·asp.net