Quickstart¶
Build your first semantic router in just a few lines of code.
1. Install StrataRouter¶
Note
See the Installation Guide for more options, virtual environments, and platform-specific instructions.
2. Create Your First Router¶
Create a Python file, e.g. my_router.py:
from stratarouter import Router, Route
import random
# 1. Create router
router = Router(dimension=384, threshold=0.5)
# 2. Define routes
billing = Route(
id="billing",
description="Billing and payment questions",
keywords=["invoice", "payment", "refund", "charge", "bill"],
examples=[
"Where's my invoice?",
"I need a refund",
"Update my payment method"
]
)
support = Route(
id="support",
description="Technical support and bug reports",
keywords=["bug", "crash", "error", "broken", "login"],
examples=[
"App is crashing",
"Can't login",
"Getting an error message"
]
)
# 3. Add routes to router
router.add_route(billing)
router.add_route(support)
# 4. Build the HNSW index with embeddings
# In production, use real embeddings from a model (see Step 3 below)
embeddings = [
[random.random() for _ in range(384)], # billing embedding
[random.random() for _ in range(384)] # support embedding
]
router.build_index(embeddings)
# 5. Route a query
query_embedding = [random.random() for _ in range(384)]
result = router.route("I need my invoice for last month", query_embedding)
print(f"Route: {result.route_id}") # "billing"
print(f"Confidence: {result.confidence:.3f}") # e.g. 0.892
print(f"Latency: {result.latency_ms:.2f}ms") # e.g. 1.24ms
Run it:
Success
You just routed a query in milliseconds. Step 3 shows how to use real embeddings for production accuracy.
3. Use Real Embeddings¶
For accurate routing, generate embeddings from an actual model:
from stratarouter import Router, Route
from sentence_transformers import SentenceTransformer
# Load a local embedding model (free, no API key needed)
model = SentenceTransformer("all-MiniLM-L6-v2") # 384 dimensions
router = Router(dimension=384, threshold=0.7)
routes = [
Route(
id="billing",
description="Billing, payments, invoices, and refunds",
keywords=["invoice", "payment", "refund", "billing", "charge"],
examples=["Where's my invoice?", "I need a refund", "Payment failed"]
),
Route(
id="support",
description="Technical support, bugs, errors, and troubleshooting",
keywords=["bug", "crash", "error", "broken", "login"],
examples=["App is crashing", "Can't login", "Feature not working"]
),
Route(
id="sales",
description="Pricing, plans, upgrades, and sales inquiries",
keywords=["price", "cost", "upgrade", "plan", "buy"],
examples=["What's your pricing?", "Can I upgrade?", "Enterprise plans?"]
)
]
for route in routes:
router.add_route(route)
# Generate embeddings from route descriptions
descriptions = [r.description for r in routes]
embeddings = model.encode(descriptions).tolist()
router.build_index(embeddings)
# Route with a real query embedding
test_queries = [
"Where's my invoice?",
"App is crashing",
"What's your pricing?"
]
for query in test_queries:
query_embedding = model.encode([query])[0].tolist()
result = router.route(query, query_embedding)
print(f"{query:30} → {result.route_id:10} ({result.confidence:.3f})")
Output:
from stratarouter import Router, Route
from openai import OpenAI
client = OpenAI()
def embed(text: str) -> list[float]:
resp = client.embeddings.create(
model="text-embedding-3-small", # 1536-dim
input=text
)
return resp.data[0].embedding
router = Router(dimension=1536, threshold=0.7)
routes = [
Route(
id="billing",
description="Billing, payments, invoices, and refunds",
keywords=["invoice", "payment", "refund"]
),
Route(
id="support",
description="Technical support, bugs, errors, and troubleshooting",
keywords=["bug", "crash", "error"]
)
]
for route in routes:
router.add_route(route)
# Build index with OpenAI embeddings
embeddings = [embed(r.description) for r in routes]
router.build_index(embeddings)
# Route with real embedding
query = "Where can I download my invoice?"
result = router.route(query, embed(query))
print(f"→ {result.route_id} ({result.confidence:.3f})") # billing (0.934)
4. Score Breakdown¶
Understand how StrataRouter calculates routing scores:
result = router.route(query, query_embedding)
# Primary decision
print(f"Route: {result.route_id}")
print(f"Confidence: {result.confidence:.3f}")
print(f"Latency: {result.latency_ms:.2f}ms")
# Detailed score breakdown
print(f"\nScore breakdown:")
print(f" Semantic: {result.scores.semantic:.3f}") # Dense embedding similarity
print(f" Keyword: {result.scores.keyword:.3f}") # BM25 keyword matching
print(f" Pattern: {result.scores.pattern:.3f}") # Rule-based patterns
print(f" Total: {result.scores.total:.3f}") # Fused (64% sem + 29% kw + 7% rule)
# Alternative routes
for route_id, conf in result.alternatives:
print(f" Alt: {route_id} ({conf:.3f})")
Tip
StrataRouter uses hybrid scoring — semantic embeddings (64%) + BM25 keyword matching (29%) + rule-based patterns (7%). This combination outperforms embedding-only approaches, especially for domain-specific terms.
5. Handle Edge Cases¶
from stratarouter import Router, Route
router = Router(dimension=384, threshold=0.7)
# ... (add routes and build index) ...
def smart_route(query: str, query_embedding: list) -> str:
"""Route query with fallback for low confidence."""
result = router.route(query, query_embedding)
if result.confidence < 0.5:
print(f"Low confidence ({result.confidence:.1%}) — using fallback")
return "general_support" # default fallback
print(f"Routing to '{result.route_id}' with {result.confidence:.1%} confidence")
return result.route_id
Common Patterns¶
from stratarouter import Router, Route
router = Router(dimension=384, threshold=0.6)
router.add_route(Route(id="billing", description="Billing, invoices, payments"))
router.add_route(Route(id="support", description="Technical issues, bugs"))
router.add_route(Route(id="sales", description="Pricing, plans, upgrades"))
router.build_index(embeddings)
result = router.route("My payment failed", query_embedding)
print(result.route_id) # "billing"
from stratarouter import Router, Route
router = Router(dimension=384)
router.add_route(Route(id="analyst", description="Data analysis and reports"))
router.add_route(Route(id="researcher", description="Research and information"))
router.add_route(Route(id="coder", description="Programming and code"))
router.build_index(embeddings)
result = router.route("Write Python code for ML", query_embedding)
agent = result.route_id # "coder"
from stratarouter import Router, Route
router = Router(dimension=384)
router.add_route(Route(id="docs", description="Product documentation"))
router.add_route(Route(id="faq", description="Frequently asked questions"))
router.add_route(Route(id="blog", description="Blog posts and tutorials"))
router.build_index(embeddings)
result = router.route("How do I get started?", query_embedding)
kb = result.route_id # "docs"
from stratarouter import Router, Route
router = Router(dimension=384)
router.add_route(Route(id="gpt5", description="Complex reasoning and analysis"))
router.add_route(Route(id="claude", description="Long context and coding"))
router.add_route(Route(id="local", description="Privacy-sensitive queries"))
router.build_index(embeddings)
result = router.route("Analyze this 50-page document", query_embedding)
model = result.route_id # "claude"
Troubleshooting¶
ImportError: No module named 'stratarouter'
Make sure you installed it:
Check the installation:
If still failing, check you're in the correct virtual environment:
DimensionMismatch error
Your embedding dimension doesn't match the router configuration. Always match them:
Routes not routing correctly
- Better descriptions: Make route descriptions specific and distinct
- Lower threshold: Try
Router(threshold=0.5)instead of0.7 - Add examples and keywords: Provide multiple examples per route
Slow routing (>10ms)
- Check the HNSW index is built:
router.build_index(embeddings)before routing - Enable SIMD:
Router(dimension=384, enable_simd=True) - Reduce
hnsw_ef_searchfor fewer route counts
Debug latency:
Low confidence scores
- Improve descriptions: Be more specific
- Use a better model: Try
all-mpnet-base-v2(768d, higher quality) - Lower threshold:
Router(threshold=0.5)
Next Steps¶
Need help? Check the FAQ or open an issue on GitHub.