Skip to Content

Router

from loomflow.architecture import Router, RouterRoute

Classify input → dispatch to ONE specialist Agent. The cheapest multi-agent pattern: one classifier LLM call + one specialist run, no synthesis pass.

For the conceptual page see Router.


Class signature

class Router: name: str = "router" def __init__( self, *, routes: list[RouterRoute], fallback_route: str | None = None, require_confidence_above: float = 0.0, classifier_prompt: str | None = None, ) -> None: ...

Constructor parameters

routes

Typelist[RouterRoute]
Defaultrequired

The specialists. Must be non-empty; route names must be unique. Raises ValueError if violated.

fallback_route

Typestr | None
DefaultNone

Name of a route to use when (a) the classifier emits an unknown route name, or (b) require_confidence_above is non-zero and the classifier’s confidence is below threshold. Must reference a route in routes or raises ValueError.

When unset, classification failures or low-confidence cases terminate with session.output = "Could not route the request." and emit router.fallback_failed.

require_confidence_above

Typefloat
Default0.0

Minimum classifier confidence in [0.0, 1.0]. Classifications below this score are treated as failures and routed to fallback_route (or fail if no fallback). 0.0 (default) accepts any confidence.

classifier_prompt

Typestr | None
DefaultNone (uses built-in default)

Override the classifier’s system prompt. The default takes the route descriptions and asks for a route: <name> line plus a confidence: <0..1> line.


Methods

declared_workers

def declared_workers(self) -> dict[str, Agent]: return {r.name: r.agent for r in self._routes}

Returns the route name → specialist mapping for AgentGraph and introspection.

run

  1. Classify. One model call against deps.model with the classifier prompt + route descriptions. Parses route: and confidence: lines. Emits router.classified.
  2. Confidence check. If confidence < require_confidence_above → fall back (or fail).
  3. Dispatch. The chosen specialist agent.run(prompt) runs to completion. Forwards every event. The specialist’s RunResult.output becomes the Router’s session.output.

RouterRoute

@dataclass class RouterRoute: name: str agent: Agent description: str = ""
FieldTypeDefaultDescription
namestrrequiredWhat the classifier emits in its route: line. Must be unique within a Router. Use simple identifiers (billing, tech, sales).
agentAgentrequiredThe specialist Agent that handles this route.
descriptionstr""Shown to the classifier alongside name. Be specific and distinguishing: include both what the route handles AND what it doesn’t (e.g. "Handle billing — NOT refunds, those go to support").

Cost model

1 classifier call (typically a small fast model like Haiku) + 1 specialist run (typically your main production model). The classifier is the cost knob. Use a small fast model for classification and reserve big-model spend for specialists.

Roughly 1.2× a single-agent ReAct run.


Compared to Supervisor

  • Cheaper. 1 Classification + 1 specialist; no synthesis pass.
  • Deterministic. Single specialist owns the task end-to-end.
  • Less flexible. No multi-domain tasks; routing errors cascade.

When the request might span multiple domains (research + write + review), use Supervisor instead.


Example

from loomflow import Agent from loomflow.architecture import RouterRoute from loomflow.team import Team billing = Agent("Handle billing questions.", model="claude-opus-4-7", tools=[...]) tech = Agent("Handle technical questions.", model="claude-opus-4-7", tools=[...]) sales = Agent("Handle sales questions.", model="claude-opus-4-7") team = Team.router( routes=[ RouterRoute(name="billing", agent=billing, description="Charges, refunds, invoicing, plan changes."), RouterRoute(name="tech", agent=tech, description="Errors, debugging, integration help."), RouterRoute(name="sales", agent=sales, description="Pricing, demos, contracts, partnerships."), ], instructions="You are the customer support entry point.", model="claude-haiku-4-5", # small fast classifier fallback_route="tech", # default to tech for ambiguous requests ) result = await team.run("My credit card was charged twice.") # → routed to billing

Source

loomflow/architecture/router.py

Route descriptions are the prompt. The classifier sees each route’s name + description; the description is what makes routing correct or wrong. Spend time on descriptions; routing errors trace directly back to ambiguous descriptions.

Last updated on