Inicio / Artículos / Adónde se iba nuestra factura de la API de LLM y qué cambios de arquitectura la recortaron

Adónde se iba nuestra factura de la API de LLM y qué cambios de arquitectura la recortaron

Atribución de tokens por paso, escalonado de modelos, prompts más cortos y backoff con jitter redujeron el gasto en API de un agente de programación; con fórmulas de coste y errores de optimización habituales.

1861 palabras

Una factura de LLM puede salir alta aunque los modelos en sí no sean especialmente caros. En este caso la causa eran unos hábitos: el mismo system prompt de 1.800 tokens viajaba con cada llamada, los fallos se reintentaban al instante sin backoff y cada paso del flujo iba por defecto a un modelo de frontera, lo necesitara o no. La estimación para esta carga fue que el precio por token explicaba cerca del 20 % del problema y la arquitectura el 80 % restante. Ese reparto es propio de este sistema y no es un benchmark general. Aun así, la lección se aplica bien en otros sitios: el precio de tarifa por token te dice la tasa, no la eficiencia con la que tu aplicación la aprovecha.

Antes de cambiar de proveedor o regatear precios, se instrumentó el gasto, y así cada decisión posterior se basó en pruebas y no en intuición. No puedes optimizar lo que no registras.

Atribuye los tokens a los pasos del flujo

El primer requisito es atribuir a nivel de paso. Para cada llamada a la API, registra el paso del flujo, el modelo, los tokens de entrada y los de salida, y agrega cada noche por paso y modelo. Con precios por millón de tokens, el coste de un paso se calcula así:

step cost =
number of calls × [
  (average input tokens ÷ 1,000,000 × input price per 1M tokens)
  +
  (average output tokens ÷ 1,000,000 × output price per 1M tokens)
]

Una semana de datos dio un desglose representativo para la carga de un agente de programación, y el hallazgo principal fue una sorpresa: el paso de planificación suponía solo el 8 % de las llamadas, pero el 41 % del gasto total. Era caro porque juntaba los contextos más largos con el modelo más caro. Antes de medir se daba por hecho que lo caro era la generación de código, y los datos demostraron que no. El número de peticiones por sí solo no era la métrica correcta. El gasto total por paso sí lo era.

Una implementación mínima

Resultó sencillo, porque las respuestas de la API ya incluyen datos de uso de tokens:

import logging
from openai import OpenAI

client = OpenAI(
    api_key="KEY",
    base_url="https://api.cometapi.com/v1",
)
def tracked_call(step_name, model, messages):
    response = client.chat.completions.create(
        model=model,
        messages=messages,
        temperature=0,
    )
    usage = response.usage
    logging.info(
        "llm_call step=%s model=%s prompt=%d completion=%d",
        step_name,
        model,
        usage.prompt_tokens,
        usage.completion_tokens,
    )
    return response

Con esos registros, el informe de costes es básicamente un GROUP BY. El objetivo no es una plataforma de observabilidad sofisticada, sino garantizar que cada token se pueda rastrear hasta un paso del flujo y un modelo.

Aprovecha el descuento del gateway, pero tómalo como suelo

Aquí las peticiones pasan por CometAPI y, con este uso, el coste resultante quedó en torno a un 20 % por debajo de pagar directamente a los proveedores por la misma mezcla de modelos. Fue un ahorro de poco esfuerzo: el patrón del cliente y la elección de modelos siguieron igual, y la factura bajó en todos los modelos que ya se usaban. Se aplicó de inmediato porque apenas exigía trabajo de arquitectura.

Pero el gateway no fue la mayor palanca. Los cambios de arquitectura posteriores ahorraron más, a cambio de trabajo de ingeniería real. El orden de implantación y el impacto económico no siempre coinciden, así que aprovecha enseguida los ahorros baratos de precio y dedica el tiempo de ingeniería al enrutamiento de modelos, la sobrecarga de los prompts y el comportamiento de los reintentos. No hay motivo para aplazar un ahorro inmediato mientras construyes algo más elaborado, pero una tarifa más baja no compensa un diseño de peticiones ineficiente. Los detalles de facturación están en la documentación de precios de CometAPI.

Envía cada paso al nivel de modelo adecuado

