コンテンツにスキップ
OmniRoute source

Usage, Quota & Spend Tracking (日本語)

OmniRoute を経由するすべてのリクエストについて、次の情報を記録する使用量レコードが生成されます。

  • 識別情報: API キー、プロバイダー、モデル、コンボ
  • トークン: プロンプトトークン、完了トークン、キャッシュ済みトークン、合計
  • コスト: USD 金額(料金データから計算)
  • タイミング: レイテンシ、開始/終了タイムスタンプ
  • ステータス: 成功、エラー、レート制限、その他

これらのレコードは分析データに集計され、クォータスナップショットとして永続化され、キーごとの予算上限を適用するために使用されます。

リクエスト ──▶ chatCore ──▶ usage.record() ──▶ SQLite
│
┌───────┼───────┐
▼ ▼ ▼
分析 クォータ 請求
(ダッシュボード)(適用)(エクスポート)

usage.ts サービスは、すべてのリクエストについて使用量イベントを記録します。

フィールド 型 ソース
id string 記録時に生成される UUID
apiKeyId string リクエストを開始した API キー
provider string プロバイダー ID(openai、anthropic など)
model string モデル ID(gpt-5、claude-opus-4-6 など)
comboId string? コンボ経由でルーティングされた場合のコンボ ID
promptTokens number アップストリームレスポンスから取得
completionTokens number アップストリームレスポンスから取得
cachedTokens number キャッシュヒットしたトークン(Anthropic のプロンプトキャッシュなど)
totalTokens number プロンプト + 完了
costUsd number 料金データから計算
latencyMs number リクエストのエンドツーエンド所要時間
status enum success、error、rate_limited、timeout、cancelled
errorClass string? status != success の場合のエラークラス
timestamp string ISO 8601 UTC
metadata object プラグインによって注入されたカスタムデータ

トークンは、レスポンスハンドラーでアップストリームプロバイダーのレスポンスから抽出されます。

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

使用量を返さないプロバイダー(一部の Web Cookie プロバイダー)については、OmniRoute は 1トークンあたり約4文字 というヒューリスティックを使用してトークン数を推定します(open-sse/services/autoCombo/pipelineRouter.ts を参照)。

OmniRoute が cached_tokens を prompt_tokens とは別に追跡する理由は次のとおりです。

  • Anthropic のプロンプトキャッシュでは、キャッシュ済みトークンに対して通常料金の10%という割引料金が適用される
  • 一部のプロバイダーは、異なる料金を適用すべき cache_read_input_tokens を返す
  • 分析では、キャッシュヒット率 = cached_tokens / prompt_tokens を表示できる

コストは、LiteLLM から同期された料金データ(src/lib/pricingSync.ts)に基づいて計算されます。

モデル 入力 $/1M 出力 $/1M キャッシュ $/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 —

コスト計算式(src/lib/usage/costCalculator.ts):

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

プロンプトからキャッシュ分を差し引く理由は? キャッシュされた部分には別の料金が適用されるため、プロンプト全体に入力料金を課すと重複して計上されます。

料金データは、/api/pricing/sync エンドポイントを介して LiteLLM から自動同期されます(ユーザー向けの環境変数ではなく、組み込みの cron タスクによって実行されます)。

ターミナルウィンドウ
# 手動実行
curl -X POST http://localhost:20128/api/pricing/sync

料金データが存在しないモデルについては、OmniRoute は内部の平均料金(LiteLLM の料金データを基に算出)を使用したコスト推定にフォールバックします。


usageAnalytics.ts モジュールは、生の使用状況データからダッシュボードウィジェットを計算します。7 種類の期間をサポートしています。

範囲 期間 ユースケース
1d 過去 24 時間 1 時間単位のコスト急増検出
7d 過去 7 日間 週次レビュー
30d 過去 30 日間 月次請求
90d 過去 90 日間 四半期分析
ytd 現在の年の 1 月 1 日以降 年間予算の追跡
all 全期間 累計統計
custom ユーザー定義の開始日/終了日 監査、アドホッククエリ

計算されるダッシュボードウィジェット

