ReAct Sub Agent
ReAct Sub Agents are currently in beta and are available starting from Rasa 3.14.0.
ReAct sub agents are built-in autonomous agents that can dynamically utilize MCP (Model Context Protocol) tools and custom tools defined in Python code to complete tasks. They operate in a ReAct loop, choosing which tools to invoke based on the ongoing conversation context.
Two types of ReAct sub agents are currently supported:
- General-purpose ReAct Sub Agent: Handles open-ended tasks and requires explicit completion signaling
- Task-specific ReAct Sub Agent: Focuses on filling specific slots with automatic completion based on exit conditions
General-purpose ReAct Sub Agent
A general-purpose ReAct sub agent is designed for open-ended, exploratory tasks where the agent itself determines when the task is complete.
Unlike task-specific agents that have predefined exit conditions, general-purpose agents require explicit completion signaling through a built-in task_completed
tool.
Key Characteristics
- Open-ended tasks: Handles exploratory conversations and complex, multi-step tasks
- Autonomous completion: The agent decides when it has fully completed its assigned task
- Explicit signaling: Uses the built-in
task_completed
tool to signal completion - No exit conditions: Invoked via autonomous call steps without exit conditions
The task_completed
Tool
General-purpose ReAct sub agents have access to a built-in task_completed
tool that serves as the explicit completion mechanism. This tool is automatically available to all general-purpose ReAct sub agents and cannot be disabled.
Tool Definition
{
"type": "function",
"function": {
"name": "task_completed",
"description": "Signal that the MCP agent has FULLY completed its primary task. Once you have presented your findings, follow-up with a message summarizing the completed task in a comprehensive and well-written manner. Avoid repeating information already provided in the conversation.",
"parameters": {
"type": "object",
"properties": {
"message": {
"type": "string",
"description": "A message describing the completed task."
}
},
"required": ["message"],
"additionalProperties": false
},
"strict": true
}
}
How Completion Works
- Agent Decision: The ReAct sub agent autonomously determines when it has completed its assigned task.
- Tool Call: When ready to complete, the ReAct sub agent calls the
task_completed
tool with a summary message. - Completion Signal: The tool call immediately terminates the ReAct sub agent's execution loop.
- User Response: The message provided to the tool is sent to the user as the final response.
- Control Return: Control returns to the main flow, which can then proceed to the next step.
Task-specific ReAct Sub Agent
A task-specific ReAct sub agent is designed for structured data collection tasks where specific slots need to be filled with values. Unlike general-purpose agents that determine their own completion, task-specific agents automatically complete when predefined exit conditions are met, making them ideal for appointment booking, form filling, or data collection scenarios.
Key Characteristics
- Structured data collection: Focuses on filling specific slots with values.
- Automatic completion: Completes when exit conditions are satisfied.
- Built-in slot tools: Automatically gets
set_slot_<slot_name>
tools for each slot in exit conditions. - Exit condition driven: Invoked via autonomous call steps with
exit_if
conditions.
The set_slot_<slot_name>
Tools
Task-specific ReAct sub agents automatically receive built-in set_slot_<slot_name>
tools for each slot mentioned in the exit_if
conditions. These tools are dynamically generated based on the slot definitions and cannot be disabled.
Tool Generation
For each slot in the exit conditions, a tool is created with the following pattern:
- Tool name:
set_slot_<slot_name>
(e.g.,set_slot_user_name
,set_slot_appointment_date
) - Dynamic description: Includes slot type and allowed values (for categorical slots)
- Slot-specific parameters: Tailored to the slot's data type and constraints
Example Tool Definition
For a slot named user_name
of type text
:
{
"type": "function",
"function": {
"name": "set_slot_user_name",
"description": "Set the slot 'user_name' to a specific value. The slot type is text.",
"parameters": {
"type": "object",
"properties": {
"slot_value": {
"type": "string",
"description": "The value to assign to the slot."
}
},
"required": ["slot_value"],
"additionalProperties": false
},
"strict": true
}
}
For a slot named category
of type categorical
with allowed values ["A", "B", "C"]
:
{
"type": "function",
"function": {
"name": "set_slot_category",
"description": "Set the slot 'category' to a specific value. The slot type is categorical. The allowed values are: ['A', 'B', 'C'].",
"parameters": {
"type": "object",
"properties": {
"slot_value": {
"type": "string",
"description": "The value to assign to the slot."
}
},
"required": ["slot_value"],
"additionalProperties": false
},
"strict": true
}
}
How Slot Setting Works
- Tool Availability: The ReAct sub agent automatically receives
set_slot_<slot_name>
tools for all slots mentioned in theexit_if
conditions. - Value Assignment: When the ReAct sub agent calls a
set_slot_<slot_name>
tool, the slot value is immediately updated. - Condition Evaluation: After each slot update, the system checks if all exit conditions are satisfied.
- Automatic Completion: Once all exit conditions are met, the ReAct sub agent automatically completes without sending a response.
- Control Return: Control returns to the main flow, which can proceed to the next step.
Configuration
ReAct sub agents extend the basic sub agent configuration with additional settings.
In addition to the required agent
section, ReAct sub agents support the following configuration options:
# Basic agent information (required - see overview)
agent:
name: stock_explorer
protocol: RASA # Optional: protocol for agent connections, default is 'RASA'
description: "Agent that helps users research and analyze stock options"
# ReAct-specific configuration
configuration:
llm: # Optional: Same format as other Rasa LLM configs
model-group: openai-gpt-4o
prompt_template: sub_agents/stock_explorer/prompt_template.jinja2 # Optional: prompt template file
timeout: 30 # Optional: seconds before timing out
max_retries: 3 # Optional: connection retry attempts
module: "path.to.custom.module" # Optional: custom module for sub agent customization
# MCP server connections
connections:
mcp_servers:
- name: trade_server
include_tools: # Optional: specify which tools to include
- find_symbol
- get_company_news
- apply_technical_analysis
- fetch_live_price
exclude_tools: # Optional: tools to exclude
- place_buy_order
- view_positions
Configuration Section
The configuration
section is optional in the ReAct sub agent's config.yml
file and provides additional customization options for LLM and connection settings.
-
configuration.llm
: Defines which Large Language Model (LLM) powers the ReAct sub agent's reasoning and tool use. The configuration format matches the standard used for other Rasa LLM settings. For more information, refer to the LLM Configuration documentation. If not specified, GPT-4o is used as the default LLM. -
configuration.prompt_template
: Path to a Jinja2 template for customizing the prompt of this ReAct sub agent. By default, it uses the built-in intelligent ReAct prompt that incorporates conversation history, sub agent instructions, and tool access. -
configuration.timeout
: Specifies how many seconds to wait before timing out autonomous sub agent execution. There is no timeout by default. -
configuration.max_retries
: Number of retry attempts if MCP server connection fails. The default is 3 attempts.
Connections Section
The connections
section is mandatory for ReAct sub agents and specifies which MCP servers the ReAct sub agent should connect to. MCP servers are configured in your endpoints.yml
file. For more details, see the MCP Server Integration page.
connections.mcp_servers
(required): A list of one or more MCP servers that this ReAct agent connects to. At least one MCP server must be specified, and each server configuration follows this structure:name
(required): Name to reference this MCP server- Tool Filtering (optional):
include_tools
: List of specific MCP tools available to this sub agentexclude_tools
: List of tools to explicitly hide from this sub agent (useful for restricting certain actions)
For each MCP server, you can define which tools to include or exclude. The include_tools
and exclude_tools
parameters are mutually exclusive.
Customization
ReAct sub agents can be customized in two ways:
Modifying the Prompt Template
You can customize the prompt template of the sub agent to:
- Include any logic for how the sub agent should operate.
- Pass extra context via slots. You can mention any slot in the prompt template via the
slots
namespace, for example:{{ slots.time }}
.
The modified prompt template can be specified in the sub agent's configuration.
Default Prompt Templates
- General-purpose ReAct sub agent
- Task-specific ReAct sub agent
You are a helpful assistant that should assist the user in the best possible way.
### Task
{{ description }}
### Instructions
* Always make sure to output responses to the user in a clear, helpful format.
* Always avoid asking multiple questions at once. Ask questions sequentially one at a time and wait for the user's response before proceeding to next question.
* Always avoid making assumptions about what values to pass into tools. Ask for clarification if a user's request is ambiguous.
* Once your task is completed, you must always call the `task_completed` tool to signal that you have finished assisting the user. Do not end the conversation or indicate completion without the `task_completed` tool call.
* Strictly avoid making up information or ability to take some action which is not available in `tool` provided.
### Conversation history
{{ conversation_history }}
You are a helpful assistant that should assist the user in the best possible way.
### Description of your capabilities
{{ description }}
### Task
* Use the tools available to gather the required information to set the following slots: {{ slot_names }}.
* In order to set the slot values, use the `set_slot_<slot_name>` tool.
### Instructions
* Always make sure to output responses to the user in a clear, helpful format.
* Always avoid asking multiple questions at once. Ask questions sequentially one at a time and wait for the user's response before proceeding to next question.
* Always avoid making assumptions about what values to pass into tools. Ask for clarification if a user's request is ambiguous.
* Strictly avoid making up information or ability to take some action which is not available in `tool` provided.
### Conversation history
{{ conversation_history }}
Customizing the Runtime Engine
Runtime customization for ReAct sub agents — whether general-purpose or task-specific — follows the same pattern. You extend the appropriate abstract base class and override the available customization hooks.
- General-purpose ReAct Sub Agent
- Task-specific ReAct Sub Agent
To create a custom general-purpose ReAct sub agent, inherit from MCPOpenAgent
and override methods to modify behavior such as tool definitions or input/output processing:
from rasa.agents.protocol.mcp.mcp_open_agent import MCPOpenAgent
from rasa.agents.schemas import (
AgentInput,
AgentOutput,
AgentToolResult,
AgentToolSchema,
)
class StockAnalysisAgent(MCPOpenAgent):
def get_custom_tool_definitions() -> List[Dict[str, Any]]:
...
async def process_input(self, output: AgentInput) -> AgentInput:
...
async def process_output(self, output: AgentOutput) -> AgentOutput:
...
To create a custom task-specific ReAct sub agent, inherit from MCPTaskAgent
and override methods to modify behavior such as tool definitions or input/output processing:
from rasa.agents.protocol.mcp.mcp_task_agent import MCPTaskAgent
from rasa.agents.schemas import (
AgentInput,
AgentOutput,
AgentToolResult,
AgentToolSchema,
)
class AppointmentBookingAgent(MCPTaskAgent):
def get_custom_tool_definitions() -> List[Dict[str, Any]]:
...
async def process_input(self, output: AgentInput) -> AgentInput:
...
async def process_output(self, output: AgentOutput) -> AgentOutput:
...
Once implemented, the custom sub agent class can be referenced directly in the ReAct sub agent's configuration:
# Basic sub agent information
agent:
...
# Core configuration
configuration:
module: # path to the python class containing the customizations
Adding custom tools
You can add custom tools that are independent of the MCP server but essential for the sub agent to accomplish its task.
To define a custom tool, implement it as a Python function, for example:
async def _recommend_cars(
self, arguments: Dict[str, Any]
) -> AgentToolResult:
# your function implementation
Note: The arguments
parameter for the function will be provided as a dictionary. Extract any required values for your tool from this dictionary.
Tool executors are asynchronous. Do not use blocking calls (e.g. time.sleep
, synchronous HTTP clients like requests
, long-running CPU-bound loops) inside them. Prefer non-blocking alternatives (e.g. await asyncio.sleep(...)
, httpx.AsyncClient
, database drivers with async support), or run CPU-bound work in an executor via asyncio.to_thread
.
The function must always return an instance of AgentToolResult
, which includes the following fields:
class AgentToolResult(BaseModel):
tool_name: str
result: Optional[str] = None
is_error: bool = False
error_message: Optional[str] = None
To add custom tools, implement the get_custom_tool_definitions
method. This method should return a list of tool definitions, each adhering to the OpenAI function calling specification. Additionally, each tool definition must include a tool_executor
key, which should reference the function to execute when the tool is invoked:
{
"type": "function",
"function": {
"name": "recommend_cars",
"description": "Analyze search results and return structured car recommendations",
"parameters": {
"type": "object",
"properties": {
"search_results": {
"type": "string",
"description": "The search results to analyze for car recommendations",
},
"max_recommendations": {
"type": "integer",
"description": "Maximum number of recommendations to return",
"default": 3,
},
},
"required": ["search_results", "max_recommendations"],
"additionalProperties": False,
},
"strict": True,
},
"tool_executor": self._recommend_cars
}
Processing Input and Output
For information about customizing input and output processing, see the common customization section in the overview page.
Key Differences Between General-Purpose and Task-Specific ReAct Sub Agents
Category | General-Purpose | Task-Specific |
---|---|---|
Purpose | Open-ended exploratory conversations where the agent determines when it is done | Goal-oriented tasks that need to fill specific slots with values |
Completion | Requires calling a task_completed tool to finish its execution loop | Automatically completes when exit conditions are met |
Exit Conditions | Explicit signaling of completion via the task_completed tool | Completion determined by evaluating the exit_if conditions |
Built-in Slot Tools | No automatic slot-setting tools | Automatically gets set_slot_<slot_name> tools for each slot mentioned in the exit conditions |
Final Response | Sends a final response to the user via the task_completed tool | Completes silently without sending a response, allowing the flow to continue to the next step |