Reducir los costos de los LLM: Estrategias de optimización de tokens

Reduzca los costos de los LLM en un 80 % con una optimización inteligente de tokens

Índice

La optimización de tokens es la habilidad crítica que separa las aplicaciones de LLM rentables de los experimentos que drenan el presupuesto.

Dado que los costos de la API escalan linealmente con el uso de tokens, comprender e implementar estrategias de optimización puede reducir los gastos entre un 60-80% manteniendo la calidad.

Los bucles de agentes autoalojados añaden una segunda factura en tokens de finalización desperdiciados cuando el muestreo es demasiado alto; los parámetros de inferencia de agentes para Qwen y Gemma recopilan valores predeterminados que limitan los reintentos sin privar de capacidad de razonamiento.

arquitectura inteligente

Comprensión de la economía de tokens

Antes de optimizar, es necesario entender cómo funcionan los tokens y la facturación en diferentes proveedores de LLM.

Conceptos básicos de tokens

Los tokens son las unidades fundamentales que procesan los LLM, equivalentes aproximadamente a 4 caracteres o 0,75 palabras en inglés. La cadena “¡Hola, mundo!” contiene aproximadamente 4 tokens. Diferentes modelos utilizan diferentes tokenizadores (GPT usa tiktoken, Claude usa el suyo propio), por lo que el conteo de tokens varía ligeramente entre proveedores.

Comparación de modelos de precios

Precios de OpenAI (a partir de 2025):

  • GPT-4 Turbo: $0,01 entrada / $0,03 salida por 1K tokens
  • GPT-3.5 Turbo: $0,0005 entrada / $0,0015 salida por 1K tokens
  • GPT-4o: $0,005 entrada / $0,015 salida por 1K tokens

Precios de Anthropic:

  • Claude 3 Opus: $0,015 entrada / $0,075 salida por 1K tokens
  • Claude 3 Sonnet: $0,003 entrada / $0,015 salida por 1K tokens
  • Claude 3 Haiku: $0,00025 entrada / $0,00125 salida por 1K tokens

Para una comparación exhaustiva de Proveedores de LLM en la nube, incluyendo precios detallados, características y casos de uso, consulte nuestra guía dedicada.

Insight clave: Los tokens de salida cuestan 2-5 veces más que los tokens de entrada. Limitar la longitud de la salida tiene un impacto desproporcionado en los costos.

Ingeniería de prompts para la eficiencia

La ingeniería de prompts efectiva reduce drásticamente el consumo de tokens sin sacrificar la calidad.

1. Eliminar redundancia

Ejemplo incorrecto (127 tokens):

Eres un asistente útil. Por favor, ayúdame con la siguiente tarea.
Me gustaría que analizaras el siguiente texto y me proporcionaras
un resumen. Aquí está el texto que me gustaría que resumieras:
[texto]
Por favor, proporciona un resumen conciso de los puntos principales.

Optimizado (38 tokens):

Resume los puntos clave:
[texto]

Ahorro: 70% de reducción de tokens, calidad de salida idéntica.

2. Utilizar formatos estructurados

JSON y las salidas estructuradas reducen el desperdicio de tokens proveniente del lenguaje natural verboso.

En lugar de:

Por favor, extrae el nombre, la edad y la ocupación de la persona de este texto
y formatea tu respuesta claramente.

Usar:

Extraer a JSON: {nombre, edad, ocupación}
Texto: [entrada]

3. Optimización del aprendizaje con pocos ejemplos (Few-Shot)

Los ejemplos de few-shot son poderosos pero costosos. Optimízalos mediante:

  • Usar el mínimo de ejemplos necesarios (1-3 suelen ser suficientes)
  • Mantener los ejemplos concisos - eliminar palabras innecesarias
  • Compartir prefijos comunes - reducir instrucciones repetidas
# Prompt few-shot optimizado
prompt = """Clasificar sentimiento (pos/neg):
Texto: "¡Gran producto!" -> pos
Texto: "Decepcionado" -> neg
Texto: "{entrada_usuario}" ->"""

