Módulo 2: OpenAI API - Introducción

Pricing, Rate Limits y Optimización de Costos

Descripción de la cápsula

Ya sabes usar OpenAI API. Ahora necesitas entender:

  • Cómo se calcula el costo (input/output tokens)
  • Rate limits (cuántos requests puedes hacer)
  • Cómo optimizar costos (sin sacrificar calidad)

Esta cápsula te da herramientas para controlar tu factura.

Tiempo: 25 minutos
Dificultad: Media


💰 Pricing de OpenAI (Febrero 2026)

Modelos y precios:

ModeloInput ($/1M tokens)Output ($/1M tokens)Context Window
gpt-4-turbo$10.00$30.00128k
gpt-4$30.00$60.008k
gpt-3.5-turbo$0.50$1.5016k

Actualizado: Siempre verifica en https://openai.com/pricing


Cómo se cobra:

Fórmula:

Costo = (Input tokens × Input price) + (Output tokens × Output price)

Ejemplo:

  • Prompt: 100 tokens (input)
  • Respuesta: 200 tokens (output)
  • Modelo: GPT-3.5-turbo

Cálculo:

Input:  100 tokens × $0.50/1M = $0.00005
Output: 200 tokens × $1.50/1M = $0.00030
Total:  $0.00035 por request

Para 1000 requests: $0.35


🔢 Contar Tokens

Método 1: Del response (exacto)

response = client.chat.completions.create(
    model="gpt-3.5-turbo",
    messages=[{"role": "user", "content": "Hola"}]
)

usage = response.usage
print(f"Input tokens:  {usage.prompt_tokens}")
print(f"Output tokens: {usage.completion_tokens}")
print(f"Total tokens:  {usage.total_tokens}")

Output:

Input tokens:  8
Output tokens: 12
Total tokens:  20

Método 2: Estimación con tiktoken (antes del request)

Útil para calcular costo ANTES de enviar.

Instalación:

pip install tiktoken

Código:

import tiktoken

def count_tokens(text: str, model: str = "gpt-3.5-turbo") -> int:
    """Cuenta tokens de un texto."""
    encoding = tiktoken.encoding_for_model(model)
    return len(encoding.encode(text))

# Test
prompt = "Explica qué es Python en 50 palabras"
tokens = count_tokens(prompt)
print(f"Prompt tiene {tokens} tokens")

# Estima costo (asumiendo 100 tokens de output)
input_cost = tokens * 0.50 / 1_000_000
output_cost = 100 * 1.50 / 1_000_000
total_cost = input_cost + output_cost
print(f"Costo estimado: ${total_cost:.6f}")

Reglas de thumb (aproximadas):

  • 1 token ≈ 4 caracteres (inglés)
  • 1 token ≈ 0.75 palabras (inglés)
  • Español: 1.2-1.5x más tokens (palabras más largas)

Ejemplo:

  • "Hello world" = 2 tokens (inglés)
  • "Hola mundo" = 3 tokens (español)

📊 Calcular Costo de tu App

Ejemplo real: FAQ Chatbot

Specs:

  • 1000 usuarios/día
  • 3 queries promedio/usuario
  • 50 tokens input promedio
  • 100 tokens output promedio

Cálculo mensual:

# Volumen
users_per_day = 1000
queries_per_user = 3
days_per_month = 30
total_queries = users_per_day * queries_per_user * days_per_month  # 90,000

# Tokens
input_tokens_per_query = 50
output_tokens_per_query = 100

total_input_tokens = total_queries * input_tokens_per_query    # 4.5M
total_output_tokens = total_queries * output_tokens_per_query  # 9M

# Costo (GPT-3.5-turbo)
input_cost = (total_input_tokens / 1_000_000) * 0.50   # $2.25
output_cost = (total_output_tokens / 1_000_000) * 1.50  # $13.50

total_monthly_cost = input_cost + output_cost  # $15.75/mes

Resultado: ~$16/mes para 90k queries


🚦 Rate Limits

Qué son:

Límites de requests/tokens por minuto para prevenir abuso.

Tiers (según cuánto has gastado):

TierRequisitoGPT-3.5 (RPM)GPT-4 (RPM)TPM
Free$0 gastado60340k
Tier 1$5+ gastado500500200k
Tier 2$50+ gastado500050002M

RPM: Requests per minute
TPM: Tokens per minute

Ver tus limits: https://platform.openai.com/account/rate-limits


Error cuando excedes:

openai.RateLimitError: Rate limit reached for requests

Solución: Implementa retries (cápsula 07).


💡 Estrategias de Optimización de Costos

1. Usa GPT-3.5 cuando sea suficiente

Regla: GPT-4 solo si NECESITAS máxima calidad.

Ejemplo:

  • FAQ simple → GPT-3.5 ✅
  • Análisis legal complejo → GPT-4 ✅
  • Clasificación → GPT-3.5 ✅

Ahorro: 20x (GPT-4 es 20x más caro)


2. Minimiza context (historial)

❌ Malo:

messages = last_50_messages  # 5000 tokens

✅ Bueno:

messages = last_5_messages   # 500 tokens

Ahorro: 10x menos input tokens


3. Usa max_tokens para limitar output

❌ Malo:

max_tokens=None  # GPT decide (puede generar 1000+ tokens)

✅ Bueno:

max_tokens=150  # Suficiente para FAQ

Ahorro: 6.6x menos output tokens


4. Cache respuestas comunes

import json

