Ir al contenido
OmniRoute source

Usage, Quota & Spend Tracking (Español)

Cada solicitud que pasa por OmniRoute genera un registro de uso que contiene:

  • Identidad: qué clave de API, proveedor, modelo y combinación
  • Tokens: tokens del prompt, tokens de finalización, tokens en caché y total
  • Coste: importe en USD (calculado a partir de los datos de precios)
  • Tiempos: latencia y marcas de tiempo de inicio/fin
  • Estado: éxito, error, limitación por tasa, etc.

Estos registros se agregan en análisis, se conservan como instantáneas de cuota y se utilizan para aplicar límites de presupuesto por clave.

Solicitud ──▶ chatCore ──▶ usage.record() ──▶ SQLite
│
┌───────┼───────┐
▼ ▼ ▼
análisis cuota facturación
(panel) (aplicar) (exportar)

El servicio usage.ts captura un evento de uso para cada solicitud:

Campo Tipo Origen
id string UUID generado al registrar
apiKeyId string La clave de API que inició la solicitud
provider string ID del proveedor (openai, anthropic, etc.)
model string ID del modelo (gpt-5, claude-opus-4-6, etc.)
comboId string? ID de la combinación si se enrutó mediante una combinación
promptTokens number De la respuesta del proveedor
completionTokens number De la respuesta del proveedor
cachedTokens number Tokens encontrados en caché (caché de prompts de Anthropic, etc.)
totalTokens number prompt + finalización
costUsd number Calculado a partir de los datos de precios
latencyMs number Duración total de la solicitud
status enum success, error, rate_limited, timeout, cancelled
errorClass string? Clase de error si status != success
timestamp string ISO 8601 UTC
metadata object Datos personalizados inyectados por plugins

Los tokens se extraen de la respuesta del proveedor en el controlador de respuestas:

// De open-sse/handlers/chatCore.ts
const response = await providerExecutor.execute(provider, request);
const usage = response.usage || {
prompt_tokens: 0,
completion_tokens: 0,
cached_tokens: 0,
};

Para los proveedores que no devuelven datos de uso (algunos proveedores basados en cookies web), OmniRoute estima los tokens mediante una heurística de ~4 caracteres por token (consulte open-sse/services/autoCombo/pipelineRouter.ts).

OmniRoute registra cached_tokens por separado de prompt_tokens porque:

  • El almacenamiento en caché de prompts de Anthropic aplica una tarifa reducida a los tokens en caché (el 10 % de la tarifa normal)
  • Algunos proveedores devuelven cache_read_input_tokens, cuyo precio debe calcularse de forma diferente
  • Los análisis pueden mostrar la tasa de aciertos de caché = cached_tokens / prompt_tokens

Los costes se calculan a partir de los datos de precios sincronizados desde LiteLLM (src/lib/pricingSync.ts):

Modelo Entrada $/1M Salida $/1M En caché $/1M
gpt-5 $2.50 $10.00 —
claude-opus-4-6 $15.00 $75.00 $1.50
claude-sonnet-4-5 $3.00 $15.00 $0.30
gemini-2.5-pro $1.25 $10.00 —

La fórmula de coste (src/lib/usage/costCalculator.ts):

cost =
(prompt_tokens - cached_tokens) * input_price +
cached_tokens * cached_price +
completion_tokens * output_price;

¿Por qué se resta la parte en caché del prompt? La parte en caché tiene un precio independiente; aplicar el precio de entrada al prompt completo produciría un recuento excesivo.

Los datos de precios se sincronizan automáticamente desde LiteLLM mediante el endpoint /api/pricing/sync (activado por la tarea cron integrada, no por una variable de entorno expuesta al usuario):

Ventana de terminal
# Activación manual
curl -X POST http://localhost:20128/api/pricing/sync

Para los modelos sin datos de precios, OmniRoute recurre a estimar el coste mediante tarifas medias internas (obtenidas de los datos de precios de LiteLLM).


El módulo usageAnalytics.ts calcula los widgets del panel a partir de los datos de uso sin procesar. Admite 7 intervalos de tiempo:

Intervalo Ventana Caso de uso
1d Últimas 24 horas Detección horaria de picos de coste
7d Últimos 7 días Revisión semanal
30d Últimos 30 días Facturación mensual
90d Últimos 90 días Análisis trimestral
ytd Desde el 1 de enero del año en curso Seguimiento del presupuesto anual
all Todo el período Estadísticas históricas
custom Inicio/fin definidos por el usuario Auditorías, consultas ad hoc

Para cualquier intervalo de fechas, la capa de análisis calcula:

