pythonaillmbackendopenrouterfastapi

Un gateway para saber qué producto me quema la factura de LLM (y el día que mi README mintió)

Tengo varios productos que llaman a modelos de lenguaje. Uno le pregunta a un corpus de tesis, otro procesa imágenes, otro arma video. Todos consumen tokens, y hasta hace poco todos gastaban en el mismo pozo sin que yo supiera cuál gastaba qué.

El problema no es nuevo. Llega la factura, ves un número, y no tenés idea de qué feature lo disparó, qué producto se está yendo de rango, o si uno está repreguntando lo mismo mil veces. Te enterás cuando ya gastaste.

Esto es lo que hice para dejar de estar a ciegas, y una cosa incómoda que encontré en el camino.


La idea: un peaje en el medio

En vez de que cada producto llame directo al proveedor, todos pasan por un mismo servicio en el medio, un gateway. Expone la misma interfaz de siempre (/v1/chat/completions), así que para el producto cambia una sola cosa: la URL base. Nada más.

Y como todo pasa por ahí, el gateway puede hacer tres cosas que ningún producto por separado hacía:

Nada de esto es magia. Es un proxy con Postgres y un poco de criterio sobre qué guardar.


Por qué OpenRouter abajo

El gateway no habla con un proveedor específico, habla con OpenRouter, que es un agregador con una sola API compatible con OpenAI y acceso a muchos modelos (Gemini, Llama, Claude, y más) con una única key.

Esto resolvió dos cosas a la vez. Primero, dejé de atarme a un proveedor. Segundo, y esto es lo bueno, OpenRouter me da el gasto total pero no me lo desglosa por producto mío. El gateway se sienta justo ahí en el medio y agrega ese desglose que a OpenRouter no le corresponde tener. Cada uno hace su parte.


La parte incómoda: el README mentía

Cuando fui a revisar el repo para publicarlo, leí el README con ojos de desconocido. Prometía un failover automático: si un proveedor fallaba, la petición se reenrutaba sola a otro.

Abrí el código. No estaba. En ningún lado. Era una intención que en algún momento escribí como si ya existiera.

Es un detalle pequeño y a la vez no lo es. Un reclutador o un colega que abra ese código y note que el README dice algo que el programa no hace, deja de creerte el resto. Una feature inventada resta más de lo que suma cualquier feature real.

Así que hice lo aburrido y correcto: moví el failover a una sección de “roadmap”, marcada como no implementada, y dejé el README describiendo lo que el código hace hoy, no lo que me gustaría que hiciera. Prefiero un proyecto que promete menos y cumple todo, que uno que impresiona en el README y decepciona en el git clone.


Dónde quedó

El gateway está corriendo en producción, y el primer producto que lo consume de verdad es mi buscador de tesis: le cambié el cliente para que apunte al gateway, le pasé su identificador de tenant, y ahora cada pregunta que responde queda registrada con su costo. Lo puedo mirar y decir “este producto va por acá de gasto”, sin adivinar.

El molde quedó listo para enchufar los demás productos igual: apuntar su cliente al gateway, ponerle su nombre de tenant, y aparece solo en la contabilidad.

El código está acá: github.com/GeosData/llm-quota-gateway. Con los ADRs de las decisiones que sí tomé, y un roadmap honesto de las que todavía no.

compartir

X LinkedIn
Volver al blog