1、标题: 在 AgentScope 1.0.9 中 Toolkit#setChunkCallback 没有触发回调
2、Bug描述
在 AgentScope 1.0.9 中,通过Toolkit#setChunkCallback,设置的 callback 在 tool 执行时没有被触发。
Tool 可以正常执行,但 callback 函数不会被调用。
3、To Reproduce(如何复现)
public class DemoToolService {
@Tool(description = "生成数据")
public ToolResultBlock generate(@ToolParam(name = "count") int count, ToolEmitter emitter) { // 自动注入,无需 @ToolParam
for (int i = 0; i < count; i++) {
emitter.emit(ToolResultBlock.text("进度 " + i));
}
return ToolResultBlock.text("完成");
}
}
public class ToolEmitterChunkCallBack implements BiConsumer<ToolUseBlock, ToolResultBlock> {
@Override
public void accept(ToolUseBlock toolUseBlock, ToolResultBlock toolResultBlock) {
System.out.println(toolUseBlock.getName());
System.out.println(toolUseBlock.getContent());
System.out.println(toolResultBlock.getOutput());
}
}
public class ToolEmitterDemo {
public static void main(String[] args) {
DashScopeChatModel chatModel = DashScopeChatModel.builder()
.apiKey(System.getenv("DASH_SCOPE_API_KEY"))
.modelName("qwen3-max")
.build();
Toolkit toolkit = new Toolkit();
toolkit.registerTool(new WeatherToolService());
toolkit.setChunkCallback(new ToolEmitterChunkCallBack());
ReActAgent agent = ReActAgent.builder()
.name("Assistant")
.sysPrompt("你是一个有帮助的 AI 助手。")
.model(chatModel)
.toolkit(toolkit)
.build();
// 创建用户消息
Msg userMsg = Msg.builder().textContent("生成3个数据").build();
// 调用智能体
Mono<Msg> msgMono = agent.call(userMsg);
// 阻塞等待回复
Msg response = msgMono.block();
// 打印回复
System.out.println(response.getTextContent());
}
}
运行结果
ToolEmitterChunkCallBack never prints
4、Expected behavior(期望行为)
当 tool 执行时,setChunkCallback 设置的 callback 应该被触发,用于接收 tool 的执行过程信息。
generate {"count": 3} [进度 0]
generate {"count": 3} [进度 1]
generate {"count": 3} [进度 2]
5、 Environment(运行环境)
AgentScope Version: 1.0.9
Java Version: 21
OS: macOS
Model: DashScope qwen3-max
5.1、Maven 配置
<dependencies>
<dependency>
<groupId>io.agentscope</groupId>
<artifactId>agentscope</artifactId>
<version>1.0.9</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.4.14</version>
</dependency>
</dependencies>
6、Additional context(额外信息)
agentscope:1.0.8 可正常回调执行
7、Root Cause
step1: 入口执行
执行 Msg response = msgMono.block();
随后进入:ReActAgent#acting
Step 2:注册 ChunkCallback
toolkit.setChunkCallback((toolUse, chunk) -> notifyActingChunk(toolUse, chunk).subscribe());
调用链如下:
ReActAgent#acting
↓
Toolkit#setChunkCallback
↓
ToolExecutor#setChunkCallback
最终 callback 被保存到 ToolExecutor 中:
private BiConsumer<ToolUseBlock, ToolResultBlock> chunkCallback;
Step 3:Tool 执行时创建 ToolEmitter
在 ToolExecutor#executeCore 中执行工具时,会创建 ToolEmitter:
ToolEmitter toolEmitter = new DefaultToolEmitter(toolCall, chunkCallback);
随后构造执行参数:
ToolCallParam executionParam =
ToolCallParam.builder()
.toolUseBlock(toolCall)
.input(mergedInput)
.agent(param.getAgent())
.context(finalContext)
.emitter(toolEmitter)
.build();
toolEmitter 被传递到 tool 执行流程中。
Step 4:ToolEmitter 自动注入到 Tool 方法
在 ToolMethodInvoker#invokeAsync 中,如果 Tool 方法声明了 ToolEmitter 参数,会自动注入:
if (param.getType() == ToolEmitter.class) {
args[i] = emitter;
}
Step 5:callback 触发依赖 ToolEmitter.emit()
真正触发 callback 的逻辑在:DefaultToolEmitter#emit
public void emit(ToolResultBlock chunk) {
if (chunkCallback != null && chunk != null) {
chunkCallback.accept(toolUseBlock, chunk);
}
}
此时:并非设置chunkCallback
1、标题: 在 AgentScope 1.0.9 中
Toolkit#setChunkCallback没有触发回调2、Bug描述
在 AgentScope 1.0.9 中,通过Toolkit#setChunkCallback,设置的 callback 在 tool 执行时没有被触发。
Tool 可以正常执行,但 callback 函数不会被调用。
3、To Reproduce(如何复现)
运行结果
4、Expected behavior(期望行为)
5、 Environment(运行环境)
5.1、Maven 配置
6、Additional context(额外信息)
agentscope:1.0.8 可正常回调执行
7、Root Cause
step1: 入口执行
Step 2:注册 ChunkCallback
Step 3:Tool 执行时创建 ToolEmitter
Step 4:ToolEmitter 自动注入到 Tool 方法
Step 5:callback 触发依赖 ToolEmitter.emit()