Widget Descripción
Tarjetas de resumen Solicitudes totales, coste total, tokens totales, tasa de éxito
Gráfico de tendencia diaria Coste + tokens por día, apilados por modelo
Mapa de calor de actividad Cuadrícula de hora del día × día de la semana, color = número de solicitudes
Desglose por modelo Gráfico circular del coste por modelo
Desglose por proveedor Gráfico de barras de las solicitudes por proveedor
Principales claves de API Tabla de las 10 claves principales por coste
Análisis de errores Tasa de errores a lo largo del tiempo, principales clases de error
import { computeAnalytics } from "@/lib/usageAnalytics";
const analytics = await computeAnalytics(
history, // registros del historial de uso
"7d", // intervalo de tiempo: "1d" | "7d" | "30d" | "90d" | "ytd" | "all" | "custom"
connectionMap, // mapa de conexiones de proveedores (connectionId → nombre de la cuenta)
{
startDate: "2025-01-01", // opcional: para el intervalo "custom"
endDate: "2025-06-01", // opcional: para el intervalo "custom"
}
);
console.log(analytics.summary.totalCost); // 12.34 (centavos)
console.log(analytics.byModel[0]); // { model, cost, requests, promptTokens, completionTokens }
---
## Aplicación de cuotas
La cuota por clave de API se aplica en dos lugares:
1. **Límite flexible** (`quotaWarnAt`): advertencia en el panel cuando el uso supera el umbral
2. **Límite estricto** (`quotaLimit`): la solicitud se rechaza con HTTP 429 cuando se supera
### Configuración
```ts
// Por clave de API
await updateApiKey(keyId, {
quotaWarnAt: 5_00, // $5.00 — mostrar advertencia
quotaLimit: 10_00, // $10.00 — límite estricto
quotaWindow: "month", // "day" | "week" | "month" | "all"
});
Solicitud ──▶ quotaCheck()
│
├── ¿Dentro del límite? ──▶ permitir
│
└── ¿Límite superado? ──▶ 429 Too Many Requests
con encabezado Retry-After

La tabla quotaSnapshots almacena el estado histórico de las cuotas para el análisis de tendencias:

| Campo | Descripción | | ———– | –––––––––––––––––––––– | —— | —–– | | apiKeyId | La clave de la que se realiza el seguimiento | | window | “day” | “week” | “month” | | used | Coste utilizado en esta ventana (centavos) | | limit | El límite (centavos) | | resetAt | Cuándo se restablece la ventana | | createdAt | Cuándo se tomó la instantánea |

Se toman instantáneas en cada solicitud que tenga un coste > 0 y se utilizan para:

  • Mostrar la barra de progreso de la cuota en el panel
  • Mostrar gráficos de tendencias de cuota de 30 días
  • Activar alertas cuando el uso se aproxima al límite

Ventana de terminal
GET /api/usage?range=7d&limit=100
GET /api/usage?apiKeyId=key-123&range=30d
GET /api/usage?provider=openai&range=1d

Respuesta:

{
"records": [
{
"id": "uuid",
"apiKeyId": "key-123",
"provider": "openai",
"model": "gpt-5",
"promptTokens": 1234,
"completionTokens": 567,
"totalTokens": 1801,
"costUsd": 0.005,
"latencyMs": 1234,
"status": "success",
"timestamp": "2026-06-08T12:00:00Z"
}
],
"total": 1234,
"nextCursor": "..."
}
Ventana de terminal
GET /api/usage/analytics?range=7d&groupBy=model

Respuesta:

{
"summary": {
"totalCost": 12.34,
"totalRequests": 5678,
"totalTokens": 12345678,
"successRate": 0.987,
"avgLatencyMs": 1234
},
"models": [
{ "model": "gpt-5", "cost": 8.5, "requests": 1234, "tokens": 4567890 },
{
"model": "claude-opus-4-6",
"cost": 3.84,
"requests": 234,
"tokens": 234567
}
],
"daily": [
{ "date": "2026-06-01", "cost": 1.5, "requests": 800 },
{ "date": "2026-06-02", "cost": 2.0, "requests": 1000 }
]
}

Se accede a los datos de uso mediante el panel o las herramientas MCP, no mediante endpoints de exportación REST directa. Análisis disponibles:

  • /api/usage/analytics — métricas de uso agregadas (agrupadas por modelo, proveedor y clave)
  • /api/usage/quota — estado actual de la cuota por clave de API
  • /api/usage/history — registros del historial de solicitudes

Dos herramientas MCP exponen los datos de uso a los agentes (consulta open-sse/mcp-server/tools/):

Herramienta Descripción
omniroute_cost_report Genera un informe de costes por clave para un período determinado
omniroute_check_quota Devuelve el estado actual de la cuota de una clave de API

Ejemplo de invocación por parte de un agente:

{
"tool": "omniroute_cost_report",
"args": { "period": "week" }
}

Los datos de uso aumentan ~1-10KB por solicitud. A gran escala, esto puede ser significativo.

La retención del historial de uso se configura mediante la configuración de la base de datos en la interfaz de usuario o mediante /api/settings/database.

De forma predeterminada, el historial de uso se conserva durante 90 días.

Los registros antiguos se eliminan mediante src/lib/db/cleanup.ts:

  • Se activa mediante el proceso cron en segundo plano
  • Elimina de usage_history los registros más antiguos que el período de retención configurado en usageHistory
Tasa de solicitudes Almacenamiento de 30 días Almacenamiento de 90 días
100 solicitudes/día ~3MB ~9MB
1,000 solicitudes/día ~30MB ~90MB
10,000 solicitudes/día ~300MB ~900MB
100,000 solicitudes/día ~3GB ~9GB

Para un tráfico muy alto, considere:

  • Reducir el período de retención mediante la configuración de la base de datos
  • Usar aggregated_metrics en lugar de registros sin procesar (solo para análisis)

Ventana de terminal
# Respuesta rápida — use un modelo económico y rápido
curl -d '{"model":"auto/fast","messages":[...]}'
# Tarea compleja — priorice la calidad
curl -d '{"model":"auto/smart","messages":[...]}'

El almacenamiento en caché de prompts de Anthropic permite ahorrar un 90% en contexto repetido:

// El almacenamiento en caché es automático — simplemente incluya el mismo prompt de sistema extenso
const response = await openai.chat({
model: "claude-sonnet-4-5",
system: longSystemPrompt, // Se almacenará en caché automáticamente
messages: [{ role: "user", content: "..." }],
});

La compresión RTK + Caveman permite ahorrar entre un 15% y un 95% en sesiones con un uso intensivo de herramientas:

const config = {
compression: {
engine: "rtk",
intensity: "aggressive",
},
};

Establezca siempre quotaLimit para evitar costos descontrolados:

await updateApiKey(keyId, { quotaLimit: 10_00 }); // Límite de $10/mes

Use el panel o /api/usage/analytics para agrupar por clave de API y ordenar por costo:

Ventana de terminal
GET /api/usage/analytics?groupBy=apiKey

  1. Consulte /api/usage/analytics?groupBy=model — encuentre el modelo costoso
  2. Consulte /api/usage/analytics?groupBy=apiKey — encuentre al consumidor intensivo
  3. Verifique que los datos de precios estén actualizados: POST /api/pricing/sync
  • Compruebe la configuración de retención de la base de datos en Panel → Base de datos → Limpieza — la tarea de limpieza periódica (src/lib/db/cleanup.ts) elimina los registros antiguos
  • Compruebe si hay errores en src/lib/db/usage*.ts — los errores de escritura en la base de datos se registran, pero no se muestran
  • Verifique que la solicitud haya llegado realmente a chatCore — compruebe el enrutamiento combinado
  • Compruebe la configuración quotaLimit de la clave
  • Verifique que quotaWindow esté configurado correctamente
  • Busque registros de quotaSnapshots — deberían crearse con cada solicitud

  • DATABASE_GUIDE.md — Esquema de las tablas de uso
  • ENVIRONMENT.md — Variables de entorno de sincronización de precios
  • AUTO-COMBO.md — Cómo auto/fast y auto/cheap reducen los costos
  • API_REFERENCE.md — Referencia completa de /api/usage/*
  • Fuente: open-sse/services/usage.ts, src/lib/usageAnalytics.ts, src/lib/db/usage*.ts

Código fuente de OmniRoute (a58000c7685f)

HagiCode

HagiCode es un espacio de trabajo de programación con agentes, flujos estructurados, ejecución multiagente y vistas de Hero Dungeon.

Convierte ideas en software útil con un flujo de trabajo con agentes más inteligente, rápido y ameno.

Interfaz principal de HagiCode con tema claro
  • SmartLos flujos estructurados convierten la intención en un itinerario ejecutable desde la idea hasta la entrega.
  • EfficientLos flujos multiagente permiten avanzar en paralelo con la investigación, implementación y revisión.
  • FunHero Dungeon hace que las largas sesiones de programación sean visuales y colaborativas.
Visitar HagiCode