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
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: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
Import RouterAgent from praisonaiagents.agent.router_agent — it is not re-exported at the top level.
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.
Workflows
Workflow patterns and orchestration
AutoAgents
Automatically created and managed agents