Agentic Routing
Route inputs to specialised handler agents based on classification
Route each request to the best handler agent — a classifier picks the path, specialised agents do the work.
from praisonaiagents import Agent, AgentFlow, route
classifier = Agent(
name="Classifier",
instructions="Classify the request. Reply with ONLY 'technical', 'creative', or 'general'.",
)
tech_agent = Agent(name="TechExpert", instructions="Answer technical questions in detail.")
creative_agent = Agent(name="CreativeWriter", instructions="Write engaging creative content.")
general_agent = Agent(name="GeneralAssistant", instructions="Give clear, helpful responses.")
workflow = AgentFlow(steps=[
classifier,
route({
"technical": [tech_agent],
"creative": [creative_agent],
"default": [general_agent],
}),
])
result = workflow.start("How does machine learning work?")The user sends a request; the classifier routes it to the best handler agent.
Quick Start
- Simple Usage
python from praisonaiagents import Agent, AgentFlow, route classifier = Agent( name="Classifier", instructions="Classify the request. Reply with ONLY 'technical', 'creative', or 'general'.", ) tech_agent = Agent(name="TechExpert", instructions="Answer technical questions.") creative_agent = Agent(name="CreativeWriter", instructions="Write creative content.") general_agent = Agent(name="GeneralAssistant", instructions="Give helpful responses.") workflow = AgentFlow(steps=[ classifier, route({"technical": [tech_agent], "creative": [creative_agent], "default": [general_agent]}), ]) print(workflow.start("Write a poem about the ocean")) - With Configuration
Multi-step routes and step-complete hooks:
python from praisonaiagents import AgentFlow, route, WorkflowHooksConfig workflow = AgentFlow( steps=[ classifier, route({ "complex": [step1, step2, step3], "simple": [quick_handler], "default": [fallback], }), ], hooks=WorkflowHooksConfig( on_step_complete=lambda name, result: print(f"{name}: done"), ), )
How It Works
| Phase | What happens |
|---|---|
| 1. Classify | Classifier agent reads input and returns a label (e.g. "technical") |
| 2. Route | route() looks up the label in the routes dict; falls back to "default" if missing |
| 3. Handle | The matched handler agent (or steps) runs and produces the final response |
Choosing a Routing Approach
Pick the mechanism that matches how the decision is made.
Configuration Options
| Pattern | Description |
|---|---|
route({"key": [agent]}) | Single handler per classification |
route({"key": [a, b, c]}) | Sequential multi-step route |
"default" key | Fallback when no match |
RouterAgent — Model Selection
from praisonaiagents.agent.router_agent import RouterAgent
router = RouterAgent(
name="Smart Router",
role="Task Router",
goal="Route tasks to optimal models",
models=["gpt-4o-mini", "gpt-4o", "claude-3-5-sonnet-20241022"],
routing_strategy="cost-optimized",
)
result = router.execute("What is 2+2?")
print(router.get_usage_report())| Parameter | Default | Options |
|---|---|---|
routing_strategy | "auto" | auto, manual, cost-optimized, performance-optimized |
models | None | List of model names |
primary_model | None | Default model |
fallback_model | None | Model on error |
Best Practices
Keep classifier output constrained
Instruct the classifier to reply with exact route keys — free-form labels break mapping.
Always provide a default route
Unhandled classifications should fall through to a general handler, not fail silently.
Use cost-optimized routing in production
RouterAgent with routing_strategy="cost-optimized" saves cost on simple queries automatically.
Enable hooks while debugging routes
on_step_complete shows which handler ran — useful when classification is ambiguous.