The AgentScope Middleware System provides a powerful interception mechanism that allows developers to modify agent behavior without altering the core agent source code. It follows a modular design where middlewares are hooked into specific points of the agent's execution lifecycle, such as model calls, tool execution, and context management.
AgentScope utilizes two primary patterns for its middleware pipeline:
next_handler, which represents the next middleware in the chain or the final core logic src/agentscope/middleware/_base.py19-25on_system_prompt hook, where the system prompt string is passed through a sequential pipeline of transformations src/agentscope/middleware/_base.py27-28Middlewares can implement any of the following 7 hook points defined in MiddlewareBase src/agentscope/middleware/_base.py13-29:
| Hook Name | Purpose | Data Flow |
|---|---|---|
on_reply | Intercepts the entire Agent.reply process. | AsyncGenerator[AgentEvent | Msg] |
on_reasoning | Wraps the reasoning/LLM inference phase. | AsyncGenerator |
on_acting | Wraps individual tool execution (toolkit.call_tool). | AsyncGenerator[ToolChunk | ToolResponse] |
on_model_call | Intercepts raw Model API calls. | AsyncGenerator[ChatResponse] |
on_check_permission | Intercepts the permission engine decision. | Awaitable[PermissionDecision] |
on_compress_context | Wraps the context compression logic. | AsyncGenerator |
on_system_prompt | Transforms the system prompt string. | str -> str |
When an Agent is initialized, it filters the provided list of middlewares by the hooks they implemented. This optimization ensures that only relevant middlewares are invoked at each hook point src/agentscope/middleware/_base.py30-31
The following diagram illustrates how a middleware chain wraps the core agent logic (e.g., _reply_impl) using the Onion pattern.
Title: Middleware Execution Pipeline (Onion Pattern)
Sources: src/agentscope/middleware/_base.py13-53 src/agentscope/middleware/_base.py68-95
MiddlewareBase ClassAll middlewares must inherit from MiddlewareBase. It provides an is_implemented utility to check if a subclass has overridden a specific hook by comparing the subclass method to the base class method src/agentscope/middleware/_base.py55-66
Middlewares are executed asynchronously. For generator-based hooks (like on_reply), the middleware must iterate over the next_handler() (often using async for or anext) and yield the items to maintain the stream src/agentscope/middleware/_base.py40-45 src/agentscope/middleware/_tracing/_trace.py206-213
The Agent class manages the execution of these hooks. The middleware system automatically detects which hooks are implemented at runtime src/agentscope/middleware/_base.py30-31
Title: Association of Middleware Hooks to Agent Internals
Sources: src/agentscope/middleware/_base.py13-29 src/agentscope/middleware/_base.py68-175
AgentScope provides several built-in middlewares for common agentic tasks:
TracingMiddleware)Uses OpenTelemetry (OTel) to trace agent execution. It captures attributes like gen_ai.conversation.id, model usage (tokens), and tool execution details src/agentscope/middleware/_tracing/_trace.py117-132 It hooks into on_reply, on_model_call, and on_acting to provide a complete view of the agent's lifecycle src/agentscope/middleware/_tracing/_trace.py137-206 It also handles synthetic spans for externally executed tools src/agentscope/middleware/_tracing/_trace.py174-197
ReplyBudgetControlMiddleware)Monitors and enforces token or financial budgets for an agent's reply. It hooks into on_reply to track usage and control the reasoning-acting loop src/agentscope/middleware/_budget.py
TTSMiddleware)Integrates Text-to-Speech capabilities. It intercepts the on_reply stream, collects TextBlockDeltaEvent and TextBlockEndEvent items, and sends them to a TTSModelBase to generate audio content src/agentscope/middleware/_tts_middleware.py21-39 The audio is injected back into the stream as DataBlockDeltaEvent src/agentscope/middleware/_tts_middleware.py174-179 It supports both real-time streaming input and non-realtime synthesis src/agentscope/middleware/_tts_middleware.py67-109
Middlewares provide various strategies for persistent agent memory src/agentscope/middleware/_longterm_memory/__init__.py8-12:
RAGMiddleware)Connects an agent to a KnowledgeBase. It typically hooks into on_reply or on_reasoning to perform retrieval before the model is called src/agentscope/middleware/_rag.py
AGUIProtocolMiddleware)A specialized middleware used in the Agent Service layer (FastAPI). It intercepts text/event-stream responses and converts standard AgentEvent objects into the AGUI protocol format (e.g., converting ReplyStartEvent to RUN_STARTED) for consumption by the Web UI src/agentscope/app/middleware/_protocol/_agui.py44-74 src/agentscope/app/middleware/_protocol/_base.py68-81
Sources:
Refresh this wiki