Spring AI + MCP :打通大模型与本地服务告别硬编码Function Calling 深度揭秘springboot模块化开发
前言上一篇我们用Spring AI原生Function Calling,封装了第一个AI Skill。但有个很现实的痛点:函数定义、入参...
上一篇我们用Spring AI原生Function Calling,封装了第一个AI Skill。但有个很现实的痛点:函数定义、入参校验、业务逻辑全部耦合在Java代码里。 新增一个工具能力,就要改代码、重启服务;多团队协作时,前端、AI应用、后端服务都要同步改函数描述,维护成本很高。
MCP(Model Context Protocol,模型上下文协议)就是用来解决这个问题的。 它提供一套标准化协议,把业务能力包装成独立服务,大模型通过协议远程调用工具,不再和Spring业务代码强绑定。 本篇我们基于Spring Boot,搭建MCP服务端 + Spring AI客户端,做一个可直接跑通的实战案例:让AI调用我们的订单查询服务。
很多同学容易把三者混在一起,一句话区分:
Function Calling:底层能力,大模型识别意图、调用指定函数的基础机制;AI Skill:业务层面的能力单元,比如订单查询、库存校验、邮件发送,Skill可以基于Function Calling实现,也可以基于MCP实现;MCP:标准化传输协议,是Skill的一种远程交付方式。简单比喻: Function Calling = 本地方法调用;MCP = 标准化RPC;Skill = 对外提供的业务功能。架构简图:
大模型 ←→Spring AI MCP客户端 ←[MCP协议]→ MCP服务端 ←→ 你的Spring业务服务(订单、用户、库存)优势: ✅ 工具能力独立部署,更新工具不用重启AI应用 ✅ 一套MCP服务,可以给多个AI Agent、多个大模型客户端复用 ✅ 协议标准化,Go/Python/Java写的服务都能互通 ✅ 职责解耦:AI应用只负责对话编排,业务能力收敛在MCP服务
pom.xml核心依赖
<!-- Spring AI 核心 --> <dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-openai-spring-boot-starter</artifactId> </dependency> <!-- Spring AI MCP 客户端 --> <dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-mcp-client-spring-boot-starter</artifactId> </dependency> <!-- MCP Server 基础包 --> <dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-mcp-server</artifactId> </dependency> <!-- Web --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>说明:当前Spring AI对MCP支持高速迭代,版本尽量对齐,避免接口类找不到。
我们在MCP服务端,注册一个工具:queryOrderInfo,入参orderId,返回订单基础信息。
MCP里通过@Tool注解暴露能力,这就是我们对外的Skill:
import org.springframework.ai.tool.annotation.Tool; import org.springframework.stereotype.Service; @Service public class OrderMcpTool { private finalOrderService orderService;public OrderMcpTool(OrderService orderService) { this.orderService = orderService; } @Tool(description = "根据订单号查询订单详情,用户想知道订单状态、金额时调用") public OrderDTO queryOrderInfo(String orderId) { if(orderId == null || orderId.isBlank()){ throw new IllegalArgumentException("订单号不能为空"); } returnorderService.getOrderById(orderId); } }重点:description非常关键,大模型靠这段描述判断什么时候调用这个工具。
lication.yml
spring: ai: mcp: server: stdio: true启动这个服务,它会以stdio方式对外提供MCP协议能力;生产环境也可以切换成HTTP transport。
新建一个独立的Spring AI应用(对话入口),作为MCP客户端。 客户端不需要写任何订单查询逻辑,只需要连接MCP服务端,自动拉取全部可用Tool。
lication.yml(客户端配置)
spring: ai: openai: api-key: sk-xxx base-url: https://xxx mcp: client: servers: order-server: command: java args: - -jar - order-mcp-server.jar配置含义:客户端启动时,拉起我们上面打包好的MCP服务端jar,通过stdio通信,自动发现所有@Tool。
核心一行:McpToolCallbackProvider 自动把MCP服务端所有Skill注册成大模型可用工具,没有硬编码任何函数。
请求:
POST /ai/chat?message=帮我查一下订单号ORD20261024001的订单信息执行流程:
大模型识别意图:需要调用queryOrderInfoSpring AI客户端通过MCP协议,远程调用MCP服务端方法MCP服务端执行OrderService查询,返回结果大模型整理结果,自然语言回复用户返回示例:
你查询的订单ORD20261024001状态为已支付,金额299.00元。
现在如果我要新增一个【查询物流】的Skill: ✅ 只需要在MCP服务端新增一个@Tool方法,重启MCP服务; ✅ AI对话客户端不用改一行代码、不用重启,自动感知新增工具。 这就是MCP对比原生Function Calling最大的优势。
MCP不是用来替代Function Calling的,它是Function Calling的远程标准化封装。底层依旧是工具调用思想。
下一篇我们进入Harness工程化管控:当MCP服务越来越多、几十上百个AI Skill分散在各个服务,如何统一注册、权限、灰度、日志、调用链路监控? 《Spring AI Harness实战:AI Skill平台治理,统一管控MCP工具集群》
当前非电脑浏览器正常宽度,请使用移动设备访问本站!