# Cache en memoria (simple)
cache = {}

def ask_with_cache(prompt: str) -> str:
    """Busca en cache antes de llamar API."""
    
    # Check cache
    if prompt in cache:
        print("[CACHE HIT]")
        return cache[prompt]
    
    # Cache miss → Llamar API
    print("[CACHE MISS - API call]")
    response = client.chat.completions.create(
        model="gpt-3.5-turbo",
        messages=[{"role": "user", "content": prompt}]
    )
    
    answer = response.choices[0].message.content
    
    # Guardar en cache
    cache[prompt] = answer
    
    return answer

# Test
print(ask_with_cache("¿Qué es Python?"))  # MISS (llama API)
print(ask_with_cache("¿Qué es Python?"))  # HIT (no llama API)

Ahorro: 100% para queries repetidas


5. Batching (requests agrupados)

Si procesas muchos textos similares:

# ❌ Malo: 100 requests
for text in texts:
    response = client.chat.completions.create(...)

# ✅ Bueno: 1 request con batch
batch_prompt = "\n\n".join([f"Text {i}: {text}" for i, text in enumerate(texts)])
response = client.chat.completions.create(
    messages=[{"role": "user", "content": f"Clasifica estos textos:\n{batch_prompt}"}]
)

Ahorro: Overhead de requests (menos tiempo, similar costo)


6. Summarization de conversaciones largas

En vez de enviar 50 mensajes:

# Cada 20 mensajes, resume
if len(messages) > 20:
    summary = summarize(messages[:-5])  # Resume los viejos
    messages = [system_message, summary] + messages[-5:]  # Mantén últimos 5

Ahorro: 80% input tokens en conversaciones largas


📈 Monitoring de Usage

Dashboard de OpenAI:

  1. Ve a: https://platform.openai.com/usage
  2. Verás gráficas de:
    • Costo diario
    • Requests por modelo
    • Tokens consumidos

Configura alertas:

  • Soft limit: $5/mes (alerta email)
  • Hard limit: $10/mes (para requests)

Logging en código:

import json
from datetime import datetime

def log_usage(prompt: str, response):
    """Guarda usage en archivo JSON."""
    
    log_entry = {
        "timestamp": datetime.now().isoformat(),
        "model": response.model,
        "prompt_tokens": response.usage.prompt_tokens,
        "completion_tokens": response.usage.completion_tokens,
        "total_tokens": response.usage.total_tokens,
        "prompt_preview": prompt[:50],  # Primeros 50 chars
    }
    
    # Append a archivo
    with open("usage_log.json", "a") as f:
        f.write(json.dumps(log_entry) + "\n")

# Uso
response = client.chat.completions.create(...)
log_usage(prompt, response)

Análisis después:

import json

total_tokens = 0
with open("usage_log.json") as f:
    for line in f:
        entry = json.loads(line)
        total_tokens += entry["total_tokens"]

cost = (total_tokens / 1_000_000) * 1.0  # Asumiendo avg $1/1M
print(f"Total cost: ${cost:.2f}")

🧮 Calculadora de Costos (Tool)

def calculate_cost(
    input_tokens: int,
    output_tokens: int,
    model: str = "gpt-3.5-turbo"
) -> dict:
    """Calcula costo de un request."""
    
    pricing = {
        "gpt-3.5-turbo": {"input": 0.50, "output": 1.50},
        "gpt-4-turbo": {"input": 10.00, "output": 30.00},
        "gpt-4": {"input": 30.00, "output": 60.00},
    }
    
    if model not in pricing:
        raise ValueError(f"Modelo desconocido: {model}")
    
    prices = pricing[model]
    
    input_cost = (input_tokens / 1_000_000) * prices["input"]
    output_cost = (output_tokens / 1_000_000) * prices["output"]
    total_cost = input_cost + output_cost
    
    return {
        "input_tokens": input_tokens,
        "output_tokens": output_tokens,
        "input_cost": input_cost,
        "output_cost": output_cost,
        "total_cost": total_cost,
        "model": model
    }

# Test
result = calculate_cost(100, 200, "gpt-3.5-turbo")
print(f"Costo total: ${result['total_cost']:.6f}")

📊 Resumen

Conceptos clave:

  1. Pricing:

    • Input tokens × Input price
    • Output tokens × Output price
    • GPT-3.5: $0.50/$1.50 per 1M tokens
  2. Rate limits:

    • Free tier: 60 RPM (GPT-3.5)
    • Tier 1: 500 RPM ($5+ gastado)
    • Implementa retries para manejar límites
  3. Optimización:

    • Usa GPT-3.5 cuando suficiente
    • Minimiza context/historial
    • Cache respuestas comunes
    • Limita output con max_tokens
  4. Monitoring:

    • Dashboard OpenAI (usage diario)
    • Logs custom (análisis detallado)
    • Alertas (soft/hard limits)

🔗 Recursos adicionales

  1. OpenAI Pricing - Actualizado
  2. Rate Limits - Docs oficial
  3. Tiktoken - Token counter
  4. Usage Dashboard - Monitoring

➡️ Próximo paso

Siguiente cápsula: 07-error-handling-retries.md

Aprenderás a manejar errores de producción:

  • Rate limit errors (429)
  • Timeouts
  • API errors (500, 503)
  • Exponential backoff
  • Retry strategies

Tiempo: 25 minutos


Tiempo estimado: 25 minutos
Siguiente: 07-error-handling-retries.md