9routerで独自のAIモデルルーターを運用する方法
9routerをセルフホスト型AIモデルルーターとして運用。npmまたはDockerで導入し、curlでモデルを確認、開発ツールを接続してOpenAI互換APIを保護します。
9routerは、MITライセンスで公開されているオープンソースのルーティングプロキシです。自分のマシンやサーバー上で動作し、接続したすべてのAIプロバイダーを、OpenAI互換の単一エンドポイントhttp://localhost:20128/v1に集約します。
あるターミナルでClaude Codeを、エディターでClineを、サイドプロジェクトでOpenAI SDKを使っていると、APIキーとベースURLがそれぞれ3セットずつ必要になります。しかもモデルを切り替えるたびに、ツールごとに設定を変更しなければなりません。9routerを使えば、これらをローカルの単一エンドポイントにまとめられます。本ガイドでは、npmまたはDockerでのインストール、curlによる動作確認、各ツールの接続先設定、そしてlocalhost外からアクセスできるようにする前のセキュリティ対策について解説します。
重要ポイント
- 9routerは
npm install -g 9routerでインストールし、9routerで起動します。デフォルトでは、ダッシュボードとOpenAI互換APIの両方がポート20128で待ち受けます。 http://localhost:20128/v1/modelsにGETリクエストを送ると、ルーターが提供できるすべてのモデルとコンボが一覧表示されます。プロバイダーが接続されているかを確認する最も手軽な方法です。- コンボとは、名前を付けたモデルの順序付きリストで、
modelの値として指定します。現在のモデルがクォータを使い切った場合、レート制限を受けた場合、またはエラーを返した場合、ルーターは次のモデルに切り替えます。 INITIAL_PASSWORDを設定していない場合、ダッシュボードへの初回ログインには123456が使われます。インスタンスをlocalhost外に公開する前に、独自のパスワードを設定し、ダッシュボードの「Require API key」設定を有効のままにしておいてください。
9routerとは
9routerは、OpenAI形式のリクエストを受け付けて設定済みのアップストリームプロバイダーへルーティングし、必要に応じてOpenAI、Claude、Geminiのリクエスト形式を相互変換するセルフホスト型プロキシです。プロジェクトのREADMEには40以上の対応プロバイダーが記載されており、CLIは9router npmパッケージとして配布されています。
9routerとOpenRouterの主な違いは、ルーターがどこで動作するかです。OpenRouterはリクエストを送信する先のホスト型サービスです。一方、9routerは自分で運用するソフトウェアです。また、OpenRouterは9routerのプロバイダー一覧にも含まれているため、自前のルーターの背後にOpenRouterアカウントを配置することもできます。
| OpenRouter | 9router | |
|---|---|---|
| 動作場所 | ベンダーのクラウド | 自分のマシンまたはサーバー |
| プロバイダーの認証情報を保持する主体 | サービス側(単一のOpenRouterキーの背後) | ローカルの9routerインスタンス |
| ツールで使用するベースURL | https://openrouter.ai/api/v1 | http://localhost:20128/v1 |
セルフホスト型モデルルーターを運用するメリット
ローカルルーターを使うと、すべてのツールが同じエンドポイントを利用でき、プロバイダーの認証情報も一か所で管理できます。そのため、ツールの設定やアプリケーションコードに手を加えることなくモデルを変更できます。
- 単一のエンドポイント。 OpenAI互換のクライアントはすべて同じベースURLを使用します。
- キーの一元管理。 プロバイダーアカウントはダッシュボードで一度追加するだけです。各ツールに必要なのは9routerのAPIキーだけです。
- 文字列だけでモデルを切り替え。 モデルを変更する際に変えるのは
modelの値だけです。 - コンボ。 コンボとは、名前を付けたモデルの順序付きリストで、モデル名として使用します。最初のモデルがクォータを使い切った場合、レート制限(429)を受けた場合、またはエラーを返した場合、ルーターは次のモデルを試します。
一般的なパターンは、優先したいモデルを先頭に置き、その後ろに低コストなモデルを並べる方法です。フォールバック先を選ぶ前にトークン単価を比較したい場合は、LLM APIコスト計算ツールを利用してください。
9routerのインストールと起動
9routerはnpm install -g 9routerでグローバルなnpm CLIとしてインストールし、9routerコマンドで起動します。サーバーはポート20128で待ち受けます。
npm install -g 9router
9router
# Dashboard: http://localhost:20128
# API: http://localhost:20128/v1
グローバルインストールしたくない場合は、npx 9routerで一度だけ実行することもできます。
Dockerで実行する場合は、公式のdecolua/9routerイメージを使用します。このイメージはghcr.io/decolua/9routerでも公開されています。
docker run -d --name 9router \
-p 20128:20128 \
-v "$HOME/.9router:/app/data" \
-e DATA_DIR=/app/data \
-e INITIAL_PASSWORD='change-me' \
decolua/9router:latest
ボリュームをマウントしておくと、コンテナを再起動してもSQLiteデータベース(コンテナ内の/app/data/db/data.sqlite)が保持されます。新しいリリースは頻繁に公開され、latestタグもそれに合わせて更新されるため、再現性のあるデプロイが必要な場合は特定のバージョンタグに固定してください。
9routerが起動したら、ダッシュボードでセットアップを完了します。
http://localhost:20128を開き、ダッシュボードにログインします。- プロバイダーアカウントを1つ以上追加します。
- ツールで使用するAPIキーを作成します。
curlでルーターの動作を確認する
9routerが正しく動作しているかを確認する最も手軽な方法は、ツールを設定する前に/v1/modelsへGETリクエストを送ることです。レスポンスは、ルーターが提供できるすべてのモデルとコンボを含むJSONリストで、OpenAI標準のリスト形式で返されます。
curl http://localhost:20128/v1/models
モデル一覧はキーなしでも応答します。一方、チャットリクエストは異なります。ダッシュボードの「Require API key」設定はデフォルトで有効になっているため、ダッシュボードで作成したキーが必要です。また、特定のモデルに制限されたキーではそのモデルしか表示されないため、モデル一覧のリクエストでもキーを送信する習慣をつけておくとよいでしょう。
curl http://localhost:20128/v1/models \
-H "Authorization: Bearer $NINE_ROUTER_API_KEY"
プロバイダーのモデルIDが一覧に表示されていれば、ルーティングは正常に機能しています。一覧が空の場合は、プロバイダーがまだ接続されていません。
各ツールの接続先を9routerに設定する
カスタムのOpenAIベースURLを指定できるクライアントであれば、どれでも9routerを利用できます。ベースURLをhttp://localhost:20128/v1に設定し、ダッシュボードで作成したAPIキーを指定してください。
OpenAI SDK
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "http://localhost:20128/v1",
apiKey: process.env.NINE_ROUTER_API_KEY, // created in the 9router dashboard
});
const res = await client.chat.completions.create({
model: "<an id or combo name from /v1/models>",
messages: [{ role: "user", content: "Say hello" }],
});
console.log(res.choices[0].message.content);
別のモデルやコンボに切り替えるには、modelの文字列を変更するだけです。コードのそれ以外の部分を変更する必要はありません。
コーディングエージェント
Clineでは、APIプロバイダーとしてOpenAI Compatibleを選択し、ベースURLhttp://localhost:20128/v1、ダッシュボードのAPIキー、/v1/modelsからコピーしたモデルIDの3つの値を入力します。OpenCodeのように独自のプロバイダーを指定できるターミナル型エージェントでも、同じ3つの値を設定します。
pi-9router-extを使ったPiとの連携
pi-9router-ext拡張機能を使うと、2つの環境変数を通じてPiコーディングエージェントを9routerに接続できます。
pi install npm:pi-9router-ext
NINE_ROUTER_BASE_URL=http://localhost:20128 NINE_ROUTER_API_KEY=<key> pi
# inside Pi:
/9router-models
この拡張機能は起動時に/v1/modelsからチャットモデルを読み込みます。0.2.4リリースでは、さらに/v1/models/webにもクエリを送り、9routerのWeb検索ルートとフェッチルートを検出します。検出結果を確認するには、Pi内で/9router-modelsを実行してください。
9routerを公開する前にセキュリティを確保するには
他のマシンから9routerにアクセスできるようにする前に、ダッシュボードのパスワード、JWTシークレット、APIキーシークレットを設定し、「Require API key」を有効のままにしておいてください。デフォルト設定はlocalhost内での利用には問題ありませんが、それ以外の環境では不十分です。INITIAL_PASSWORDを設定していない場合、パスワードが保存されるまでダッシュボードへの初回ログインには123456が使われます。ポートを開放する前、またはパブリックホストにデプロイする前に、公式の.env.exampleを参考に以下の値を設定してください。
INITIAL_PASSWORD=<long-random-string> # first login otherwise uses 123456
JWT_SECRET=<long-random-string> # listed under "Required" in .env.example
API_KEY_SECRET=<long-random-string> # the example default is publicly known
AUTH_COOKIE_SECURE=true # set when serving behind an HTTPS reverse proxy
APIキーのチェック自体はダッシュボードで設定します。Endpointページを開き、Require API keyが有効になっていることを確認してください。これにより、有効なキーを持たないリクエストは拒否されます。この設定はデフォルトで有効になっており、無効な状態でエンドポイントがリモートホストからアクセス可能な場合は、ダッシュボードに警告が表示されます。
AUTH_COOKIE_SECURE=trueは、9routerの前段でTLSを終端している場合にのみ設定してください。プレーンなHTTP通信では、ブラウザーが認証Cookieを送り返さなくなります。
まとめ
9routerのようなセルフホスト型ルーターを使えば、すべてのツールで単一のエンドポイントと単一の認証情報セットを共有でき、モデルの変更もmodelの文字列を変えるだけで済みます。まずはインストールし、/v1/modelsにプロバイダーのモデルが表示されることを確認したうえで、いずれか1つのツールの接続先をhttp://localhost:20128/v1に設定してみてください。ルーターをlocalhost外に公開する前には、パスワードとシークレットを設定し、「Require API key」を有効のままにしておきましょう。
よくある質問
9routerを20128以外のポートで実行するには?
npm CLIの場合は、9router --port 8080 のように起動するとカスタムポートを使用できます。ソースから実行する場合は、PORT環境変数を設定し、あわせてNEXT_PUBLIC_BASE_URLも同じポートを指すように設定します。Dockerの場合は、ポートマッピングのホスト側を変更します(例: -p 8080:20128)。いずれの場合も、各ツールのベースURLを新しいもの(例: http://localhost:8080/v1)に変更する必要があります。
9routerの設定やデータはどこに保存されますか?
9routerは、DATA_DIRで指定したディレクトリ(デフォルトは ~/.9router)にデータを保存し、SQLiteデータベースはそのディレクトリ内の db/data.sqlite に格納されます。JWT_SECRETを設定していない場合は、自動生成された署名用シークレットも同じ場所(~/.9router/jwt-secret)に保存されます。公式のDockerイメージではDATA_DIRが /app/data に設定されているため、/app/data にボリュームをマウントすればすべてのデータを永続化できます。
別のマシン上のツールからリモートの9routerサーバーに接続するには?
クライアントマシンで npx 9router connect http://server-host:20128 を実行します。このコマンドはローカルサーバーを起動しません。ダッシュボードのパスワードでログインし、「cli-」にホスト名を付けた名前のAPIキーを再利用または新規作成したうえで、選択した各ツールの設定ファイルを書き込みます。元の設定ファイルは、.bak-9router という接尾辞を付けて一度だけバックアップされます。対象ツールをあらかじめ指定するには --tools claude,codex を、変更を元に戻すには --reset を使用します。
9routerで同じプロバイダーの複数アカウントを使用できますか?
はい。9routerはプロバイダーごとに複数のアカウントをサポートしており、ラウンドロビン方式または優先度ベースのルーティングでリクエストを分散します。あるアカウントがクォータの上限に達すると、ルーターは次のアカウントに切り替えます。これはコンボとは別の仕組みです。アカウントのローテーションでは同じモデルのまま背後の認証情報を切り替えるのに対し、コンボでは別のモデルに切り替えます。
Gain Debugging Superpowers
Unleash the power of session replay to reproduce bugs, track slowdowns and uncover frustrations in your app. Get complete visibility into your frontend with OpenReplay — the most advanced open-source session replay tool for developers.
Star on GitHub12k