Spring AI工具链式调用异常:仅执行getIpInfo未触发后续工具
问题:Spring AI工具链未自动触发多轮调用
我有两个工具:getIpInfo(对应服务端的getIpAndLatitudeAndLongitude)和getWeatherForecastByLocation。当输入「我想了解我所在城市的天气预报」时,期望Spring AI先执行getIpInfo获取经纬度,再用该结果调用getWeatherForecastByLocation,但实际仅执行了getIpInfo工具。
原因分析
Spring AI的ChatClient.call()默认只执行单轮交互:调用一次工具后就直接返回结果,不会自动根据工具返回的上下文触发下一轮工具调用。要实现链式工具调用,必须手动实现多轮交互的循环逻辑,让AI能基于上一轮的工具结果判断是否需要继续调用后续工具。
同时需确保:
getIpAndLatitudeAndLongitude返回结构化JSON格式的结果,包含清晰的latitude和longitude字段,便于AI提取参数;- 工具的描述足够明确,引导AI理解调用顺序。
解决方案
修改客户端的tool方法,实现多轮工具调用循环:
@GetMapping(value = "/tool") public String tool(String input) { ChatClient chatClient = ChatClient.builder(chatModel) .defaultAdvisors(new SimpleLoggerAdvisor()) .build(); List<ToolDefinition> toolDefinitions = toolDefinitionLoader.loadTools(); List<ToolCallback> toolCallbacks = toolDefinitionLoader.loadCallbacks(toolDefinitions); // 初始化对话消息列表,保存交互历史 List<ChatMessage> messages = new ArrayList<>(); messages.add(new UserMessage(input)); while (true) { // 发起AI请求,传入对话历史 ChatResponse response = chatClient.prompt(messages) .toolCallbacks(toolCallbacks) .call() .chatResponse(); // 将AI的响应加入对话历史 messages.add(response.getResult().getOutput()); // 检查是否有需要执行的工具调用 List<ToolCall> toolCalls = response.getResult().getToolCalls(); if (toolCalls == null || toolCalls.isEmpty()) { // 无工具调用需求,返回最终结果 return response.getResult().getOutput().getContent(); } // 执行所有工具调用,并将结果加入对话历史 for (ToolCall toolCall : toolCalls) { ToolCallback callback = toolCallbacks.stream() .filter(t -> t.getToolDefinition().getName().equals(toolCall.getToolName())) .findFirst() .orElseThrow(() -> new IllegalArgumentException("未找到工具: " + toolCall.getToolName())); String toolResult = callback.call(toolCall.getToolInput()); // 将工具返回结果作为上下文传入下一轮对话 messages.add(new ToolResultMessage(toolCall.getId(), toolCall.getToolName(), toolResult)); } } }
额外优化建议
规范工具返回格式:确保
getIpAndLatitudeAndLongitude返回结构化JSON,示例:{"latitude": "39.9042", "longitude": "116.4074", "city": "北京市"}优化工具描述:调整服务端的工具Schema描述,明确引导调用顺序:
@GetMapping("/schema") public String getSchema() { log.info("getSchema"); return """ { "getIpAndLatitudeAndLongitude": { "description": "必须优先调用此工具获取当前位置的经纬度,才能查询天气预报", "parameters": { "type": "object", "properties": {}, "required": [] } }, "getWeatherForecastByLocation": { "description": "使用经纬度查询指定位置的天气预报,需先调用getIpAndLatitudeAndLongitude获取经纬度参数", "parameters": { "type": "object", "properties": { "latitude": {"type": "string", "description": "来自getIpAndLatitudeAndLongitude返回的纬度值"}, "longitude": {"type": "string", "description": "来自getIpAndLatitudeAndLongitude返回的经度值"} }, "required": ["latitude", "longitude"] } } } """; }版本要求:使用Spring AI 0.8.0及以上版本,确保工具调用相关API稳定支持。
内容的提问来源于stack exchange,提问作者詹花惹草
相关产品推荐
相关产品推荐