Para más patrones de optimización en Python y atajos de sintaxis, consulte nuestra Hoja de trucos de Python.

Estrategias de caché de contexto

El caché de contexto es la optimización más efectiva para aplicaciones con contenido estático repetido.

Cómo funciona el caché de contexto

Proveedores como OpenAI y Anthropic almacenan en caché los prefijos de prompts que aparecen en múltiples solicitudes. Las porciones en caché cuestan un 50-90% menos que los tokens regulares.

Requisitos:

  • Contenido mínimo en caché: 1024 tokens (OpenAI) o 2048 tokens (Anthropic)
  • TTL de caché: 5-60 minutos dependiendo del proveedor
  • El contenido debe ser idéntico y aparecer al inicio del prompt

Ejemplo de implementación

from openai import OpenAI

client = OpenAI()

# Mensaje del sistema en caché entre solicitudes
SYSTEM_PROMPT = """Eres una IA de servicio al cliente para TechCorp.
Políticas de la empresa:
[Documento de política grande - 2000 tokens]
"""

# Esto se almacena en caché automáticamente
response = client.chat.completions.create(
    model="gpt-4-turbo",
    messages=[
        {"role": "system", "content": SYSTEM_PROMPT},
        {"role": "user", "content": "¿Cómo devuelvo un artículo?"}
    ]
)

# Las llamadas posteriores dentro del TTL de la caché usan el prompt del sistema en caché
# Pagando solo por el mensaje del usuario + salida

Impacto en el mundo real: Las aplicaciones con bases de conocimiento o instrucciones extensas ven una reducción de costos del 60-80%.

Estrategia de selección de modelos

Usar el modelo correcto para cada tarea es crucial para la optimización de costos.

La escalera de modelos

  1. GPT-4 / Claude Opus - Razonamiento complejo, tareas creativas, precisión crítica
  2. GPT-4o / Claude Sonnet - Rendimiento/costo equilibrado, uso general
  3. GPT-3.5 / Claude Haiku - Tareas simples, clasificación, extracción
  4. Modelos pequeños ajustados (fine-tuned) - Tareas repetitivas especializadas

Patrón de enrutamiento

def route_request(task_complexity, user_query):
    """Enrutar al modelo apropiado según la complejidad"""
    
    # Clasificación simple - usar Haiku
    if task_complexity == "simple":
        return call_llm("claude-3-haiku", user_query)
    
    # Moderado - usar Sonnet
    elif task_complexity == "moderate":
        return call_llm("claude-3-sonnet", user_query)
    
    # Razonamiento complejo - usar Opus
    else:
        return call_llm("claude-3-opus", user_query)

Estudio de caso: Un chatbot de servicio al cliente que enruta el 80% de las consultas a GPT-3.5 y el 20% a GPT-4 redujo los costos en un 75% en comparación con usar GPT-4 para todo.

Procesamiento por lotes (Batch)

Para cargas de trabajo no sensibles al tiempo, el procesamiento por lotes ofrece descuentos del 50% de la mayoría de los proveedores.

API por lotes de OpenAI

from openai import OpenAI
client = OpenAI()

# Crear archivo de lotes
batch_requests = [
    {"custom_id": f"request-{i}", 
     "method": "POST",
     "url": "/v1/chat/completions",
     "body": {
         "model": "gpt-3.5-turbo",
         "messages": [{"role": "user", "content": query}]
     }}
    for i, query in enumerate(queries)
]

# Enviar lote (50% de descuento, procesamiento de 24h)
batch = client.batches.create(
    input_file_id=upload_batch_file(batch_requests),
    endpoint="/v1/chat/completions",
    completion_window="24h"
)

Casos de uso:

  • Etiquetado y anotación de datos
  • Generación de contenido para blogs/SEO
  • Generación de informes
  • Traducciones por lotes
  • Generación sintética de conjuntos de datos

Técnicas de control de salida

Dado que los tokens de salida cuestan 2-5 veces más, controlar la longitud de la salida es crítico.

