Router
from loomflow.architecture import Router, RouterRouteClassify 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
| Type | list[RouterRoute] |
| Default | required |
The specialists. Must be non-empty; route names must be unique.
Raises ValueError if violated.
fallback_route
| Type | str | None |
| Default | None |
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
| Type | float |
| Default | 0.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
| Type | str | None |
| Default | None (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
- Classify. One model call against
deps.modelwith the classifier prompt + route descriptions. Parsesroute:andconfidence:lines. Emitsrouter.classified. - Confidence check. If
confidence < require_confidence_above→ fall back (or fail). - Dispatch. The chosen specialist
agent.run(prompt)runs to completion. Forwards every event. The specialist’sRunResult.outputbecomes the Router’ssession.output.
Related types
RouterRoute
@dataclass
class RouterRoute:
name: str
agent: Agent
description: str = ""| Field | Type | Default | Description |
|---|---|---|---|
name | str | required | What the classifier emits in its route: line. Must be unique within a Router. Use simple identifiers (billing, tech, sales). |
agent | Agent | required | The specialist Agent that handles this route. |
description | str | "" | 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 billingSource
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.