Router-R1 Selection
Router-R1 uses an LLM as the router itself, performing multi-round "think" and "route" actions to make intelligent routing decisions. The router can reason about query requirements, model capabilities, and cost trade-offs before making selections.
Reference: Router-R1: Teaching LLMs Multi-Round Routing and Aggregation via Reinforcement Learning by Hu et al., NeurIPS 2025. Our implementation is inspired by this paper's think/route action pattern.
Paper vs Implementation
The original Router-R1 paper introduces multi-round, multi-model routing and aggregation - the router calls multiple models sequentially, integrates their responses into its context, and synthesizes a final answer. This is the paper's core contribution.
Our implementation provides a simplified single-model selection variant that uses the think/route action pattern for deliberative routing. For full multi-model aggregation, see the advanced configuration below.
Algorithm Flow
Think/Route Protocol
The Router LLM uses a structured output format with two action types:
| Action | Description |
|---|---|
<think>...</think> | Reasoning step - analyzes the query (can repeat) |
<route>model</route> | Final routing decision |
Example Output
<think>
Analyzing query: "Debug this Python code"
- Query type: coding task
- Requires: code understanding, debugging
- Best model: code-llama (specialized for code)
</think>
<route>code-llama</route>
How It Works
Single-Model Selection (Default)
- Router LLM receives the user query and model descriptions
- LLM performs THINK actions to analyze query requirements
- LLM performs ROUTE action to select the best model
- Selected model processes the request
- If the route is invalid, retry up to max_iterations
Multi-Model Aggregation (Advanced)
When enable_aggregation: true, Router-R1 can call multiple models:
- Router LLM reasons about which models to consult
- Router calls Model A, receives response, integrates into context
- Router decides whether to call additional models
- Router synthesizes final answer from all responses
This matches the paper's multi-round aggregation approach.
RL-Based Training
The router is trained using reinforcement learning with rewards for:
- Format correctness: Proper use of think/route tags
- Outcome quality: Quality of the final response
- Cost efficiency: Balance between performance and cost
Core Algorithm (Go)
// Select using LLM-as-Router
func (s *RouterR1Selector) Select(ctx context.Context, selCtx *SelectionContext) (*SelectionResult, error) {
if s.routerEndpoint == "" && s.fallbackToStatic {
return s.staticSelector.Select(ctx, selCtx)
}
history := []string{}
for i := 0; i < s.maxIterations; i++ {
response, err := s.callRouterLLM(ctx, selCtx.Query, selCtx.ModelDescriptions, history)
if err != nil {
if s.fallbackToStatic {
return s.staticSelector.Select(ctx, selCtx)
}
return nil, err
}
action := s.parseAction(response)
if action.Type == ActionRoute {
if s.isValidModel(action.Model, selCtx.CandidateModels) {
return &SelectionResult{
SelectedModel: action.Model,
Method: MethodRouterR1,
Reason: action.Reasoning,
}, nil
}
}
history = append(history, response)
}
// Max iterations reached
if s.fallbackToStatic {
return s.staticSelector.Select(ctx, selCtx)
}
return nil, fmt.Errorf("router failed after %d iterations", s.maxIterations)
}