Escalonar significa asignar modelos distintos a pasos distintos del flujo según la calidad que necesita cada uno. La planificación sí necesitaba un modelo de frontera. Tiene poco volumen pero mucho impacto, porque un mal plan puede estropear todas las acciones que vienen después. Las ediciones masivas y las correcciones de lint tienen otras necesidades: mucho volumen, alcance muy acotado y facilidad para reintentar o verificar. La lógica de enrutamiento cambió en consecuencia:

def choose_model(step):
    if step in ("plan", "hard_refactor"):
        return "claude-sonnet-4-6"  # High-value reasoning steps

if step in ("bulk_edit", "lint_fix"):
        return "gemini-2.5-flash"  # Lower-cost, fast, retry failures
    return "gpt-5-mini"  # Middle-tier default

Eso trasladó el 46 % de las llamadas a un modelo más barato y rápido, y reservó el caro para la planificación y la generación difícil. El escalonado dio la mayor reducción individual de la factura, porque atacó los pasos de mucho volumen y no persiguió pequeños ahorros en los de poco. El principio es simple: usa el modelo más potente donde los errores salen más caros aguas abajo, no en todas partes por defecto.

Elimina la sobrecarga repetida del prompt

El system prompt de 1.800 tokens acompañaba a cada petición. Buena parte era texto defensivo acumulado durante meses: cada instrucción parecía inofensiva al añadirla, pero juntas formaban un coste fijo enorme por llamada. La solución fue quitar instrucciones redundantes, dejar solo las restricciones esenciales y mover la parte estable a un prefijo en caché siempre que el proveedor admita prompt caching.

Es fácil subestimar la escala. Con un millón de llamadas, solo un system prompt invariable de 1.800 tokens supone:

1,000,000 calls × 1,800 tokens
= 1.8 billion input tokens

y eso antes de cualquier contexto específico de la tarea. Los tokens del prompt son tokens como cualquier otro. El prompt inflado encarecía la API y además se comía la cuota de tokens por minuto en cada petición, así que limpiarlo ayudó dos veces: bajó el coste recurrente de entrada y permitió meter más trabajo útil dentro de los mismos límites de tasa. Se recortó antes de cachear, porque cachear texto innecesario solo habría conservado el problema de diseño de fondo.

Reintenta con backoff y jitter

Los reintentos suponían el 12 % de las llamadas. Muchos llegaban tras una respuesta HTTP 429 por límite de tasa: el sistema reintentaba al momento en condiciones casi idénticas, recibía otro 429 y a veces parecía alargar el periodo de bloqueo. El reintento inmediato se sustituyó por backoff exponencial con jitter. El backoff aumenta progresivamente la espera entre intentos y el jitter añade algo de aleatoriedad para que las peticiones concurrentes no reintenten todas en el mismo instante. El volumen de reintentos cayó a menos de la mitad.

No todas las peticiones rechazadas se facturan igual, pero los reintentos a ciegas aumentan igualmente el volumen de peticiones y pueden provocar trabajo facturable repetido cuando una petición llega a ejecutarse en el modelo. Aquí, controlar los reintentos mejoró la fiabilidad y además contuvo el coste. La regla general es que un reintento debe responder a la causa del fallo, y repetir la misma petición al instante no es recuperarse.

Qué cambio pesó más

Los cuatro cambios atacaron partes distintas de la ecuación de coste:

  • El escalonado de modelos dio la mayor reducción individual: pasó el 46 % de las llamadas a un modelo más barato mientras el caro conservaba el trabajo más importante. Implantarlo llevó cerca de un día.
  • El enrutamiento por gateway fue el ahorro inmediato más fácil: recortó alrededor de un 20 % el coste de la misma mezcla de modelos casi sin ingeniería.
  • Recortar y cachear el prompt eliminó la sobrecarga recurrente de entrada, porque hasta la tarea más sencilla arrastraba el prompt de 1.800 tokens.
  • El backoff y el jitter redujeron el volumen innecesario de peticiones: los reintentos pasaron del 12 % de las llamadas a menos de la mitad de eso.

