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:
| Modelo | Input ($/1M tokens) | Output ($/1M tokens) | Context Window |
|---|---|---|---|
| gpt-4-turbo | $10.00 | $30.00 | 128k |
| gpt-4 | $30.00 | $60.00 | 8k |
| gpt-3.5-turbo | $0.50 | $1.50 | 16k |
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):
| Tier | Requisito | GPT-3.5 (RPM) | GPT-4 (RPM) | TPM |
|---|---|---|---|---|
| Free | $0 gastado | 60 | 3 | 40k |
| Tier 1 | $5+ gastado | 500 | 500 | 200k |
| Tier 2 | $50+ gastado | 5000 | 5000 | 2M |
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:
- Ve a: https://platform.openai.com/usage
- 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:
-
Pricing:
- Input tokens × Input price
- Output tokens × Output price
- GPT-3.5: $0.50/$1.50 per 1M tokens
-
Rate limits:
- Free tier: 60 RPM (GPT-3.5)
- Tier 1: 500 RPM ($5+ gastado)
- Implementa retries para manejar límites
-
Optimización:
- Usa GPT-3.5 cuando suficiente
- Minimiza context/historial
- Cache respuestas comunes
- Limita output con
max_tokens
-
Monitoring:
- Dashboard OpenAI (usage diario)
- Logs custom (análisis detallado)
- Alertas (soft/hard limits)
🔗 Recursos adicionales
- OpenAI Pricing - Actualizado
- Rate Limits - Docs oficial
- Tiktoken - Token counter
- 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