Spring AI MCP实战:自然语言指令生成BI数据图表

大家好,我是小冬瓜。随着chatgpt、deepseek等大模型越来越火,企业如何将自身的业务数据和大模型进行结合输出成为很多公司的热门话题。不论是RAG,Function Call还是MCP这些技术很大程度上都是在解决如何在不调节大模型参数的情况下,既能保证数据安全,又能很好的利用大模型的能力进行定制化输出。本文使用spring-ai-mcp框架,用简单的几行代码完整演示下如何将本地私有化数据通过大模型输出,废话不多说直接上代码。

需求目标

通过自然语言将本地私有化数据图表展示。

输入:近7日交易手续费趋势

输出:将本地数据图表形式展示

演示效果

模块介绍

bi: 应用主机,mcp-client

mcp-server-data: 本地mcp服务,主要模拟查询本地私有化数据 http://localhost:8081/sse

mcp-server-chart: 图表mcp服务,在modelscope mcp广场找的服务,可以生成面积、条线图、柱状图、饼图等各种图形的MCP服务(详情),本地化部署 http://localhost:1122/sse,

代码示例

mcp-server-data模块

pom文件

 <dependencies>
  <dependency>
   <groupId>org.springframework.ai</groupId>
   <artifactId>spring-ai-starter-mcp-server-webmvc</artifactId>
  </dependency>
  <dependency>
   <groupId>org.projectlombok</groupId>
   <artifactId>lombok</artifactId>
  </dependency>
 </dependencies>

配置文件

server:
  port: 8081

spring:
  ai:
    mcp:
      server:
        name: mcp-server-data
        version: 0.0.1 

DataService

/**
 * @author 任海东
 * @since 2025年6月24日
 */
@Service
@Slf4j
public class DataService {

 public record IndicatorByDay(String time, double value) {
 }

 public record ChartData(String type, String axisXTitle, String axisYTitle, List<?> data) {
 }

 @Tool(description = "获取近N天某指标数据,指标包括交易金额(trade_amount)、交易笔数(trade_count)、交易手续费(fee)等")
 public ChartData getLastNDaysIndicator(final int days, final String indicator) {
  log.info("查询近{}天的{}数据", days, indicator);
  // 模拟查询数据库select dt as time, sum({indicator}) as value from ads_trade_data where
  // dt >= date_sub(curdate(), interval {days} day) group by dt
  final List<IndicatorByDay> data = List.of(new IndicatorByDay("2025-06-01", 1000.0),
    new IndicatorByDay("2025-06-02", 1200.0), new IndicatorByDay("2025-06-03", 900.0),
    new IndicatorByDay("2025-06-04", 1100.0), new IndicatorByDay("2025-06-05", 1300.0),
    new IndicatorByDay("2025-06-06", 1400.0), new IndicatorByDay("2025-06-07", 1500.0));
  return new ChartData("area", "交易日期", indicator, data);
 }

 @Tool(description = "获取交易排行top10的分公司")
 public String getTop10() {
  // 模拟返回数据
  return "top10";
 }

 // ...更多查询数据的方法

}    

工具注册

 @Bean
 public ToolCallbackProvider dataTool(final DataService dataService) {
  return MethodToolCallbackProvider.builder().toolObjects(dataService).build();
 }

bi模块

pom文件

 <dependencies>
  <dependency>
   <groupId>org.springframework.ai</groupId>
   <artifactId>spring-ai-starter-model-openai</artifactId>
  </dependency>
  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
  <dependency>
   <groupId>org.springframework.ai</groupId>
   <artifactId>spring-ai-starter-mcp-client</artifactId>
  </dependency>
  <dependency>
   <groupId>com.alibaba</groupId>
   <artifactId>fastjson</artifactId>
  </dependency>
  <dependency>
   <groupId>org.projectlombok</groupId>
   <artifactId>lombok</artifactId>
  </dependency>
 </dependencies>

配置文件

spring:
  application:
    name: bi
  ai:
    openai:
      api-key: ${DASHSCOPE_API_KEY}
      base-url: https://dashscope.aliyuncs.com/compatible-mode
#      base-url: https://localhost:11434
      chat:
        options:
          model: qwen-plus
#          model: qwen3:0.6
    mcp:
      client:
        sse:
          connections:
            chart:
              url: http://localhost:1122/sse
            data:
              url: http://localhost:8081/sse
        toolcallback:
          enabled: false
logging:
  level:
    '[io.modelcontextprotocol.client]': debug
    '[io.modelcontextprotocol.spec]': debug

这里使用的百炼大模型,开始使用的本地qwen3:0.6b模型,效果不是很好。

代码

/**
 * @author 任海东
 * @since 2025年6月24日
 */
@SpringBootApplication
@RestController
@AllArgsConstructor
public class BIApplication {

 private final List<McpSyncClient> mcpClients;

 private final ChatClient.Builder builder;

