Zum Inhalt springen
OmniRoute source

Usage, Quota & Spend Tracking (Deutsch)

Jede Anfrage, die OmniRoute durchläuft, erzeugt einen Nutzungsdatensatz, der Folgendes erfasst:

  • Identität: welcher API-Schlüssel, Anbieter, welches Modell und welche Kombination
  • Tokens: Prompt-Tokens, Vervollständigungs-Tokens, zwischengespeicherte Tokens, Gesamtzahl
  • Kosten: Betrag in USD (anhand von Preisdaten berechnet)
  • Zeitmessung: Latenz, Start-/Endzeitstempel
  • Status: erfolgreich, Fehler, ratenbegrenzt usw.

Diese Datensätze werden zu Analysen aggregiert, als Kontingent-Snapshots gespeichert und zur Durchsetzung von Budgetlimits pro Schlüssel verwendet.

Anfrage ──▶ chatCore ──▶ usage.record() ──▶ SQLite
│
┌───────┼───────┐
▼ ▼ ▼
Analysen Kontingent Abrechnung
(Dashboard) (Durchsetzung) (Export)

Der Dienst usage.ts erfasst für jede Anfrage ein Nutzungsereignis:

Feld Typ Quelle
id string Beim Erfassen generierte UUID
apiKeyId string Der API-Schlüssel, der die Anfrage initiiert hat
provider string Anbieter-ID (openai, anthropic usw.)
model string Modell-ID (gpt-5, claude-opus-4-6 usw.)
comboId string? Kombinations-ID, falls über eine Kombination weitergeleitet
promptTokens number Aus der Antwort des Upstream-Anbieters
completionTokens number Aus der Antwort des Upstream-Anbieters
cachedTokens number Tokens aus Cache-Treffern (Anthropic-Prompt-Caching usw.)
totalTokens number Prompt + Vervollständigung
costUsd number Anhand von Preisdaten berechnet
latencyMs number Gesamtdauer der Anfrage
status enum success, error, rate_limited, timeout, cancelled
errorClass string? Fehlerklasse, falls Status != Erfolg
timestamp string ISO 8601 UTC
metadata object Benutzerdefinierte, durch Plugins eingefügte Daten

Tokens werden im Antwort-Handler aus der Antwort des Upstream-Anbieters extrahiert:

// Aus 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,
};

Für Anbieter, die keine Nutzungsdaten zurückgeben (einige Web-Cookie-Anbieter), schätzt OmniRoute die Token-Anzahl anhand der Heuristik ~4 Zeichen pro Token (siehe open-sse/services/autoCombo/pipelineRouter.ts).

OmniRoute erfasst cached_tokens getrennt von prompt_tokens, weil:

  • Anthropic-Prompt-Caching für zwischengespeicherte Tokens einen reduzierten Preis berechnet (10 % des normalen Preises)
  • Einige Anbieter cache_read_input_tokens zurückgeben, die anders abgerechnet werden sollten
  • Analysen die Cache-Trefferrate anzeigen können = cached_tokens / prompt_tokens

Die Kosten werden anhand von Preisdaten berechnet, die von LiteLLM synchronisiert werden (src/lib/pricingSync.ts):

Modell Eingabe $/1M Ausgabe $/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 —

Die Kostenformel (src/lib/usage/costCalculator.ts):

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

Warum werden zwischengespeicherte Token von den Prompt-Token abgezogen? Der zwischengespeicherte Anteil wird separat berechnet; wenn der Eingabepreis auf den gesamten Prompt angewendet würde, käme es zu einer Doppelberechnung.

Die Preisdaten werden über den Endpunkt /api/pricing/sync automatisch von LiteLLM synchronisiert (ausgelöst durch die integrierte Cron-Aufgabe, nicht durch eine benutzerseitige Umgebungsvariable):

Terminal-Fenster
# Manuelle Auslösung
curl -X POST http://localhost:20128/api/pricing/sync

Bei Modellen ohne Preisdaten greift OmniRoute auf eine Kostenschätzung anhand interner Durchschnittspreise zurück (basierend auf den Preisdaten von LiteLLM).


Das Modul usageAnalytics.ts berechnet Dashboard-Widgets aus Rohdaten zur Nutzung. Es unterstützt 7 Zeiträume:

Zeitraum Zeitfenster Anwendungsfall
1d Letzte 24 Stunden Erkennung stündlicher Kostenspitzen
7d Letzte 7 Tage Wöchentliche Auswertung
30d Letzte 30 Tage Monatliche Abrechnung
90d Letzte 90 Tage Quartalsanalyse
ytd Seit dem 1. Januar des aktuellen Jahres Überwachung des Jahresbudgets
all Gesamter Zeitraum Gesamtstatistiken
custom Benutzerdefinierter Start-/Endpunkt Audits, Ad-hoc-Abfragen

