Router
The Router is a central component of the AgentOpera framework that intelligently routes user messages to the most appropriate agent based on intent classification. This document explains how the Router system works and how to extend it with custom intents and domain-specific agents.
Core Concepts
Intent Classification
The Router system uses an LLM-based intent classifier to determine the user's intent from their messages. Each intent is associated with a specific agent that is specialized to handle tasks related to that intent.
Agent Registry
The Agent Registry maintains a catalog of available agents and their capabilities. It serves as a lookup service that maps intents to appropriate agents and provides descriptions of agent capabilities.
Semantic Router Agent
The Semantic Router Agent orchestrates the routing process. It receives user messages, determines the appropriate agent through intent classification, and forwards the messages to the selected agent.
Router Architecture
The Router architecture in AgentOpera consists of three key components:
Intent Classifier: Analyzes user messages to identify their intent.
Agent Registry: Maintains a catalog of available agents and their capabilities.
Semantic Router Agent: Routes messages to the appropriate agent based on the classified intent.
Implementation Details
Intent Registry
The Intent Registry manages the mapping between intents and agents:
from typing import Dict, Union, Set, Optional
class IntentRegistry:
def __init__(
self,
intent_descriptions: Dict[str, str],
agent_intent_mapping: Dict[str, str],
agent_descriptions: Dict[str, Union[str, list[str]]],
schema_overrides: Optional[Dict[str, dict]] = None
):
self.intent_descriptions = intent_descriptions
self.agent_intent_mapping = agent_intent_mapping
self.agent_descriptions = agent_descriptions
self.schema_overrides = schema_overrides or {}
def get_agent_for_intent(self, intent: str) -> str:
"""Returns agent_id associated with the given intent."""
return self.agent_intent_mapping.get(intent, "chat")
def get_tool_schemas(self) -> list[dict]:
"""Builds OpenAI-compatible tool definitions for all registered intents."""
# Implementation details...
LLM Intent Classifier
The LLM Intent Classifier uses a language model to determine the user's intent:
class LLMIntentClassifier(SingleIntentClassifier):
def __init__(self, intent_registry: IntentRegistry, model="Llama-3.1-8B-Instruct"):
self.intent_registry = intent_registry
self.model_name = model
self.client = self._set_model_client(model)
# Additional initialization...
async def classify_intent(self, message: TextMessage | MultiModalMessage, timeout: Optional[float] = 80.0) -> str:
"""Returns the intent with the highest confidence score."""
# Implementation details...
Semantic Router Agent
The Semantic Router Agent handles routing logic:
class SemanticRouterAgent(RoutedAgent):
def __init__(self, name: str) -> None:
super().__init__("Semantic Router Agent")
self._name = name
self._initialized = False
# Additional initialization...
@message_handler
async def route_to_agent(self, message: TextMessage | MultiModalMessage, ctx: MessageContext) -> None:
# Implementation details for routing messages...
Quick Start Guide for Adding a New Business Agent
To add a new domain-specific agent to the Router system:
Define your intent: Create a clear description of what your agent handles
intent_description = "financial_planning_intent": "Help with personal financial planning and investment strategies"
Create your agent implementation: Implement a
RoutedAgent
subclassfrom agentopera.engine import RoutedAgent, MessageContext, message_handler from agentopera.chatflow.messages import TextMessage class FinancialPlanningAgent(RoutedAgent): def __init__(self) -> None: super().__init__("Financial Planning Agent") @message_handler async def handle_planning_request(self, message: TextMessage, ctx: MessageContext) -> None: # Process financial planning request and respond await self.publish_message( TextMessage(content="Here's your financial plan...", source="financial_agent"), ctx.message_channel, message_id=ctx.message_id )
Update the intent registry: Add your intent and agent mapping
from agentopera.router.agent_registry import AgentFactory # Add to existing dictionaries intent_descriptions = { "financial_planning_intent": "Help with personal financial planning and investment strategies", "chat_intent": "General conversation and queries" } agent_intent_mapping = { "financial_planning_intent": "financial_agent", "chat_intent": "chat_agent" } agent_descriptions = { "financial_agent": "Agent that provides financial planning and investment advice", "chat_agent": "General chat assistant" } # Create or update intent registry intent_registry = AgentFactory.create_intent_registry( intent_descriptions, agent_intent_mapping, agent_descriptions )
Register your agent with the runtime: Make it available for routing
from agentopera.engine import SingleThreadedAgentRuntime from agentopera.router.semantic_router_agent import SemanticRouterAgent # Set up runtime runtime = SingleThreadedAgentRuntime() # Register router agent await SemanticRouterAgent.register(runtime, "router", lambda: SemanticRouterAgent("router")) # Register your custom agent await FinancialPlanningAgent.register( runtime, "financial_agent", lambda: FinancialPlanningAgent() ) # Start runtime runtime.start()
Test your agent: Send a message that should trigger your agent's intent
from agentopera.engine import AgentId # Send a test message to the router (will be classified and routed to your agent) await runtime.send_message( TextMessage(content="I need help planning for retirement", source="user"), AgentId("router", "default") )
Last updated