拥抱未来:Spring AI 与 MCP 如何重塑 Java 中的 AI 集成
在人工智能(AI)技术,特别是大型语言模型(LLM)迅猛发展的今天,将 AI 能力无缝、高效、可维护地集成到企业级应用中已成为开发者的核心诉求。Java 作为企业级开发的基石,其生态系统也在积极拥抱这一变革。Spring AI 和 MCP (Model Context Protocol) 正是这一浪潮中的两个关键推动力。Spring AI 提供了优雅的抽象层,而 MCP 则为复杂 AI 交互定义了清晰的通信标准。本文将深入探讨这两者,分析它们如何协同工作,以及如何利用它们构建强大的 AI 增强型 Spring Boot 应用。
1. 引言:AI 集成的挑战与机遇
将 LLM 集成到传统应用中并非易事。开发者面临诸多挑战:
- API 碎片化: OpenAI, Anthropic, Google, Mistral, 本地部署模型等,每个提供商都有其独特的 API。
- 提示工程复杂性: 构建有效的提示(Prompt)、处理上下文、管理对话历史、进行函数调用(Function Calling / Tool Calling)等需要大量样板代码。
- 结果解析: 将 LLM 的非结构化输出(文本、JSON)可靠地解析成应用内部数据结构。
- 可移植性与测试: 代码与特定模型强耦合,难以切换模型或进行单元/集成测试。
- 上下文管理: 在多轮对话或复杂工作流中,有效管理与模型交互的上下文信息。
Spring AI 的诞生正是为了解决这些痛点。它借鉴了 Spring 生态系统中成功的抽象模式(如 Spring Data, Spring Security),为 AI 提供了一套统一、简洁、可扩展的 API。而 MCP 则更进一步,它定义了一个协议,旨在标准化 AI 模型与外部工具/系统之间的交互方式,特别是在涉及工具调用(Tool Use)和上下文传递的场景中。
2. 深入理解 Spring AI
Spring AI 是一个由 Pivotal(现 VMware Tanzu)发起的开源项目,目标是让 Java 和 JVM 开发者能够轻松地将 AI 能力集成到 Spring 应用中。它不是一个模型本身,而是一个抽象层和集成框架。
核心理念:
- 抽象化: 提供
ChatClient,EmbeddingClient等接口,屏蔽底层模型提供商(如 OpenAI, Azure AI, Google Vertex AI, Hugging Face, Ollama 等)的具体实现细节。 - 约定优于配置: 提供合理的默认值,简化配置。
- Spring 风格: 充分利用 Spring Boot 的自动配置、依赖注入(DI)、条件化配置等特性。
- 可扩展性: 通过 SPI (Service Provider Interface) 支持轻松添加新的模型提供商。
核心组件与 API:
-
ChatClient: 这是与 LLM 进行对话的核心接口。它抽象了发送消息、接收响应的过程。prompt()方法: 接收一个Prompt对象,该对象封装了消息列表(Message)和可选的请求选项(Options,如温度、最大生成长度等)。Message类型: 代表对话中的不同角色消息:UserMessage: 用户输入。AssistantMessage: 模型的回复。SystemMessage: 系统指令,用于设定模型行为、角色、格式等(至关重要!)。
Response对象: 包含模型的回复(Data)、元数据(如使用的 Token 数、模型名称)、以及可能的ToolCall信息。
示例:
@Service public class SimpleChatService { private final ChatClient chatClient; public SimpleChatService(ChatClient.Builder chatClientBuilder) { // 使用 Builder 构建,可以配置选项 this.chatClient = chatClientBuilder .defaultSystem("你是一个乐于助人的助手。") .defaultAdvisoryOptions(options -> options.withTemperature(0.7)) .build(); } public String askQuestion(String userQuestion) { // 直接使用字符串(会被包装成 UserMessage) return chatClient.prompt(userQuestion).call().getResult().getOutput().getContent(); } public String askWithCustomSystem(String userQuestion, String systemPrompt) { Prompt prompt = new Prompt( List.of( new SystemMessage(systemPrompt), new UserMessage(userQuestion) ), PromptOptions.builder() .withModel("gpt-4-turbo") // 覆盖默认模型 .build() ); return chatClient.call(prompt).getResult().getOutput().getContent(); } } -
PromptOptions: 用于配置特定请求的参数,如model(指定模型)、temperature,maxTokens,topP,frequencyPenalty,presencePenalty等。ChatClient.Builder允许设置全局默认值。 -
Function Calling/Tool Calling: Spring AI 支持让 LLM 调用预定义的 Java 方法(工具)。这是实现 AI Agent 能力的关键。- 定义一个 POJO 或带有
@Bean的类,其方法用@Tool注解标记。 - Spring AI 会自动将这些方法注册为 LLM 可用的工具,并生成符合模型要求的 Function/Tool 描述(Schema)。
- 当 LLM 决定调用工具时,
ChatClient会解析ToolCall请求,执行对应的 Java 方法,并将结果返回给 LLM 继续生成最终回复。
示例(天气工具):
@Component // 或 @Service public class WeatherService { @Tool(description = "根据城市名称获取当前天气信息") public String getCurrentWeather(String cityName) { // 调用真实的天气 API WeatherData data = weatherApiClient.getWeather(cityName); return String.format("城市 %s 的天气是 %s, 温度 %.1f°C", data.getCity(), data.getCondition(), data.getTemperature()); } }在
ChatClient配置中启用工具调用(通常通过ChatModel实现类的配置)。 - 定义一个 POJO 或带有
-
EmbeddingClient: 用于生成文本的向量嵌入(Embeddings),是实现语义搜索、文本相似度计算等功能的基础。@Service public class EmbeddingService { private final EmbeddingClient embeddingClient; public EmbeddingService(EmbeddingClient embeddingClient) { this.embeddingClient = embeddingClient; } public List<Double> embedText(String text) { return embeddingClient.embed(text); } } -
自动配置与依赖: Spring AI 提供了
spring-ai-openai-spring-boot-starter等 starter 依赖。引入后,只需在application.yml中配置 API Key 和基础 URL,ChatClient和EmbeddingClient的 Bean 就会自动创建。# application.yml spring: ai: openai: api-key: your-openai-api-key-here # base-url: https://api.openai.com/v1 # 可选,用于非官方端点
3. 揭秘 MCP (Model Context Protocol)
MCP 是一个相对较新但极具潜力的概念,它由 Anthropic 等公司推动,旨在解决 AI Agent 与外部世界交互的标准化问题。你可以将 MCP 理解为 “AI Agent 的通用语言”。
核心思想:
- 标准化通信: 定义一个清晰、结构化的 JSON 格式协议,用于在 LLM 运行时(如 Anthropic’s Claude)和外部工具/系统之间传递信息。
- 关注上下文: 协议的核心是传递上下文——不仅仅是工具调用的请求和响应,还包括对话历史、元数据、状态信息等,确保交互的连贯性和一致性。
- 双向流式通信: 支持流式传输,允许工具在执行过程中逐步返回信息(如进度、中间结果),LLM 也可以流式生成调用请求。
- 解耦: 工具实现(Tool Implementation)与 LLM 的决策逻辑(Orchestrator)通过 MCP 协议进行通信,实现松耦合。
MCP 的关键组成部分:
mcp-server: 这是一个独立的、可执行的进程或服务,它实现了特定的工具集(如数据库查询、文件操作、API 调用、代码执行等)。它监听来自 LLM 运行时的 MCP 消息。mcp-client: 这是 LLM 运行时(或其代理)的一部分,负责将 LLM 生成的工具调用请求序列化为 MCP 消息,并发送给mcp-server;同时接收mcp-server的响应并反序列化,将结果传递回 LLM。mcp-spec: 定义了消息格式的规范。核心消息类型包括:request: 从客户端发送到服务器的调用请求。response: 从服务器发送回客户端的调用结果。notification: 服务器向客户端发送的异步通知(如日志、进度更新)。error: 传输过程中的错误信息。
mcp-tool: 一个工具的定义,包含其名称、描述、输入/输出 Schema (通常用 JSON Schema 描述)。
MCP 的工作流程:
- 用户向 LLM 提出一个需要外部工具的问题(如 “查询我账户的最新三笔交易”)。
- LLM 分析问题,决定需要调用
get_account_transactions工具。 - LLM 运行时(通过
mcp-client)生成一个符合 MCP 规范的request消息,内容类似:{ "type": "request", "id": "req-123", "method": "get_account_transactions", "arguments": { "account_id": "acc_456", "limit": 3 } } mcp-client通过标准传输(如 stdin/stdout, HTTP, gRPC)将此消息发送给mcp-server。mcp-server解析消息,调用其内部实现的get_account_transactions方法。mcp-server执行操作(可能涉及数据库查询),获取结果。mcp-server生成一个 MCPresponse消息:{ "type": "response", "id": "req-123", // 关联回请求 "result": [ {"id": "tx_789", "amount": 99.99, "date": "2025-07-30", "desc": "Online Purchase"}, ... // 其他两笔交易 ] }mcp-server将响应发送回mcp-client。mcp-client将响应结果(result字段的内容)以自然语言或结构化数据的形式,注入到 LLM 的下一个输入上下文中。- LLM 结合原始问题、系统指令和工具返回的结果,生成最终的人类可读回复:"您账户的最新三笔交易是:1. 7 月 30 日在线购买 99.99 元;2. … "。
MCP 的优势:
- 标准化: 不再需要为每个模型提供商或每个工具编写特定的适配器。
- 安全性: 工具在独立的
mcp-server中运行,与 LLM 运行时隔离,降低了风险(如代码注入攻击)。 - 可组合性: 可以轻松地将多个
mcp-server(每个提供不同工具集)连接到同一个 LLM 运行时。 - 可观察性: MCP 消息流(
notification)提供了强大的调试和监控能力。 - 流式支持: 支持长耗时操作的进度反馈。
4. Spring AI 与 MCP:协同增效
Spring AI 和 MCP 并非竞争关系,而是互补的。它们在不同的层次上发挥作用,共同构建更强大、更标准化的 AI 应用生态。
- Spring AI 的定位: 应用层集成框架。它让 Java 开发者在 Spring Boot 应用内部,以声明式、类型安全的方式与 LLM 交互。它处理了与特定云服务商 API 的对接、提示管理、结果解析、简单的工具调用(在 JVM 内部)等。
- MCP 的定位: 运行时/代理层通信协议。它定义了 LLM 核心(或其代理)与外部工具执行环境(
mcp-server)之间的标准化通信管道。它关注的是跨进程、跨网络、跨信任边界的交互。
它们如何协同工作?
想象一个更复杂的场景:你的 Spring Boot 应用需要一个强大的 AI Agent,该 Agent 需要调用多种外部服务(数据库、内部 API、甚至执行代码片段)。
-
场景一(MCP 作为 Spring AI 的后端):
- 你可以在你的 Spring Boot 应用中启动一个或多个
mcp-server进程(例如,用 Python, Go 或 Node.js 编写,利用其生态优势)。 - Spring AI 的
ChatModel实现(比如一个自定义的AnthropicChatModel)可以被配置为使用 MCP 作为其与工具交互的机制。 - 当 Spring AI 的
ChatClient检测到 LLM 需要调用工具时,它(作为mcp-client)会通过 MCP 协议将调用请求发送给本地或远程的mcp-server。 mcp-server执行工具逻辑,通过 MCP 返回结果。- Spring AI 接收结果,将其整合,继续与 LLM 对话。
- 优势: Spring Boot 应用利用 Spring AI 的便捷 API,同时通过 MCP 获得了与外部工具安全、标准化交互的能力,特别是当工具用非 Java 语言编写时。
- 你可以在你的 Spring Boot 应用中启动一个或多个
-
场景二(Spring AI 应用消费 MCP 服务):
- 你的组织可能已经部署了通用的
mcp-server集群,提供如 “文档搜索”、“数据分析”、“审批流程” 等标准工具。 - 你的 Spring Boot 应用(通过 Spring AI 或其他方式)可以作为一个智能前端,接收用户请求。
- 当需要调用这些标准工具时,Spring Boot 应用内的组件可以直接作为
mcp-client,与组织的mcp-server通信,获取结果,然后可能再将结果送回 LLM 进行最终回复生成或直接返回给用户。 - 优势: 服务复用,标准化接口,安全隔离。
- 你的组织可能已经部署了通用的
-
场景三(混合模式):
- 应用内部一些简单的、安全的工具调用(如格式化日期、查询内存缓存)直接用 Spring AI 的
@Tool注解在 JVM 内执行。 - 对于涉及敏感数据、复杂计算或需要特定语言库的工具,则通过 MCP 协议调用外部的
mcp-server。 - 优势: 性能与安全性的平衡。
- 应用内部一些简单的、安全的工具调用(如格式化日期、查询内存缓存)直接用 Spring AI 的
5. 实践:构建一个 Spring AI + MCP 增强的应用(概念性示例)
由于 MCP 生态仍在发展中,直接在 Spring Boot 中集成 MCP 的成熟库可能有限。但我们可以勾勒一个概念性架构。
目标: 创建一个 AI 助手,能回答关于公司销售数据的问题,需要查询数据库。
架构:
- Spring Boot 应用 (
spring-ai-app):- 依赖
spring-ai-openai-spring-boot-starter。 - 配置
ChatClient。 - 实现一个服务,能发起 MCP 请求(可能需要一个 MCP 客户端库或自己实现基础通信)。
- 依赖
- MCP Server (
sales-data-mcp-server): (用 Python 为例,利用pandas,sqlalchemy)- 实现
mcp-server,监听 stdin/stdout。 - 提供
query_sales_data工具,接收查询参数(如时间范围、产品线),连接数据库执行查询,返回结果。 - 使用
mcpPython 库(如果存在)或手动处理 MCP 消息。
- 实现
- 通信:
spring-ai-app启动sales-data-mcp-server进程(或连接到已运行的实例),通过进程间通信(IPC)或网络(HTTP/gRPC)使用 MCP 协议交互。
Spring Boot 侧伪代码:
@Service
public class SalesAssistantService {
private final ChatClient chatClient;
private final MpcClient mpcClient; // 假设存在或自实现的 MCP 客户端
public SalesAssistantService(ChatClient chatClient, MpcClient mpcClient) {
this.chatClient = chatClient;
this.mpcClient = mpcClient;
}
public String answerSalesQuestion(String question) {
// 1. 让 LLM 决定是否需要查询数据
Prompt decisionPrompt = new Prompt(
List.of(
new SystemMessage("判断用户问题是否需要查询销售数据库。如果需要,回复 'NEED_QUERY: <查询参数>';如果不需要,回复 'NO_QUERY: <直接回答>'。"),
new UserMessage(question)
)
);
String decision = chatClient.call(decisionPrompt).getResult().getOutput().getContent();
if (decision.startsWith("NEED_QUERY:")) {
String queryArgs = extractQueryArgs(decision); // 解析参数
// 2. 通过 MCP 调用外部工具
MpcResponse mpcResponse = mpcClient.call("query_sales_data", queryArgs);
if (mpcResponse.isSuccess()) {
Object queryResult = mpcResponse.getResult(); // 从 MCP 响应中获取数据
// 3. 将查询结果和原始问题一起交给 LLM 生成最终回答
Prompt finalPrompt = new Prompt(
List.of(
new SystemMessage("根据以下销售数据,用中文清晰地回答用户的问题。"),
new UserMessage("用户问题:" + question + "\n\n查询结果:" + queryResult.toString())
)
);
return chatClient.call(finalPrompt).getResult().getOutput().getContent();
} else {
return "抱歉,查询数据时出错:" + mpcResponse.getError();
}
} else if (decision.startsWith("NO_QUERY:")) {
return extractAnswer(decision);
} else {
return "无法理解您的问题。";
}
}
}
MCP Server 侧 (Python) 伪代码:
# sales_data_mcp_server.py
import sys
import json
from mcp import Server, StdioServerTransport # 假设存在 mcp 库
import database_query # 你的数据库查询逻辑
server = Server(transport=StdioServerTransport())
@server.tool("query_sales_data")
def query_sales_data(time_range: str, product_line: str = None):
"""查询销售数据"""
try:
result = database_query.execute(time_range, product_line)
return result # 返回字典或列表
except Exception as e:
raise Exception(f"Query failed: {str(e)}")
# 启动服务器,监听 stdin/stdout
server.run()
6. 挑战与未来展望
- MCP 生态成熟度: MCP 规范仍在演进,成熟的客户端/服务器库(尤其在 JVM 生态)可能还不丰富,需要更多社区投入。
- 性能开销: 进程间或网络通信会带来延迟,对于简单工具,JVM 内调用(Spring AI @Tool)可能更高效。
- 错误处理与重试: 需要完善的机制处理 MCP 通信失败、工具执行失败等情况。
- 认证与授权: MCP 通信的安全性(如 mTLS, API Key)需要仔细设计。
- 调试复杂性: 调试跨越多个进程和协议的 AI 工作流更具挑战性。
未来展望:
- Spring AI 内建 MCP 支持: 未来 Spring AI 可能会提供原生的
McpChatModel或相关模块,简化集成。 - 标准化工具市场: 基于 MCP 的通用工具市场可能出现,方便复用。
- 更智能的 Agent 框架: 结合 Spring AI 的易用性和 MCP 的强大通信能力,会出现更复杂的、能自主规划、多步执行的 AI Agent 框架。
- 与 Spring 生态深度整合: MCP 工具可以轻松访问 Spring Data JPA, Spring Security, Spring Cloud 等。
7. 结论
Spring AI 和 MCP 代表了 AI 集成的两个重要方向:应用层的简化与运行时的标准化。
- Spring AI 是 Java 开发者拥抱 AI 的最佳起点。它极大地降低了门槛,让你能快速在 Spring Boot 应用中添加聊天、文本生成、嵌入等功能,并通过
@Tool实现基本的 AI Agent 能力。 - MCP 则着眼于构建更安全、更强大、更可扩展的 AI Agent 生态系统。它通过定义清晰的协议,解决了工具调用的标准化和安全隔离问题,为复杂、企业级的 AI 应用铺平了道路。
最佳实践建议:
- 从 Spring AI 开始: 对于大多数 Java 项目,优先使用 Spring AI 来集成 LLM。它成熟、文档丰富、社区活跃。
- 评估 MCP 需求: 如果你的应用需要:
- 调用大量用非 Java 编写的工具。
- 需要严格的安全隔离(如执行不受信任的代码)。
- 希望构建可复用的、标准化的工具服务供多个 AI 应用使用。
- 需要强大的流式进度反馈和可观测性。
那么,探索 MCP 集成是值得的。
- 关注演进: 密切关注 Spring AI 和 MCP 项目的发展。它们的融合将催生下一代企业级 AI 应用。
Spring AI 为你提供了在 Java 世界中驾驭 AI 的“方向盘”和“油门”,而 MCP 则在构建一个更广阔、更互联的“AI 高速公路”。掌握这两者,你将能更自信地驶向智能化应用的未来。
参考资料:
- Spring AI 官方网站与文档:https://spring.io/projects/spring-ai
- Model Context Protocol (MCP) 规范:https://github.com/anthropics/mcp (请查找最新官方链接)
- Anthropic MCP 文档:https://docs.anthropic.com/claude/docs/tool-use (查看 Tool Use with MCP 部分)
- Spring Boot 官方文档
更多推荐



所有评论(0)