SpringAI+MCP协议 实战

06-01 1121阅读

文章目录

  • 前言
    • Spring AI
    • Mcp(Model Context Protocol)
    • 快速实战
      • Spring AI
      • Spring AI 集成 MCP 协议
        • Spring Mcp Client 示例
        • Spring Mcp Server 示例

          前言

          大模型发展可能到了接近成熟的程度了,但是业界的重点肯定不会仅仅就放在大模型上的,还有就是业务和应用。

          大模型如果投入应用,其中很重要的配套技术叫AI Agents,就是智能体。AI Agent(也称人工智能代理)是一种能够感知环境、进行决策和执行动作的智能实体。智能体像人一样,它有记忆、有逻辑分析能力、有任务的拆解能力、问题的拆解能力和最后综合回来统一解决问题的能力。

          AI Agents竞争就是未来很重要的方向。我们大部分人都优势应该不是大模型,但可以是AI Agents,也就是在配套技术上面有很多的优势,才能使得他做任何一个业务的完成度极大地提升了。

          现在,Agent 基本就等于 “大模型 + 插件 + 执行流程 / 思维链”,分别会对应控制端 (Brain / 大脑)、感知端 (Preception)、执行端 (Action) 环节:SpringAI+MCP协议 实战

          Spring AI

          尽管Python最近成为了编程语言的首选,但是Java在人工智能领域的地位同样不可撼动,得益于强大的Spring框架。随着人工智能技术的快速发展,我们正处于一个创新不断涌现的时代。从智能语音助手到复杂的自然语言处理系统,人工智能已经成为了现代生活和工作中不可或缺的一部分。在这样的背景下,Spring AI 项目迎来了发展的机遇。尽管该项目汲取了Python项目如LangChain和LlamaIndex的灵感,但Spring AI并不是简单的移植。该项目的初衷在于推进生成式人工智能应用程序的发展,使其不再局限于Python开发者。

          Spring AI 的核心理念是提供高度抽象化的组件,作为开发AI应用程序的基础。这些抽象化组件具备多种实现,使得开发者能够以最少的代码改动便捷地交换和优化功能模块。

          具体而言,Spring AI 提供了支持多种主流模型提供商的功能,包括OpenAI、Microsoft、Amazon、Google和Hugging Face。支持的模型类型涵盖了从聊天机器人到文本生成、图像处理、语音识别等多个领域。而其跨模型提供商的可移植API设计,不仅支持同步和流式接口,还提供了针对特定模型功能的灵活选项。

          此外,Spring AI 还支持将AI模型输出映射为POJO,以及与主流矢量数据库提供商(如Apache Cassandra、Azure Vector Search、MongoDB Atlas等)无缝集成的能力。其功能不仅局限于模型本身,还包括了数据工程中的ETL框架和各种便利的函数调用,使得开发AI应用程序变得更加高效和可靠。

          Spring Ai官网:https://spring.io/projects/spring-ai

          Mcp(Model Context Protocol)

          什么是Mcp?

          SpringAI+MCP协议 实战

          Model Context Protocol 是Anthropic 于2024年11月重磅开源的「模型上下文协议」MCP。其是一种开放的通信协议,是人工智能领域的 “USB 接口”,在大模型和其他数据源(数据、工具、开发环境等)之间建立了双向、并且更加安全的连接。

          Mcp 将LLM的数据孤岛被彻底打破,LLM应用和外部数据源、工具都将无缝集成。目标是实现LLM应用程序与外部数据源和工具之间的无缝集成。

          官方文档:https://modelcontextprotocol.io/introduction

          SpringAI+MCP协议 实战

          快速实战

          Spring AI

          当我们开始时,首先需要创建一个项目结构。我们可以前往官方网站,快速生成Spring AI的依赖并创建项目。

          SpringAI+MCP协议 实战

          IDEA配置方式不过多介绍,参考:https://blog.csdn.net/qq_15437629/article/details/131912201

          Maven 仓库配置在pom.xml中添加以下内容:

            
              spring-milestones
              Spring Milestones
              https://repo.spring.io/milestone
              
                false
              
            
            
              spring-snapshots
              Spring Snapshots
              https://repo.spring.io/snapshot
              
                false
              
            
          
          

          导入 Spring AI BOM

              
                  
                      org.springframework.ai
                      spring-ai-bom
                      1.0.0-SNAPSHOT
                      pom
                      import
                  
              
          
          

          添加 OpenAI 聊天

              org.springframework.ai
              spring-ai-openai-spring-boot-starter
          
          

          使用 OpenAI 创建 API 来访问 ChatGPT 模型。在OpenAI 注册页面创建账户并在API 密钥页面生成令牌。如果需要其他AI,则添加对应的starter即可,如Ollama:

              org.springframework.ai
              spring-ai-ollama-spring-boot-starter
          
          

          Ollama Chat 示例:

          https://docs.spring.io/spring-ai/reference/api/chat/ollama-chat.html

          package com.example.spring_ai;
          import org.springframework.ai.chat.messages.UserMessage;
          import org.springframework.ai.chat.model.ChatResponse;
          import org.springframework.ai.chat.prompt.Prompt;
          import org.springframework.ai.ollama.OllamaChatModel;
          import org.springframework.beans.factory.annotation.Autowired;
          import org.springframework.web.bind.annotation.GetMapping;
          import org.springframework.web.bind.annotation.RequestParam;
          import org.springframework.web.bind.annotation.RestController;
          import reactor.core.publisher.Flux;
          import java.util.Map;
          @RestController
          public class ChatController {
              private final OllamaChatModel chatModel;
              @Autowired
              public ChatController(OllamaChatModel chatModel) {
                  this.chatModel = chatModel;
              }
              @GetMapping("/ai/generate")
              public Map generate(@RequestParam(value = "message", defaultValue = "Tell me a joke") String message) {
                  return Map.of("generation", this.chatModel.call(message));
              }
              @GetMapping("/ai/generateStream")
              public Flux generateStream(@RequestParam(value = "message", defaultValue = "Tell me a joke") String message) {
                  Prompt prompt = new Prompt(new UserMessage(message));
                  return this.chatModel.stream(prompt);
              }
          }
          

          application.properities:

          spring.application.name=spring-ai
          spring.ai.ollama.base-url=http://localhost:11434
          spring.ai.ollama.chat.options.model=deepseek-r1
          server.port=8181
          logging.level.org.springframework.ai=DEBUG
          

          pom.xml:

          
          	4.0.0
          	
          		org.springframework.boot
          		spring-boot-starter-parent
          		3.4.4
          		 
          	
          	com.example
          	spring-ai
          	0.0.1-SNAPSHOT
          	spring-ai
          	Demo project for Spring Boot
          	
          	
          		
          	
          	
          		
          	
          	
          		
          		
          		
          		
          	
          	
          		17
          		1.0.0-M6 
          	
          	
          		
          			org.springframework.boot
          			spring-boot-starter-web
          		
          		
          			org.springframework.ai
          			spring-ai-ollama-spring-boot-starter
          		
          		
          			org.projectlombok
          			lombok
          			true
          		
          		
          			org.springframework.boot
          			spring-boot-starter-test
          			test
          		
          	
          	
          		
          			
          				org.springframework.ai
          				spring-ai-bom
          				${spring-ai.version}
          				pom
          				import
          			
          		
          	
          	
          		
          			
          				org.apache.maven.plugins
          				maven-compiler-plugin
          				
          					
          						
          							org.projectlombok
          							lombok
          						
          					
          				
          			
          			
          				org.springframework.boot
          				spring-boot-maven-plugin
          				
          					
          						
          							org.projectlombok
          							lombok
          						
          					
          				
          			
          		
          	
          
          

          测试结果:

          SpringAI+MCP协议 实战

          Spring AI 集成 MCP 协议

          SpringAI+MCP协议 实战

          对于 Mcp Client,Spring AI 提供了如下两个 Starter 集成 MCP Client;

          • spring-ai-mcp-client-spring-boot-starter: 实现基于 STDIO 和 HTTP 的 SSE 传输协议的 Mcp Client
          • spring-ai-mcp-client-webflux-spring-boot-starter: 实现基于 WebFlux 的 SSE 传输协议的 Mcp Client

            对于 Mcp Server, Spring AI 提供了如下三个 Starter 集成 Mcp Server:

            • spring-ai-mcp-server-spring-boot-starter: 实现支持 STDIO 传输协议的 Mcp Server
            • spring-ai-mcp-server-webmvc-spring-boot-starter: 实现基于 webmvc 的 SSE 传输协议的 Mcp Server
            • spring-ai-mcp-server-webflux-spring-boot-starter: 实现基于 webflux 的 SSE 传输协议的 Mcp Server

              Spring Mcp Client 示例

              https://docs.spring.io/spring-ai/reference/api/mcp/mcp-client-boot-starter-docs.html

              基于SpringAI 1.0.0-M5实现:

              对于 Mcp Client,Spring AI 提供了如下两个 Starter 集成 MCP Client;

              spring-ai-mcp-client-spring-boot-starter: 实现基于 STDIO 和 HTTP 的 SSE 传输协议的 Mcp Client
              spring-ai-mcp-client-webflux-spring-boot-starter: 实现基于 WebFlux 的 SSE 传输协议的 Mcp Client
              

              pom依赖:

              		
              			org.springframework.ai
              			spring-ai-mcp-client-spring-boot-starter
              		
              

              配置文件:

              spring.application.name=spring-ai
              spring.ai.ollama.base-url=http://localhost:11434
              spring.ai.ollama.chat.options.model=qwen2.5:0.5b
              server.port=8181
              # MCP Client Configuration
              spring.ai.mcp.client.enabled=true
              spring.ai.mcp.client.name=mcp-client
              spring.ai.mcp.client.version=1.0.0
              spring.ai.mcp.client.type=SYNC
              spring.ai.mcp.client.request-timeout=30s
              spring.ai.mcp.client.stdio.servers-configuration=classpath:/mcp-servers-config.json
              

              mcp-servers-config.json:

              {
                "mcpServers": {
                  "filesystem": {
                    "command": "D:\\\\node_js\\\\npx.cmd",
                    "args": [
                      "-y",
                      "@modelcontextprotocol/server-filesystem",
                      "."
                    ]
                  }
                }
              }
              

              1,服务包说明:

              @modelcontextprotocol/server-filesystem 是 MCP 协议中用于对接文件系统的标准化服务模块,其配置通过 Node.js 环境快速启动,使 LLM 能够安全、可控地操作本地文件资源‌。

              MCP 生态中还有其他类型的服务包,例如:

              ‌@modelcontextprotocol/server-postgres‌:支持数据库查询‌;

              ‌@modelcontextprotocol/server-http‌:集成 RESTful API‌。

              2,npx

              本地需要提前安装配置npx和uvx。npx是nodeJs下的一个工具可以执行一些Ts或者JS脚本甚至应用程序,uvx的功能则和他很类似是python环境下执行脚本的工具。简单来说,使用 TypeScript 编写的 MCP server 可以通过 npx 命令来运行,使用 Python 编写的 MCP server 可以通过 uvx 命令来运行。npx 是 Node.js 自带的工具,无需单独安装,但需先安装 Node.js。

              npm 全局目录配置:

              mkdir D:\node_js\pm-cache
              npm config set prefix "D:\node_js"
              npm config set cache "D:\node_js\pm-cache"
              npm config get prefix
              npm config get cache
              npm cache clean --force
              

              执行以下命令检查是否成功:

              npx -v          # 应输出 npx 版本(如 10.8.2)
              npm ls -g --depth=0  # 检查全局依赖是否可正常列出
              

              如果出现权限问题: 右键点击 D:\node_js → 属性 → 安全 → 高级 ,添加当前用户并勾选 完全控制

              3,模型选择

              出现报错:deepseek-r1 does not support tools,需要选择支持tools的模型:

              SpringAI+MCP协议 实战

              示例代码:

              package com.example.spring_ai;
              import jakarta.annotation.Resource;
              import org.springframework.ai.chat.client.ChatClient;
              import org.springframework.ai.ollama.OllamaChatModel;
              import org.springframework.web.bind.annotation.GetMapping;
              import org.springframework.web.bind.annotation.RequestParam;
              import org.springframework.web.bind.annotation.RestController;
              import org.springframework.ai.mcp.SyncMcpToolCallbackProvider;
              @RestController
              public class ChatController {
                  @Resource
                  private OllamaChatModel ollamaChatModel;
                  @Resource
                  private SyncMcpToolCallbackProvider toolCallbackProvider;
                  @GetMapping("/chat")
                  public String call(@RequestParam String input) {
                          ChatClient chatClient = ChatClient.builder(ollamaChatModel)
                                  .defaultTools(toolCallbackProvider.getToolCallbacks())
                                  .build();
                          return chatClient.prompt(input).call().content();
                  }
              }
              

              测试结果:

              SpringAI+MCP协议 实战

              SpringAI+MCP协议 实战

              Spring Mcp Server 示例

              https://docs.spring.io/spring-ai/reference/api/mcp/mcp-server-boot-starter-docs.html

              基于SpringAI 1.0.0-M6实现:

              依赖:

              
                  org.springframework.ai
                  spring-ai-mcp-server-spring-boot-starter
              
              
              
                org.springframework.ai
                spring-ai-mcp-server-webmvc-spring-boot-starter
              
              
              
                  org.springframework.ai
                  spring-ai-mcp-server-webflux-spring-boot-starter
              
              

              一个标准的MCP服务端程序需要包含三个主要信息分别为Tools、Prompts、Resources

              • 资源(Resources):资源是AI可以读取的数据,比如文件内容、数据库查询结果或API的响应。 例如,AI可能通过资源获取你的日历事件列表。
              • 工具(Tools):工具是AI可以调用的函数,用于执行特定操作,比如添加新任务或发送邮件,使用工具时,通常需要用户先批准,以确保安全。
              • 提示词(Prompts):提示词是服务器提供给AI的预写消息或模板,帮助AI理解如何使用资源和工具,例如,服务器可能告诉AI:“你可以添加任务,试试说‘添加任务:买牛奶’”,从而帮助用户更轻松地完成任务。提示词虽然直接提供给AI,但实际上是通过AI间接帮助用户,比如AI会根据提示词告诉用户如何操作。

                依赖版本:

                	17
                	1.0.0-M6 
                		
                
                	io.modelcontextprotocol.sdk
                	mcp
                	0.8.1
                
                

                配置:

                spring.ai.mcp.server.enabled=true
                spring.ai.mcp.server.name=custom-mcp-server
                spring.ai.mcp.server.version=1.0.0
                spring.ai.mcp.server.type=ASYNC   
                spring.ai.mcp.server.sse-message-endpoint=/mcp/stream  # SSE????
                

                1,定义外部工具类

                实现两个示例工具:查询当前时间和计算数学表达式。

                package com.example.spring_ai;
                import io.swagger.v3.oas.annotations.Parameter;
                import org.springframework.ai.tool.annotation.Tool;
                import javax.script.ScriptEngine;
                import javax.script.ScriptEngineManager;
                import javax.script.ScriptException;
                import java.time.LocalDateTime;
                import java.time.format.DateTimeFormatter;
                public class CustomTools {
                    @Tool(description = "获取当前系统时间")
                    public String getCurrentTime() {
                        return LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
                    }
                    @Tool(description = "执行数学运算(支持加减乘除)")
                    public double calculateExpression(
                            @Parameter(name = "expression", description = "数学表达式,如 3+5*2") String expr
                    ) {
                        ScriptEngineManager mgr = new ScriptEngineManager();
                        ScriptEngine engine = mgr.getEngineByName("JavaScript");
                        try {
                            return (double) engine.eval(expr);
                        } catch (ScriptException e) {
                            throw new RuntimeException("表达式解析失败: " + e.getMessage());
                        }
                    }
                }
                

                ps:Java 15+ 移除了 Nashorn JavaScript 引擎,导致 getEngineByName(“JavaScript”) 返回 null:

                
                    org.openjdk.nashorn
                    nashorn-core
                    15.4
                
                

                2,注册工具到MCP服务器

                通过@Configuration类将工具暴露为MCP协议的可调用接口:

                package com.example.spring_ai;
                import org.springframework.ai.tool.ToolCallback;
                import org.springframework.ai.tool.ToolCallbackProvider;
                import org.springframework.ai.tool.ToolCallbacks;
                import org.springframework.context.annotation.Bean;
                import org.springframework.context.annotation.Configuration;
                @Configuration
                public class McpServerConfig {
                    @Bean
                    @Primary // 添加此注解指定优先使用此Bean
                    public ToolCallbackProvider toolProvider() {
                        // 注册工具类实例
                        ToolCallback[] callbacks = ToolCallbacks.from(new CustomTools());
                        return ToolCallbackProvider.from(callbacks);
                    }
                }
                

                4,客户端调用示例

                package com.example.spring_ai;
                import org.springframework.ai.chat.client.ChatClient;
                import org.springframework.ai.tool.ToolCallbackProvider;
                import org.springframework.web.bind.annotation.GetMapping;
                import org.springframework.web.bind.annotation.RequestMapping;
                import org.springframework.web.bind.annotation.RequestParam;
                import org.springframework.web.bind.annotation.RestController;
                @RestController
                @RequestMapping("/client")
                public class McpClientController {
                    private final ChatClient chatClient;
                    public McpClientController(ChatClient.Builder builder, ToolCallbackProvider tools) {
                        this.chatClient = builder.defaultTools(tools).build();
                    }
                    @GetMapping("/time")
                    public String getTime() {
                        return chatClient.prompt("调用getCurrentTime工具").call().content();
                    }
                    @GetMapping("/calc")
                    public String calculate(@RequestParam String expr) {
                        return chatClient.prompt("计算表达式:" + expr).call().content();
                    }
                }
                

                当客户端发送请求时,Spring AI 的底层流程会遍历所有已注册工具,检查输入文本是否与工具描述(如:执行数学运算(支持加减乘除))匹配。若匹配成功,直接调用 对应方法,无需显式指定工具名称。

                测试结果如下:

                SpringAI+MCP协议 实战

                SpringAI+MCP协议 实战

                日志:

                [spring-ai] [nio-8181-exec-3] o.s.a.m.tool.DefaultToolCallingManager   : Executing tool call: getCurrentTime
                [spring-ai] [nio-8181-exec-3] o.s.ai.tool.method.MethodToolCallback    : Starting execution of tool: getCurrentTime
                [spring-ai] [nio-8181-exec-3] o.s.ai.tool.method.MethodToolCallback    : Successful execution of tool: getCurrentTime
                [spring-ai] [nio-8181-exec-3] o.s.a.t.e.DefaultToolCallResultConverter : Converting tool result to JSON.
                [spring-ai] [nio-8181-exec-7] o.s.a.m.tool.DefaultToolCallingManager   : Executing tool call: calculateExpression
                [spring-ai] [nio-8181-exec-7] o.s.ai.tool.method.MethodToolCallback    : Starting execution of tool: calculateExpression
                [spring-ai] [nio-8181-exec-7] o.s.ai.tool.method.MethodToolCallback    : Successful execution of tool: calculateExpression
                [spring-ai] [nio-8181-exec-7] o.s.a.t.e.DefaultToolCallResultConverter : Converting tool result to JSON.
                

                SpringAI+MCP协议 实战

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们。

目录[+]

取消
微信二维码
微信二维码
支付宝二维码