Configuration
Semantic Router uses one canonical YAML document across the CLI, Dashboard, Helm, and Operator. The top-level structure is:
version:
listeners:
providers:
routing:
entrypoints:
recipes:
global:
Most deployments begin with version, listeners, providers, and one
top-level routing profile. Add entrypoints and recipes when one deployment
needs several isolated policies. Add global settings only for shared services
or runtime behavior that differs from the built-in defaults.
What belongs where
| Section | Owns |
|---|---|
version | Canonical schema version. Use v0.3. |
listeners | Public Router listeners and timeouts. |
providers | Logical provider models, physical backend endpoints, pricing, capabilities, and defaults. |
routing | The default recipe: model cards, signals, projections, decisions, strategy, algorithms, and route plugins. |
entrypoints | Public virtual model aliases mapped to named recipes. |
recipes | Additional isolated routing profiles that share providers and global infrastructure. |
global | Router services, stores, integrations, observability, learning, and router-owned model assets. |
Keep these boundaries clear:
- signals detect facts;
- projections combine evidence;
- decisions define eligibility and route policy;
- algorithms choose or coordinate candidate models;
- plugins add behavior at route-specific hook points; and
- providers bind logical model names to inference endpoints.
Provider pricing belongs beside each concrete model under
providers.models[].pricing. It accepts an optional uppercase three-letter
currency plus non-negative prompt_per_1m, completion_per_1m,
cached_input_per_1m, and cache_write_per_1m rates. Routing model cards do not
repeat deployment prices or credentials.
Use Protocol Compatibility to choose the model's
backend api_format. Then see
Backend Target Compatibility before moving its
bindings between Docker, Helm, the Operator, and Dashboard workflows. The
target matrix distinguishes canonical pass-through from Kubernetes discovery
and records which URL, path, weight, and provider fields each surface
preserves.
Router-wide debugging surfaces stay closed by default.
global.services.observability.profiling serves Go pprof endpoints, and only
when it is explicitly enabled; it then binds 127.0.0.1:6060 so profiles never
reach a routable interface without an explicit bind change. The switch is read
once at startup, so changing it requires a Router restart. See
API and Observability.
Built-in category/domain classification uses the local variant selector when
no remote backend is configured. To call a named external classifier, attach a
backend under global.model_catalog.modules.classifier.domain and resolve
its model from global.model_catalog.external[] with
model_role: classification. The shared backend fields are protocol,
contract, model, and optional deadline_ms; category
currently supports http_classify with the full label_distribution.v1
response contract. Omit backend to retain local behavior. The deprecated
use_modernbert and use_mmbert_32k keys remain readable, while generated
canonical configuration uses variant: candle, variant: modernbert, or
variant: mmbert32k.
The Routing Pipeline explains the design. Capability pages under Capabilities document each signal, projection, decision, algorithm, plugin, and global block.
Capability catalog
Use this catalog to choose a reusable building block, then open its guide for
configuration details. The inventory comes from config/fragments/; each
one-line goal comes from the matching guide's Overview. The documentation
build regenerates this block and fails if the checked-in catalog has drifted.
Signals
| Family and type | Use it to | Reusable fragment | Guide |
|---|---|---|---|
authz — heuristic signal | authz turns identity and policy bindings into reusable routing inputs under routing.signals.role_bindings. | config/fragments/signal/authz/ | Guide |
classifier — learned signal | classifier exposes reusable label scores from a local native sequence classifier, a remote sequence classifier, or a configured external LLM. | config/fragments/signal/classifier/ | Guide |
complexity — learned signal | complexity estimates whether a request is easy, medium, or hard by comparing it with configured example sets. | config/fragments/signal/complexity/ | Guide |
context — heuristic signal | context detects requests that need a larger effective context window. | config/fragments/signal/context/ | Guide |
conversation — heuristic signal | conversation routes on chat structure and protocol facts, such as message count, developer instructions, available tools, explicit tool-use constraints, or an active tool loop. | config/fragments/signal/conversation/ | Guide |
domain — learned signal | domain classifies the request topic family. | config/fragments/signal/domain/ | Guide |
embedding — learned signal | embedding matches requests by semantic similarity to representative examples. | config/fragments/signal/embedding/ | Guide |
event — heuristic signal | event routes structured event-like requests by event type, severity, urgency, or domain-specific action code. | config/fragments/signal/event/ | Guide |
fact-check — learned signal | fact-check decides whether a prompt should be treated as evidence-sensitive traffic. | config/fragments/signal/fact-check/ | Guide |
hallucination — learned signal | hallucination checks the model's answer against the grounding context the request carried, such as tool results or retrieved documents, and reports the claims that context does not support. | config/fragments/signal/hallucination/ | Guide |
input-modality — heuristic signal | input_modality deterministically matches which kinds of input — text, image, audio, or video — are present in the parsed request. | config/fragments/signal/input-modality/ | Guide |
jailbreak — learned signal | jailbreak detects prompt-injection and jailbreak attempts before the Router commits to a route. | config/fragments/signal/jailbreak/ | Guide |
kb — learned signal | kb binds routing signals to the output of a named knowledge base instance. | config/fragments/signal/kb/ | Guide |
keyword — heuristic signal | keyword matches explicit words and phrases in the request. | config/fragments/signal/keyword/ | Guide |
language — heuristic signal | language detects the request language and exposes it as a routing signal. | config/fragments/signal/language/ | Guide |
metadata — heuristic signal | metadata matches bounded string values supplied by the caller in request metadata. | config/fragments/signal/metadata/ | Guide |
modality — learned signal | modality detects whether a request should stay in text generation, switch into image generation, or support both. | config/fragments/signal/modality/ | Guide |
pii — learned signal | pii detects sensitive personal data in requests. | config/fragments/signal/pii/ | Guide |
preference — learned signal | preference infers response-style preferences from examples and classifier settings. | config/fragments/signal/preference/ | Guide |
reask — learned signal | reask detects when the current user turn semantically repeats recent user turns in the same conversation. | config/fragments/signal/reask/ | Guide |
structure — heuristic signal | structure detects request-shape facts such as many explicit questions, ordered workflow markers, or dense constraint phrasing. | config/fragments/signal/structure/ | Guide |
user-feedback — learned signal | user-feedback detects correction, dissatisfaction, or escalation feedback from the conversation. | config/fragments/signal/user-feedback/ | Guide |
Selection algorithms
| Family and type | Use it to | Reusable fragment | Guide |
|---|---|---|---|
automix — selection algorithm | automix is an experimental selector that ranks candidate models by configured quality and cost plus internal verification and escalation estimates. | config/fragments/algorithm/selection/automix.yaml | Guide |
hybrid — selection algorithm | hybrid combines Elo ratings, Router-DC description similarity, AutoMix's one-model value estimate, and cost into one weighted candidate score. | config/fragments/algorithm/selection/hybrid.yaml | Guide |
kmeans — selection algorithm | kmeans sends a request to the model assigned to its nearest learned cluster. | config/fragments/algorithm/selection/kmeans.yaml | Guide |
knn — selection algorithm | knn chooses a candidate from the models that performed well on the most similar recorded requests. | config/fragments/algorithm/selection/knn.yaml | Guide |
latency-aware — selection algorithm | latency_aware ranks eligible candidates using observed TTFT and TPOT percentiles and selects the lowest relative-latency score. | config/fragments/algorithm/selection/latency-aware.yaml | Guide |
mlp — selection algorithm | mlp runs a trained neural classifier on CPU to map a request to a candidate model. | config/fragments/algorithm/selection/mlp.yaml | Guide |
multi-factor — selection algorithm | multi_factor ranks candidates by a configurable combination of quality, latency, cost, and load, then rejects any candidate that violates a hard limit. | config/fragments/algorithm/selection/multi-factor.yaml | Guide |
prompt — selection algorithm | prompt uses a concrete helper model to select exactly one model from the matched decision's modelRefs. | config/fragments/algorithm/selection/prompt.yaml | Guide |
router-dc — selection algorithm | router_dc embeds the request and each model description, then selects the candidate with the strongest semantic similarity. | config/fragments/algorithm/selection/router-dc.yaml | Guide |
static — selection algorithm | static provides deterministic model choice without metrics or learned state. | config/fragments/algorithm/selection/static.yaml | Guide |
svm — selection algorithm | svm uses a trained linear or RBF support-vector classifier to map request features to a candidate model. | config/fragments/algorithm/selection/svm.yaml | Guide |