Why ReActAgent Beats a Single LLM Call: Reasoning + Acting Loop Explained
The article breaks down the ReAct reasoning‑acting loop that powers AgentScope's ReActAgent, details its builder parameters, and compares the synchronous call() method with the streaming stream() approach, showing when each should be used for backend processing or interactive UI.
1. ReAct = Reasoning While Acting
Traditional QA follows a "ask once, answer once" pattern, whereas ReAct alternates Reasoning and Acting . The model first thinks (e.g., "I need the weather"), then acts by invoking a tool, observes the tool's result, and repeats until a final answer is produced. This loop enables agents to decompose tasks, call tools, and dynamically adjust based on intermediate results. The official diagram (shown below) visualises the cycle, which runs up to maxIters times (default 10) to avoid infinite loops.
2. Constructing a ReActAgent – Full Parameter Overview
name(required): the agent’s identifier. model (required): the large language model to use. sysPrompt: system prompt that defines persona and rules. toolkit: toolbox of tools (covered in Day 4). maxIters: maximum reasoning iterations, default 10. stateStore / defaultSessionId: state persistence (Day 5). hooks: hooks before/after Reasoning, Acting, and Summary. modelExecutionConfig / toolExecutionConfig: timeout and retry settings for model and tool calls.
3. call() : Get the Complete Reply at Once
The simplest invocation blocks until the model finishes and returns a Mono<Msg>. After calling .block(), getTextContent() extracts the text. This method is suited for backend batch jobs or internal services where real‑time display is unnecessary, but the user experiences a noticeable wait for long responses.
ReActAgent agent = ReActAgent.builder()
.name("Assistant")
.sysPrompt("你是一个简洁的助手。")
.model("dashscope:qwen-plus")
.toolkit(new Toolkit())
.build();
Msg response = agent.call(new UserMessage("你好,用一句话自我介绍")).block();
System.out.println(response.getTextContent());4. stream() : Incremental Token‑by‑Token Output
stream()returns a Flux<Event>. Each event carries either a REASONING chunk, a TOOL_RESULT, or a HINT. By configuring StreamOptions, developers can select which event types to receive, enable incremental delivery, and include reasoning tokens for a type‑writer effect.
Toolkit toolkit = new Toolkit(); // register tools in Day 4
ReActAgent agent = ReActAgent.builder()
.name("StreamingAgent")
.sysPrompt("你是一个带数学工具的助手。")
.model(DashScopeChatModel.builder()
.apiKey(System.getenv("DASHSCOPE_API_KEY"))
.modelName("qwen-max")
.stream(true)
.formatter(new DashScopeChatFormatter())
.build())
.toolkit(toolkit)
.build();
StreamOptions opts = StreamOptions.builder()
.eventTypes(EventType.REASONING, EventType.TOOL_RESULT)
.incremental(true)
.includeReasoningChunk(true)
.build();
agent.stream(List.of(new UserMessage("3 乘以 7 等于几?")), opts, null)
.doOnNext(event -> {
if (event.getType() == EventType.REASONING && !event.isLast()) {
System.out.print(event.getMessage().getTextContent());
} else if (event.getType() == EventType.TOOL_RESULT && event.isLast()) {
System.out.println("
[工具结果] " + event.getMessage().getTextContent());
}
})
.blockLast();5. Choosing Between call() and stream()
Return type : call() → Mono<Msg>; stream() → Flux<Event>.
Experience : call() waits for the full response; stream() delivers tokens/events in real time.
Suitable scenarios : call() for batch processing or internal APIs; stream() for chat UIs, Web SSE, or long replies where users benefit from incremental display.
Text extraction : call() uses resp.getTextContent(); stream() requires aggregating events.
In short: use stream() for human‑facing interfaces and call() for programmatic consumption.
6. Day 3 Summary
ReAct loop: Reason → Act → Observe repeats until an answer is formed. maxIters defaults to 10 to prevent endless loops. call() returns a complete Msg synchronously – simple but blocks. stream() (or streamEvents()) yields a Flux<Event> for incremental output.
Event types: REASONING, TOOL_RESULT, HINT. StreamOptions controls which events appear and whether they are incremental.
Next up (Day 4) will show how to equip the Act step with custom tools using the @Tool annotation and explore permission control via ToolBase.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Tech Ocean
Focused on AI programming, sharing ready-to-use development efficiency solutions.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