 public static void main(final String[] args) {
  SpringApplication.run(BIApplication.class, args);
 }

 @GetMapping("/bi")
 public ResponseEntity<InputStreamResource> generate(
   @RequestParam(value = "msg", defaultValue = "近7天交易金额趋势") final String msg) {
  final String prompt = """
    请根据用户输入信息: %s (e.g. 近7天交易金额趋势)
    1. 选择合适的工具查询数据;
    2. 将查询的数据作为参数,根据<type>选择合适工具生成图表,并返回图片url;
    3. 输出格式:key为url的json字符串。
    """.formatted(msg);
  final var chatClient = builder.defaultToolCallbacks(new SyncMcpToolCallbackProvider(mcpClients)).build();
  final String res = chatClient.prompt(prompt).call().content();
  final String url = JSON.parseObject(res).getString("url");
  Assert.hasLength(url, "未解析出正确的图片");
  return url2Resp(url);
 }

 /**
  * 将图片url转换为响应实体
  *
  * @param url
  * @return
  */
 private ResponseEntity<InputStreamResource> url2Resp(final String url) {
  try {
   final URLConnection conn = new URI(url).toURL().openConnection();
   return ResponseEntity.ok().contentType(MediaType.IMAGE_JPEG)
     .body(new InputStreamResource(conn.getInputStream()));
  } catch (IOException | URISyntaxException e) {
   throw new RuntimeException("系统处理失败: " + e.getMessage(), e);
  }

 }

}

至此,整个流程完成,客户端不需要手动编排mcp服务的调用链,系统会根据提示词自动处理,是不是超超级简单呢,欢迎关注小冬瓜,一起学下交流!

### Spring AI MCP Java SDK 概述 Spring AI MCP 是一种基于 Model Context Protocol (MCP) 的 Java 实现,旨在简化模型上下文协议的应用开发过程。通过该 SDK,开发者可以轻松构建支持 MCP 协议的服务端和客户端应用程序[^1]。 #### 核心功能 - **多传输选项**:支持多种通信方式,便于灵活集成到不同的技术栈中。 - **三层架构设计**: - **MCP 客户端**:负责向服务端发送请求并处理响应。 - **MCP 服务器**:提供 API 接口供客户端调用,并管理模型的上下文数据。 - **工具回调接口(ToolCallbackProvider)**:允许扩展自定义行为以适应特定需求[^2]。 --- ### 使用方法 以下是关于如何使用 Spring AI MCP Java SDK 构建服务端和客户端的具体指导: #### 1. 引入 Maven 依赖 在项目的 `pom.xml` 文件中添加以下依赖项来引入 Spring AI MCP SDK: ```xml <dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-mcp</artifactId> <version>1.0.0-M6</version> </dependency> ``` #### 2. 配置 YML 文件 创建或修改项目中的 `application.yml` 或 `application.properties` 文件,设置必要的参数。例如: ```yaml spring: ai: mcp: server-url: http://localhost:8080/mcp-server client-id: my-client-id secret-key: my-secret-key ``` #### 3. 编写服务端代码 服务端需要实现 ToolCallbackProvider 并将其注册到容器中。示例代码如下: ```java import org.springframework.ai.mcp.ToolCallbackProvider; import org.springframework.stereotype.Component; @Component public class MyToolCallbackProvider implements ToolCallbackProvider { @Override public String handleRequest(String requestPayload) { // 自定义逻辑处理接收到的数据 return "Response from tool callback provider"; } } ``` 同时,在控制器类中暴露 RESTful API 来接收来自客户端的请求: ```java import org.springframework.web.bind.annotation.*; @RestController @RequestMapping("/mcp-server") public class McpServerController { private final ToolCallbackProvider toolCallbackProvider; public McpServerController(ToolCallbackProvider toolCallbackProvider) { this.toolCallbackProvider = toolCallbackProvider; } @PostMapping("/process") public String process(@RequestBody String payload) { return toolCallbackProvider.handleRequest(payload); } } ``` #### 4. 编写客户端代码 客户端可以通过简单的 HTTP 请求与服务端交互。下面展示了一个基本的 Controller 示例: ```java import org.springframework.beans.factory.annotation.Value; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import org.springframework.web.client.RestTemplate; @RestController @RequestMapping("/mcp-client") public class McpClientController { private final RestTemplate restTemplate; @Value("${spring.ai.mcp.server-url}") private String serverUrl; public McpClientController(RestTemplate restTemplate) { this.restTemplate = restTemplate; } @GetMapping("/send-request") public ResponseEntity<String> sendRequest() { String url = serverUrl + "/process"; String requestBody = "{\"key\":\"value\"}"; return restTemplate.postForEntity(url, requestBody, String.class); } } ``` --- ### 总结 Spring AI MCP 提供了一套完整的解决方案,帮助开发者快速搭建基于 MCP 协议的应用程序。无论是作为服务提供商还是消费者角色,都可以借助其强大的功能模块完成复杂的业务场景需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值