You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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));
        }
    }
}

额外优化建议

  1. 规范工具返回格式:确保getIpAndLatitudeAndLongitude返回结构化JSON,示例:

    {"latitude": "39.9042", "longitude": "116.4074", "city": "北京市"}
    
  2. 优化工具描述:调整服务端的工具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"]
                        }
                    }
                }
                """;
    }
    
  3. 版本要求:使用Spring AI 0.8.0及以上版本,确保工具调用相关API稳定支持。

内容的提问来源于stack exchange,提问作者詹花惹草

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 19:45:18