1. Establecer tokens máximos

response = client.chat.completions.create(
    model="gpt-4",
    messages=messages,
    max_tokens=150  # Límite estricto previene costos descontrolados
)

2. Usar secuencias de parada

response = client.chat.completions.create(
    model="gpt-4",
    messages=messages,
    stop=["END", "\n\n\n"]  # Detenerse en marcadores
)

3. Solicitar formatos concisos

Añadir instrucciones como:

  • “Responder en menos de 50 palabras”
  • “Proporcionar solo puntos clave”
  • “Devolver solo JSON, sin explicación”

Transmisión (Streaming) para una mejor UX

Aunque la transmisión no reduce los costos, mejora el rendimiento percibido y permite la terminación temprana.

stream = client.chat.completions.create(
    model="gpt-4",
    messages=messages,
    stream=True
)

for chunk in stream:
    if chunk.choices[0].delta.content:
        token = chunk.choices[0].delta.content
        print(token, end="")
        
        # Terminación temprana si la respuesta se desvía
        if undesired_pattern(token):
            break

Optimización de RAG

La Generación Aumentada con Recuperación (RAG) añade contexto, pero un RAG no optimizado desperdicia tokens.

Patrón de RAG eficiente

def optimized_rag(query, vector_db):
    # 1. Recuperar fragmentos relevantes
    chunks = vector_db.search(query, top_k=3)  # No demasiados
    
    # 2. Comprimir fragmentos - eliminar redundancia
    compressed = compress_chunks(chunks)  # Compresión personalizada
    
    # 3. Truncar al límite de tokens
    context = truncate_to_tokens(compressed, max_tokens=2000)
    
    # 4. Prompt estructurado
    prompt = f"Contexto:\n{context}\n\nP: {query}\nR:"
    
    return call_llm(prompt)

Técnicas de optimización:

  • Usar segmentación semántica (no de tamaño fijo)
  • Eliminar el formato de markdown de los fragmentos recuperados
  • Implementar re-clasificación para obtener el contenido más relevante
  • Considerar la resumen de fragmentos para documentos grandes

Caché de respuestas

Almacenar en caché solicitudes idénticas o similares para evitar llamadas a la API por completo.

Implementación con Redis

import redis
import hashlib
import json

redis_client = redis.Redis()

def cached_llm_call(prompt, model="gpt-4", ttl=3600):
    # Crear clave de caché desde el prompt + modelo
    cache_key = hashlib.md5(
        f"{model}:{prompt}".encode()
    ).hexdigest()
    
    # Verificar caché
    cached = redis_client.get(cache_key)
    if cached:
        return json.loads(cached)
    
    # Llamar al LLM
    response = call_llm(model, prompt)
    
    # Almacenar resultado en caché
    redis_client.setex(
        cache_key, 
        ttl, 
        json.dumps(response)
    )
    
    return response

Caché semántico: Para consultas similares (no idénticas), usar embeddings vectoriales para encontrar respuestas en caché.

Monitoreo y analítica

Rastrear el uso de tokens para identificar oportunidades de optimización.

Métricas esenciales

class TokenTracker:
    def __init__(self):
        self.metrics = {
            'total_tokens': 0,
            'input_tokens': 0,
            'output_tokens': 0,
            'cost': 0.0,
            'requests': 0
        }
    
    def track_request(self, response, model):
        usage = response.usage
        self.metrics['input_tokens'] += usage.prompt_tokens
        self.metrics['output_tokens'] += usage.completion_tokens
        self.metrics['total_tokens'] += usage.total_tokens
        self.metrics['cost'] += calculate_cost(usage, model)
        self.metrics['requests'] += 1
    
    def report(self):
        return {
            'avg_tokens_per_request': 
                self.metrics['total_tokens'] / self.metrics['requests'],
            'total_cost': self.metrics['cost'],
            'input_output_ratio': 
                self.metrics['input_tokens'] / self.metrics['output_tokens']
        }

Alertas de costos

Establecer alertas cuando el uso exceda los umbrales:

