Pular para o conteúdo
OmniRoute source

Usage, Quota & Spend Tracking (Português (Brasil))

Cada solicitação que passa pelo OmniRoute gera um registro de uso que captura:

  • Identidade: qual chave de API, provedor, modelo e combo
  • Tokens: tokens do prompt, tokens de conclusão, tokens em cache e total
  • Custo: valor em USD (calculado a partir dos dados de preços)
  • Temporização: latência e timestamps de início/fim
  • Status: sucesso, erro, limitação de taxa etc.

Esses registros são agregados em análises, persistidos como snapshots de cota e usados para aplicar limites de orçamento por chave.

Solicitação ──▶ chatCore ──▶ usage.record() ──▶ SQLite
│
┌───────┼───────┐
▼ ▼ ▼
análises cota cobrança
(painel) (aplicação) (exportação)

O serviço usage.ts captura um evento de uso para cada solicitação:

Campo Tipo Origem
id string UUID gerado no momento do registro
apiKeyId string A chave de API que iniciou a solicitação
provider string ID do provedor (openai, anthropic etc.)
model string ID do modelo (gpt-5, claude-opus-4-6 etc.)
comboId string? ID do combo, caso o roteamento tenha sido feito por um combo
promptTokens number Obtido da resposta do upstream
completionTokens number Obtido da resposta do upstream
cachedTokens number Tokens de acerto de cache (cache de prompt da Anthropic etc.)
totalTokens number prompt + conclusão
costUsd number Calculado a partir dos dados de preços
latencyMs number Duração de ponta a ponta da solicitação
status enum success, error, rate_limited, timeout, cancelled
errorClass string? Classe do erro se o status != success
timestamp string ISO 8601 UTC
metadata object Dados personalizados injetados por plugins

Os tokens são extraídos da resposta do provedor upstream no manipulador de resposta:

// 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 provedores que não retornam dados de uso (alguns provedores baseados em cookies da web), o OmniRoute estima os tokens usando uma heurística de ~4 caracteres por token (consulte open-sse/services/autoCombo/pipelineRouter.ts).

O OmniRoute rastreia cached_tokens separadamente de prompt_tokens porque:

  • O cache de prompts da Anthropic cobra uma tarifa reduzida pelos tokens em cache (10% da tarifa normal)
  • Alguns provedores retornam cache_read_input_tokens, que devem ter preços calculados de forma diferente
  • As análises podem mostrar a taxa de acerto do cache = cached_tokens / prompt_tokens

Os custos são calculados com base nos dados de preços sincronizados do LiteLLM (src/lib/pricingSync.ts):

Modelo Entrada $/1M Saída $/1M Cache $/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 —

A fórmula de custo (src/lib/usage/costCalculator.ts):

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

Por que subtrair os tokens em cache do prompt? A parte em cache é tarifada separadamente; aplicar o preço de entrada ao prompt inteiro resultaria em uma cobrança excessiva.

Os dados de preços são sincronizados automaticamente do LiteLLM por meio do endpoint /api/pricing/sync (acionado pela tarefa cron integrada, e não por uma variável de ambiente acessível ao usuário):

Janela do terminal
# Acionamento manual
curl -X POST http://localhost:20128/api/pricing/sync

Para modelos sem dados de preços, o OmniRoute recorre à estimativa de custo usando taxas médias internas (obtidas dos dados de preços do LiteLLM).


O módulo usageAnalytics.ts calcula os widgets do painel a partir dos dados brutos de uso. Ele oferece suporte a 7 intervalos de tempo:

Intervalo Período Caso de uso
1d Últimas 24 horas Detecção de picos de custo por hora
7d Últimos 7 dias Revisão semanal
30d Últimos 30 dias Faturamento mensal
90d Últimos 90 dias Análise trimestral
ytd Desde 1º de janeiro do ano atual Acompanhamento do orçamento anual
all Todo o período Estatísticas acumuladas
custom Início/fim definidos pelo usuário Auditorias, consultas pontuais