Für jeden Datumsbereich berechnet die Analyseschicht Folgendes:

Widget Beschreibung
Übersichtskarten Gesamtzahl der Anfragen, Gesamtkosten, Gesamtzahl der Token, Erfolgsquote
Tägliches Trenddiagramm Kosten und Token pro Tag, nach Modell gestapelt
Aktivitäts-Heatmap Raster aus Tageszeit × Wochentag, Farbe = Anzahl der Anfragen
Modellaufschlüsselung Kreisdiagramm der Kosten nach Modell
Anbieteraufschlüsselung Balkendiagramm der Anfragen nach Anbieter
Wichtigste API-Schlüssel Tabelle der 10 Schlüssel mit den höchsten Kosten
Fehleranalyse Fehlerrate im Zeitverlauf, häufigste Fehlerklassen
import { computeAnalytics } from "@/lib/usageAnalytics";
const analytics = await computeAnalytics(
history, // Datensätze des Nutzungsverlaufs
"7d", // Zeitraum: "1d" | "7d" | "30d" | "90d" | "ytd" | "all" | "custom"
connectionMap, // Zuordnung der Anbieter-Verbindungen (connectionId → Kontoname)
{
startDate: "2025-01-01", // optional: für den Zeitraum "custom"
endDate: "2025-06-01", // optional: für den Zeitraum "custom"
}
);
console.log(analytics.summary.totalCost); // 12.34 (Cent)
console.log(analytics.byModel[0]); // { model, cost, requests, promptTokens, completionTokens }
---
## Kontingentdurchsetzung
Das Kontingent pro API-Schlüssel wird an zwei Stellen durchgesetzt:
1. **Weiches Limit** (`quotaWarnAt`): Warnung im Dashboard, wenn die Nutzung den Schwellenwert überschreitet
2. **Hartes Limit** (`quotaLimit`): Anfrage wird bei Überschreitung mit HTTP 429 abgelehnt
### Konfiguration
```ts
// Pro API-Schlüssel
await updateApiKey(keyId, {
quotaWarnAt: 5_00, // $5.00 — Warnung anzeigen
quotaLimit: 10_00, // $10.00 — harte Begrenzung
quotaWindow: "month", // "day" | "week" | "month" | "all"
});
Anfrage ──▶ quotaCheck()
│
├── Innerhalb des Limits? ──▶ zulassen
│
└── Limit überschritten? ──▶ 429 Too Many Requests
mit Retry-After-Header

Die Tabelle quotaSnapshots speichert den historischen Kontingentstatus für Trendanalysen:

| Feld | Beschreibung | | ———– | —————————————— | —— | —–– | | apiKeyId | Der verfolgte Schlüssel | | window | “day” | “week” | “month” | | used | In diesem Zeitfenster verbrauchte Kosten (Cent) | | limit | Das Limit (Cent) | | resetAt | Zeitpunkt, zu dem das Zeitfenster zurückgesetzt wird | | createdAt | Zeitpunkt, zu dem der Snapshot erstellt wurde |

Snapshots werden bei jeder Anfrage erstellt, deren Kosten > 0 sind, und für Folgendes verwendet:

  • Darstellung des Kontingent-Fortschrittsbalkens im Dashboard
  • Anzeige von Diagrammen zum Kontingenttrend der letzten 30 Tage
  • Auslösung von Warnungen, wenn sich die Nutzung dem Limit nähert

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

Antwort:

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

Antwort:

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

Auf Nutzungsdaten wird über das Dashboard oder MCP-Tools zugegriffen, nicht über direkte REST-Export-Endpunkte. Verfügbare Analysen:

  • /api/usage/analytics — aggregierte Nutzungsmetriken (gruppiert nach Modell, Anbieter, Schlüssel)
  • /api/usage/quota — aktueller Kontingentstatus pro API-Schlüssel
  • /api/usage/history — Protokolle des Anfrageverlaufs

Zwei MCP-Tools stellen Agenten Nutzungsdaten zur Verfügung (siehe open-sse/mcp-server/tools/):

Tool Beschreibung
omniroute_cost_report Erstellt einen Kostenbericht pro Schlüssel für einen bestimmten Zeitraum
omniroute_check_quota Gibt den aktuellen Kontingentstatus für einen API-Schlüssel zurück

Beispiel für einen Agentenaufruf:

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

Nutzungsdaten wachsen um ca. 1–10 KB pro Anfrage. Bei entsprechender Skalierung kann dies erheblich sein.

Die Aufbewahrung des Nutzungsverlaufs wird über die Datenbankeinstellungen in der Benutzeroberfläche oder über /api/settings/database konfiguriert.

Standardmäßig wird der Nutzungsverlauf 90 Tage lang aufbewahrt.

Alte Datensätze werden durch src/lib/db/cleanup.ts bereinigt:

  • Wird durch den Cron-Hintergrundprozess ausgelöst
  • Löscht Datensätze aus usage_history, die älter als die konfigurierte Aufbewahrungseinstellung usageHistory sind
Anfragerate Speicherbedarf für 30 Tage Speicherbedarf für 90 Tage
100 Anfragen/Tag ~3 MB ~9 MB
1.000 Anfragen/Tag ~30 MB ~90 MB
10.000 Anfragen/Tag ~300 MB ~900 MB
100.000 Anfragen/Tag ~3 GB ~9 GB

Bei sehr hohem Datenverkehr sollten Sie Folgendes erwägen:

  • Verkürzen des Aufbewahrungszeitraums über die Datenbankeinstellungen
  • Verwenden von aggregated_metrics anstelle von Rohdatensätzen (nur für Analysen)

Terminal-Fenster
# Schnelle Antwort — günstig und schnell verwenden
curl -d '{"model":"auto/fast","messages":[...]}'
# Komplexe Aufgabe — hohe Qualität verwenden
curl -d '{"model":"auto/smart","messages":[...]}'

Das Prompt-Caching von Anthropic spart bei wiederholtem Kontext 90 %:

// Das Caching erfolgt automatisch — fügen Sie einfach denselben umfangreichen System-Prompt ein
const response = await openai.chat({
model: "claude-sonnet-4-5",
system: longSystemPrompt, // Wird automatisch im Cache gespeichert
messages: [{ role: "user", content: "..." }],
});

Die RTK- und Caveman-Komprimierung spart bei Sitzungen mit intensiver Tool-Nutzung 15–95 %:

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

Legen Sie immer quotaLimit fest, um unkontrollierte Kosten zu vermeiden:

await updateApiKey(keyId, { quotaLimit: 10_00 }); // Obergrenze von 10 $/Monat

Verwenden Sie das Dashboard oder /api/usage/analytics, um nach API-Schlüssel zu gruppieren und nach Kosten zu sortieren:

Terminal-Fenster
GET /api/usage/analytics?groupBy=apiKey

  1. Prüfen Sie /api/usage/analytics?groupBy=model — ermitteln Sie das teure Modell
  2. Prüfen Sie /api/usage/analytics?groupBy=apiKey — ermitteln Sie den größten Verbraucher
  3. Vergewissern Sie sich, dass die Preisdaten aktuell sind: POST /api/pricing/sync
  • Prüfen Sie die Einstellungen zur Datenbankaufbewahrung unter Dashboard → Database → Cleanup — alte Datensätze werden durch die regelmäßige Bereinigungsaufgabe (src/lib/db/cleanup.ts) gelöscht
  • Prüfen Sie src/lib/db/usage*.ts auf Fehler — Fehler beim Schreiben in die Datenbank werden protokolliert, aber nicht angezeigt
  • Vergewissern Sie sich, dass die Anfrage tatsächlich chatCore erreicht hat — prüfen Sie das Combo-Routing
  • Prüfen Sie die Einstellung quotaLimit des Schlüssels
  • Vergewissern Sie sich, dass quotaWindow korrekt festgelegt ist
  • Suchen Sie nach quotaSnapshots-Datensätzen — sie sollten bei jeder Anfrage erstellt werden

  • DATABASE_GUIDE.md — Schema für Nutzungstabellen
  • ENVIRONMENT.md — Umgebungsvariablen für die Preissynchronisierung
  • AUTO-COMBO.md — Wie auto/fast und auto/cheap die Kosten senken
  • API_REFERENCE.md — Vollständige Referenz zu /api/usage/*
  • Quelle: open-sse/services/usage.ts, src/lib/usageAnalytics.ts, src/lib/db/usage*.ts

OmniRoute-Quellcode (a58000c7685f)

HagiCode

HagiCode ist ein agentischer Coding-Arbeitsplatz mit strukturierten Workflows, Multi-Agent-Ausführung und Hero-Dungeon-Ansichten.

Mit einem intelligenteren, schnelleren und unterhaltsameren agentischen Workflow wird aus Ideen nutzbare Software.

HagiCode-Hauptoberfläche im hellen Design
  • SmartStrukturierte Workflows machen aus Absichten einen umsetzbaren Weg von der Idee bis zur Auslieferung.
  • EfficientMulti-Agent-Workflows führen Recherche, Umsetzung und Prüfung parallel aus.
  • FunHero Dungeon macht lange Coding-Sitzungen anschaulich und gemeinschaftlich.
HagiCode besuchen