Skip to content

Conversation

@sun-jin-xin
Copy link

@sun-jin-xin sun-jin-xin commented Dec 20, 2025

AgentScope-Java Version

1.0.4-SNAPSHOT

Description

Background

The group has long promoted the internalization of AI capabilities. Early business systems were built on a custom native agent framework, which hinders long-term iterative optimization and maintenance. To address this, we selected the lightweight AgentScope framework for system reconstruction. Notably, the business has strict requirements for high system throughput, and the current Hook event notification mechanism of ReActAgent has exposed prominent performance bottlenecks that cannot meet business needs:

  1. Redundant Repeated Sorting Overhead
    The getSortedHooks() method is invoked to re-sort the Hook list on every event trigger (e.g., PreReasoning, ReasoningChunk). In high-frequency scenarios (e.g., streaming models returning 100+ Chunks), this generates unnecessary CPU consumption and invalid computations, wasting system resources.

  2. Inefficient Synchronous Blocking Execution
    Hooks are executed sequentially through for loops combined with flatMap, which fails to leverage Reactor's asynchronous non-blocking advantages. This leads to linear latency growth as the number of Hooks increases, severely restricting concurrent processing capabilities.

Quantified Performance Limitations
These bottlenecks result in subpar system performance:

  • Streaming Chunk throughput is only 30 Chunk/sec
  • 10-round ReAct iteration response time exceeds 2000ms
  • Under high concurrency, CPU utilization reaches ~70% with a TPS of merely 40 req/sec
  • The above metrics fail to satisfy the business's high-throughput requirements

Optimization Objectives

  1. Eliminate redundant Hook re-sorting overhead to reduce CPU usage in high-frequency event scenarios and improve resource utilization.
  2. Implement asynchronous sequential execution of Hooks (while preserving priority order) to maximize Reactor's non-blocking performance and enhance event notification efficiency.
  3. Achieve preset performance targets to meet business high-throughput demands, while ensuring full backward compatibility without disrupting existing functionalities.

Key Implementation Changes

1. Pre-Sorting and Caching of Hook List (Eliminate Redundant Sorting)

  • Added a private, immutable member variable sortedHooks in ReActAgent to cache the pre-sorted Hook list, avoiding repeated sorting during subsequent event notifications.
  • In the ReActAgent constructor, the Hook list is sorted once by priority (ascending order: lower priority indicates earlier execution) via Stream API, and collected into an unmodifiable list to ensure cache immutability and thread safety.
  • Removed all redundant calls to getSortedHooks() in Hook notification methods, and uniformly used the cached sortedHooks list to eliminate invalid CPU computations.

2. Asynchronous Sequential Execution of Hooks (Optimize Execution Efficiency)

  • Refactored all event notification methods in the inner HookNotifier class (including notifyPreReasoning, notifyPostReasoning, notifyPreActing, notifyReasoningChunk, etc.):
    • For scenarios requiring final event return (e.g., notifyPreReasoning): Adopted Flux.reduce to implement asynchronous sequential execution, ensuring Hook priority order while leveraging Reactor's non-blocking capabilities.
    • For fire-and-forget scenarios (e.g., notifyReasoningChunk, notifyActingChunk): Used Flux.concatMap to guarantee execution order and improve asynchronous processing throughput.
  • Replaced the original for loop + sequential flatMap synchronous blocking logic with reactive stream processing, reducing thread blocking time and improving concurrent processing performance.

3. Compatibility and Standardization Optimization

  • Retained the original Hook priority execution order and event processing logic, with no modifications to external APIs, enabling seamless upgrade for existing business systems.
  • Completed Javadoc comments for the newly added sortedHooks variable and all refactored methods, complying with the project's documentation conventions.
  • Formatted the code with mvn spotless:apply to align with the project's coding style requirements.

Test Plan for This PR

To fully verify the performance improvement and functional stability of the optimization, the following multi-layered test plan is executed:

1. Micro-Benchmark Test (Isolated Hook Notification Performance)

  • Tool: JMH (Java Microbenchmark Harness)
  • Test Target: Core Hook notification methods (e.g., HookNotifier.notifyPreReasoning())
  • Test Steps:
    1. Develop a JMH benchmark class to simulate 10 Hooks with different priorities and 10 test messages.
    2. Run the benchmark to compare the average latency and throughput of Hook notifications before and after optimization.
  • Verification Criteria: Average latency reduced by ≥30%; throughput increased by ≥20%.

2. Integration Test (End-to-End Agent Performance)

  • Tool: JUnit 5 + Reactor Test
  • Test Scenarios:
    1. Multi-Hook Scenario: Integrate 5 core Hooks (RAG + Long-Term Memory + Plan + Structured Output + Custom Hook) to test the 10-round ReAct iteration response time.
    2. Streaming Output Scenario: Simulate a model returning 100 Chunks to test Chunk processing throughput.
  • Verification Criteria:
    1. 10-round ReAct iteration response time reduced by ≥15%.
    2. Streaming Chunk throughput increased by ≥25%.

3. High Concurrency Pressure Test (System-Level Throughput)

  • Tool: Gatling
  • Test Steps:
    1. Package the ReActAgent as an HTTP interface based on Spring Boot.
    2. Simulate 100 concurrent users for continuous 3-minute requests.
    3. Compare TPS, P95/P99 response time, and CPU utilization before and after optimization.
  • Verification Criteria:
    1. TPS increased by ≥20%.
    2. P95 response time reduced by ≥30%.
    3. CPU utilization reduced by ≥10% under the same concurrency.

4. Functional Compatibility Test (Prevent Regression)

  • Execute all existing unit tests via mvn test to ensure 100% test case pass rate.
  • Manually verify core Hook-dependent functionalities (structured output, RAG retrieval, long-term memory storage) to confirm no functional regression.

Checklist

  • Code has been formatted with mvn spotless:apply
  • All tests are passing (mvn test)
  • Javadoc comments are complete and follow project conventions
  • Related documentation has been updated (e.g., links, examples, etc.)
  • Code is ready for review

@sun-jin-xin sun-jin-xin requested a review from a team December 20, 2025 05:12
@cla-assistant
Copy link

cla-assistant bot commented Dec 20, 2025

CLA assistant check
All committers have signed the CLA.

@cla-assistant
Copy link

cla-assistant bot commented Dec 20, 2025

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@sun-jin-xin sun-jin-xin changed the title feat(hook): Hook notifier optimize feat(hook): Hook notifier optimize(#266) Dec 20, 2025
@codecov
Copy link

codecov bot commented Dec 20, 2025

Codecov Report

❌ Patch coverage is 89.28571% with 3 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...e/src/main/java/io/agentscope/core/ReActAgent.java 89.28% 3 Missing ⚠️

📢 Thoughts on this report? Let us know!

@sun-jin-xin sun-jin-xin requested a review from AlbumenJ December 20, 2025 11:04
@sun-jin-xin sun-jin-xin requested a review from AlbumenJ December 22, 2025 17:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants