Usage, Quota & Spend Tracking (日本語)
OmniRoute を経由するすべてのリクエストについて、次の情報を記録する使用量レコードが生成されます。
- 識別情報: API キー、プロバイダー、モデル、コンボ
- トークン: プロンプトトークン、完了トークン、キャッシュ済みトークン、合計
- コスト: USD 金額(料金データから計算)
- タイミング: レイテンシ、開始/終了タイムスタンプ
- ステータス: 成功、エラー、レート制限、その他
これらのレコードは分析データに集計され、クォータスナップショットとして永続化され、キーごとの予算上限を適用するために使用されます。
リクエスト ──▶ chatCore ──▶ usage.record() ──▶ SQLite │ ┌───────┼───────┐ ▼ ▼ ▼ 分析 クォータ 請求 (ダッシュボード)(適用)(エクスポート)記録される内容
Section titled “記録される内容”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 | プラグインによって注入されたカスタムデータ |
トークンの取得元
Section titled “トークンの取得元”トークンは、レスポンスハンドラーでアップストリームプロバイダーのレスポンスから抽出されます。
// 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 を参照)。
キャッシュ済みトークン
Section titled “キャッシュ済みトークン”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 の料金データを基に算出)を使用したコスト推定にフォールバックします。
日付範囲の集計
Section titled “日付範囲の集計”usageAnalytics.ts モジュールは、生の使用状況データからダッシュボードウィジェットを計算します。7 種類の期間をサポートしています。
| 範囲 | 期間 | ユースケース |
|---|---|---|
1d |
過去 24 時間 | 1 時間単位のコスト急増検出 |
7d |
過去 7 日間 | 週次レビュー |
30d |
過去 30 日間 | 月次請求 |
90d |
過去 90 日間 | 四半期分析 |
ytd |
現在の年の 1 月 1 日以降 | 年間予算の追跡 |
all |
全期間 | 累計統計 |
custom |
ユーザー定義の開始日/終了日 | 監査、アドホッククエリ |
計算されるダッシュボードウィジェット
Section titled “計算されるダッシュボードウィジェット”任意の日付範囲について、分析レイヤーは以下を計算します。
| ウィジェット | 説明 |
|---|---|
| サマリーカード | リクエスト総数、総コスト、トークン総数、成功率 |
| 日次トレンドチャート | モデル別に積み上げ表示された、1 日あたりのコストとトークン数 |
| アクティビティヒートマップ | 時間帯 × 曜日のグリッド。色はリクエスト数を表す |
| モデル別内訳 | モデル別コストの円グラフ |
| プロバイダー別内訳 | プロバイダー別リクエスト数の棒グラフ |
| 上位 API キー | コスト上位 10 キーの表 |
| エラー分析 | 時系列のエラー率、上位のエラークラス |
プログラムからのアクセス
Section titled “プログラムからのアクセス”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 ヘッダー付きクォータスナップショット
Section titled “クォータスナップショット”quotaSnapshots テーブルには、傾向分析のための過去のクォータ状態が保存されます。
| フィールド | 説明 |
| ———– | ––––––––––––––––––– | —— | —–– |
| apiKeyId | 追跡対象のキー |
| window | “day” | “week” | “month” |
| used | この期間内で使用したコスト(セント) |
| limit | 上限(セント) |
| resetAt | 期間がリセットされる日時 |
| createdAt | スナップショットが取得された日時 |
スナップショットは、コストが 0 を超えるすべてのリクエスト時に取得され、次の目的で使用されます。
- ダッシュボードにクォータ進捗バーを表示する
- 30 日間のクォータ傾向チャートを表示する
- 使用量が上限に近づいたときにアラートを発生させる
REST API
Section titled “REST API”使用量レコードの一覧取得
Section titled “使用量レコードの一覧取得”GET /api/usage?range=7d&limit=100GET /api/usage?apiKeyId=key-123&range=30dGET /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": "..."}分析サマリーの取得
Section titled “分析サマリーの取得”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 } ]}使用量分析の照会
Section titled “使用量分析の照会”使用量データには、REST の直接エクスポートエンドポイントではなく、ダッシュボードまたは MCP ツールを介してアクセスします。利用可能な分析は次のとおりです。
/api/usage/analytics— 集計された使用量メトリクス(モデル、プロバイダー、キー別にグループ化)/api/usage/quota— API キーごとの現在のクォータ状態/api/usage/history— リクエスト履歴ログ
MCP ツール
Section titled “MCP ツール”2 つの MCP ツールが、エージェントに使用量データを提供します(open-sse/mcp-server/tools/ を参照)。
| ツール | 説明 |
|---|---|
omniroute_cost_report |
指定期間について、キーごとのコストレポートを生成する |
omniroute_check_quota |
API キーの現在のクォータ状態を返す |
エージェント呼び出しの例:
{ "tool": "omniroute_cost_report", "args": { "period": "week" }}保持とクリーンアップ
Section titled “保持とクリーンアップ”使用量データは、リクエストごとに約1~10KB増加します。大規模環境では、これは無視できない量になる可能性があります。
使用履歴の保持期間は、UIのDatabase Settingsまたは/api/settings/databaseで設定します。
デフォルトでは、使用履歴は90日間保持されます。
クリーンアップ
Section titled “クリーンアップ”古いレコードはsrc/lib/db/cleanup.tsによってクリーンアップされます。
- バックグラウンドのcronプロセスによって実行される
- 設定された
usageHistory保持期間より古いレコードをusage_historyから削除する
ストレージ使用量の見積もり
Section titled “ストレージ使用量の見積もり”| リクエスト頻度 | 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を使用する(分析用途のみ)
コスト最適化のヒント
Section titled “コスト最適化のヒント”1. 適切なモデルを使用する
Section titled “1. 適切なモデルを使用する”# 簡単な回答 — 安価で高速なモデルを使用curl -d '{"model":"auto/fast","messages":[...]}'
# 複雑なタスク — 高品質なモデルを使用curl -d '{"model":"auto/smart","messages":[...]}'2. キャッシュを有効にする
Section titled “2. キャッシュを有効にする”Anthropicのプロンプトキャッシュにより、繰り返し使用されるコンテキストのコストを90%削減できます。
// キャッシュは自動的に行われます — 同じ大規模なシステムプロンプトを含めるだけですconst response = await openai.chat({ model: "claude-sonnet-4-5", system: longSystemPrompt, // 自動的にキャッシュされます messages: [{ role: "user", content: "..." }],});3. 圧縮を使用する
Section titled “3. 圧縮を使用する”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トラブルシューティング
Section titled “トラブルシューティング”「コストが予想より高い」
Section titled “「コストが予想より高い」”- **
/api/usage/analytics?groupBy=model**を確認し、コストの高いモデルを特定する - **
/api/usage/analytics?groupBy=apiKey**を確認し、使用量の多いユーザーを特定する - 料金データが最新であることを確認する:
POST /api/pricing/sync
「レコードが見つからない」
Section titled “「レコードが見つからない」”- Dashboard → Database → CleanupでDBの保持設定を確認する。古いレコードは定期クリーンアップタスク(
src/lib/db/cleanup.ts)によって削除されます src/lib/db/usage*.tsでエラーを確認する。DBへの書き込み失敗はログに記録されますが、表面化しません- リクエストが実際に
chatCoreへ到達したことを確認する。コンボルーティングを確認してください
「クォータが適用されない」
Section titled “「クォータが適用されない」”- キーの
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
HagiCode
HagiCode は構造化ワークフロー、マルチエージェント実行、Hero Dungeon ビューを備えたエージェント型コーディングワークスペースです。
よりスマートで速く、楽しいエージェント型ワークフローで、使いやすいソフトウェアを形にします。

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