标题
ToolResultBlock.error() 生成的错误前缀与 determineToolResultState() 检查的前缀不一致,导致工具超时/失败结果被标记为 SUCCESS
环境
版本:agentscope-core 2.0.0
MCP SDK:0.17.0
Java:21
问题描述
MCP 工具执行超时后,ToolExecutor 重试 2 次均失败,最终错误结果被标记为 state=SUCCESS 而非 state=ERROR,导致 Agent 推理循环无法感知工具失败。
根因
存在两条错误处理路径,使用了不同的错误前缀:
路径 A(正确):ReActAgent.buildErrorToolResult()(第 1750 行)
private static ToolResultBlock buildErrorToolResult(String toolId, String errorMessage) {
return ToolResultBlock.builder()
.id(toolId)
.output(List.of(TextBlock.builder().text("[ERROR] " + errorMessage).build()))
.build();
}
前缀:"[ERROR] " ✅ 能被 determineToolResultState() 识别
路径 B(有 Bug):ToolExecutor.executeWithInfrastructure()(第 399 行)
.onErrorResume(e -> {
String errorMsg = ExceptionUtils.getErrorMessage(e);
return Mono.just(ToolResultBlock.error("Tool execution failed: " + errorMsg));
});
ToolResultBlock.error()(第 206 行):
public static ToolResultBlock error(String errorMessage) {
return new ToolResultBlock(null, null,
List.of(TextBlock.builder().text("Error: " + errorMessage).build()),
null); // state = null
}
前缀:"Error: " ❌ 不能被 determineToolResultState() 识别
determineToolResultState()(第 2783 行):
if (text.startsWith("[ERROR]")) // 只检查 "[ERROR]"
return ToolResultState.ERROR;
return ToolResultState.SUCCESS; // 默认返回 SUCCESS
复现步骤
配置 MCP 工具(如高德地图 maps_weather),timeout 设为 30 秒
断开 MCP 服务连接(如 hosts 文件:127.0.0.1 mcp.amap.com)
发起对话触发工具调用
等待 3 次超时(约 90 秒)
观察日志:
text
WARN Retrying tool call 'maps_weather' (attempt 1/2) due to: Tool execution timeout after PT30S
WARN Retrying tool call 'maps_weather' (attempt 2/2) due to: Tool execution timeout after PT30S
INFO POST_ACTING | name=maps_weather, result_len=96, state=SUCCESS ← 应为 ERROR
标题
ToolResultBlock.error() 生成的错误前缀与 determineToolResultState() 检查的前缀不一致,导致工具超时/失败结果被标记为 SUCCESS
环境
版本:agentscope-core 2.0.0
MCP SDK:0.17.0
Java:21
问题描述
MCP 工具执行超时后,ToolExecutor 重试 2 次均失败,最终错误结果被标记为 state=SUCCESS 而非 state=ERROR,导致 Agent 推理循环无法感知工具失败。
根因
存在两条错误处理路径,使用了不同的错误前缀:
路径 A(正确):ReActAgent.buildErrorToolResult()(第 1750 行)
private static ToolResultBlock buildErrorToolResult(String toolId, String errorMessage) {
return ToolResultBlock.builder()
.id(toolId)
.output(List.of(TextBlock.builder().text("[ERROR] " + errorMessage).build()))
.build();
}
前缀:"[ERROR] " ✅ 能被 determineToolResultState() 识别
路径 B(有 Bug):ToolExecutor.executeWithInfrastructure()(第 399 行)
.onErrorResume(e -> {
String errorMsg = ExceptionUtils.getErrorMessage(e);
return Mono.just(ToolResultBlock.error("Tool execution failed: " + errorMsg));
});
ToolResultBlock.error()(第 206 行):
public static ToolResultBlock error(String errorMessage) {
return new ToolResultBlock(null, null,
List.of(TextBlock.builder().text("Error: " + errorMessage).build()),
null); // state = null
}
前缀:"Error: " ❌ 不能被 determineToolResultState() 识别
determineToolResultState()(第 2783 行):
if (text.startsWith("[ERROR]")) // 只检查 "[ERROR]"
return ToolResultState.ERROR;
return ToolResultState.SUCCESS; // 默认返回 SUCCESS
复现步骤
配置 MCP 工具(如高德地图 maps_weather),timeout 设为 30 秒
断开 MCP 服务连接(如 hosts 文件:127.0.0.1 mcp.amap.com)
发起对话触发工具调用
等待 3 次超时(约 90 秒)
观察日志:
text
WARN Retrying tool call 'maps_weather' (attempt 1/2) due to: Tool execution timeout after PT30S
WARN Retrying tool call 'maps_weather' (attempt 2/2) due to: Tool execution timeout after PT30S
INFO POST_ACTING | name=maps_weather, result_len=96, state=SUCCESS ← 应为 ERROR