如何使用Spring AI框架开发mcp接口并发布成微服务
Spring AI提供了一套简洁的机制,可以将Java方法暴露为AI模型可调用的工具。以下是完整的开发指南:
1. 环境准备
首先添加Spring AI依赖到你的项目中:
<!-- pom.xml -->
<dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-core</artifactId><version>0.8.1</version> <!-- 使用最新版本 -->
</dependency>
2. 基础工具开发
2.1 创建工具类
import org.springframework.ai.tool.Tool;
import org.springframework.ai.tool.P;
import org.springframework.stereotype.Component;@Component
public class BusinessTools {// 简单工具示例@Tool(name = "calculate", description = "执行数学计算")public double calculate(@P(description = "第一个操作数") double a,@P(description = "运算符(+,-,*,/)") String op,@P(description = "第二个操作数") double b) {return switch (op) {case "+" -> a + b;case "-" -> a - b;case "*" -> a * b;case "/" -> a / b;default -> throw new IllegalArgumentException("不支持的运算符: " + op);};}
}
2.2 注册工具
import org.springframework.ai.tool.ToolCallbackProvider;
import org.springframework.ai.tool.method.MethodToolCallbackProvider;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**通过MethodToolCallbackProvider自动注册服务类中的工具方法*/
@Configuration
public class ToolConfiguration {@Beanpublic ToolCallbackProvider businessTools(BusinessTools tools) {return MethodToolCallbackProvider.builder().toolObjects(tools) // 注册包含@Tool注解的bean.build();}
}
3. 复杂工具开发
3.1 使用DTO作为参数
// 定义DTO
public record OrderRequest(String customerId,List<String> productIds,String shippingAddress) {}// 在工具类中添加方法
@Tool(name = "createOrder", description = "创建新订单")
public OrderResult createOrder(@P(description = "订单请求") OrderRequest request) {// 实际业务逻辑return orderService.create(request);
}
3.2 异步工具
@Tool(name = "generateReport", description = "生成业务报表")
public CompletableFuture<Report> generateReport(@P(description = "报表类型") ReportType type,@P(description = "日期范围") String dateRange) {return CompletableFuture.supplyAsync(() -> {// 长时间运行的报表生成逻辑return reportService.generate(type, dateRange);});
}
4. 工具调用控制
4.1 添加权限控制
@Tool(name = "deleteUser", description = "删除用户账户")
public String deleteUser(@P(description = "用户名") String username) {// 检查权限Authentication auth = SecurityContextHolder.getContext().getAuthentication();if (!auth.getAuthorities().contains("ROLE_ADMIN")) {throw new AccessDeniedException("无权执行此操作");}return userService.delete(username);
}
4.2 输入验证
@Tool(name = "reserveRoom", description = "预订会议室")
public ReservationResult reserveRoom(@P(description = "会议室ID") @Min(1) int roomId,@P(description = "开始时间(yyyy-MM-dd HH:mm)") @Future String startTime,@P(description = "持续时间(分钟)") @Min(15) @Max(240) int duration) {// 方法参数会自动验证return reservationService.reserve(roomId, startTime, duration);
}
5. 集成AI模型
5.1 配置AI客户端
import org.springframework.ai.chat.ChatClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class AiConfig {@Beanpublic ChatClient chatClient(ToolCallbackProvider toolCallbackProvider) {return new OpenAiChatClient.Builder().apiKey("your-api-key").toolCallbackProvider(toolCallbackProvider) // 注册工具.build();}
}
5.2 创建控制器
import org.springframework.ai.chat.ChatResponse;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.web.bind.annotation.*;@RestController
@RequestMapping("/api/ai")
public class AiController {private final ChatClient chatClient;public AiController(ChatClient chatClient) {this.chatClient = chatClient;}@PostMapping("/chat")public String chat(@RequestBody String userMessage) {Prompt prompt = new Prompt(userMessage);ChatResponse response = chatClient.call(prompt);return response.getResult().getOutput().getContent();}
}
6. 转换成微服务
6.1 添加启动类
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class McpServerApplication {public static void main(String[] args) {SpringApplication.run(McpServerApplication.class, args);}
}
6.2 添加application.yml
spring.ai.mcp.server.name=my-ai-server
spring.ai.mcp.server.version=0.0.1
server.port=9090
最佳实践
- 命名规范:使用动词-名词组合(如
createOrder
、calculateSum
) - 参数描述:为每个参数提供清晰的自然语言描述
- 错误处理:定义明确的错误响应格式
- 性能考虑:长时间运行的操作实现为异步
- 文档化:为每个工具添加详细的JavaDoc注释
- 安全审计:记录所有工具调用日志
通过以上步骤,你可以有效地将Java方法暴露为AI可调用微服务,构建智能化的业务应用,也可提供给dify、bisheng等智能体调用。