Módulo 5: OpenRouter - Introducción

Cost Optimization con OpenRouter

Descripción

Aprenderás estrategias para minimizar costos eligiendo el modelo más barato que cumpla requisitos.

Tiempo: 25 minutos
Dificultad: Media


🎯 Objetivos

  • ✅ Comparar precios por modelo
  • ✅ Implementar cost-aware routing
  • ✅ Tracking de gastos
  • ✅ Estrategias de ahorro

💰 Pricing por Modelo (Feb 2026)

Tabla comparativa:

ModeloInput ($/1M)Output ($/1M)CalidadUse Case
Mixtral 8x7B$0.24$0.24⭐⭐⭐⭐General (barato)
Claude 3 Haiku$0.25$1.25⭐⭐⭐⭐Rápido + barato
GPT-3.5-turbo$0.50$1.50⭐⭐⭐⭐Estándar
Gemini Pro$0.50$1.50⭐⭐⭐⭐Google ecosystem
GPT-4-turbo$10.00$30.00⭐⭐⭐⭐⭐Máxima calidad
Claude 3 Opus$15.00$75.00⭐⭐⭐⭐⭐Textos largos

📊 Cost Calculator

def calculate_cost(tokens: int, model: str) -> float:
    """Calcula costo para un modelo."""
    
    pricing = {
        "mistralai/mixtral-8x7b-instruct": 0.24,
        "anthropic/claude-3-haiku": 0.25,
        "openai/gpt-3.5-turbo": 0.50,
        "google/gemini-pro": 0.50,
        "openai/gpt-4-turbo": 10.00,
        "anthropic/claude-3-opus": 15.00
    }
    
    price_per_million = pricing.get(model, 0.50)
    cost = (tokens / 1_000_000) * price_per_million
    
    return cost

# Test
tokens = 1000
for model in ["mistralai/mixtral-8x7b-instruct", "openai/gpt-3.5-turbo", "openai/gpt-4-turbo"]:
    cost = calculate_cost(tokens, model)
    print(f"{model}: ${cost:.6f}")

Output:

mixtral: $0.000240
gpt-3.5: $0.000500 (2x más caro)
gpt-4: $0.010000 (42x más caro!)

🎯 Strategy 1: Tiered Routing

Por complejidad:

def smart_route(prompt: str, context_length: int = 0) -> str:
    """Elige modelo según complejidad."""
    
    # Tier 1: Simple (FAQs, greetings)
    if len(prompt) < 50:
        return "mistralai/mixtral-8x7b-instruct"  # $0.24/1M
    
    # Tier 2: Moderate (explanations)
    elif len(prompt) < 200:
        return "anthropic/claude-3-haiku"  # $0.25/1M
    
    # Tier 3: Complex (analysis)
    else:
        return "openai/gpt-4-turbo"  # $10/1M

Ahorro: 95%+ en queries simples


💡 Strategy 2: Keywords-Based

def keyword_route(prompt: str) -> str:
    """Elige modelo según keywords."""
    
    prompt_lower = prompt.lower()
    
    # Código → Code-specialized model
    if any(word in prompt_lower for word in ["python", "código", "code", "function"]):
        return "mistralai/codestral-latest"  # Especializado código
    
    # Análisis complejo → GPT-4
    elif any(word in prompt_lower for word in ["analiza", "explica detalladamente", "razonamiento"]):
        return "openai/gpt-4-turbo"
    
    # Default: Mixtral (barato)
    else:
        return "mistralai/mixtral-8x7b-instruct"

# Test
print(keyword_route("Hola"))  # Mixtral
print(keyword_route("Escribe función Python"))  # Codestral
print(keyword_route("Analiza este contrato legal"))  # GPT-4

📊 Strategy 3: Budget Limiter

class BudgetAwareChat:
    """Chat con límite de presupuesto."""
    
    def __init__(self, daily_budget: float = 1.0):
        self.daily_budget = daily_budget
        self.spent_today = 0.0
        self.client = OpenAI(
            base_url="https://openrouter.ai/api/v1",
            api_key=os.getenv("OPENROUTER_API_KEY")
        )
    
    def chat(self, prompt: str) -> str:
        """Chat con budget check."""
        
        # Estimate cost
        estimated_tokens = len(prompt.split()) * 1.5  # Rough estimate
        
        # Si cerca del límite → Modelo barato
        if self.spent_today > self.daily_budget * 0.8:
            model = "mistralai/mixtral-8x7b-instruct"
            print(f"[Budget warning: Using cheap model]")
        else:
            model = "openai/gpt-3.5-turbo"
        
        response = self.client.chat.completions.create(
            model=model,
            messages=[{"role": "user", "content": prompt}]
        )
        
        # Track spending
        cost = calculate_cost(response.usage.total_tokens, model)
        self.spent_today += cost
        
        print(f"[Cost: ${cost:.6f} | Total today: ${self.spent_today:.6f}]")
        
        return response.choices[0].message.content