Juntos lograron más que cualquier cambio por separado. No sumes los ahorros como si fueran descuentos independientes. El precio del gateway cambia la tarifa por token, el escalonado cambia la tarifa media combinada entre pasos, el recorte del prompt cambia el número de tokens de entrada y el control de reintentos cambia el número de peticiones. Además, cada cambio modifica la base de coste sobre la que actúa el siguiente.

Cómo calcular el coste mensual

Supongamos que un sistema atiende un millón de peticiones al mes, con una media de 2.000 tokens de entrada y 500 de salida cada una. El volumen mensual de tokens es:

Input:
1,000,000 × 2,000
= 2 billion tokens

Output:
1,000,000 × 500
= 500 million tokens

Con precios por millón de tokens, el coste mensual de partida es:

monthly cost =
2,000 × input price per 1M tokens
+
500 × output price per 1M tokens

Aquí, el gateway recortó esa base cerca de un 20 % antes de cualquier cambio de arquitectura. Después, el escalonado bajó la tarifa combinada por token, porque el 46 % de las peticiones pasó a un modelo que cuesta una fracción por token. El recorte del prompt redujo los tokens de entrada de cada petición afectada y el control de reintentos eliminó peticiones innecesarias. Por tanto, un cálculo correcto necesita cuatro variables: el volumen de peticiones, la mezcla de tokens de entrada y salida, la asignación de modelos por paso del flujo y los precios actuales de cada modelo. Por eso no existe una cifra universal de «ahorrarás un X %». La única estimación útil sale de tu propia carga.

Tres maneras de que el trabajo de costes salga mal

Optimizar pasos de poco volumen porque es fácil. Tienta arañar céntimos de un paso pequeño mientras uno de mucho volumen se come casi todo el presupuesto. Ordena los objetivos por gasto total y no por lo fácil que es cambiarlos, y por eso la atribución tiene que ir primero.

Recortar costes sin comprobar la calidad. Un paso pasa a un modelo más barato, la factura baja y el cambio parece un éxito. Tres semanas después alguien nota que la salida ha empeorado. Somete cada cambio de modelo a un conjunto de evaluación, una colección representativa de tareas que detecte regresiones. Un ahorro que no supera el listón de calidad no es una optimización.

Construir una caché antes de medir la reutilización. La caché solo ayuda donde el contenido se repite de verdad. Una caché elaborada, montada antes de comprobar cuánto se reutilizan los prompts, puede quemar tiempo de ingeniería sin tocar el principal motor de coste. Comprueba primero cuánta repetición hay y solo entonces cachea los prefijos o respuestas que de verdad vuelven. El trabajo de costes sin medición puede mejorar la factura y a la vez empeorar la calidad, la latencia o la fiabilidad.

Deja la instrumentación encendida

No apagues la instrumentación tras la primera pasada, porque los costes vuelven a subir poco a poco. El system prompt se alarga de a poco, un paso nuevo del flujo arranca con el modelo caro, vuelve un viejo bug de reintentos o el tráfico se desplaza a un paso que antes era secundario. El panel que destapó el problema original es también lo que impide que regrese en silencio. Una revisión mensual de la tabla de costes por paso lleva unos diez minutos y ya ha detectado dos regresiones.

Arquitectura, no precios

Un precio por token es solo una tarifa. Lo que gastas de verdad depende de tu arquitectura: cuántos tokens compras, qué modelos los procesan y cuánto trabajo se repite. Para la carga de este agente de programación, la secuencia más eficaz fue:

  1. Instrumentar cada llamada por paso del flujo y modelo.
  2. Aprovechar el ahorro del gateway, que cuesta poco esfuerzo.
  3. Enviar cada paso al modelo más barato que cumpla sus requisitos de calidad.
  4. Quitar la sobrecarga repetida del prompt y cachear los prefijos estables donde se admita.
  5. Sustituir los reintentos a ciegas por backoff y jitter.
  6. Mantener la monitorización de forma permanente para que los costes no vuelvan a colarse.

Mayor victoria: el escalonado. Victoria más rápida: el gateway, con casi un 20 %. Recortar el prompt quitó un coste fijo de cada petición y unos reintentos más inteligentes redujeron el tráfico de reintentos a menos de la mitad. Buscar el precio por token más barato anunciado importa mucho menos que saber adónde van tus propios tokens. Medir es lo que hace visible la arquitectura.