Para qualquer intervalo de datas, a camada de análise calcula:

Widget Descrição
Cartões de resumo Total de solicitações, custo total, total de tokens, taxa de sucesso
Gráfico de tendência diária Custo + tokens por dia, empilhados por modelo
Mapa de calor de atividade Grade de hora do dia × dia da semana, cor = número de solicitações
Detalhamento por modelo Gráfico de pizza do custo por modelo
Detalhamento por provedor Gráfico de barras das solicitações por provedor
Principais chaves de API Tabela das 10 principais chaves por custo
Análise de erros Taxa de erros ao longo do tempo, principais classes de erro
import { computeAnalytics } from "@/lib/usageAnalytics";
const analytics = await computeAnalytics(
history, // registros do histórico de uso
"7d", // intervalo de tempo: "1d" | "7d" | "30d" | "90d" | "ytd" | "all" | "custom"
connectionMap, // mapa de conexões do provedor (connectionId → nome da conta)
{
startDate: "2025-01-01", // opcional: para o intervalo "custom"
endDate: "2025-06-01", // opcional: para o intervalo "custom"
}
);
console.log(analytics.summary.totalCost); // 12.34 (centavos)
console.log(analytics.byModel[0]); // { model, cost, requests, promptTokens, completionTokens }
---
## Aplicação de cotas
A cota por chave de API é aplicada em dois pontos:
1. **Limite flexível** (`quotaWarnAt`): aviso no painel quando o uso excede o limite
2. **Limite rígido** (`quotaLimit`): solicitação rejeitada com HTTP 429 quando excedido
### Configuração
```ts
// Por chave de API
await updateApiKey(keyId, {
quotaWarnAt: 5_00, // $5.00 — exibir aviso
quotaLimit: 10_00, // $10.00 — interrupção obrigatória
quotaWindow: "month", // "day" | "week" | "month" | "all"
});
Solicitação ──▶ quotaCheck()
│
├── Dentro do limite? ──▶ permitir
│
└── Acima do limite? ──▶ 429 Too Many Requests
com o cabeçalho Retry-After

A tabela quotaSnapshots armazena o estado histórico das cotas para análise de tendências:

| Campo | Descrição | | ———– | –––––––––––––––– | —— | —–– | | apiKeyId | A chave que está sendo monitorada | | window | “day” | “week” | “month” | | used | Custo usado nesta janela (centavos) | | limit | O limite (centavos) | | resetAt | Quando a janela é redefinida | | createdAt | Quando o snapshot foi obtido |

Os snapshots são obtidos em cada solicitação que usa um custo > 0 e são usados para:

  • Renderizar a barra de progresso da cota no painel
  • Exibir gráficos de tendência da cota dos últimos 30 dias
  • Disparar alertas quando o uso se aproxima do limite

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

Resposta:

{
"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": "..."
}
Janela do terminal
GET /api/usage/analytics?range=7d&groupBy=model

Resposta:

{
"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 }
]
}

Os dados de uso são acessados pelo painel ou pelas ferramentas MCP, e não por endpoints REST de exportação direta. Análises disponíveis:

  • /api/usage/analytics — métricas de uso agregadas (agrupadas por modelo, provedor e chave)
  • /api/usage/quota — status atual da cota por chave de API
  • /api/usage/history — logs do histórico de solicitações

Duas ferramentas MCP expõem dados de uso aos agentes (consulte open-sse/mcp-server/tools/):

Ferramenta Descrição
omniroute_cost_report Gera um relatório de custos por chave para um determinado período
omniroute_check_quota Retorna o status atual da cota de uma chave de API

Exemplo de invocação por um agente:

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

Os dados de uso aumentam em aproximadamente 1-10KB por solicitação. Em escala, isso pode ser significativo.

A retenção do histórico de uso é configurada por meio das Configurações do Banco de Dados na interface ou por meio de /api/settings/database.

Por padrão, o histórico de uso é retido por 90 dias.

Os registros antigos são limpos por src/lib/db/cleanup.ts:

  • Acionada pelo processo cron em segundo plano
  • Exclui registros de usage_history mais antigos que o período configurado na opção de retenção usageHistory
Taxa de solicitações Armazenamento por 30 dias Armazenamento por 90 dias
100 sol./dia ~3MB ~9MB
1.000 sol./dia ~30MB ~90MB
10.000 sol./dia ~300MB ~900MB
100.000 sol./dia ~3GB ~9GB

Para tráfego muito alto, considere:

  • Reduzir o período de retenção por meio das Configurações do Banco de Dados
  • Usar aggregated_metrics em vez de registros brutos (somente para análises)

Janela do terminal
# Resposta rápida — use um modelo barato e rápido
curl -d '{"model":"auto/fast","messages":[...]}'
# Tarefa complexa — priorize a qualidade
curl -d '{"model":"auto/smart","messages":[...]}'

O cache de prompts da Anthropic proporciona uma economia de 90% em contextos repetidos:

// O cache é automático — basta incluir o mesmo prompt de sistema extenso
const response = await openai.chat({
model: "claude-sonnet-4-5",
system: longSystemPrompt, // Será armazenado em cache automaticamente
messages: [{ role: "user", content: "..." }],
});

A compressão RTK + Caveman proporciona uma economia de 15-95% em sessões com uso intensivo de ferramentas:

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

Sempre defina quotaLimit para evitar custos descontrolados:

await updateApiKey(keyId, { quotaLimit: 10_00 }); // Limite de US$ 10/mês

Use o painel ou /api/usage/analytics para agrupar por chave de API e ordenar por custo:

Janela do terminal
GET /api/usage/analytics?groupBy=apiKey

  1. Verifique /api/usage/analytics?groupBy=model — encontre o modelo caro
  2. Verifique /api/usage/analytics?groupBy=apiKey — encontre o maior consumidor
  3. Verifique se os dados de preços estão atualizados: POST /api/pricing/sync
  • Verifique as configurações de retenção do banco de dados em Painel → Banco de Dados → Limpeza — os registros antigos são excluídos pela tarefa de limpeza periódica (src/lib/db/cleanup.ts)
  • Verifique se há erros em src/lib/db/usage*.ts — as falhas de gravação no banco de dados são registradas em log, mas não são exibidas
  • Verifique se a solicitação realmente chegou a chatCore — confira o roteamento combinado
  • Verifique a configuração quotaLimit da chave
  • Verifique se quotaWindow está definido corretamente
  • Procure registros de quotaSnapshots — eles devem ser criados a cada solicitação

  • DATABASE_GUIDE.md — Esquema das tabelas de uso
  • ENVIRONMENT.md — Variáveis de ambiente para sincronização de preços
  • AUTO-COMBO.md — Como auto/fast e auto/cheap reduzem os custos
  • API_REFERENCE.md — Referência completa de /api/usage/*
  • Código-fonte: open-sse/services/usage.ts, src/lib/usageAnalytics.ts, src/lib/db/usage*.ts

Código-fonte do OmniRoute (a58000c7685f)

HagiCode

HagiCode é um ambiente de programação com agentes, fluxos estruturados, execução multiagente e visualizações Hero Dungeon.

Transforme ideias em software útil com um fluxo de trabalho com agentes mais inteligente, rápido e agradável.

Interface principal do HagiCode no tema claro
  • SmartFluxos estruturados transformam intenções em um caminho executável da ideia à entrega.
  • EfficientFluxos multiagente mantêm pesquisa, implementação e revisão em andamento simultaneamente.
  • FunO Hero Dungeon torna longas sessões de programação mais visuais e colaborativas.
Acessar HagiCode