Managing multiple LLMs in production can be a nightmare. I used to hardcode model selections—GPT-4 for complex tasks, Claude Haiku for fast text extraction. But as my app scaled, this became unmaintainable. I needed a way to dynamically route requests based on the prompt's intent. Here is the routing system I built.
The Routing Concept
Prompt routing involves evaluating an incoming user request and deciding which LLM is best suited (cost, speed, capability) to handle it. You send everything to one endpoint, and a lightweight classifier makes the decision.
Step 1: The Fast Classifier
I use a very fast, cheap model (like Llama-3-8B or Claude Haiku) as the "router." Its only job is to categorize the prompt into predefined buckets.
def classify_prompt(user_prompt):
router_prompt = f"""
Categorize the following request into one of three categories:
1. 'coding'
2. 'summarization'
3. 'general_chat'
Request: {user_prompt}
Output ONLY the category name.
"""
# Call fast model here
return fast_llm.predict(router_prompt)Step 2: The Dispatcher
Once classified, I route the task. For coding, I might want Claude 3.5 Sonnet. For summarization, GPT-4o mini. For general chat, a local model.
def handle_request(user_prompt):
category = classify_prompt(user_prompt)
if category == 'coding':
return call_claude_sonnet(user_prompt)
elif category == 'summarization':
return call_gpt4o_mini(user_prompt)
else:
return call_local_model(user_prompt)Handling Edge Cases
Sometimes the classifier gets it wrong. I implemented a fallback mechanism. If the target model fails or returns a low-confidence response, the router automatically retries with my heaviest model (usually GPT-4o) to guarantee a good user experience.
By implementing this simple router, I cut API costs by nearly 40% while keeping response times fast for simple queries.