Spring AI + MCP 实战:构建标准化、可扩展的 AI Agent 架构体系
第一章:AI 应用范式的演进与 Spring AI MCP 概览
在生成式 AI 爆发的初期,开发者主要关注的是如何通过 Prompt Engineering 调用大模型(LLM)的 API。然而,随着应用场景的深入,我们发现单纯的"对话"远不能满足业务需求。AI 必须能够感知外部世界、操作外部工具,这就是所谓的 AI Agent(智能体)。
在这一演进过程中,开发者面临一个核心痛点:工具集成与上下文管理的碎片化。每一个 AI 应用可能需要连接数十个外部系统(如数据库、GitHub、Slack、搜索引擎)。如果每个系统都要为不同的 AI 模型编写适配代码,这种 N 对 M 的关系将导致灾难性的维护成本。
正是基于这一背景,Anthropic 推出了 Model Context Protocol (MCP)。MCP 旨在成为 AI 领域的"LSP(Language Server Protocol)"。正如 LSP 统一了编程语言与 IDE 之间的交互,MCP 旨在统一大模型与外部数据源、工具之间的交互协议。
Spring AI 作为 Java 生态中对接 AI 的领军框架,率先提供了对 MCP 的深度支持。通过 Spring AI MCP,Java 开发者可以利用熟悉的 Spring Boot 开发范式,快速构建标准的 MCP Server(提供数据和工具)或 MCP Client(连接现有的 MCP 生态)。这种架构不仅实现了大模型与具体工具的解耦,还极大地增强了 AI 应用的可扩展性和安全性。
对于 Java 企业级开发者而言,掌握 Spring AI + MCP 的实战技能,不仅是技术栈的升级,更是从"调用 API"向"构建 AI 系统架构"转变的关键一步。本篇文章将带你深入这个前沿领域,从底层原理到代码实战,全面剖析如何构建下一代 AI Agent。
第二章:MCP (Model Context Protocol) 核心原理深度剖析
要真正掌握 Spring AI MCP 实战,必须理解其背后的协议规范。MCP 的核心设计理念是 Client-Server 架构,但其交互模式比传统的 HTTP RESTful 更有深度。
1. 核心抽象组件
MCP 协议定义了三个核心实体,它们构成了 AI 感知与行动的基础:
- Resources(资源):只读的数据源。它可以是本地文件内容、数据库查询结果、甚至是实时的 API 数据流。对于 LLM 而言,资源就像是它的"参考资料库"。
- Tools(工具):可执行的函数。AI 可以根据用户的意图主动调用这些工具,并获得返回结果。例如:"查询昨日订单量"或"发送一封确认邮件"。
- Prompts(提示词模版):预定义的指令模板。Server 可以向 Client 暴露特定场景的 Prompt,确保 AI 在执行特定任务时能遵循最佳实践的指令结构。
2. 分层架构与传输协议
MCP 的底层交互基于 JSON-RPC 2.0 规范。这种选择保证了协议的轻量级与标准化。在传输层(Transport Layer),MCP 目前主要支持两种方式:
- Stdio(标准输入输出):适用于本地进程间通信。Client 启动 Server 作为一个子进程,通过标准 IO 流进行二进制或文本交换。这是目前本地 AI 助手(如 Claude Desktop)最常用的模式。
- SSE (Server-Sent Events) / HTTP:适用于远程服务。通过 SSE 建立持久连接,支持跨网络的服务调用。这正是 Spring AI 所擅长的企业级微服务场景。
3. 握手与发现机制
当 MCP Client 连接到 Server 时,会进行一次握手(Initialize)。在此过程中,Server 会通过 ListResources、ListTools 等接口向 Client 宣告自己的"能力清单"。这种"自描述"特性使得 AI 能够动态地理解并利用新接入的工具,而无需重新硬编码 Client 端的业务逻辑。这种解耦是实现真正插件化 AI 架构的基石。
第三章:Spring AI 框架体系与开发环境构建
在进入代码实战之前,我们需要准备好开发环境,并理解 Spring AI 是如何将 MCP 融入其生态系统的。
1. 技术栈要求
- JDK 17 或更高版本:Spring Boot 3.x 及其相关的 Spring AI 模块依赖于 JDK 17 的特性,如 Records 和密封类。
- Maven 3.6+ 或 Gradle 8+:用于依赖管理。
- Spring Boot 3.2.x+:Spring AI 的基础框架。
- API 密钥:如 OpenAI、Anthropic 或本地部署的 Ollama,用于驱动 Agent 进行思考。
2. 依赖管理
在 pom.xml 中,我们需要引入 Spring AI 的 BOM(Bill of Materials)以及 MCP 相关的 Starter。Spring AI 采用模块化设计,MCP 功能位于独立的库中。
xml
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-bom</artifactId>
<version>${spring-ai.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- MCP Spring Boot Starter -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-mcp-spring-boot-starter</artifactId>
</dependency>
<!-- 选择一个 AI 模型实现,如 OpenAI -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-openai-spring-boot-starter</artifactId>
</dependency>
</dependencies>
3. Spring AI 的 MCP 抽象层
Spring AI 并不是简单地封装了 MCP 协议,而是将其深度整合到了其 ChatClient 和 ToolCallback 体系中。这意味着你编写的一个 MCP Tool,在 Spring AI 的视角下,与一个普通的 @Tool 注解方法在逻辑上是等价的,这极大地降低了学习成本。框架自动处理了 JSON-RPC 的编解码、连接生命周期管理以及复杂的并发调度。
第四章:实战:基于 Spring Boot 构建高性能 MCP Server
MCP Server 是能力的提供者。本节我们将通过一个实际案例:构建一个"企业天气与差旅策略"查询 Server,展示如何发布资源与工具。
1. 配置 McpServer
在 Spring Boot 中,配置一个 MCP Server 非常直观。我们可以选择基于 SSE 的 Web Server 模式,方便远程调用。
java
@Configuration
public class McpServerConfig {
@Bean
public McpServer mcpServer(McpServerTransport transport) {
return McpServer.using(transport)
.serverInfo("Travel-Agent-Server", "1.0.0")
.capabilities(McpServerFeatures.builder()
.resources(true) // 开启资源支持
.tools(true) // 开启工具支持
.prompts(true) // 开启 Prompt 模版支持
.build())
.build();
}
}
2. 实现业务工具(Tools)
在 Spring AI MCP 中,你可以通过简单的 POJO 或者特定的 McpTool 接口来定义工具。以下是一个查询天气的工具示例:
java
@Component
public class WeatherTools {
@Tool(description = "获取指定城市的当前天气及差旅建议")
public String getWeather(String city) {
// 在实际场景中,这里会调用第三方天气 API
if ("Beijing".equalsIgnoreCase(city)) {
return "晴朗,25度。建议穿着轻便。";
}
return "未知城市天气";
}
}
Spring AI 会自动扫描带有 @Tool 注解的 Bean,并将其注册到 MCP Server 的工具列表中。它会自动提取方法的参数名、类型和描述,生成符合 MCP 规范的 JSON Schema。
3. 发布静态与动态资源(Resources)
资源可以用来暴露规章制度、文档等。
java
@Bean
public McpResource travelPolicy() {
return new McpResource("resource://policy/travel", "差旅报销制度", "text/plain");
}
当 Client 请求该 URI 时,Server 会返回预定义的文本。通过这种方式,我们可以将企业的知识库以标准化的方式喂给 AI。
第五章:实战:Spring AI Client 深度连接 MCP 生态
有了 Server 之后,我们需要一个"大脑"(Client)来调用它。Spring AI 的 ChatClient 是核心组件。
1. 配置 McpClient
Client 需要知道 Server 的地址。如果是 SSE 模式,配置如下:
java
@Bean
public McpClient mcpClient() {
McpTransport transport = new SseMcpTransport("http://localhost:8080/mcp/sse");
McpClient client = McpClient.using(transport).build();
client.initialize(); // 执行握手
return client;
}
2. 自动工具绑定
这是最神奇的部分。Spring AI 允许你直接将 MCP Client 发现的所有工具绑定到聊天会话中。
java
@Service
public class AiService {
private final ChatClient chatClient;
private final McpClient mcpClient;
public AiService(ChatClient.Builder builder, McpClient mcpClient) {
this.mcpClient = mcpClient;
this.chatClient = builder
.defaultAdvisors(new MessageChatMemoryAdvisor(new InMemoryChatMemory()))
.build();
}
public String ask(String question) {
return chatClient.prompt(question)
// 关键点:将 MCP Client 中的所有工具转化为 Spring AI 可识别的回调
.toolCallbacks(mcpClient.asToolCallbacks())
.call()
.content();
}
}
当用户问"我想去北京出差,帮我看看天气并根据制度给点建议"时,AI 会自动识别出需要调用 getWeather 工具,并同时读取 resource://policy/travel 资源,最后合并生成回答。
3. 处理多 Server 场景
在复杂架构中,一个 Client 可能会连接多个 MCP Server(例如一个负责数据库,一个负责搜索)。Spring AI 支持通过 McpClientManager 统一管理这些连接,实现工具的汇聚与冲突处理。
第六章:进阶:MCP 中的上下文管理与复杂 Prompts 设计
AI 的表现很大程度上取决于上下文的质量。MCP 协议中的 Prompts 功能提供了一种标准化的方式来下发"系统提示词"。
1. 结构化 Prompt 模板
Server 可以预设一些高质量的 Prompt 模板。例如,一个 SQL 生成 Server 可能会提供如下模板:
json
{
"name": "sql-helper",
"description": "辅助生成 SQL 语句",
"arguments": [
{"name": "table", "description": "表名", "required": true}
]
}
Client 动态获取这个模板,填充参数后再发送给 LLM。这种方式保证了即使更换了 Client UI,AI 处理特定任务的逻辑依然是一致的。
2. 上下文截断与优先级
当 MCP Server 提供了海量的资源时,Context Window(上下文窗口)可能会溢出。Spring AI 提供了 ContextOptimizer 的概念。在实战中,我们需要根据 Tool 返回结果的大小,动态决定是否将其转化为"资源引用"而非直接嵌入到 Prompt 中。
3. 动态资源绑定
在会话过程中,AI 可以请求"订阅"某个资源的变更。例如,监控一个日志文件的实时输出。MCP 协议支持 notifications/resources/updated 机制,Spring AI 结合 Reactor 框架(Mono/Flux),可以实现响应式的 AI 交互流,这对于构建实时监控 Agent 至关重要。
第七章:企业级应用:MCP 的安全性、性能优化与生产实践
将 Spring AI MCP 投入生产环境,需要考虑比 Demo 复杂得多的因素。
1. 安全性与权限控制
- 工具调用鉴权 :不是所有的用户都能调用所有的 Tool。在 Spring AI 中,建议在
ToolCallback层增加安全拦截器,校验当前上下文中的用户信息。 - 沙箱化执行:对于可能执行代码或修改数据的 Tool(如 Python 解释器或数据库更新),务必在受限的环境中运行。
- 传输加密:SSE 模式下必须强制使用 HTTPS,并结合 Spring Security 实施 OAuth2 认证。
2. 性能优化
- 并发调用:当 AI 决定同时调用多个工具时,Spring AI 的底层执行器支持并行执行,显著降低端到端延迟。
- 缓存策略:对于不经常变动的资源请求,在 Client 端实施 LRU 缓存,减少网络开销和 Server 负载。
- 连接池管理:对于 SSE 连接,合理配置连接超时和重连策略,避免由于网络波动导致的 Agent 响应失败。
3. 容错与降级
AI 具有不确定性。有时 LLM 会生成错误的工具参数,或者 Server 响应超时。实战中应采用"重试+兜底"策略。例如,当天气 API 挂掉时,返回本地缓存的旧数据或提示"暂时无法获取实时信息",而不是让整个 Agent 崩溃。
第八章:总结与进阶:新手学习路线与实战建议
Spring AI + MCP 的组合,为 Java 开发者打开了 AI 应用开发的新大门。它让我们可以像搭积木一样,通过标准协议连接各种 AI 能力。
1. 学习路线图
- 第一阶段:夯实基础。熟练掌握 Spring Boot 3.x 的核心概念,理解 Reactive Programming(Project Reactor),因为 AI 流式响应大量使用了这些技术。
- 第二阶段:理解 MCP 规范。阅读 Anthropic 的 MCP 官方文档,搞清楚 JSON-RPC 消息流。
- 第三阶段:Spring AI 入门 。从简单的
ChatClient开始,掌握 Prompt Template 和 Output Parsers。 - 第四阶段:MCP 实战。亲手写一个 MCP Server,尝试暴露本地数据库给 AI。
- 第五阶段:复杂 Agent 构建 。探索
Advisors、Vector Stores与 MCP 的联动。
2. 实践建议
- 从本地 Stdio 开始:新手建议先尝试开发能被 Claude Desktop 识别的本地 MCP Server,这样反馈最快。
- 重视文档描述 :在
@Tool里的 description 写得越详细,AI 调用的准确率就越高。记住,description 是给 AI 看的"API 文档"。 - 模块化思维:不要构建一个巨大的 MCP Server。按照业务领域拆分,例如 User-Service-MCP, Order-Service-MCP,这样更易于维护和复用。
AI 的浪潮下,Java 开发者并不落后。通过 Spring AI + MCP,我们能将深厚的企业级架构经验转化为强大的 AI 生产力。现在,就开始你的第一个 MCP 项目吧!