Section titled “計算されるダッシュボードウィジェット”

任意の日付範囲について、分析レイヤーは以下を計算します。

ウィジェット 説明
サマリーカード リクエスト総数、総コスト、トークン総数、成功率
日次トレンドチャート モデル別に積み上げ表示された、1 日あたりのコストとトークン数
アクティビティヒートマップ 時間帯 × 曜日のグリッド。色はリクエスト数を表す
モデル別内訳 モデル別コストの円グラフ
プロバイダー別内訳 プロバイダー別リクエスト数の棒グラフ
上位 API キー コスト上位 10 キーの表
エラー分析 時系列のエラー率、上位のエラークラス
import { computeAnalytics } from "@/lib/usageAnalytics";
const analytics = await computeAnalytics(
history, // 使用履歴レコード
"7d", // 期間: "1d" | "7d" | "30d" | "90d" | "ytd" | "all" | "custom"
connectionMap, // プロバイダー接続マップ(connectionId → アカウント名)
{
startDate: "2025-01-01", // 任意: "custom" 範囲用
endDate: "2025-06-01", // 任意: "custom" 範囲用
}
);
console.log(analytics.summary.totalCost); // 12.34(セント)
console.log(analytics.byModel[0]); // { model, cost, requests, promptTokens, completionTokens }
---
## クォータの適用
API キーごとのクォータは、次の 2 か所で適用されます。
1. **ソフトリミット**(`quotaWarnAt`):使用量がしきい値を超えた場合にダッシュボードへ警告を表示
2. **ハードリミット**(`quotaLimit`):超過した場合、リクエストを HTTP 429 で拒否
### 設定
```ts
// API キーごとの設定
await updateApiKey(keyId, {
quotaWarnAt: 5_00, // $5.00 — 警告を表示
quotaLimit: 10_00, // $10.00 — ハードストップ
quotaWindow: "month", // "day" | "week" | "month" | "all"
});
リクエスト ──▶ quotaCheck()
│
├── 上限以内? ──▶ 許可
│
└── 上限超過? ──▶ 429 Too Many Requests
Retry-After ヘッダー付き

quotaSnapshots テーブルには、傾向分析のための過去のクォータ状態が保存されます。

| フィールド | 説明 | | ———– | ––––––––––––––––––– | —— | —–– | | apiKeyId | 追跡対象のキー | | window | “day” | “week” | “month” | | used | この期間内で使用したコスト(セント) | | limit | 上限(セント) | | resetAt | 期間がリセットされる日時 | | createdAt | スナップショットが取得された日時 |

スナップショットは、コストが 0 を超えるすべてのリクエスト時に取得され、次の目的で使用されます。

  • ダッシュボードにクォータ進捗バーを表示する
  • 30 日間のクォータ傾向チャートを表示する
  • 使用量が上限に近づいたときにアラートを発生させる

ターミナルウィンドウ
GET /api/usage?range=7d&limit=100
GET /api/usage?apiKeyId=key-123&range=30d
GET /api/usage?provider=openai&range=1d

レスポンス:

{
"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": "..."
}
ターミナルウィンドウ
GET /api/usage/analytics?range=7d&groupBy=model

レスポンス:

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

使用量データには、REST の直接エクスポートエンドポイントではなく、ダッシュボードまたは MCP ツールを介してアクセスします。利用可能な分析は次のとおりです。

  • /api/usage/analytics — 集計された使用量メトリクス(モデル、プロバイダー、キー別にグループ化)
  • /api/usage/quota — API キーごとの現在のクォータ状態
  • /api/usage/history — リクエスト履歴ログ

2 つの MCP ツールが、エージェントに使用量データを提供します(open-sse/mcp-server/tools/ を参照)。

ツール 説明
omniroute_cost_report 指定期間について、キーごとのコストレポートを生成する
omniroute_check_quota API キーの現在のクォータ状態を返す

エージェント呼び出しの例:

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

使用量データは、リクエストごとに約1~10KB増加します。大規模環境では、これは無視できない量になる可能性があります。

使用履歴の保持期間は、UIのDatabase Settingsまたは/api/settings/databaseで設定します。

デフォルトでは、使用履歴は90日間保持されます。

古いレコードはsrc/lib/db/cleanup.tsによってクリーンアップされます。

  • バックグラウンドのcronプロセスによって実行される
  • 設定されたusageHistory保持期間より古いレコードをusage_historyから削除する
リクエスト頻度 30日間のストレージ 90日間のストレージ
100 req/day ~3MB ~9MB
1,000 req/day ~30MB ~90MB
10,000 req/day ~300MB ~900MB
100,000 req/day ~3GB ~9GB

トラフィックが非常に多い場合は、以下を検討してください。

  • Database Settingsで保持期間を短縮する
  • 生のレコードの代わりにaggregated_metricsを使用する(分析用途のみ)

ターミナルウィンドウ
# 簡単な回答 — 安価で高速なモデルを使用
curl -d '{"model":"auto/fast","messages":[...]}'
# 複雑なタスク — 高品質なモデルを使用
curl -d '{"model":"auto/smart","messages":[...]}'

Anthropicのプロンプトキャッシュにより、繰り返し使用されるコンテキストのコストを90%削減できます。

// キャッシュは自動的に行われます — 同じ大規模なシステムプロンプトを含めるだけです
const response = await openai.chat({
model: "claude-sonnet-4-5",
system: longSystemPrompt, // 自動的にキャッシュされます
messages: [{ role: "user", content: "..." }],
});

RTK + Caveman圧縮により、ツール使用の多いセッションで15~95%節約できます。

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

4. キーごとのクォータを設定する

Section titled “4. キーごとのクォータを設定する”

コストの際限ない増加を防ぐため、必ずquotaLimitを設定してください。

await updateApiKey(keyId, { quotaLimit: 10_00 }); // 月額$10の上限

5. 使用量の多いユーザーを監査する

Section titled “5. 使用量の多いユーザーを監査する”

ダッシュボードまたは**/api/usage/analytics**を使用し、APIキー別にグループ化してコスト順に並べ替えます。

ターミナルウィンドウ
GET /api/usage/analytics?groupBy=apiKey

  1. **/api/usage/analytics?groupBy=model**を確認し、コストの高いモデルを特定する
  2. **/api/usage/analytics?groupBy=apiKey**を確認し、使用量の多いユーザーを特定する
  3. 料金データが最新であることを確認する:POST /api/pricing/sync
  • Dashboard → Database → CleanupでDBの保持設定を確認する。古いレコードは定期クリーンアップタスク(src/lib/db/cleanup.ts)によって削除されます
  • src/lib/db/usage*.tsでエラーを確認する。DBへの書き込み失敗はログに記録されますが、表面化しません
  • リクエストが実際にchatCoreへ到達したことを確認する。コンボルーティングを確認してください
  • キーのquotaLimit設定を確認する
  • quotaWindowが正しく設定されていることを確認する
  • quotaSnapshotsレコードを確認する。これらはリクエストごとに作成される必要があります

  • DATABASE_GUIDE.md — 使用量テーブルのスキーマ
  • ENVIRONMENT.md — 料金同期用の環境変数
  • AUTO-COMBO.md — auto/fast、auto/cheapによるコスト削減方法
  • API_REFERENCE.md — /api/usage/*の完全なリファレンス
  • ソース:open-sse/services/usage.ts、src/lib/usageAnalytics.ts、src/lib/db/usage*.ts

OmniRoute ソースコード (a58000c7685f)

HagiCode

HagiCode は構造化ワークフロー、マルチエージェント実行、Hero Dungeon ビューを備えたエージェント型コーディングワークスペースです。

よりスマートで速く、楽しいエージェント型ワークフローで、使いやすいソフトウェアを形にします。

HagiCode ライトテーマのメイン画面
  • Smart構造化ワークフローは意図をアイデアから変更のリリースまで実行可能な道筋にします。
  • Efficientマルチエージェントのワークフローで調査、実装、レビューを並行して進めます。
  • FunHero Dungeon により長時間のコーディングを視覚的で協力的な体験にします。
HagiCode を見る