Model Radar
OpenRouterモデル選択CLI。自然言語による制約をtoken:value形式の引数に解析し、モデルのメタデータとランキングのローカルキャッシュを検索して、エージェントがマークダウンテーブルとしてレンダリングするためのJSONを出力します。
セットアップ
- ランタイム: Node.js 18+(インストール不要、npm依存関係なし)
- APIキー不要 — OpenRouterの公開エンドポイントを使用
- すべてのコマンドはこのスキルディレクトリ(このファイルが含まれるディレクトリ)から実行
- 初回実行時にキャッシュをネットワークから取得し、以降はローカルキャッシュを使用(モデルTTL 6時間、ランキングTTL 24時間)
- 自己更新はデフォルトで有効。各CLI実行時に固定のGitHubソースを最大24時間に1回チェックし、インストール済みコピーに自動更新を適用します。
MODEL_RADAR_AUTO_UPDATE=0を設定すると無効化できます。
ワークフロー
- スキルを使用する前に
node scripts/self-update.js autoを実行します。stderrにMODEL_RADAR_UPDATEDが出力された場合は、続行する前にこのSKILL.mdを再読み込みしてください。 - ユーザーのリクエストを以下の 意図→トークン マッピングを使用して
token:value引数に解析します - コマンドを選択:
list(フィルタ+ソート)、recommend(プリセットに対する加重スコア)、compare(並列比較) - スキルディレクトリから実行します。
scripts/main.jsも自動的に同じ自己更新プレフライトを実行するため、直接CLIを使用しても最新の状態が維持されます。 - JSON出力を マークダウンテーブル としてレンダリングします(出力 を参照)
Data as of {fetched_at}で終了し、12時間以上経過している場合はrefreshを提案します
コマンド
node scripts/main.js list [トークン...] # フィルタ + ソート
node scripts/main.js recommend [トークン...] # プリセットに対する加重スコア
node scripts/main.js compare <id|名前>... # 並列比較
node scripts/main.js refresh # 両方のキャッシュを強制リフレッシュ
node scripts/self-update.js status # 更新状態の確認
node scripts/self-update.js check # GitHubの更新を確認
node scripts/self-update.js apply # 最新のスキル更新を適用
自己更新
- ソースは
package.json.repository:primexiao/agent-skills、パスskills/model-radarで固定されています。 - インストール済みコピーは自動更新されます。ソースチェックアウトは、
MODEL_RADAR_AUTO_UPDATE_SOURCE=1が設定されていない限り自動更新をスキップします。 - スキルディレクトリ下のローカル未コミット変更がある場合、自動更新はスキップされます。
scripts/main.jsを直接使用すると、自己更新が成功した後に現在のコマンドを再起動し、更新されたコードで結果が生成されます。- 更新では一時チェックアウトを使用し、必要なファイルを検証し、現在のスキルをバックアップし、ランタイム以外のファイルを置き換え、失敗時にはロールバックします。
- 成功した更新は
cache/raw.json、cache/models.json、cache/rankings.jsonをクリアし、新しいコードが古いデータキャッシュと混ざらないようにします。 - 自己更新のステータスと警告はstderrに出力されます。コマンドJSONはstdoutに残ります。
トークン構文
Tailwindインスパイアの位置指定 token:value 引数。順序は問いません。
| トークン | 意味 | 値の形式 | 例 |
|---|---|---|---|
sort | ソート次元 | プリセットワード(下記参照) | sort:cheap sort:popular |
price | $/MTok ブレンド | ..max / min.. / min..max / 裸=最大値 | price:..10 price:5..20 |
ctx | コンテキスト長 | 同上、k/m 接尾辞、裸=最小値 | ctx:128k ctx:128k..1m |
out | 最大出力トークン数 | 同上、裸=最小値 | out:32k |
cap | 機能(AND) | カンマ区切り | cap:tool_use,reasoning |
in | 入力モダリティ(AND) | カンマ区切り | in:image in:audio,image |
gen | 出力モダリティ(AND) | カンマ区切り | gen:image gen:audio |
open | オープンソースフィルター | true / false | open:true |
top | 結果制限数 | 数値(デフォルト: list=20, recommend=3) | top:5 |
preset | スコアリングプリセット(recommendのみ) | プリセット名 | preset:coding |
sort 値: cheap expensive new(デフォルト) ctx popular throughput latency
機能: tool_use reasoning structured_output vision long_output prompt_caching web_search audio_input video_input file_input image_generation audio_output
入力モダリティ: text image audio video file
出力モダリティ: text image audio
レコメンドプリセット: coding batch chat vision(重みと必須機能については config/presets.json を参照)
意図 → トークン
| ユーザーの発言 | トークン |
|---|---|
| "予算$X" / "~$X未満" | price:..X |
| "少なくとも$X" / "プレミアム層" | price:X.. |
| "少なくともNkコンテキスト" | ctx:Nk |
| "ツール使用/ビジョン/推論が必要" | cap:tool_use / cap:vision / cap:reasoning |
| "構造化出力" / "JSONモード" | cap:structured_output |
| "音声/画像入力を受け付け可能" | in:audio / in:image |
| "画像/音声を生成可能" | gen:image / gen:audio |
| "オープンソースのみ" | open:true |
| "最も安い" / "最も手頃" | sort:cheap |
| "最も人気" / "トレンド" | sort:popular |
| "最新" / "新しい" | sort:new |
| "最速" / "最低レイテンシー" | sort:latency |
| "最高スループット" | sort:throughput |
| "コーディングエージェント" | recommend preset:coding |
| "バッチ / バルクジョブ" | recommend preset:batch |
| "ビジョンエージェント" | recommend preset:vision |
モデルマッチング (compare)
compare の各引数に対するマッチング優先順位:
- 完全一致ID —
anthropic/claude-sonnet-4-5 - 接尾辞完全一致 —
claude-sonnet-4→anthropic/claude-sonnet-4(-fastバリアントは対象外) - ID/名前の部分部分文字列 一致、最新リリースが優先 —
claude-sonnet→ 最新のSonnet
出力
JSON出力は常に マークダウンテーブル としてレンダリングします — テーブルが主要な表示形式です。
list
| # | モデル | $/MTok (P/C/ブレンド) | コンテキスト | 出力 | 機能 | 人気順位# |
$/MTok: プロンプト / 補完 / ブレンド価格機能: 短いタグ(toolreasonvision…)人気順位#: ランキングキャッシュが最新の場合は人気順位、それ以外は—
recommend
| 順位 | モデル | スコア | コスト↑ | コンテキスト↑ | 出力↑ | 機能↑ | $/MTok | 機能 |
モデルごとに1行の理由を追加します。スコアと次元ごとのスコアは [0, 1] の範囲です。
compare
縦型テーブル — モデルごとに1列、次元ごとに1行:
| 次元 | モデルA | モデルB | モデルC |
| ------------------ | ------- | ------- | ------- |
| 価格 (P/C/ブレンド) | … | … | … |
| コンテキスト | … | … | … |
| 最大出力 | … | … | … |
| 入力モダリティ | … | … | … |
| 出力モダリティ | … | … | … |
| 機能 | … | … | … |
| 人気順位 | … | … | … |
| 週間リクエスト | … | … | … |
常に以下で終了: Data as of {fetched_at}。12時間以上経過している場合は、node scripts/main.js refresh の実行を提案します。
キャッシュ
cache/
raw.json — OpenRouterフロントエンドカードデータをローカル生スキーマに変換(TTL 6時間)
models.json — 拡張版: 正規化された価格設定 + 機能ラベル(TTL 6時間)
rankings.json — 人気度 / スループット / レイテンシー + 使用状況分析(TTL 24時間)
config/
presets.json
tier1-categories.json
- キャッシュファイルは
cache/の下にあり、コミットされません — 初回実行時にネットワークにアクセスします - TTLが切れると、CLIはタイムアウト10秒で再取得します
- 取得に失敗した場合、古いキャッシュにフォールバックし、stderrに
[warn]を出力します — そのため読み取り専用/オフラインのサンドボックスでも(古い可能性はあるが)応答します - スキルの自己更新が成功すると、モデルデータのキャッシュファイルが削除されます。次のモデルコマンドで再取得されます。
サンドボックスノート
- Codex CLI:
-s workspace-write(CLIがcache/に書き込む)とopenrouter.aiへのネットワーク送信が必要です。TTL内ではネットワーク呼び出しは発生しません。 - 新しいチェックアウトでの最初の呼び出し のみが厳密にネットワークを必要とします。
- 自己更新には、このスキルディレクトリへのファイルシステム書き込みアクセスとGitHubへのネットワークアクセスが必要です。利用できない場合は警告を出力するかスキップし、モデルコマンドはローカルの現在のコピーで実行されます。
既知の問題
- OpenRouterの フロントエンド API(
/api/frontend/v1/models/find?active=true&fmt=cards)は非公式です。失敗した場合、CLIは利用可能な古いキャッシュにフォールバックし、[warn]を出力します。
データソース
- モデル:
https://openrouter.ai/api/frontend/v1/models/find?active=true&fmt=cards - ランキング: 同じエンドポイントに
order=top-weekly、order=throughput-high-to-low、order=latency-low-to-highを指定