Workflow Routing
Decision-based branching in workflows using the route() helper
Workflow Routing
Route workflows to different paths based on the output of a decision step. This pattern is also known as Agentic Routing or Conditional Branching.
from praisonaiagents import Agent, AgentFlow, when
router = Agent(name="Router", instructions="Pick the next branch")
flow = AgentFlow(
agents=[router],
steps=[
when(
condition="{{score}} >= 50",
then_steps=["high_path"],
else_steps=["low_path"],
)
],
variables={"score": 72},
)
flow.start("Route by score")The user supplies inputs; routing chooses the next branch at runtime.
Quick Start
- Define classifier and handlers
python from praisonaiagents import AgentFlow, WorkflowContext, StepResult from praisonaiagents import route def classify_request(ctx: WorkflowContext) -> StepResult: input_lower = ctx.input.lower() if "urgent" in input_lower: return StepResult(output="priority: high") elif "question" in input_lower: return StepResult(output="priority: support") return StepResult(output="priority: normal") # Route handlers def handle_high(ctx: WorkflowContext) -> StepResult: return StepResult(output="🚨 Escalating to senior team!") def handle_support(ctx: WorkflowContext) -> StepResult: return StepResult(output="💬 Routing to help desk") def handle_normal(ctx: WorkflowContext) -> StepResult: return StepResult(output="📋 Added to queue") - Route by classifier output
python workflow = AgentFlow(steps=[ classify_request, route({ "high": [handle_high], "support": [handle_support], "normal": [handle_normal], "default": [handle_normal] }) ]) result = workflow.start("This is URGENT!") print(result["output"]) # "🚨 Escalating to senior team!"
API Reference
route()
route(
routes: Dict[str, List], # Key: pattern to match, Value: steps to execute
default: Optional[List] = None # Fallback steps if no match
) -> RouteParameters
| Parameter | Type | Description |
|---|---|---|
routes | Dict[str, List] | Dictionary mapping patterns to step lists |
default | Optional[List] | Steps to execute if no pattern matches |
How Matching Works
The router checks if any route key (case-insensitive) is contained in the previous step’s output:
# If previous output is "priority: high"
route({
"high": [...], # ✅ Matches - "high" is in "priority: high"
"low": [...], # ❌ No match
})Examples
Multi-Step Routes
Each route can contain multiple steps:
workflow = AgentFlow(steps=[
classifier,
route({
"approve": [
validate_approval,
send_notification,
update_database
],
"reject": [
log_rejection,
notify_requester
]
})
])Chained Routing
Routes can be chained for complex decision trees:
workflow = AgentFlow(steps=[
initial_classifier,
route({
"category_a": [
sub_classifier_a,
route({
"sub_a1": [handler_a1],
"sub_a2": [handler_a2]
})
],
"category_b": [handler_b]
})
])With Agents
Routes can include Agent instances:
from praisonaiagents import Agent
researcher = Agent(name="Researcher", role="Research topics")
writer = Agent(name="Writer", role="Write content")
workflow = AgentFlow(steps=[
topic_classifier,
route({
"technical": [researcher, writer],
"creative": [writer]
})
])Use Cases
| Use Case | Description |
|---|---|
| Request Triage | Route support tickets to appropriate teams |
| Content Moderation | Route content based on classification |
| Approval Workflows | Different paths for approved/rejected items |
| A/B Testing | Route to different processing pipelines |
| Error Handling | Route based on success/failure status |
How It Works
| Phase | What happens |
|---|---|
| 1. Classify | A step (function or agent) returns a string label as its output |
| 2. Match | route() looks up the label in the routes dict; uses "default" if no key matches |
| 3. Execute | The matched handler list runs sequentially within the chosen branch |
| 4. Continue | Execution resumes with the next workflow step after the route block |
Best Practices
Always include a default route
Handle unexpected classifier output gracefully instead of failing the workflow.
Use unambiguous route keys
Short, distinct keys reduce mis-routing when LLM output is noisy.
Keep each route focused
One clear purpose per branch simplifies testing and observability.
Log routing decisions
Record which route was taken to debug triage and moderation pipelines.