def check_cost_threshold(daily_cost, threshold=100):
    if daily_cost > threshold:
        send_alert(f"El costo diario de ${daily_cost} superó los ${threshold}")

Técnicas avanzadas

1. Modelos de compresión de prompts

Usar modelos dedicados para comprimir prompts:

  • LongLLMLingua
  • AutoCompressors
  • Tokens de compresión aprendidos

Estos pueden lograr ratios de compresión de 10x manteniendo un rendimiento de tarea superior al 90%.

2. Decodificación especulativa

Ejecutar un modelo pequeño junto con un modelo grande para predecir tokens, reduciendo las llamadas al modelo grande. Típicamente una aceleración de 2-3x y reducción de costos para una calidad similar.

3. Cuantización

Para modelos autoalojados, la cuantización (4-bit, 8-bit) reduce la memoria y el cómputo:

  • 4-bit: ~75% de reducción de memoria, pérdida mínima de calidad
  • 8-bit: ~50% de reducción de memoria, pérdida de calidad insignificante

Si estás ejecutando LLMs localmente, Ollama proporciona una excelente plataforma para desplegar modelos cuantizados con una configuración mínima. Para la selección de hardware y benchmarks de rendimiento, nuestra comparación entre NVIDIA DGX Spark, Mac Studio y RTX-4080 muestra el rendimiento en el mundo real en diferentes configuraciones de hardware ejecutando modelos cuantizados grandes.

Lista de verificación de optimización de costos

  • Perfilar el uso actual de tokens y costos por punto final
  • Auditar prompts en busca de redundancia - eliminar palabras innecesarias
  • Implementar caché de contexto para contenido estático > 1K tokens
  • Configurar enrutamiento de modelos (pequeño para tareas simples, grande para complejas)
  • Añadir límites de max_tokens a todas las solicitudes
  • Implementar caché de respuestas para consultas idénticas
  • Usar la API por lotes para cargas de trabajo no urgentes
  • Habilitar la transmisión para una mejor UX
  • Optimizar RAG: menos fragmentos, mejor clasificación
  • Monitorear con rastreo de tokens y alertas de costos
  • Considerar ajuste fino (fine-tuning) para tareas repetitivas
  • Evaluar modelos más pequeños (Haiku, GPT-3.5) para clasificación

Estudio de caso en el mundo real

Escenario: Chatbot de soporte al cliente, 100K solicitudes/mes

Antes de la optimización:

  • Modelo: GPT-4 para todas las solicitudes
  • Tokens de entrada promedio: 800
  • Tokens de salida promedio: 300
  • Costo: 100K × (800 × 0,00003 + 300 × 0,00006) = $4.200/mes

Después de la optimización:

  • Enrutamiento de modelos: 80% GPT-3.5, 20% GPT-4
  • Caché de contexto: 70% de los prompts en caché
  • Compresión de prompts: 40% de reducción
  • Caché de respuestas: 15% de tasa de acierto en caché

Resultados:

  • El 85% de las solicitudes evitaban GPT-4
  • El 70% se beneficiaba del descuento por caché de contexto
  • 40% menos tokens de entrada
  • Costo efectivo: $780/mes
  • Ahorro: 81% ($3.420/mes)

Enlaces útiles

Conclusión

La optimización de tokens transforma la economía de los LLM, pasando de ser prohibitivamente costosa a escalable de manera sostenible. Al implementar compresión de prompts, caché de contexto, selección inteligente de modelos y caché de respuestas, la mayoría de las aplicaciones logran una reducción de costos del 60-80% sin comprometer la calidad.

Comience con las victorias rápidas: audite sus prompts, habilite el caché de contexto y enrute tareas simples a modelos más pequeños. Monitoree su uso de tokens con rigor: lo que se mide se optimiza. La diferencia entre una aplicación de LLM rentable y una costosa no es la tecnología, es la estrategia de optimización.

Artículos relacionados

Suscribirse

Recibe nuevas publicaciones sobre sistemas, infraestructura e ingeniería de IA.