Spring AI 实现MCP简单案例

Spring AI 实现MCP简单案例

引言

随着大型语言模型(LLM)在企业应用中的普及,如何有效地连接模型与外部工具、数据和服务成为了开发人员面临的重要挑战。2024年11月,Anthropic推出了模型上下文协议(Model Context Protocol,简称MCP),这一开放标准为解决AI系统中组件协同问题提供了全新的解决方案。本文将深入探讨MCP的核心概念,并通过一个实际的Spring AI示例项目展示其强大功能。

MCP协议简介

MCP(Model Context Protocol)是一种专为人工智能模型设计的通信协议,旨在解决复杂AI系统中多个模型或组件之间的协同工作问题。你可以把MCP想象成AI领域的"USB接口",它提供了一种统一的方式将AI模型连接到各种工具和数据源。

MCP的核心优势

  1. 标准化通信:定义了模型与外部工具交互的标准接口
  2. 自动发现能力:客户端可以自动发现并使用服务端提供的工具
  3. 跨平台兼容:任何实现MCP的系统都可以无缝集成
  4. 降低集成成本:开发者无需为每个模型重新实现工具调用逻辑
  5. 增强安全性:提供了安全的数据交换机制

Spring AI中的MCP实现

Spring AI框架已经内置了对MCP协议的支持,使Java开发者能够轻松构建MCP服务器和客户端应用。在本文中,我们将通过一个实际的示例项目来演示Spring AI如何实现MCP功能。

项目架构概览

我们的示例项目mcp-demos包含两个主要模块:

  1. mcp-server-demo:实现了MCP服务器,提供天气查询等工具服务
  2. mcp-client-demo:实现了MCP客户端,连接到本地Ollama模型并自动发现服务器提供的工具

服务端实现详解

创建MCP服务器

MCP服务器是一个基于Spring Boot的应用程序,通过简单的配置即可启用MCP功能。

首先,让我们看看主应用类的实现:

java 复制代码
@SpringBootApplication
public class McpServerApplication {

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

    @Bean
    public ToolCallbackProvider weatherTools(WeatherService weatherService) {
        return MethodToolCallbackProvider.builder().toolObjects(weatherService).build();
    }

    public record TextInput(String input) {}

    @Bean
    public ToolCallback toUpperCase() {
        return FunctionToolCallback.builder("toUpperCase", (TextInput input) -> input.input().toUpperCase())
                .inputType(TextInput.class)
                .description("Put the text to upper case")
                .build();
    }
}

在这段代码中,我们看到了两个关键的Bean定义:

  1. weatherTools:将WeatherService类中标记为工具的方法注册为MCP服务
  2. toUpperCase:创建了一个简单的文本转换工具,用于将文本转换为大写

实现工具服务

下面是WeatherService类的核心实现,展示了如何定义MCP工具方法:

java 复制代码
@Service
public class WeatherService {

    private static final String BASE_URL = "https://api.weather.gov";
    private final RestClient restClient;

    // 构造函数初始化RestClient...

    @Tool(description = "Get weather forecast for a specific latitude/longitude")
    public String getWeatherForecastByLocation(double latitude, double longitude) {
        // 实现天气查询逻辑...
    }

    @Tool(description = "Get weather alerts for a US state. Input is Two-letter US state code (e.g. CA, NY)")
    public String getAlerts(String state) {
        // 实现天气警报查询逻辑...
    }
}

关键技术点

  1. 使用@Tool注解标记可被MCP发现的方法
  2. description参数提供了工具的描述,帮助模型理解工具的功能和使用方式
  3. 方法参数和返回类型会被自动转换为适合模型理解的格式

服务端配置

服务端的MCP功能通过application.properties文件进行配置:

properties 复制代码
spring.ai.mcp.server.name=mcp-server-demo
spring.ai.mcp.server.version=0.0.1
spring.ai.mcp.server.protocol=SSE
spring.ai.mcp.server.capabilities.resource=true
spring.ai.mcp.server.capabilities.tool=true
spring.ai.mcp.server.capabilities.completion=true
spring.ai.mcp.server.capabilities.prompt=true
spring.ai.mcp.server.streamable-http.mcp-endpoint=/mcp

配置说明

  • spring.ai.mcp.server.name:服务器名称
  • spring.ai.mcp.server.protocol:通信协议,这里使用SSE(Server-Sent Events)
  • spring.ai.mcp.server.capabilities.*:声明服务器支持的功能
  • spring.ai.mcp.server.streamable-http.mcp-endpoint:MCP端点路径

客户端实现详解

创建MCP客户端

MCP客户端连接到本地Ollama模型,并自动发现服务端提供的工具:

java 复制代码
@Configuration
public class OllamaConfig {

    @Value("${ai.user.input}")
    private String userInput;

    @Bean
    public ChatClient.Builder chatClientBuilder(OllamaChatModel ollamaChatModel) {
        return ChatClient.builder(ollamaChatModel);
    }

    @Bean
    public CommandLineRunner predefinedQuestions(ChatClient.Builder chatClientBuilder
            , ToolCallbackProvider tools, ConfigurableApplicationContext context) {

        System.out.println(tools.getToolCallbacks());
        return args -> {
            var chatClient = chatClientBuilder
                    .defaultToolCallbacks(tools)
                    .build();

            System.out.println("\n>>> QUESTION: " + userInput);
            System.out.println("\n>>> ASSISTANT: " + chatClient.prompt(userInput).call().content());

            context.close();
        };
    }
}

