> ## Documentation Index
> Fetch the complete documentation index at: https://praison.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# 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.

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
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.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph LR
    In[Request] --> Router[Classifier]
    Router --> Handler[Matched Handler]
    Handler --> Out[Response]

    classDef input fill:#8B0000,stroke:#7C90A0,color:#fff
    classDef process fill:#189AB4,stroke:#7C90A0,color:#fff
    classDef output fill:#10B981,stroke:#7C90A0,color:#fff

    class In input
    class Router,Handler process
    class Out output
```

## Quick Start

<Steps>
  <Step title="Simple Usage">
    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    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"))
    ```
  </Step>

  <Step title="With Configuration">
    Multi-step routes and step-complete hooks:

    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    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"),
        ),
    )
    ```
  </Step>
</Steps>

***

## How It Works

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
sequenceDiagram
    participant User
    participant Classifier
    participant Route
    participant HandlerAgent

    User->>Classifier: Request
    Classifier-->>Route: Classification label
    Route->>HandlerAgent: Dispatch to matched handler
    HandlerAgent-->>User: Response
```

| 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.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph TB
    Q[How is the path chosen?] --> A[LLM classifies text]
    Q --> B[Fixed rules on the input]
    Q --> C[Optimise model per query]
    A --> R1[route with a classifier agent]
    B --> R2[route with a deterministic key]
    C --> R3[RouterAgent model selection]

    classDef decision fill:#6366F1,stroke:#7C90A0,color:#fff
    classDef option fill:#10B981,stroke:#7C90A0,color:#fff
    class Q,A,B,C decision
    class R1,R2,R3 option
```

## 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

<Warning>
  Import `RouterAgent` from `praisonaiagents.agent.router_agent` — it is not re-exported at the top level.
</Warning>

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
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

<AccordionGroup>
  <Accordion title="Keep classifier output constrained">
    Instruct the classifier to reply with exact route keys — free-form labels break mapping.
  </Accordion>

  <Accordion title="Always provide a default route">
    Unhandled classifications should fall through to a general handler, not fail silently.
  </Accordion>

  <Accordion title="Use cost-optimized routing in production">
    `RouterAgent` with `routing_strategy="cost-optimized"` saves cost on simple queries automatically.
  </Accordion>

  <Accordion title="Enable hooks while debugging routes">
    `on_step_complete` shows which handler ran — useful when classification is ambiguous.
  </Accordion>
</AccordionGroup>

***

## Related

<CardGroup cols={2}>
  <Card title="Workflows" icon="diagram-project" href="/docs/features/workflows">
    Workflow patterns and orchestration
  </Card>

  <Card title="AutoAgents" icon="robot" href="/docs/features/autoagents">
    Automatically created and managed agents
  </Card>
</CardGroup>
