agentscope-ai / agentscope-ai/agentscope-java

[Bug]: 1.0.11 流式模式下 ToolUseBlock name 为 null

Abierto
#1,237 0 comentarios 0 reacciones 1 asignado Reclamado por @chickenlj Ver en GitHub
area/core/model bug
Lenguaje dominante
Java
Estrellas
5.6k
Forks
1.3k
Merge medio
4 d 12 h
PR fusionados (30 d)
77

Descripción

## 问题描述
Java 使用 AgentScope 1.0.11 + 非 OpenAI 模型(如 Qwen3-14b)开启流式响应(`stream=true`)时,ReAct Agent 执行 MCP 工具调用后,日志中持续输出以下警告且agent无法调用mcp且无法正常返回响应给客户端, 设置 `agent.stream=false`后问题消失。

```plain
WARN i.a.c.f.o.OpenAIMessageConverter - ToolUseBlock has null id or name, skipping
```

## 影响范围
+ **功能影响**:agent无法调用mcp且无法正常返回响应给客户端
+ **日志噪音**:每轮 ReAct 迭代重复打印 WARN
+ **潜在风险**:被丢弃的 ToolUseBlock 不会出现在发给模型的对话历史中,可能影响模型对上下文的理解

## 根因定位
**缺陷位置**:`io.agentscope.core.agent.accumulator.ToolCallsAccumulator.ToolCallBuilder#build()`

### 调用链路
1. LLM(Qwen3, stream)返回流式 chunk,部分 chunk 不携带 `function.name`
2. `OpenAIResponseParser.parseChunkResponse()` 将 name 为 null 的 chunk 设为空串 `""`,创建 fragment ToolUseBlock(`name="__fragment__"`)
3. `ToolCallsAccumulator.ToolCallBuilder.merge()` 判断 `"__fragment__"` 为 placeholder,跳过赋值
4. `ToolCallBuilder.name` 始终为初始值 `null`
5. `ToolCallBuilder.build()` 生成 `ToolUseBlock(id=generated, name=null)`
6. `ReasoningContext.buildFinalMessage()` 将该 ToolUseBlock 存入 Memory 的 assistant Msg
7. 下一轮迭代 `OpenAIMessageConverter.convertAssistantMessage()` 检测到 `name==null`,打印 WARN 并跳过

### 代码缺陷
`ToolCallBuilder.build()` 对 `toolId` 做了 null 兜底(生成合成 ID),但对 `name` 没有做任何兜底处理,直接透传了可能为 null 的字段:

```plain
// ToolCallBuilder.build() 反编译还原
ToolUseBlock.builder()
.id(toolId != null ? toolId : generateId()) // ✅ 有兜底
.name(name) // ❌ 无兜底,可为 null
.input(mergedArgs)
.build();
```

## 临时规避
```plain
agent:
stream: false
```

Guía de contribución

Abrir la guía de contribución

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.