External Sub Agent
External Sub Agents are currently in beta and are available starting from Rasa 3.14.0.
External sub agents connected via the A2A (Agent-to-Agent) protocol operate as autonomous entities that can handle complex, multi-turn conversations independently.
When invoked through a call
step in your flows, these agents take control of the conversation and interact with users until their task is complete.
A2A Protocol Connection
Rasa connects to external sub agents through the A2A (Agent-to-Agent) protocol, which provides a standardized way for different AI agents to communicate and collaborate. Here's how the connection process works:
Connection Process
-
Agent Card Resolution: Rasa first retrieves the external sub agent's capabilities by loading its agent card, which can be either:
- A local JSON file path
- A remote URL pointing to the agent card
-
Client Initialization: Rasa creates an A2A client configured with:
- Authentication credentials (if required)
- Supported transport protocols (JSON-RPC, HTTP JSON, gRPC)
- Streaming capabilities for real-time communication
- Timeout and retry settings
-
Health Check: Before establishing the connection, Rasa performs a health check by sending a test message to verify that the external sub agent is responsive and properly configured.
-
Message Exchange: Once connected, Rasa communicates with the external sub agent by:
- Sending user messages and conversation context
- Receiving responses and structured data
- Handling task status updates and completion signals
Supported Transport Protocols
The A2A protocol supports multiple transport mechanisms:
- JSON-RPC: Lightweight remote procedure calls over HTTP
- HTTP JSON: Simple HTTP-based JSON messaging
- gRPC: High-performance RPC framework with streaming support
Rasa automatically negotiates the best available transport protocol with the external sub agent during the connection process.
Authentication
External sub agents can require authentication for secure communication. Rasa supports various authentication methods including API keys, OAuth 2.0, and pre-issued tokens, which are configured in the exteranl sub agent's configuration file.
Best Practices
An A2A agent can respond with a Task
or a Message
.
Task
s should be used for long-running operations and Message
s for immediate responses.
Rasa maps all Message
objects to INPUT_REQUIRED
state, meaning the response is forwarded to the user while the external sub agent waits for input and continues running.
Recommended Approaches:
- Task-only: Use
Task
s for the complete workflow - Hybrid: Use
Task
s for main operations andMessage
s only for clarifications
This approach aligns with Google's recommendations for agent design and provides better control over conversation flow and state management.
Configuration
External sub agents extend the basic sub agent configuration with A2A protocol-specific settings.
In addition to the required agent
section, external sub agents require an agent card configuration:
# Basic agent information (required - see overview)
agent:
name: car_shopping_agent
protocol: A2A
description: "Helps users shop for cars by connecting them with dealers and facilitating purchases"
# A2A-specific configuration
configuration:
agent_card: ./sub_agents/car_shopping_agent/agent_card.json
module: "path.to.custom.module" # Optional: custom module for sub agent customization
The agent_card
is a mandatory artifact specified by the A2A protocol that helps an agent expose its capabilities to the outside world. It can be:
- A local file path (relative to the project root)
- A URL pointing to the agent card
For more information about agent cards, see the A2A protocol specification.
Authentication
External sub agents support multiple authentication methods for connecting to external services:
- API Key: Static key attached as
Authorization: Bearer <token>
- OAuth 2.0 (Client Credentials): Automatic token retrieval with client ID/secret
- Pre-issued Token: Direct token usage until expiry
Authentication settings are specified using the auth
field within the configuration
section in your config.yml
file.
Below are several examples of how you can configure authentication:
- API Key
- API Key (Custom Header)
- OAuth 2.0
- Pre-issued Token
configuration:
agent_card: ./sub_agents/shopping_agent/agent_card.json
auth:
api_key: "${API_KEY}"
configuration:
agent_card: ./sub_agents/shopping_agent/agent_card.json
auth:
api_key: "${API_KEY}"
header_name: "X-API-Key"
header_format: "{key}"
configuration:
agent_card: ./sub_agents/shopping_agent/agent_card.json
auth:
oauth:
client_id: "${CLIENT_ID}"
client_secret: "${CLIENT_SECRET}"
token_url: "https://auth.company.com/oauth/token"
scope: "read:users"
configuration:
agent_card: ./sub_agents/shopping_agent/agent_card.json
auth:
token: "${ACCESS_TOKEN}"
The $
syntax is required for the following sensitive parameters:
api_key
token
client_secret
This ensures that they are not stored in plain text in your configuration files.
For other parameters like client_id
, using the $
syntax is optional —
you can either reference an environment variable using the $
syntax or provide the value directly in the configuration.
Customization
External sub agents can be customized by implementing a Python interface. This enables you to modify how the external sub agent processes inputs and outputs, allowing for sophisticated data transformation and business logic integration.
Customization is particularly useful when you need to filter slot values to send only relevant information to the external sub agent, extract structured data from sub agent responses and store it in slots for downstream use, apply custom business rules to agent inputs and outputs, or convert between different data formats or schemas.
Creating a Custom Sub Agent
To customize an external sub agent, create a Python class that inherits from A2AAgent
and override the necessary methods.
Here is an example:
from rasa.agents.protocol.a2a.a2a_agent import A2AAgent
from rasa.agents.schemas import (
AgentInput,
AgentOutput
)
class CarShoppingAgent(A2AAgent):
async def process_input(self, input: AgentInput) -> AgentInput:
# Customize input processing
return input
async def process_output(self, output: AgentOutput) -> AgentOutput:
# Customize output processing
return output
Make sure to specify your custom external sub agent class in the external sub agent's configuration:
agent:
name: car_shopping_agent
protocol: A2A
description: "Helps users shop for cars by connecting them with dealers"
configuration:
agent_card: ./sub_agents/car_shopping_agent/agent_card.json
module: "sub_agents.car_shopping_agent.custom_agent.CarShoppingAgent"
Input and Output Processing Customization
For information about customizing input and output processing, see the common customization section in the overview page.