AI 学习与实战系列:Spring AI + MCP 深度实战------构建标准化、可扩展的智能 Agent 系统
1. 开启 AI 开发的新纪元:从碎片化集成到协议化连接
在人工智能应用爆发的今天,开发者面临的最大挑战之一已不再是单纯的模型调用,而是如何让模型"理解"并"操作"企业内部纷繁复杂的业务数据与工具系统。早期的 AI 集成往往是"烟囱式"的:为每一个特定的工具编写专属的适配器,为每一种数据源编写复杂的清洗逻辑。这种做法在 Agent(智能体)规模扩大时,会导致代码难以维护、扩展性极差。
Spring AI 作为一个致力于简化 Java AI 应用开发的框架,近期引入了对 Model Context Protocol (MCP) 的支持。MCP 是由 Anthropic 牵头推出的一项开放协议,其核心目标是为 AI 模型提供一种标准化的方式来访问外部工具(Tools)和数据资源(Resources)。它就像是 AI 领域的"USB 接口协议",一旦你的服务遵循了 MCP 标准,它可以无缝地连接到任何支持 MCP 的 AI 客户端中。
本篇文章将深入探讨 Spring AI 与 MCP 的实战结合。我们将从底层的协议原理讲起,逐步深入到如何利用 Spring 生态快速构建自己的 MCP Server,并将其集成到 Spring AI 的 ChatClient 中。通过这一过程,你将掌握构建企业级、插件化 AI 系统的核心技术能力,告别低效的硬编码集成方案。
2. 深度拆解 MCP:模型上下文协议的核心机制
要玩转 Spring AI + MCP,首先必须理解 MCP 的设计哲学。MCP 采用典型的 客户端-服务器(Client-Server)架构。在这一架构中,AI 应用程序(如基于 Spring AI 构建的应用)充当 MCP Client,而提供数据、文件或 API 操作的服务则充当 MCP Server。
2.1 核心原语:Resources、Prompts 与 Tools
MCP 协议定义了三种主要的能力:
- Resources (资源):静态或动态的数据源。例如,一个本地日志文件、数据库查询结果或是一个实时读取的文档。它们通常是只读的,为模型提供必要的背景信息。
- Prompts (提示词模板):服务器可以预置一些经过优化的提示词模板,供客户端调用。这有助于在不同应用间复用高质量的 Prompt 工程成果。
- Tools (工具):这是 Agent 能够产生"动作"的关键。工具允许模型执行代码、更新数据库记录或触发外部 API 调用。Tools 是具有副作用(Side Effects)的可执行逻辑。
2.2 通讯协议:JSON-RPC 2.0
MCP 并不重新发明底层传输,它选择了轻量且成熟的 JSON-RPC 2.0。这意味着请求和响应都是高度结构化的。在传输层上,MCP 支持 Stdio(标准输入输出)和 HTTP with SSE(服务器发送事件)。Stdio 模式常用于本地进程间通讯(如 IDE 插件),而 SSE 模式则是云原生 Web 应用的首选,能够支持长连接下的实时状态推送。
2.3 发现机制
当 MCP Client 连接到 Server 时,会进行一次"初始化握手"(Initialize Handshake)。在此过程中,Server 会通过 list_tools 或 list_resources 接口告诉 Client 它能做什么、拥有什么。这种动态发现机制使得 AI 系统具备了极强的灵活性------你可以随时热拔插不同的 MCP Server,而无需修改 Client 的核心逻辑。
3. Spring AI 生态下的 MCP 支持架构
Spring 框架一向擅长抽象。在 Spring AI 中,对 MCP 的支持并非简单的 API 调用,而是深度的生态整合。Spring AI 为开发者提供了 McpClient 和 McpServer 两个核心抽象,并配套了自动配置逻辑。
3.1 为什么选择 Spring AI
Java 开发者在构建 AI 应用时,最担心的就是与模型厂商绑定太死。Spring AI 通过统一的 ChatClient 抽象层,屏蔽了 OpenAI、Anthropic、DeepSeek 等不同厂商的 API 差异。当 MCP 引入后,这种抽象优势被进一步放大:
- 函数调用的自动转换:Spring AI 能自动将 MCP Server 提供的 Tools 转换为 LLM 能够识别的 Function Calling 定义。
- 依赖注入的无缝衔接 :你可以像配置数据源一样,在
application.yml中定义 MCP 服务器的连接信息。 - 生命周期管理:Spring 容器负责 MCP 连接的创建、保活与优雅关闭。
3.2 架构分层
在 Spring AI MCP 架构中,通常分为三层:
- Transport 层:处理字节流到 JSON-RPC 消息的转换(SSE 或 Stdio)。
- Protocol 层 :处理 MCP 协议状态机,如
initialize、ping、list等请求的响应。 - Feature 层:开发者编写的业务逻辑,即具体的 Tool 逻辑或 Resource 获取逻辑。
通过这种分层,Spring AI 确保了开发者只需要关注第 3 层,即真正的业务价值所在。
4. 实战:从零构建一个 Spring Boot MCP Server
在本节中,我们将实战编写一个基于 Spring Boot 的 MCP Server。这个 Server 将提供一个简单的工具:查询企业内部的实时库存状态。
4.1 引入依赖
首先,在 pom.xml 中引入 Spring AI 相关的 MCP Server SDK 依赖:
xml
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-mcp-server-spring-boot-starter</artifactId>
</dependency>
4.2 定义 Tool
我们不需要编写复杂的 JSON 定义,只需利用 Spring 的注解。创建一个 Service 类:
java
@Service
public class InventoryService {
@McpTool(name = "getInventory", description = "根据产品ID获取实时库存余量")
public String getStockLevel(@McpToolParameter(description = "产品唯一编码") String productId) {
// 这里可以是数据库查询逻辑
return "产品 " + productId + " 当前库存为:150 件";
}
}
@McpTool 注解告诉 Spring AI,这个方法需要作为 MCP 工具暴露出去。Spring 会自动生成符合 MCP 标准的 JSON Schema。
4.3 配置传输方式
在 application.properties 中,我们选择 SSE 模式:
properties
spring.ai.mcp.server.transport=webflux-sse
spring.ai.mcp.server.path=/mcp/v1/sse
此时,启动应用,你的 MCP Server 就已经准备就绪。它不仅能被 Spring AI Client 调用,甚至可以连接到 Claude Desktop 或其他支持 MCP 的开源 AI 平台。
5. 客户端集成:让 Spring AI 驱动 MCP 工具
拥有了 Server 之后,我们需要在主应用(MCP Client)中消费这些工具。
5.1 配置 MCP Client
在 Client 应用中,我们需要定义如何连接到刚才创建的 Server:
java
@Configuration
public class McpClientConfig {
@Bean
public McpClient mcpClient() {
McpTransport transport = new SseClientTransport("http://localhost:8081/mcp/v1/sse");
return McpClient.using(transport).sync();
}
}
5.2 将 MCP 工具绑定到 ChatClient
这是最关键的一步。我们需要将从 MCP Server 获取到的工具,动态地注入到 Spring AI 的对话模型中:
java
@RestController
public class ChatController {
private final ChatClient chatClient;
private final McpClient mcpClient;
public ChatController(ChatClient.Builder builder, McpClient mcpClient) {
// 在构建 ChatClient 时,通过 mcpClient 自动发现并绑定工具
this.chatClient = builder
.defaultAdvisors(new McpToolCallingAdvisor(mcpClient))
.build();
this.mcpClient = mcpClient;
}
@GetMapping("/ask")
public String ask(@RequestParam String prompt) {
return chatClient.prompt(prompt).call().content();
}
}
McpToolCallingAdvisor 是 Spring AI 提供的一个强大组件。它会自动向 MCP Server 请求工具列表,并将其作为 ChatOptions 传递给 LLM。当模型决定调用工具时,Advisor 会拦截请求、调用远程 MCP Server 并返回结果给模型,整个过程对开发者几乎透明。
6. 进阶模式:多服务器编排与动态资源管理
在复杂的企业场景中,一个 Agent 可能需要同时连接多个 MCP Server:一个负责查数据库,一个负责发邮件,还有一个负责从文档库检索。
6.1 多 Server 聚合
Spring AI 允许你配置一个 CompositeMcpClient。它像是一个代理,将来自不同物理服务器的 Tools 和 Resources 聚合成一个逻辑上的整体。
- 冲突检测:当两个服务器提供同名工具时,可以通过 Prefix(前缀)进行区分。
- 并发调用:对于不相关的工具调用,Client 可以并行发起请求,缩短响应延迟。
6.2 动态 Resource 注入
除了 Tools,Resources 的利用同样重要。例如,你可以定义一个 Resource,其 URI 为 myserver://logs/today。当用户问"今天有什么系统异常吗?"时,应用可以先从 MCP Server 读取该资源内容,将其作为 System Message 的一部分喂给模型。 Spring AI 提供了 McpResourceAdvisor,它可以基于向量检索或特定规则,动态地将 MCP 资源内容注入到上下文窗口中,从而实现高效的 RAG(检索增强生成)流程。
7. 性能优化与安全注意事项
在实战中,如果不注意细节,MCP 系统可能会面临性能瓶颈或安全风险。
7.1 上下文窗口管理
MCP 允许模型访问大量的外部资源,但这很容易撑爆模型的上下文窗口(Context Window)。
- 精简输出:确保 MCP Server 返回的数据是精简后的。如果是一个 10MB 的日志文件,不应全部返回,而应先由 Server 进行初步筛选。
- Token 监控 :利用 Spring AI 的
ChatResponse元数据监控 Token 消耗,防止因为工具返回数据量过大导致高昂的 API 账单。
7.2 安全性保障
- 工具执行隔离:MCP Server 执行的操作必须在受控环境下。例如,执行 Shell 命令的工具应具备严格的权限控制。
- 输入校验 :LLM 可能会生成恶意或畸形的参数。在 MCP Server 端,必须对接收到的
productId等参数进行严格的 Schema 校验。 - 身份验证:对于 SSE 模式,务必在 HTTP 层面增加 OAuth2 或 API Key 认证,防止 MCP Server 被未授权访问。
7.3 超时与重试
网络调用总是不稳定的。在配置 McpTransport 时,应设置合理的请求超时时间,并结合 Spring Retry 实现重试机制,确保 Agent 在面对网络波动时依然健壮。
8. 综合案例:构建一个企业级知识库助手
让我们串联起所有知识点,构思一个完整的场景:一个"企业入职咨询助手"。
- 数据源:员工手册存储在 Git 仓库,实时考勤数据在 SQL 数据库。
- MCP Server A (Git-Server) :暴露一个 Resource
git://hr/handbook,定期抓取手册内容。 - MCP Server B (Attendance-Server) :提供一个 Tool
query_attendance(userId)。 - Spring AI Client :
- 用户问:"我下周一请假怎么操作?"
- Client 发现问题涉及请假规则,通过 Advisor 获取
git://hr/handbook的内容作为上下文。 - 模型读取手册后回答:"请通过 OA 系统提交申请,你想查一下你当前的剩余假期吗?"
- 用户答:"好,帮我查查。"
- 模型调用
query_attendance工具,从 Server B 获取实时数据并返回。
通过 MCP,上述逻辑不再是硬编码的 if-else,而是模型在标准协议驱动下,自主、动态地选择和使用资源的过程。这正是未来 AI 软件架构的核心特征。
学习路线与实践建议
对于希望跟进 Spring AI + MCP 的新手,建议按照以下阶段进行学习:
第一阶段:夯实基础(1-2 周)
- Java 17+ 与 Spring Boot 3.x:这是 Spring AI 的前置条件。
- JSON-RPC 2.0 规范:理解 MCP 通讯的底层格式。
- Spring AI 核心概念 :熟悉
ChatClient、Prompt、Advisor的用法。
第二阶段:MCP 协议入门(1 周)
- 阅读 MCP 官方文档,理解什么是 Host、Client 和 Server。
- 安装 Claude Desktop,尝试连接几个开源的 MCP Server(如 Filesystem, Google Search),感受 MCP 的实际效果。
第三阶段:代码实战(2 周)
- 动手写 Server:仿照本文第 4 节,写一个能连接你本地数据库或调用某个第三方 API 的 MCP Server。
- 手动接入 Client :在 Spring Boot 应用中配置
McpClient,并尝试手动发起一次listTools调用。 - 集成 ChatClient :使用
McpToolCallingAdvisor实现自动工具调用。
第四阶段:进阶与调优(持续)
- 探索 SSE 传输:在分布式环境下部署你的 MCP Server。
- 安全加固:学习如何在 MCP 通讯中加入认证与授权。
- 关注社区 :Spring AI 更新非常快,关注 Spring AI GitHub 的最新 Release Note。
实践建议: 不要试图一次性构建复杂的 Agent。从一个简单的"计算器"工具或"本地文件读取"工具开始,调通整个链路后,再引入复杂的业务逻辑。记住,AI 开发中,Prompt 的质量与工具定义的描述(Description)同样重要,花点时间打磨工具的描述,能显著提升模型调用的准确率。