# Uso
bot = BudgetAwareChat(daily_budget=0.10)
print(bot.chat("Hola"))
print(bot.chat("¿Qué es Python?"))

🔄 Strategy 4: Fallback Chain (Cheap to Expensive)

def chat_with_fallback(prompt: str) -> str:
    """Intenta modelo barato, fallback a caro si falla."""
    
    models = [
        "mistralai/mixtral-8x7b-instruct",  # Cheap
        "anthropic/claude-3-haiku",  # Medium
        "openai/gpt-3.5-turbo"  # Standard
    ]
    
    for model in models:
        try:
            response = client.chat.completions.create(
                model=model,
                messages=[{"role": "user", "content": prompt}]
            )
            print(f"[Used: {model}]")
            return response.choices[0].message.content
        except Exception as e:
            print(f"[{model} failed: {e}]")
            continue
    
    return "Error: All models failed"

# Test
print(chat_with_fallback("Hola"))

📊 Cost Tracking Dashboard

import json
from datetime import datetime

class CostTracker:
    """Trackea gastos por modelo."""
    
    def __init__(self):
        self.log_file = "cost_log.json"
        self.load_log()
    
    def load_log(self):
        try:
            with open(self.log_file) as f:
                self.log = json.load(f)
        except:
            self.log = []
    
    def track(self, model: str, tokens: int, cost: float):
        """Registra uso."""
        entry = {
            "timestamp": datetime.now().isoformat(),
            "model": model,
            "tokens": tokens,
            "cost": cost
        }
        self.log.append(entry)
        self.save_log()
    
    def save_log(self):
        with open(self.log_file, "w") as f:
            json.dump(self.log, f, indent=2)
    
    def summary(self):
        """Resumen de gastos."""
        total_cost = sum(entry["cost"] for entry in self.log)
        total_tokens = sum(entry["tokens"] for entry in self.log)
        
        print(f"Total requests: {len(self.log)}")
        print(f"Total tokens: {total_tokens:,}")
        print(f"Total cost: ${total_cost:.6f}")
        
        # Por modelo
        by_model = {}
        for entry in self.log:
            model = entry["model"]
            if model not in by_model:
                by_model[model] = {"requests": 0, "cost": 0}
            by_model[model]["requests"] += 1
            by_model[model]["cost"] += entry["cost"]
        
        print("\nBy model:")
        for model, stats in by_model.items():
            print(f"  {model}: {stats['requests']} requests, ${stats['cost']:.6f}")

# Uso
tracker = CostTracker()
tracker.track("mixtral", 1000, 0.00024)
tracker.track("gpt-3.5", 500, 0.00025)
tracker.summary()

💡 Best Practices

1. Default a modelo barato:

DEFAULT_MODEL = "mistralai/mixtral-8x7b-instruct"

Solo escala a GPT-4 cuando necesario.


2. Cache respuestas comunes:

cache = {}

def cached_chat(prompt: str) -> str:
    if prompt in cache:
        print("[Cache hit - $0]")
        return cache[prompt]
    
    response = chat(prompt)
    cache[prompt] = response
    return response

Ahorro: 100% en queries repetidas


3. Batch queries:

Si múltiples queries similares, usa un solo request:

# ❌ Malo: 3 requests
for q in ["¿Qué es Python?", "¿Qué es Java?", "¿Qué es Go?"]:
    chat(q)  # $0.0015 total

# ✅ Bueno: 1 request
batch_prompt = """
Responde cada pregunta en 20 palabras:
1. ¿Qué es Python?
2. ¿Qué es Java?
3. ¿Qué es Go?
"""
chat(batch_prompt)  # $0.0005 total (3x cheaper)

✅ Resumen

Estrategias de ahorro:

  1. Tiered routing (simple → barato)
  2. Keywords-based selection
  3. Budget limits
  4. Fallback cheap-to-expensive
  5. Cost tracking
  6. Caching
  7. Batching

Potencial ahorro: 80-95% vs usar solo GPT-4


Siguiente: 05-fallback-strategies.md

Aprenderás a implementar fallback robusto para high availability.

Tiempo: 20 min