Advanced patterns for multi-provider LLM switching including fallback, load balancing, and circuit breakers
While basic multi-provider support lets you assign different LLMs to different agents, ModelRouter and RouterAgent add dynamic switching, cost optimisation, and resilience.
from praisonaiagents import RouterAgentagent = RouterAgent(name="router", instructions="Route tasks to the best provider.")agent.start("Summarise this report using the cheapest capable model.")
The user submits a task; the router picks a provider based on policy, cost, and availability.
PR #2122: A model string like my-custom-model no longer defaults to the OpenAI provider — it raises ValueError. Use the provider/model form, e.g. ollama/llama3, bedrock/anthropic.claude-3-sonnet.
from praisonaiagents import ModelRouter, RouterAgentclass CustomRouter(ModelRouter): def select_model(self, task_description: str, **kwargs): if any(k in task_description.lower() for k in ["code", "programming", "function"]): return "deepseek/deepseek-coder" if any(k in task_description.lower() for k in ["creative", "story", "poem"]): return "claude-3-opus-20240229" return "gemini/gemini-1.5-flash"router_agent = RouterAgent(router=CustomRouter())
from praisonaiagents import RouterAgentimport randomclass LoadBalancedRouter(RouterAgent): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.model_usage = {model: 0 for model in self.models} def select_model_balanced(self): min_usage = min(self.model_usage.values()) candidates = [m for m, u in self.model_usage.items() if u == min_usage] selected = random.choice(candidates) self.model_usage[selected] += 1 return selectedrouter = LoadBalancedRouter( models=["gpt-4o-mini", "gemini/gemini-1.5-flash", "claude-3-haiku"])