Projections
Overview
Projections sit between signal extraction and decision matching. They resolve competition among signals, combine several signals into a score, and turn that score into named outputs a decision can reference.
The route pipeline is:
routing.signalsextracts facts.routing.projectionscoordinates or derives facts.routing.decisionsmatches policy and chooses candidate models.
Key Advantages
- Reuses one coordination or threshold policy across several decisions.
- Keeps numeric aggregation out of boolean decision trees.
- Preserves named, explainable outputs for replay and debugging.
What Problem Does It Solve?
Individual signals are intentionally narrow. Real routing policy often needs one winner from a competing intent group or one reusable difficulty score from several weak indicators. Without projections, that logic is duplicated across decisions and numeric thresholds become hard to audit.
When to Use
Use projections when:
- only one member of a domain or embedding group should remain active
- several signals should contribute to one continuous score
- several decisions should share the same named threshold bands
Skip projections when one raw signal expresses the route condition clearly or when multiple matches should remain independently visible.
Projection Types
| Type | Goal | Decision-visible? | Guide |
|---|---|---|---|
partitions | Keep one winner from competing domain or embedding signals | No; decisions still reference the winning raw signal | Partitions |
scores | Combine signal values with weighted_sum | No; scores feed mappings or other scores | Scores |
mappings | Convert a score into named threshold outputs | Yes, through type: projection | Mappings |
| trace | Explain partition, score, and mapping results in Router Replay | Operational only | Projection Traces |
Current methods are:
- partition semantics:
exclusiveandsoftmax_exclusive - score method:
weighted_sum - mapping methods:
threshold_bands(first matching output) andmulti_emit(every matching output; requires at least two outputs) - optional mapping calibration:
sigmoid_distance
Configuration
routing:
signals:
embeddings:
- name: technical-support
threshold: 0.75
candidates: [installation help, troubleshooting]
- name: account-management
threshold: 0.72
candidates: [billing issue, subscription change]
context:
- name: long-context
min_tokens: 4K
max_tokens: 200K
projections:
partitions:
- name: support-intents
semantics: exclusive
members: [technical-support, account-management]
default: technical-support
scores:
- name: request-difficulty
method: weighted_sum
inputs:
- type: embedding
name: technical-support
value_source: confidence
weight: 0.5
- type: context
name: long-context
weight: 0.5
mappings:
- name: difficulty-band
source: request-difficulty
method: threshold_bands
outputs:
- name: support-fast
lt: 0.5
- name: support-escalated
gte: 0.5
decisions:
- name: escalated-support
description: Route difficult support requests to the larger model.
priority: 150
rules:
operator: AND
conditions:
- type: projection
name: support-escalated
modelRefs:
- model: support-large
Only mapping output names are referenced with type: projection. Decisions do
not reference partition or score names directly.
The DSL exposes the same three concepts through PROJECTION partition,
PROJECTION score, and PROJECTION mapping blocks. The Dashboard exposes them
under Config > Projections.
Dependencies and Limitations
- Projections make no additional model or storage calls; they consume signal results already computed for the request.
- A partition default is a fallback, not evidence that its member matched.
- Weighted sums do not automatically calibrate inputs from different signal families. Evaluate weights and mapping bands together on labeled traffic.
- Cycles between derived scores are rejected during validation.
- See the
balancerecipe for an end-to-end example.