Skip to main content
Returns a router that picks a model per prompt based on learned per-cluster error profiles + a cost weight. See Auto-routing for the conceptual model.

Parameters

Returns — UniRouteRouter

Attributes

Methods

.route(prompt, available_models=None, cost_weight_override=None) → RoutingDecision

Routes a single prompt.

.route_batch(prompts: list[str]) → list[RoutingDecision]

Batched routing. Embeds everything in one call for throughput.

.route_and_execute(prompt, messages, **kwargs) → ModelResponse

Convenience that routes, then immediately calls ot.completion on the chosen model. Shorter than writing the pair yourself.

.get_best_model_for_cluster(cluster_id) → str

Given a cluster id, returns the model that minimizes expected_error + λ·cost. Useful for analytics (“what would I route to on cluster 42?”).

.analyze_routing_distribution(prompts) → dict

Returns a histogram: {model_id: count} over a batch of prompts.

.reset_stats()

Zero out the routing counters.

Examples

Simple load and route

Restrict candidates (cost ceiling)

Override λ per-call

Python backend (introspection)

Failure modes

Engine backends — why the default matters

engine="go" is the default because the Go backend:
  • Is 5–10× faster per routing decision (sub-millisecond vs a few ms).
  • Runs in a subprocess so Python GIL contention doesn’t slow routing.
  • Uses the same ONNX runtime across all platforms — deterministic behavior.
The Python backend exists for:
  • Research / inspection (you can swap the cluster assigner, monkey-patch profiles, etc.).
  • Environments that forbid process-spawn (some sandboxes, Lambda, etc.).
Avoid engine="auto" in production. It silently falls back to Python if the Go binary is missing, which usually means a misconfigured install rather than an intentional choice. Explicit "go" fails loudly with a clear message.