网络商城营业执照经营范围,网站搭建推广优化,宁波 网站建设,可以看封禁网站的浏览器1. 工程结构概览Spring AI 提供了完整的工具调用#xff08;Tool Calling#xff09;能力#xff0c;让 AI 模型可以调用外部服务。同时#xff0c;Spring AI 还支持 MCP#xff08;Model Context Protocol#xff09;#xff0c;这是一个标准化的工具协议。spring-ai-m…1. 工程结构概览Spring AI 提供了完整的工具调用Tool Calling能力让 AI 模型可以调用外部服务。同时Spring AI 还支持 MCPModel Context Protocol这是一个标准化的工具协议。spring-ai-model/├── tool/ # 工具调用核心│ ├── ToolCallback.java # 工具回调接口│ ├── ToolDefinition.java # 工具定义│ ├── method/ # 方法工具│ │ └── MethodToolCallback.java│ ├── function/ # 函数工具│ │ └── FunctionToolCallback.java│ └── resolution/ # 工具解析│ ├── ToolCallbackResolver.java│ └── SpringBeanToolCallbackResolver.java│└── model/tool/ # 工具调用管理├── ToolCallingManager.java└── DefaultToolCallingManager.javamcp/ # MCP 协议支持├── common/ # MCP 核心│ ├── AsyncMcpToolCallback.java│ ├── SyncMcpToolCallback.java│ ├── AsyncMcpToolCallbackProvider.java│ └── SyncMcpToolCallbackProvider.java└── mcp-annotations-spring/ # MCP 注解支持└── annotation/spring/2. 技术体系与模块关系工具调用和 MCP 的关系image.png3. 关键场景示例代码3.1 方法工具使用 Tool 注解定义工具Servicepublic class WeatherService {Tool(name get_weather, description 获取天气信息)public String getWeather(String city) {// 调用天气 APIreturn weatherApi.getWeather(city);}Tool(name get_forecast, description 获取天气预报)public WeatherForecast getForecast(String city,int days,ToolContext context // 可选获取工具上下文) {// 可以从 context 中获取对话历史等return weatherApi.getForecast(city, days);}}3.2 函数工具使用函数式接口定义工具FunctionToolCallbackString, String weatherTool FunctionToolCallback.builder(get_weather,(String city) - weatherApi.getWeather(city)).description(获取天气信息).build();3.3 MCP 工具MCP 工具通过 MCP 客户端自动发现// MCP 工具会自动从 MCP 服务器发现// 无需手动定义通过 AsyncMcpToolCallbackProvider 提供ChatClient chatClient ChatClient.builder(chatModel).defaultAdvisors(// MCP 工具会自动注册).build();3.4 工具调用流程工具调用是自动的// 1. 定义工具Tool(name search_docs, description 搜索文档)public String searchDocs(String query) {return docService.search(query);}// 2. 使用 ChatClient工具会自动发现ChatClient chatClient ChatClient.builder(chatModel).build();// 3. 模型会自动调用工具String response chatClient.prompt().user(帮我搜索 Spring AI 的文档).call().content();// 模型会自动调用 search_docs 工具4. 核心时序图4.1 工具调用完整流程image.png4.2 MCP 工具发现流程image.png5. 入口类与关键类关系image.png6. 关键实现逻辑分析6.1 工具注册机制Spring AI 支持多种工具注册方式方式一Tool 注解推荐Servicepublic class MyService {Tool(name my_tool, description 我的工具)public String myTool(String input) {return 处理结果: input;}}MethodToolCallbackProvider 会自动扫描所有 Tool 注解的方法public class MethodToolCallbackProvider implements ToolCallbackProvider {Overridepublic ToolCallback[] getToolCallbacks() {return toolObjects.stream().flatMap(toolObject -Stream.of(ReflectionUtils.getDeclaredMethods(toolObject.getClass())).filter(this::isToolAnnotatedMethod).map(method - MethodToolCallback.builder().toolDefinition(ToolDefinitions.from(method)).toolMethod(method).toolObject(toolObject).build())).toArray(ToolCallback[]::new);}}方式二手动注册ToolCallback tool FunctionToolCallback.builder(my_tool,(String input) - 结果: input).build();ToolCallingChatOptions options ToolCallingChatOptions.builder().withToolCallbacks(tool).build();方式三MCP 自动发现MCP 工具通过 AsyncMcpToolCallbackProvider 自动发现public class AsyncMcpToolCallbackProvider implements ToolCallbackProvider {Overridepublic ToolCallback[] getToolCallbacks() {// 从 MCP 客户端获取工具列表ListTool mcpTools mcpClient.listTools();return mcpTools.stream().map(tool - AsyncMcpToolCallback.builder().mcpClient(mcpClient).tool(tool).build()).toArray(ToolCallback[]::new);}}6.2 工具发现机制ToolCallbackResolver 负责解析工具public class DelegatingToolCallbackResolver implements ToolCallbackResolver {private final ListToolCallbackResolver resolvers;Overridepublic ToolCallback resolve(String toolName) {// 按顺序尝试每个解析器for (ToolCallbackResolver resolver : resolvers) {ToolCallback tool resolver.resolve(toolName);if (tool ! null) {return tool;}}return null;}}SpringBeanToolCallbackResolver 从 Spring 容器中查找public class SpringBeanToolCallbackResolver implements ToolCallbackResolver {Overridepublic ToolCallback resolve(String toolName) {// 1. 检查缓存ToolCallback cached cache.get(toolName);if (cached ! null) {return cached;}// 2. 从 Spring 容器中查找 Beantry {Object bean applicationContext.getBean(toolName);ResolvableType toolType resolveBeanType(bean);// 3. 构建 ToolCallbackToolCallback tool buildToolCallback(toolName, toolType, bean);// 4. 缓存cache.put(toolName, tool);return tool;} catch (Exception e) {return null;}}}6.3 工具调用执行DefaultToolCallingManager 负责执行工具调用public class DefaultToolCallingManager implements ToolCallingManager {Overridepublic ToolExecutionResult executeToolCalls(Prompt prompt, ChatResponse response) {// 1. 提取工具调用请求AssistantMessage assistantMessage extractToolCalls(response);// 2. 构建工具上下文ToolContext toolContext buildToolContext(prompt, assistantMessage);// 3. 执行每个工具调用ListToolResponse toolResponses new ArrayList();for (ToolCall toolCall : assistantMessage.getToolCalls()) {// 3.1 解析工具回调ToolCallback callback resolveToolCallback(toolCall.getName());// 3.2 执行工具String result callback.call(toolCall.getArguments(), toolContext);// 3.3 构建响应toolResponses.add(new ToolResponse(toolCall.getId(), result));}// 4. 构建工具响应消息ToolResponseMessage toolResponseMessage new ToolResponseMessage(toolResponses);// 5. 构建对话历史ListMessage conversationHistory buildConversationHistory(prompt.getInstructions(),assistantMessage,toolResponseMessage);return ToolExecutionResult.builder().conversationHistory(conversationHistory).returnDirect(shouldReturnDirect()).build();}}6.4 MCP 工具适配MCP 工具通过 AsyncMcpToolCallback 适配到 Spring AIpublic class AsyncMcpToolCallback implements ToolCallback {Overridepublic String call(String toolInput, ToolContext toolContext) {// 1. 解析工具输入MapString, Object arguments jsonToMap(toolInput);// 2. 转换工具上下文McpMeta mcpMeta toolContextToMcpMetaConverter.convert(toolContext);// 3. 构建 MCP 请求CallToolRequest request CallToolRequest.builder().name(tool.name()) // 使用原始工具名.arguments(arguments).meta(mcpMeta).build();// 4. 调用 MCP 客户端CallToolResult response mcpClient.callTool(request).onErrorMap(exception -new ToolExecutionException(getToolDefinition(), exception)).block();// 5. 处理错误if (response.isError()) {throw new ToolExecutionException(getToolDefinition(),new IllegalStateException(Error: response.content()));}// 6. 返回结果return toJsonString(response.content());}}7. MCP 协议集成7.1 MCP 是什么MCPModel Context Protocol是一个标准化的协议用于让 AI 模型访问外部工具和数据源。它定义了工具发现服务器可以暴露可用的工具工具调用客户端可以调用工具资源访问客户端可以访问服务器资源7.2 MCP 工具提供者AsyncMcpToolCallbackProvider 负责从 MCP 服务器发现工具public class AsyncMcpToolCallbackProvider implements ToolCallbackProvider {Overridepublic ToolCallback[] getToolCallbacks() {// 1. 从 MCP 客户端获取工具列表ListTool tools mcpClient.listTools();// 2. 转换为 Spring AI ToolCallbackreturn tools.stream().map(tool - AsyncMcpToolCallback.builder().mcpClient(mcpClient).tool(tool).toolNamePrefixGenerator(prefixGenerator).build()).toArray(ToolCallback[]::new);}}7.3 MCP 工具动态更新MCP 支持工具的动态添加和删除// MCP 客户端监听工具变更事件mcpClient.onToolsChanged(event - {// 重新获取工具列表ListTool newTools mcpClient.listTools();// 更新工具提供者toolCallbackProvider.updateTools(newTools);});8. 外部依赖8.1 工具调用Spring FrameworkIoC 容器和反射JacksonJSON 处理工具 Schema 生成Swagger AnnotationsSchema 生成8.2 MCPMCP Java SDKMCP 协议实现Reactor Core响应式支持AsyncMcpToolCallback9. 工程总结Spring AI 的工具调用和 MCP 能力设计有几个亮点统一的工具抽象。所有工具方法、函数、MCP都实现 ToolCallback 接口这让工具调用变得统一和透明。不管工具来自哪里调用方式都一样。灵活的注册机制。支持注解、手动注册、MCP 自动发现等多种方式适应不同的使用场景。想用注解加个 Tool 就行。想手动注册创建 ToolCallback 就行。智能的工具发现。通过 ToolCallbackResolver 链可以按顺序尝试多个解析器支持 Spring Bean、静态工具、MCP 工具等多种来源。找不到工具换个解析器试试。MCP 协议集成。通过 MCP 适配器Spring AI 可以无缝集成 MCP 服务器提供的工具支持工具的动态发现和更新。MCP 服务器添加了新工具Spring AI 会自动同步。工具上下文传递。工具可以接收 ToolContext获取对话历史、用户信息等上下文这让工具可以做出更智能的决策。比如根据用户历史记录提供个性化服务。总的来说Spring AI 的工具调用和 MCP 能力既强大又灵活。统一的抽象让工具调用变得简单灵活的机制让系统可以适应各种场景。这种设计让 Spring AI 既能支持简单的本地工具也能支持复杂的 MCP 服务器工具。