From 1aa2fe0550856619059c0e280b3b0315b3d7ee01 Mon Sep 17 00:00:00 2001 From: zhanghangwei Date: Tue, 10 Feb 2026 11:42:35 +0800 Subject: [PATCH] =?UTF-8?q?fix(767):=20=E6=94=AF=E6=8C=81=E8=AE=BE?= =?UTF-8?q?=E7=BD=AE=E7=94=9F=E6=88=90=E9=80=89=E9=A1=B9=E4=BC=A0=E9=80=92?= =?UTF-8?q?=E7=BB=99=E6=A8=A1=E5=9E=8B=E4=BB=A5=E4=BE=BF=E8=B7=9F=E8=B8=AA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在ReActAgent中添加generateOptions字段,用于配置生成参数(温度、topP、最大token等) - 更新buildGenerateOptions方法,将modelExecutionConfig与generateOptions合并 - 在预推理事件通知中包含生成选项以丰富事件信息 - 在Builder中新增generateOptions设置方法,支持链式调用 - 添加单元测试,验证生成选项正确传递给模型并在调用中生效 --- .../java/io/agentscope/core/ReActAgent.java | 35 +++++++++++++++---- .../agentscope/core/agent/ReActAgentTest.java | 29 +++++++++++++++ 2 files changed, 58 insertions(+), 6 deletions(-) diff --git a/agentscope-core/src/main/java/io/agentscope/core/ReActAgent.java b/agentscope-core/src/main/java/io/agentscope/core/ReActAgent.java index 2de490fa0..3622ded47 100644 --- a/agentscope-core/src/main/java/io/agentscope/core/ReActAgent.java +++ b/agentscope-core/src/main/java/io/agentscope/core/ReActAgent.java @@ -136,6 +136,7 @@ public class ReActAgent extends StructuredOutputCapableAgent { private final String sysPrompt; private final Model model; private final int maxIters; + private final GenerateOptions generateOptions; private final ExecutionConfig modelExecutionConfig; private final ExecutionConfig toolExecutionConfig; private final PlanNotebook planNotebook; @@ -157,6 +158,7 @@ private ReActAgent(Builder builder, Toolkit agentToolkit) { this.sysPrompt = builder.sysPrompt; this.model = builder.model; this.maxIters = builder.maxIters; + this.generateOptions = builder.generateOptions; this.modelExecutionConfig = builder.modelExecutionConfig; this.toolExecutionConfig = builder.toolExecutionConfig; this.planNotebook = builder.planNotebook; @@ -786,11 +788,14 @@ private List extractPendingToolCalls() { @Override protected GenerateOptions buildGenerateOptions() { - GenerateOptions.Builder builder = GenerateOptions.builder(); - if (modelExecutionConfig != null) { - builder.executionConfig(modelExecutionConfig); - } - return builder.build(); + // Build options with modelExecutionConfig (timeout, retry, etc.) + GenerateOptions executionOptions = + modelExecutionConfig != null + ? GenerateOptions.builder().executionConfig(modelExecutionConfig).build() + : null; + // Merge: user's generateOptions (temperature, topP, maxTokens, etc.) as base, + // executionOptions overrides executionConfig + return GenerateOptions.mergeOptions(executionOptions, generateOptions); } // ==================== Hook Notification Methods ==================== @@ -807,7 +812,8 @@ private Mono notifyHooks(T event) { } private Mono notifyPreReasoningEvent(List msgs) { - return notifyHooks(new PreReasoningEvent(this, model.getModelName(), null, msgs)); + return notifyHooks( + new PreReasoningEvent(this, model.getModelName(), buildGenerateOptions(), msgs)); } private Mono notifyPostReasoning(Msg msg) { @@ -977,6 +983,7 @@ public static class Builder { private Toolkit toolkit = new Toolkit(); private Memory memory = new InMemoryMemory(); private int maxIters = 10; + private GenerateOptions generateOptions; private ExecutionConfig modelExecutionConfig; private ExecutionConfig toolExecutionConfig; private final Set hooks = new LinkedHashSet<>(); @@ -1124,6 +1131,22 @@ public Builder enableMetaTool(boolean enableMetaTool) { return this; } + /** + * Sets the generation options for model API calls. + * + *

This configuration includes generation parameters such as temperature, topP, + * maxTokens, etc. When set, these options will be passed to the model and recorded + * in trace spans (e.g., gen_ai.request.temperature for OpenTelemetry). + * + * @param generateOptions The generation options (temperature, topP, maxTokens, etc.) + * @return This builder instance for method chaining + * @see GenerateOptions + */ + public Builder generateOptions(GenerateOptions generateOptions) { + this.generateOptions = generateOptions; + return this; + } + /** * Sets the execution configuration for model API calls. * diff --git a/agentscope-core/src/test/java/io/agentscope/core/agent/ReActAgentTest.java b/agentscope-core/src/test/java/io/agentscope/core/agent/ReActAgentTest.java index 46536c692..433b4a262 100644 --- a/agentscope-core/src/test/java/io/agentscope/core/agent/ReActAgentTest.java +++ b/agentscope-core/src/test/java/io/agentscope/core/agent/ReActAgentTest.java @@ -36,6 +36,7 @@ import io.agentscope.core.message.ToolUseBlock; import io.agentscope.core.model.ChatResponse; import io.agentscope.core.model.ChatUsage; +import io.agentscope.core.model.GenerateOptions; import io.agentscope.core.tool.Toolkit; import io.agentscope.core.util.JsonUtils; import java.time.Duration; @@ -101,6 +102,34 @@ void testInitialization() { assertTrue(agent.getMemory().getMessages().isEmpty(), "Memory should be empty initially"); } + @Test + @DisplayName("Should pass generateOptions (temperature, topP, maxTokens) to model for tracing") + void testGenerateOptionsPassedToModel() { + GenerateOptions options = + GenerateOptions.builder().temperature(0.7).topP(0.9).maxTokens(1000).build(); + + ReActAgent agentWithOptions = + ReActAgent.builder() + .name(TestConstants.TEST_REACT_AGENT_NAME) + .sysPrompt(TestConstants.DEFAULT_SYS_PROMPT) + .model(mockModel) + .toolkit(mockToolkit) + .memory(memory) + .generateOptions(options) + .build(); + + Msg userMsg = TestUtils.createUserMessage("User", TestConstants.TEST_USER_INPUT); + agentWithOptions + .call(userMsg) + .block(Duration.ofMillis(TestConstants.DEFAULT_TEST_TIMEOUT_MS)); + + GenerateOptions lastOptions = mockModel.getLastOptions(); + assertNotNull(lastOptions, "Model should receive GenerateOptions"); + assertEquals(0.7, lastOptions.getTemperature(), "Temperature should be passed to model"); + assertEquals(0.9, lastOptions.getTopP(), "TopP should be passed to model"); + assertEquals(1000, lastOptions.getMaxTokens(), "MaxTokens should be passed to model"); + } + @Test @DisplayName("Should generate simple text response") void testSimpleReply() {