The Smart Router is an intelligent routing system that automatically routes user queries to appropriate AI models based on query complexity and semantic similarity. It uses vector embeddings and machine learning techniques to make routing decisions without manual configuration.
- System Architecture
- Core Components
- Workflow
- Features & Benefits
- Important Notes
- Tool Usage
- File Structure
- API Reference
User Query
↓
1. Prefix Detection (Highest Priority)
├── "旗舰:" or "F:" → Flagship Model
└── "轻量:" or "L:" → Lightweight Model
↓
2. Embedding API (with timeout protection)
↓
3. Patch Search (User Learning Data)
├── High similarity (>0.92) → Match
└── Continue to next step
↓
4. DNA Intent Search (Static Features)
├── Has learning data → Threshold 0.3
├── No learning data → Accept any match
└── Match by semantic similarity
↓
5. Keyword Matching (Offline Fallback)
├── Flagship keywords: code, write, implement, etc.
└── Lightweight keywords: explain, what is, how to, etc.
↓
6. Default Lightweight Model (Fallback)
Static semantic feature vectors that represent different task categories:
- CODE: Code writing, debugging, refactoring
- REASON: Complex reasoning, logic, math, planning
- CHAT: Daily conversation, casual interaction
- WRITE: Text generation, content creation
- FACT: Factual queries, knowledge retrieval
- TRANS: Format conversion, data transformation
Personalized learning data accumulated from user interactions:
- Created when users explicitly specify model tier via prefix
- Stored in
~/.openclaw/smart-router/user_memory.bin - Time-decay weighting for recency bias
- Overrides DNA matching when similarity > 0.92
Three-tier search strategy:
- Patch Layer: User's personal learning data (highest priority)
- DNA Layer: Static semantic feature vectors
- Keyword Layer: Offline fallback for robustness
File: src/smart-router/routing/router.ts
Main routing engine that implements the decision logic.
Key Methods:
decide(query: string): Main entry point for routing decisionsrecordLearning(query, tier): Record user preferences for learningloadDNA(intents): Load static DNA intent definitionsinitialize(): Load vector store and patches
File: src/smart-router/dna/loader.ts
Binary file loader for DNA intent data.
Features:
- Parses VCTR format binary files (40-byte header)
- Automatic fallback to package seed files
- Runtime file copying from package to user directory
File: src/smart-router/routing/layered-index.ts
Manages three-tier search:
- Patch search (user learning data)
- DNA search (static features)
- Configurable similarity thresholds
File: src/smart-router/memory/vector-store.ts
Persistent storage for user learning data:
- Binary format:
user_memory.bin - Time-decay weight calculation
- Automatic compaction
File: src/smart-router/routing/prefix-detector.ts
Detects user-specified model tier from query prefix.
Supported Prefixes:
- Flagship:
旗舰:,旗舰,Force:,Force,F:,F - Lightweight:
轻量:,轻量,Fast:,Fast,L:,L
-
Generate DNA Seed File
python scripts/generate-vctr-dna.py
- Reads JSON seed data files
- Calls SiliconFlow API for embeddings
- Calculates centroid vectors per label
- Generates
src/smart-router/dna/base_dna.bin
-
Build Project
pnpm build
- Compiles TypeScript
- Copies DNA file to
dist/smart-router/dna/base_dna.bin
-
Enable Smart Routing
openclaw smart-router enable- Interactive CLI wizard
- Configures vector API provider
- Copies seed file to
~/.openclaw/smart-router/base_dna.bin - Sets up model tiers
-
User Sends Query
"帮我写个正则匹配的代码" -
Router Processing
- Check for prefix commands
- Call embedding API
- Search patches/DNA
- Return routing decision
-
Model Selection
{ modelTier: "flagship", selectedModel: "zai/glm-4.7", confidence: 0.892, reasoning: "Intent matched: code (similarity 0.89)" } -
Query Execution
- Route to selected model
- Return response to user
- No manual configuration needed
- Routes complex tasks to powerful models
- Routes simple tasks to fast models
- Cost optimization through intelligent routing
- Learns from user behavior
- Records explicit preferences via prefix commands
- Time-decay weighting for recency bias
- Personalized routing over time
- Graceful degradation at every layer
- Works offline with keyword matching
- Always returns a valid decision
- Robust and reliable
- Vector similarity matching is fast
- Embedded API timeout protection
- Binary file format for quick loading
- Minimal latency impact
- Vector embeddings capture query semantics
- DNA intents represent task categories
- Better than keyword matching
- More accurate routing
- Chinese and English keyword matching
- Chinese and English prefix commands
- Language-agnostic DNA matching
- Truly multilingual
- User learning data stored locally:
~/.openclaw/smart-router/ - No data sent to external servers except embedding API
- Privacy-preserving design
-
DNA Seed File
- Source:
src/smart-router/dna/base_dna.bin - Auto-copied to:
~/.openclaw/smart-router/base_dna.bin - Regenerate with:
python scripts/generate-vctr-dna.py
- Source:
-
User Memory
- Location:
~/.openclaw/smart-router/user_memory.bin - Grows with user interactions
- Automatic compaction when threshold reached
- Location:
-
Config File
- Location:
~/.openclaw/smart-router/config.json - Stores smart router settings
- Separate from main config
- Location:
-
Flagship Models: High capability, higher cost
- Examples:
zai/glm-4.7,claude-opus-4-5 - Use case: Complex tasks, code, reasoning
- Examples:
-
Lightweight Models: Fast, lower cost
- Examples:
zai/glm-4.5-air,haiku - Use case: Simple queries, chat, explanation
- Examples:
Similarity Thresholds:
patchSimilarityThreshold: 0.92 (default)dnaSimilarityThreshold: 0.85 (default)- Lower values = more aggressive matching
- Higher values = more conservative matching
openclaw smart-router enableInteractive wizard will prompt for:
- Vector provider (OpenAI, Gemini, SiliconFlow, Custom)
- API key
- Model tier confirmation
openclaw smart-router disableopenclaw smart-router status# Default output: src/smart-router/dna/base_dna.bin
python scripts/generate-vctr-dna.py
# Custom output path
python scripts/generate-vctr-dna.py /path/to/output.binRequirements:
- Python 3.7+
requestslibrary- SiliconFlow API key
Data Files (default):
openclaw_seed_data_200.jsonopenclaw_seed_data_batch2_v3.json
The smart router system uses a dedicated configuration file, separate from the main config for clean management and maintenance.
Location: ~/.openclaw/smart-router/config.json
Purpose: Stores all smart router settings including model selection, vector API, threshold parameters, etc.
Complete Configuration Example:
{
"enabled": true,
"lightweightModels": ["zai/glm-4.5-air", "haiku"],
"flagshipModels": ["zai/glm-4.7", "opus"],
"memorySearch": {
"provider": "openai",
"model": "text-embedding-3-small",
"remote": {
"apiKey": "sk-...",
"baseUrl": "https://api.openai.com/v1"
}
},
"vectorStore": {
"configDir": "~/.openclaw/smart-router",
"vectorDim": 1024,
"dataFilePath": "~/.openclaw/smart-router/user_memory.bin",
"enableCompaction": true,
"compactionThreshold": 1500
},
"prefix": {
"flagship": ["旗舰:", "旗舰 ", "Force:", "Force ", "F:", "F "],
"lightweight": ["轻量:", "轻量 ", "Fast:", "Fast ", "L:", "L "]
},
"timeDecay": {
"gamma": 0.95,
"halfLifeDays": 30,
"deathThreshold": 0.1,
"minRetention": 3
},
"embedding": {
"timeoutMs": 1500,
"maxRetries": 2,
"retryDelayMs": 500
},
"patchSimilarityThreshold": 0.92,
"dnaSimilarityThreshold": 0.85,
"softPartitionThreshold": 0.1,
"defaultLightweightModel": "haiku",
"defaultFlagshipModel": "opus"
}Configuration Details:
| Option | Type | Default | Description |
|---|---|---|---|
enabled |
boolean | false | Whether smart routing is enabled |
lightweightModels |
string[] | ["haiku"] | List of lightweight model names |
flagshipModels |
string[] | ["opus"] | List of flagship model names |
defaultLightweightModel |
string | "haiku" | Default lightweight model to use |
defaultFlagshipModel |
string | "opus" | Default flagship model to use |
Note: Lightweight models are for simple tasks (chat, explanation), flagship models for complex tasks (code, reasoning). The system automatically selects the appropriate tier based on query analysis.
| Option | Type | Description |
|---|---|---|
provider |
string | Vector API provider: openai, gemini, siliconflow, custom |
model |
string | Embedding model name, e.g., text-embedding-3-small |
remote.apiKey |
string | API key |
remote.baseUrl |
string | API base URL (for custom providers) |
Note: Used to convert query text to vectors for semantic similarity matching.
| Option | Type | Default | Description |
|---|---|---|---|
configDir |
string | ~/.openclaw/smart-router | Configuration directory |
vectorDim |
number | 1024 | Vector dimension (must match embedding model) |
dataFilePath |
string | user_memory.bin | User learning data storage path |
enableCompaction |
boolean | true | Whether to enable automatic compaction |
compactionThreshold |
number | 1500 | Patch count threshold to trigger compaction |
Note: Manages storage and compaction of user learning data. When patch count reaches threshold, system automatically cleans outdated learning data.
| Option | Type | Default | Description |
|---|---|---|---|
flagship |
string[] | ["旗舰:", "F:", ...] | Prefixes to force flagship model usage |
lightweight |
string[] | ["轻量:", "L:", ...] | Prefixes to force lightweight model usage |
Note: Users can add prefixes to queries to explicitly specify model tier. For example:
旗舰: 帮我写个Python函数→ Force flagship model轻量: 今天天气怎么样→ Force lightweight model
| Option | Type | Default | Description |
|---|---|---|---|
gamma |
number | 0.95 | Decay coefficient (0-1, lower = faster decay) |
halfLifeDays |
number | 30 | Half-life in days |
deathThreshold |
number | 0.1 | Death threshold (data below this weight is cleaned) |
minRetention |
number | 3 | Minimum retention per partition |
Note: User learning data decays over time, old data has gradually reduced impact. This ensures routing decisions adapt to changes in user behavior.
| Option | Type | Default | Description |
|---|---|---|---|
timeoutMs |
number | 1500 | API call timeout (milliseconds) |
maxRetries |
number | 2 | Maximum retry attempts |
retryDelayMs |
number | 500 | Retry delay (milliseconds) |
Note: Controls vector embedding API call behavior. On timeout, system automatically falls back to keyword matching.
| Option | Type | Default | Description |
|---|---|---|---|
patchSimilarityThreshold |
number | 0.92 | Patch similarity threshold (0-1) |
dnaSimilarityThreshold |
number | 0.85 | DNA similarity threshold (0-1) |
softPartitionThreshold |
number | 0.1 | Soft partition boundary threshold |
Note:
- Patch threshold: When user learning data similarity exceeds this, prioritize user learning results
- DNA threshold: Minimum similarity required for DNA intent matching
- Soft partition threshold: Boundary control for layered indexing
Tuning Recommendations:
- Lower threshold → More aggressive matching (may misclassify, but covers more scenarios)
- Higher threshold → More conservative matching (more accurate, but may miss some queries)
Location: ~/.openclaw/config.json
Note: Main configuration file contains OpenClaw's global settings. Smart router uses a separate config file to avoid polluting the main config.
The DNA seed data is stored in JSON files with the following format:
{
"text": "Query text content",
"label": "Category label",
"lang": "Language code"
}| Field | Type | Description | Examples |
|---|---|---|---|
text |
string | The query text sample | "帮我写个离职信", "What is the capital of France?"` |
label |
string | Intent category label | CHAT, FACT, TRANS, CODE, REASON, WRITE |
lang |
string | Language code | zh, en |
| Label | Type | Description | Sample Queries |
|---|---|---|---|
CHAT |
Lightweight | Daily conversation, casual chat | "早上好", "Hello", "最近怎么样" |
FACT |
Lightweight | Factual queries, knowledge retrieval | "什么是量子力学", "What is AI?" |
TRANS |
Lightweight | Format conversion, data transformation | "JSON转XML", "Convert to CSV" |
CODE |
Flagship | Code writing, debugging, refactoring | "写个Python函数", "Debug this code" |
REASON |
Flagship | Complex reasoning, logic, math | "证明勾股定理", "Solve for x" |
WRITE |
Lightweight | Text generation, content creation | "写首诗", "Write a story" |
The seed data JSON files serve as training samples for the DNA intent system:
- Collection: Manually curated query examples for each category
- Embedding: Convert text to 1024-dimension vectors via API
- Aggregation: Calculate centroid (average vector) for each label
- Generation: Create
base_dina.binwith VCTR format
File Example: my_seed_data.json
[
{
"text": "今天天气不错",
"label": "CHAT",
"lang": "zh"
},
{
"text": "Write a function to sort an array",
"label": "CODE",
"lang": "en"
},
{
"text": "帮我写个离职信",
"label": "WRITE",
"lang": "zh"
},
{
"text": "What is the capital of France?",
"label": "FACT",
"lang": "en"
}
]- Sample Size: 50-100 samples per label for good centroids
- Diversity: Include various phrasings and styles
- Quality: Use realistic user queries, not artificial examples
- Balance: Ensure even distribution across labels
- Language: Match samples to your target user base
The generator supports multiple JSON files:
# In generate-vctr-dna.py, modify:
json_files = [
'my_seed_data.json',
'additional_data.json'
]# Use default files
python scripts/generate-vctr-dna.py
# Or specify custom output
python scripts/generate-vctr-dna.py custom_data.json# Copy to src/smart-router/dna/
cp custom_data.bin src/smart-router/dna/base_dna.bin
# Build project
pnpm build
# Test routing
openclaw smart-router enableJSON Files (Manual)
↓
generate-vctr-dna.py (Python Script)
↓
SiliconFlow API → Embeddings
↓
Calculate Centroids per Label
↓
base_dna.bin (Binary File)
↓
pnpm build
↓
dist/smart-router/dna/base_dna.bin
↓
npm install -g openclaw
↓
User: openclaw smart-router enable
↓
~/.openclaw/smart-router/base_dna.bin
openclaw/
├── src/
│ ├── commands/
│ │ └── smart-router.ts # CLI commands
│ └── smart-router/
│ ├── types/
│ │ └── smart-router.types.ts # Type definitions
│ ├── routing/
│ │ ├── router.ts # Main router
│ │ ├── layered-index.ts # Search index
│ │ ├── prefix-detector.ts # Prefix detection
│ │ └── similarity.ts # Vector math
│ ├── memory/
│ │ └── vector-store.ts # User memory storage
│ └── dna/
│ ├── loader.ts # DNA file loader
│ ├── base_dna.bin # DNA seed data (binary)
│ └── generate-vctr-dna.py # DNA generator script
├── scripts/
│ ├── copy-dna-seed.ts # Build-time copy
│ └── postinstall.js # Install-time checks
└── ~/.openclaw/
└── smart-router/
├── config.json # Smart router config
├── base_dna.bin # Auto-copied seed
└── user_memory.bin # User learning data
interface RoutingDecision {
modelTier: 'flagship' | 'lightweight'
selectedModel: string
confidence: number // 0.0 to 1.0
reasoning: string
}interface SmartRouterConfig {
vectorStore: {
configDir: string
vectorDim: number
dataFilePath: string
enableCompaction: boolean
compactionThreshold: number
}
prefix: {
flagship: string[]
lightweight: string[]
}
embedding: {
timeoutMs: number
maxRetries: number
retryDelayMs: number
}
patchSimilarityThreshold: number
dnaSimilarityThreshold: number
defaultLightweightModel: string
defaultFlagshipModel: string
}interface DNAIntent {
id: string
name: string
description: string
preferredTier: 'flagship' | 'lightweight'
centroid: Float32Array // 1024-dim vector
confidence: number
sampleCount: number
keywords?: string[]
}Symptom: [DNA Loader] DNA file not found
Solution:
- Check if
src/smart-router/dna/base_dna.binexists - Run
python scripts/generate-vctr-dna.pyto regenerate - Run
pnpm buildto copy to dist/
Symptom: [SmartRouter] Embedding failed, fallback to keyword matching
Solutions:
- Check API key in config
- Increase timeout in config:
embedding.timeoutMs - Check network connectivity
Symptom: Intent matched: xxx (no learning data)
Explanation: This is normal! It means DNA matching is working but you haven't used prefix commands yet.
To add learning data:
旗舰: 帮我写个Python函数
轻量: 今天天气怎么样
Symptom: Simple task routed to flagship model
Solutions:
- Use prefix to override:
轻量: 解释什么是量子力学 - Adjust similarity thresholds in config
- Add more training data for better DNA matching
- Use real, representative queries for each category
- Balance categories (CHAT, CODE, WRITE, etc.)
- Minimum 50-100 samples per category for good centroids
- Regenerate DNA when adding significant new categories
- Flagship: Code, reasoning, complex tasks
- Lightweight: Chat, explanation, simple queries
- Balance cost vs. quality based on use case
- Check
openclaw smart-router statusperiodically - Review routing logs in console output
- Adjust thresholds based on accuracy
- Backup
user_memory.binbefore major changes - Regenerate DNA when adding new categories
- Clear user memory if routing quality degrades over time
Edit scripts/generate-vctr-dna.py:
LABELS = ["CHAT", "FACT", "TRANS", "CODE", "REASON", "WRITE", "CUSTOM"]Then regenerate seed file.
Edit src/smart-router/routing/router.ts:
prefix: {
flagship: ['旗舰:', 'Flagship:', 'F:'],
lightweight: ['轻量:', 'Lightweight:', 'L:']
}In config file:
{
"patchSimilarityThreshold": 0.90,
"dnaSimilarityThreshold": 0.80
}Lower = more aggressive matching, Higher = more conservative.
The Smart Router System provides:
- ✅ Automatic model selection based on query complexity
- ✅ Self-learning from user behavior
- ✅ Semantic understanding via vector embeddings
- ✅ Multi-layer fallback for robustness
- ✅ Bilingual support (Chinese/English)
- ✅ Cost optimization through intelligent routing
- ✅ Privacy-preserving local storage
- ✅ High performance with minimal latency
Key Innovation: Combines static semantic features (DNA) with personalized learning (Patches) for accurate, adaptive routing without manual configuration.