Spring AI Alibaba 1.x 系列【14】ReactAgent 工具执行异常处理

文章目录

  • [1. Sping AI ChatClient](#1. Sping AI ChatClient)
  • [2. Spring AI Alibaba ReactAgent](#2. Spring AI Alibaba ReactAgent)
    • 2.1 AgentToolNode#executeToolByType
    • [2.2 异常处理](#2.2 异常处理)
      • [2.2.1 ToolExecutionException](#2.2.1 ToolExecutionException)
      • [2.2.2 Exception](#2.2.2 Exception)
    • [2.3 执行流程](#2.3 执行流程)
  • [3. 演示案例](#3. 演示案例)
    • [3.1 RuntimeException](#3.1 RuntimeException)
    • [3.1 Exception](#3.1 Exception)
    • [3.3 ServiceException](#3.3 ServiceException)
    • [3.4 强制抛出异常](#3.4 强制抛出异常)
    • [3.5 选择性抛出异常](#3.5 选择性抛出异常)
    • [3.6 强制不抛出异常](#3.6 强制不抛出异常)

1. Sping AI ChatClient

1.1 ToolCallback#call()

ToolCallback 工具对象在调用时,会进行异常捕获和转换,方法型、函数型工具内部抛出的异常,都会被包装为 ToolExecutionException

方法型工具 MethodToolCallback 在反射执行时,会将工具方法内部抛出的异常包装为 ToolExecutionException

java 复制代码
/**
 * 【核心方法】反射调用AI工具的具体方法
 * 负责:权限处理 + 反射执行 + 异常包装(将反射异常转为业务异常)
 * @param methodArguments 工具方法的入参数组
 * @return 工具方法执行结果,允许返回null
 */
@Nullable
private Object callMethod(Object[] methodArguments) {
    // 如果工具类 或 工具方法 不是public修饰,强制开启反射访问权限(突破Java访问检查)
    if (isObjectNotPublic() || isMethodNotPublic()) {
        this.toolMethod.setAccessible(true);
    }

    // 定义工具方法执行结果
    Object result;
    try {
        // ===================== 核心执行 =====================
        // 通过Java反射,调用目标工具方法(如 WeatherTool.getWeather())
        // toolObject:工具实例(WeatherTool对象)
        // methodArguments:方法入参(如城市名)
        result = this.toolMethod.invoke(this.toolObject, methodArguments);
    }
    // 捕获:反射权限访问异常(无法调用方法时抛出)
    catch (IllegalAccessException ex) {
        throw new IllegalStateException("Could not access method: " + ex.getMessage(), ex);
    }
    // 捕获:【反射包装异常】工具方法内部抛出的异常,都会被反射包装成此异常
    catch (InvocationTargetException ex) {
        // 解包!获取工具方法内部【真实抛出的异常】
        // 并将其包装为【业务专属异常】ToolExecutionException 抛出
        // 外层就能直接捕获 ToolExecutionException 处理业务异常
        throw new ToolExecutionException(this.toolDefinition, ex.getCause());
    }

    // 返回工具方法执行成功的结果
    return result;
}

函数型工具 FunctionToolCallback 在执行时,也会将方法内部抛出的异常包装为 ToolExecutionException

java 复制代码
/**
 * 【函数式工具核心执行方法】
 * 泛型说明:I=工具入参类型,O=工具出参类型
 * 负责:调用函数式工具(BiFunction)+ 统一异常包装
 * @param request 工具入参对象(如天气工具的城市参数)
 * @param toolContext 工具执行上下文(可为null,传递执行环境信息)
 * @return 工具执行结果
 */
private <I, O> O callMethod(I request, @Nullable ToolContext toolContext) {
	try {
		// 核心:直接执行 函数式工具(BiFunction)的 apply 方法
		// 对应你 WeatherTool 实现的 BiFunction.apply() 逻辑
		return this.toolFunction.apply(request, toolContext);
	}
	// 捕获:已经是【业务专属异常】ToolExecutionException,直接抛出,不重复包装
	catch (ToolExecutionException ex) {
		throw ex;
	}
	// 捕获:工具执行中抛出的【所有其他异常】(未知异常、运行时异常、系统异常)
	catch (Exception ex) {
		// 统一包装为 业务专属异常 ToolExecutionException 抛出
		// 保证外层代码只需要捕获这一种异常,统一处理
		throw new ToolExecutionException(this.toolDefinition, ex);
	}
}

重点

  • 如果工具内部主动抛出 ToolExecutionException → 直接抛出
  • 如果工具抛出其他任何异常(如空指针、API 调用失败、网络异常)→ 统一包装成 ToolExecutionException

1.2 DefaultToolCallingManager#executeToolCall()

Sping AI 中,当工具执行抛出异常时,DefaultToolCallingManager 会捕获 ToolExecutionException ,然后调用 ToolExecutionExceptionProcessor 进行处理:

java 复制代码
// 1. 开启工具调用的观测(Micrometer 监控/追踪),构建观测上下文
String toolCallResult = ToolCallingObservationDocumentation.TOOL_CALL
    // 初始化观测器:使用约定、注册中心、当前工具调用的观测上下文
    .observation(this.observationConvention, DEFAULT_OBSERVATION_CONVENTION, () -> observationContext,
            this.observationRegistry)
    // 2. 执行工具调用逻辑,并自动完成观测的开始/停止/上报
    .observe(() -> {
        // 定义工具执行结果
        String toolResult;
        try {
            // 3. 执行实际的工具回调(核心业务逻辑:调用第三方接口/本地方法)
            toolResult = toolCallback.call(finalToolInputArguments, toolContext);
        }
        catch (ToolExecutionException ex) {
            // 4. 捕获工具执行异常(Spring AI 标准工具异常)
            // 调用异常处理器,将异常转为 LLM 能理解的文本信息
            toolResult = this.toolExecutionExceptionProcessor.process(ex);
        }
        // 5. 将工具执行结果(成功/异常)设置到观测上下文,用于监控日志记录
        observationContext.setToolCallResult(toolResult);
        // 6. 返回最终工具结果(成功结果 or 异常处理后的文本)
        return toolResult;
    });

注意事项

  • 只捕获 ToolExecutionException 异常,然后调用异常处理器
  • ToolExecutionException 不会被捕获直接向外抛出

1.3 ToolExecutionExceptionProcessor

Spring AI 默认工具异常处理器中有两种分支结果:

  • 第一种:抛出异常(throw
  • 第二种:返回格式化后的错误信息,交给大模型 LLM 解析理解

处理逻辑

java 复制代码
/**
 * 处理工具执行异常,将异常转换为LLM可读的错误信息,支持指定异常直接抛出
 * @param exception 工具执行抛出的ToolExecutionException
 * @return 格式化后的错误信息
 */
@Override
public String process(ToolExecutionException exception) {
	// 断言:异常对象不能为空,为空则直接抛出参数异常
	Assert.notNull(exception, "exception cannot be null");

	// 获取原始异常根源(即工具方法中真正抛出的业务异常)
	Throwable cause = exception.getCause();

	// 判断根异常是否是运行时异常
	if (cause instanceof RuntimeException runtimeException) {
		// 遍历配置的【需要直接重新抛出】的异常列表
		// 如果根异常属于列表中的异常类型,则直接抛出该运行时异常(不做包装处理)
		if (this.rethrownExceptions.stream().anyMatch(rethrown -> rethrown.isAssignableFrom(cause.getClass()))) {
			throw runtimeException;
		}
	}
	else {
		// 如果根异常不是运行时异常(例如IOException、Error等)
		// 直接抛出外层的ToolExecutionException,不进行友好转换
		throw exception;
	}

	// 如果配置了 alwaysThrow = true,则无论什么情况,都直接抛出异常
	if (this.alwaysThrow) {
		throw exception;
	}

	// 获取异常的提示信息
	String message = exception.getMessage();
	// 如果异常信息为空或空白字符串,构建默认的标准化错误信息
	if (message == null || message.isBlank()) {
		message = "Exception occurred in tool: " + exception.getToolDefinition().name() + " ("
				+ cause.getClass().getSimpleName() + ")";
	}

	// 打印DEBUG级别日志:记录工具名称、错误信息、完整异常堆栈
	logger.debug("Exception thrown by tool: {}. Message: {}", exception.getToolDefinition().name(), message,
			exception);

	// 返回格式化后的错误信息,交给大模型LLM解析理解
	return message;
}

1.3.1 直接抛出

触发条件

  • 根异常不是 RuntimeException(如 IOExceptionSQLException
  • 根异常是 RuntimeException,但在 rethrownExceptions 列表里
  • 配置 alwaysThrow=true,强制抛出

注意事项 :如果直接 throw 异常,会直接中断流程,不会返回任何信息给大模型,适用于严重不应该让 LLM 处理的错误。

1.3.2 格式化后返回给大模型

触发条件

  • 根异常是 RuntimeException
  • 不在重抛异常列表里
  • alwaysThrow=false(默认值)

异常中包含错误信息,会直接返回错误字符串,示例:

java 复制代码
API 调用失败

如果,原异常没有错误信息,会添加默认,示例:

java 复制代码
Exception occurred in tool: xxxTool (RuntimeException)

最后包装为 ToolResponse 返回:

java 复制代码
	public record ToolResponse(String id, String name, String responseData) {

	}

注意事项:如果是普通业务错误,格式化后的错误消息可以让大模型读懂并友好回复用户,流程正常继续,不会中断。

2. Spring AI Alibaba ReactAgent

2.1 AgentToolNode#executeToolByType

ReactAgent#AgentToolNode 工具执行节点中,最终的同步或异步工具执行方法中,都会捕获异常并处理:

  • catch ToolExecutionException :调用 ToolExecutionExceptionProcessor 进行处理,返回 ToolCallResponse.of() 包装的响应结果
  • catch Exception: 返回 ToolCallResponse.error() 包装的响应结果

捕获逻辑:

java 复制代码
/**
 * 同步执行工具调用的核心方法
 * 负责调用具体的工具回调对象,处理执行结果、异常,并返回标准化的工具响应
 *
 * @param callback 工具回调对象(Spring AI 标准工具执行器)
 * @param request  工具调用请求对象,包含工具名、参数、调用ID等
 * @param toolContextMap 工具执行上下文参数(会话信息、用户信息等)
 * @param config   运行时配置(包含线程ID、Agent配置等)
 * @return 工具调用的标准化响应对象(成功/失败结果)
 */
private ToolCallResponse executeSyncTool(ToolCallback callback, ToolCallRequest request,
			Map<String, Object> toolContextMap, RunnableConfig config) {

	// 1. 构建工具执行上下文,封装传入的上下文参数
	ToolContext context = new ToolContext(toolContextMap);

	try {
		// 2. 核心:调用工具的执行方法,传入JSON格式的参数和上下文,获取执行结果
		String result = callback.call(request.getArguments(), context);

		// 3. 判断是否开启Agent执行日志,打印工具执行成功日志
		if (enableActingLog) {
			// 打印基础执行日志:线程ID、Agent名称、执行完成的工具名
			logger.info("[ThreadId {}] Agent {} acting, tool {} finished",
					config.threadId().orElse(THREAD_ID_DEFAULT), agentName, request.getToolName());
			// Debug级别:打印工具返回的详细结果
			if (logger.isDebugEnabled()) {
				logger.debug("Tool {} returned: {}", request.getToolName(), result);
			}
		}

		// 4. 构建并返回【成功】的工具调用响应
		return ToolCallResponse.of(request.getToolCallId(), request.getToolName(), result);
	}
	catch (ToolExecutionException e) {
		// 5. 捕获【工具执行专属异常】:使用自定义异常处理器处理业务异常
		logger.error("Tool {} execution failed, handling with processor: {}", request.getToolName(),
				toolExecutionExceptionProcessor.getClass().getName(), e);
		// 调用异常处理器生成友好的错误结果
		String result = toolExecutionExceptionProcessor.process(e);
		// 返回处理后的异常响应
		return ToolCallResponse.of(request.getToolCallId(), request.getToolName(), result);
	}
	catch (Exception e) {
		// 6. 捕获【所有未知/系统异常】:通用异常处理
		logger.error("Tool {} execution failed: {}", request.getToolName(), e.getMessage(), e);
		// 构建并返回【错误】的工具调用响应(自动封装异常信息)
		return ToolCallResponse.error(request.getToolCallId(), request.getToolName(), e);
	}
}

2.2 异常处理

2.2.1 ToolExecutionException

AgentToolNode 构建方法中,如果没有配置 ToolExecutionExceptionProcessor ,默认使用也是 Spring AI 中的 DefaultToolExecutionExceptionProcessor

java 复制代码
		public Builder toolExecutionExceptionProcessor(
				ToolExecutionExceptionProcessor toolExecutionExceptionProcessor) {
			if (toolExecutionExceptionProcessor == null) {
				toolExecutionExceptionProcessor = DefaultToolExecutionExceptionProcessor.builder()
						.alwaysThrow(false)
						.build();			}
			this.toolExecutionExceptionProcessor = toolExecutionExceptionProcessor;
			return this;
		}

如果工具执行返回 ToolExecutionException ,进入异常处理器中,处理逻辑和 Spring AI 一致:

  • 直接 throw 异常
  • 返回格式化后的异常信息

比如没有抛出异常,处理器返回结果:

java 复制代码
API 调用失败

然后再调用 of 方法返回统一的工具执行结果:

java 复制代码
	public static ToolCallResponse of(String toolCallId, String toolName, String result) {
		return new ToolCallResponse(result, toolName, toolCallId);
	}

最终返回给 LLM 的工具执行失败示例:

java 复制代码
{
  "toolCallId": "call_123",
  "toolName": "weatherTool",
  "result": "API 调用失败",
}

2.2.2 Exception

如果工具执行返回 Exception ,会调用 error 方法构建错误消息。

处理逻辑:

java 复制代码
/**
 * 根据异常 Throwable 构建工具执行失败的错误响应
 * 作用:统一封装工具异常,返回给大模型 LLM 标准格式
 * 如果异常消息为null,则保留异常类名(保证LLM一定能读到错误)
 *
 * @param toolCallId 工具调用ID(LLM生成的唯一标识)
 * @param toolName   工具名称
 * @param cause      工具执行抛出的异常
 * @return 封装好的工具错误响应
 */
public static ToolCallResponse error(String toolCallId, String toolName, Throwable cause) {
    // 构建错误消息:
    // 异常有消息 → 使用异常消息
    // 异常无消息 → 使用异常类名(例如 NullPointerException)
    String errorMessage = cause.getMessage() != null ? cause.getMessage() : cause.getClass().getSimpleName();
    
    // 调用重载方法,统一封装成 ToolCallResponse
    return error(toolCallId, toolName, errorMessage);
}

最后调用统一的 error 统一封装工具执行失败的错误响应:

java 复制代码
/**
 * 根据错误字符串构建工具执行失败的响应
 * 统一格式:固定前缀 + 错误信息 + 元数据
 *
 * @param toolCallId    工具调用ID
 * @param toolName      工具名称
 * @param errorMessage  错误提示文本
 * @return 标准错误格式的 ToolCallResponse
 */
public static ToolCallResponse error(String toolCallId, String toolName, String errorMessage) {
    // 构建并返回错误响应:
    // 1. 内容:"Error: " + 错误信息
    // 2. 工具名、toolCallId 原样带回
    // 3. 状态:error
    // 4. 元数据:标记 error=true,存储错误消息
    return new ToolCallResponse(
        "Error: " + errorMessage,   // 给LLM看的错误内容
        toolName,                   // 工具名
        toolCallId,                 // 工具调用ID
        "error",                    // 状态:错误
        Map.of(                     // 扩展元数据
            "error", true, 
            "errorMessage", errorMessage
        )
    );

最终返回给 LLM 的工具执行失败示例:

java 复制代码
{
  "toolCallId": "call_123",
  "toolName": "weatherTool",
  "content": "Error: 连接天气服务超时",
  "status": "error",
  "metadata": {
    "error": true,
    "errorMessage": "连接天气服务超时"
  }
}

2.3 执行流程

流程极简说明:

  • 工具调用:
    • 正常→ 直接返回成功结果
    • 异常→ 包装为 ToolExecutionException
  • 工具执行:
    • 捕获 ToolExecutionException→ 走异常处理器
      • 直接抛出异常→ 流程中断
      • 异常处理器生成友好文案→ 统一通用响应封装→ 大模型处理
    • 捕获 Exception (系统异常)→ 统一通用错误封装→ 大模型处理

3. 演示案例

3.1 RuntimeException

定义一个天气查询工具,内部抛出 RuntimeException

java 复制代码
public class WeatherTool {

    @Tool(description = "查询指定城市的天气")
    public String getWeather(@ToolParam String city) {
        if (1==1){
            throw  new RuntimeException("天气 API 调用失败");
        }
        return "%s 天气:晴天,26℃,空气质量优".formatted(city);
    }
}

执行调用:

java 复制代码
        ReactAgent chatAgent = ReactAgent.builder()
                .name("my-agent")
                .model(zhiPuAiChatModel)
                .methodTools(new WeatherTool())
                .build();

        String text = chatAgent.call("查询长沙的天气情况").getText();
        System.out.println(text);

RuntimeException 在执行时会包装为 ToolExecutionException ,根异常是 RuntimeException ,默认的异常处理器中,则会格式化并回复给大模型处理。

控制台输出示例:

java 复制代码
Caused by: java.lang.RuntimeException: 天气 API 调用失败
	at com.example.aialibaba.config.WeatherTool.getWeather(WeatherTool.java:28) ~[classes/:na]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
	at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
	at org.springframework.ai.tool.method.MethodToolCallback.callMethod(MethodToolCallback.java:185) ~[spring-ai-model-1.1.2.jar:1.1.2]
	... 116 common frames omitted


很抱歉,查询长沙天气时遇到了技术问题,无法获取到天气信息。可能是天气服务暂时不可用或网络连接问题。

建议您:
1. 稍后再试查询天气
2. 或者可以通过其他天气应用、网站获取长沙的天气信息
3. 如果您有其他需要帮助的地方,请告诉我

工具调用响应结果如下:

3.1 Exception

如果工具内部抛出 Exception

java 复制代码
    @Tool(description = "查询指定城市的天气")
    public String getWeather(@ToolParam String city) throws Exception {
        if (1==1){
            throw  new Exception("天气 API 调用失败");
        }
        return "%s 天气:晴天,26℃,空气质量优".formatted(city);
    }

Exception 在执行时也会包装为 ToolExecutionException ,根异常是 Exception ,默认的异常处理器中,由于根异常不是 RuntimeException ,则会直接抛出异常,流程中断。

控制台输出示例:

java 复制代码
Caused by: java.lang.Exception: 天气 API 调用失败
	at com.example.aialibaba.config.WeatherTool.getWeather(WeatherTool.java:28) ~[classes/:na]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
	at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
	at org.springframework.ai.tool.method.MethodToolCallback.callMethod(MethodToolCallback.java:185) ~[spring-ai-model-1.1.2.jar:1.1.2]
	... 116 common frames omitted

Disconnected from the target VM, address: '127.0.0.1:60077', transport: 'socket'

3.3 ServiceException

在实际企业开发中,一般都会定义一个通用业务异常,例如业务操作中的参数类错误、数据 / 业务规则错误等异常信息。

ServiceException 简单示例:

java 复制代码
public class ServiceException extends RuntimeException {

    private static final long serialVersionUID = 1L;

    /** 异常提示信息 */
    private String message;
    /** 异常编码(业务错误码) */
    private String code;
    /** 占位符参数(用于国际化/格式化消息) */
    private Object[] args;
    /** 异常详细信息 */
    private String detailMessage;

    // ===================== 保留你原有构造函数 =====================
    public ServiceException() {
    }

    public ServiceException(String message) {
        // 修复:调用父类构造,保证Throwable.getMessage()生效
        super(message);
        this.message = message;
    }

    public ServiceException(String message, String code) {
        super(message);
        this.message = message;
        this.code = code;
    }

    public ServiceException(String message, Object... args) {
        super(message);
        this.message = message;
        this.args = args;
    }

    public ServiceException(String message, String code, String detailMessage) {
        super(message);
        this.message = message;
        this.code = code;
        this.detailMessage = detailMessage;
    }

    // ===================== 生产级新增:带根异常的构造器(必备) =====================
    public ServiceException(String message, String code, Throwable cause) {
        super(message, cause);
        this.message = message;
        this.code = code;
    }

    // ===================== 保留你原有链式方法 =====================
    public ServiceException setCode(String code) {
        this.code = code;
        return this;
    }

    public ServiceException setDetailMessage(String detailMessage) {
        this.detailMessage = detailMessage;
        return this;
    }

    // ===================== 生产级新增:Getter方法(外部必须读取异常信息) =====================
    @Override
    public String getMessage() {
        return this.message;
    }

    public String getCode() {
        return code;
    }

    public Object[] getArgs() {
        return args;
    }

    public String getDetailMessage() {
        return detailMessage;
    }
}

模拟工具调用时,出现的业务异常:

java 复制代码
    @Tool(description = "查询指定城市的天气")
    public String getWeather(@ToolParam String city) {
        if (1==1){
            // 调用某个业务类,出现业务异常
            throw  new ServiceException("天气 API 调用失败");
        }
        return "%s 天气:晴天,26℃,空气质量优".formatted(city);
    }
}

执行时包装为 ToolExecutionException 如下:

工具调用响应结果如下:

3.4 强制抛出异常

DefaultToolExecutionExceptionProcessor 可以通过 alwaysThrow 配置只要是发生异常,就中断流程直接抛出。

示例:

java 复制代码
        DefaultToolExecutionExceptionProcessor exceptionProcessor = DefaultToolExecutionExceptionProcessor.builder()
                .alwaysThrow(true) // 总是抛出异常
                //.rethrowExceptions()
                .build();

        ReactAgent chatAgent = ReactAgent.builder()
                .name("my-agent")
                .toolExecutionExceptionProcessor(exceptionProcessor)
                .model(zhiPuAiChatModel)
                .methodTools(new WeatherTool())
                .build();
                
        String text = chatAgent.call("查询长沙的天气情况").getText();
        System.out.println(text);

3.5 选择性抛出异常

DefaultToolExecutionExceptionProcessor 可以通过 rethrowExceptions 配置哪些异常直接抛出。

示例:

java 复制代码
        DefaultToolExecutionExceptionProcessor exceptionProcessor = DefaultToolExecutionExceptionProcessor.builder()
                .rethrowExceptions(List.of(ServiceException.class)) // ServiceException 直接抛出
                .build();

        ReactAgent chatAgent = ReactAgent.builder()
                .name("my-agent")
                .toolExecutionExceptionProcessor(exceptionProcessor)
                .model(zhiPuAiChatModel)
                .methodTools(new WeatherTool())
                //.interceptors(toolEmulatorInterceptor)
                .build();

        String text = chatAgent.call("查询长沙的天气情况").getText();
        System.out.println(text);

注意 :此时,抛出的是根异常,不是包装后的 ToolExecutionException

3.6 强制不抛出异常

ToolErrorInterceptor(错误处理拦截器)最简单的错误处理拦截器,捕获所有异常并返回错误消息,而非抛出异常中断 流程。

示例:

java 复制代码
        ToolErrorInterceptor toolErrorInterceptor = ToolErrorInterceptor.builder().build();

        DefaultToolExecutionExceptionProcessor exceptionProcessor = DefaultToolExecutionExceptionProcessor.builder()
                .alwaysThrow(false) // 总是抛出异常
                .rethrowExceptions(List.of(ServiceException.class)) // ServiceException 直接抛出
                .build();

        ReactAgent chatAgent = ReactAgent.builder()
                .name("my-agent")
                .toolExecutionExceptionProcessor(exceptionProcessor)
                .model(zhiPuAiChatModel)
                .methodTools(new WeatherTool())
                .interceptors(toolErrorInterceptor)
                .build();

        String text = chatAgent.call("查询长沙的天气情况").getText();
        System.out.println(text);

此时,无论是 ServiceExceptionToolExecutionExceptionException 都不会直接抛出异常:

java 复制代码
Caused by: com.example.aialibaba.config.ServiceException: 天气 API 调用失败
	at com.example.aialibaba.config.WeatherTool.getWeather(WeatherTool.java:29) ~[classes/:na]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
	at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
	at org.springframework.ai.tool.method.MethodToolCallback.callMethod(MethodToolCallback.java:185) ~[spring-ai-model-1.1.2.jar:1.1.2]
	... 118 common frames omitted


很抱歉,查询长沙天气时出现了技术问题,无法获取到天气信息。这可能是由于天气服务暂时不可用或网络连接问题导致的。

建议您可以:
1. 稍后再试查询
2. 使用其他天气应用或网站查看长沙的天气情况
3. 如果您需要其他帮助,我很乐意为您提供其他服务
相关推荐
xixixi777772 小时前
智算中心建设新范式:GPT-6/Rubin架构+1.6T光模块+量子安全网关+AI安全沙箱,算力·效率·安全·成本的最优平衡
人工智能·gpt·安全·机器学习·架构·大模型·通信
耿雨飞2 小时前
第五章:工具系统与函数调用 —— 从定义到执行的完整链路
人工智能·langchain
fzxwl2 小时前
集成MidScene的AI测试管理平台
人工智能
涵星同学2 小时前
从深度学习到大模型的跃迁:Transformer的核心突破
人工智能·深度学习·transformer
Magic-Yuan2 小时前
如何提高AI落地的成功率 - 成功率函数
大数据·人工智能
Zldaisy3d2 小时前
数字孪生与AI的共生将如何影响职业发展和企业竞争力
人工智能
ShiMetaPi2 小时前
NeurIPS 2024 | 丝滑视觉新极限:EPA 框架利用事件相机突破插帧伪影瓶颈
人工智能·嵌入式硬件·计算机视觉·自动驾驶·事件相机·evs
丶党玲儿2 小时前
AI-agent工程化(开源git分享)
人工智能·git·开源
code_li2 小时前
淘宝动效全链路解决方案:一次制作多端复用
网络·人工智能·电商·淘宝技术