关键技术点

  1. 通过ToolCallbackProvider自动获取所有可用的工具(包括通过MCP发现的远程工具)
  2. 将这些工具配置到ChatClient中,使其可以在与模型交互时自动选择合适的工具

客户端配置

客户端的配置同样在application.properties文件中:

properties 复制代码
spring.ai.model.chat=ollama
spring.ai.ollama.base-url=http://localhost:11434
spring.ai.ollama.chat.options.model=llama3.2:1b
spring.ai.mcp.client.name=mcp-client-demo
spring.ai.mcp.client.toolcallback.enabled=true
spring.ai.mcp.client.sse.connections.mcp-server-demo.url=http://localhost:8080
ai.user.input=What tools are available?

配置说明

  • spring.ai.model.chat=ollama:使用Ollama作为聊天模型
  • spring.ai.ollama.*:配置Ollama连接信息
  • spring.ai.mcp.client.toolcallback.enabled=true:启用MCP工具回调
  • spring.ai.mcp.client.sse.connections.*:配置MCP服务器连接

实际使用示例

示例1:获取天气预报

当用户发送如下请求时:

rust 复制代码
What's the weather forecast for New York City?

系统的执行流程如下:

  1. 客户端将请求发送给Ollama模型
  2. 模型分析请求,发现需要获取纽约的天气预报
  3. 模型识别到可以使用getWeatherForecastByLocation工具
  4. 客户端调用该工具(通过MCP协议)
  5. 服务端执行天气查询并返回结果
  6. 模型处理结果并返回给用户

示例2:使用文本转换工具

当用户发送如下请求时:

sql 复制代码
Please convert 'hello world' to uppercase.

系统会使用toUpperCase工具将文本转换为大写,整个过程对用户完全透明。

MCP的工作原理

MCP协议的工作原理可以概括为以下几个步骤:

  1. 服务注册:MCP服务器启动时,会注册所有标记为工具的方法
  2. 客户端发现:MCP客户端连接到服务器后,自动发现可用的工具
  3. 工具调用:当模型需要使用工具时,通过MCP协议调用远程工具
  4. 结果处理:工具执行结果通过MCP返回给客户端,然后由模型进行处理

这种机制使得模型可以无缝地使用各种外部工具,而不需要了解工具的具体实现细节。

实现细节与最佳实践

工具方法设计

在设计MCP工具方法时,应遵循以下最佳实践:

  1. 清晰的描述 :使用详细的description参数,帮助模型理解工具的用途
  2. 合理的参数:使用简单明了的参数类型和名称
  3. 结构化返回:返回格式良好的结构化数据
  4. 错误处理:妥善处理可能发生的异常

性能优化

对于生产环境的MCP应用,可以考虑以下性能优化策略:

  1. 工具缓存:缓存工具发现结果,减少重复发现开销
  2. 请求批处理:批量处理相关的工具调用
  3. 异步执行:使用异步方式执行耗时的工具调用
  4. 连接池管理:合理管理MCP连接池

MCP与其他方案的对比

相比传统的API集成方式,MCP具有以下优势:

特性 MCP 传统API
自动发现
标准接口 各厂商不同
模型理解 描述性元数据
跨平台兼容 需要适配
集成复杂度

未来发展与趋势

随着MCP协议的不断发展,我们可以期待:

  1. 更多框架和平台对MCP的支持
  2. 更丰富的工具生态系统
  3. 安全性和隐私保护的增强
  4. 更高效的通信协议和机制

结论

MCP协议为AI模型与外部工具的交互提供了一种标准化、高效的解决方案。通过Spring AI的实现,Java开发者可以轻松构建支持MCP的应用程序,实现模型与工具的无缝集成。本文介绍的示例项目展示了MCP的基本功能和使用方法,希望能为开发者提供有价值的参考。

随着AI技术的不断发展,MCP这样的标准化协议将在AI应用生态系统中发挥越来越重要的作用,推动AI应用的普及和创新。

参考文献

  1. MCP官方文档
  2. Spring AI MCP文档
  3. Anthropic, "Model Context Protocol: A New Standard for AI Tool Integration", 2024

代码链接

gitee.com/tree_boss/m...

相关推荐
大头an2 小时前
Spring事务传播机制深度解析:7种传播行为的使用场景和陷阱
java
吴祖贤2 小时前
5.2 Spring AI OpenAI 嵌入模型
后端
星光一影2 小时前
SpringBoot+Vue3无人机AI巡检系统
人工智能·spring boot·websocket·mysql·intellij-idea·mybatis·无人机
lichong9512 小时前
【macOS 版】Android studio jdk 1.8 gradle 一键打包成 release 包的脚本
android·java·前端·macos·android studio·大前端·大前端++
hxj..2 小时前
如何进行AI作图(架构图,流程图等)
人工智能·ai·ai作画
失散132 小时前
分布式专题——53 ElasticSearch高可用集群架构实战
java·分布式·elasticsearch·架构
飞哥数智坊2 小时前
初级岗正在消失!1.8亿岗位数据让我看清:AI协同时代已经来了
人工智能
爱叫啥叫啥2 小时前
C语言核心概念详解:指针的解引用,基本指针运算`*p++` 和 `(*p)++` 的区别
后端