OpenClaw Model Manager:モデルルーティングJSONの手編集をやめるためのGUI
- カテゴリ
- ツールとダウンロード
- 公開日
- 2026年7月11日
- 著者
- Jacob Lloyd — プロジェクト完了後、AIの支援を受けて執筆
- 読了時間
- 約11分で読めます
かんたんに言うと: 自宅のAI環境にちゃんとしたコントロールパネルを与える無料のデスクトップアプリです。設定ファイルを手で書き換える危ない作業の代わりに、各AIヘルパーがどの「頭脳」を使っているかを一覧表示し、クリックで切り替えられます。壊れる設定は保存を拒否——たった1文字のタイプミスでアシスタントが黙り込んだ苦い経験から生まれました。
昔、JSONファイルのモデルIDをタイポして、そのエージェントがただ黙り込んだことがあります。エラーなし、クラッシュなし。存在しないモデルに延々と話しかけるエージェントを尻目に、私はもっと面白そうなバグを探して時間を溶かしていました。二度とごめんなので、このアプリを作りました。
TL;DR
- これは何:OpenClawスタックの全エージェント・サブエージェント・cronジョブがどのLLMと話すかを決める設定ファイル
openclaw.jsonを編集する、GTK4/libadwaitaのデスクトップアプリです。 - 費用:無料。MITライセンスで、ソースは下のzipに入っています。
- 必要なもの:GTK4 + libadwaita + PyGObject の入ったLinux(パッケージマネージャ1行で入ります)、Python 3.11以上、そしてOpenClaw環境。なければ同梱のサンプル設定からゼロで始められます。
- 手に入るもの:全エージェントのモデルが1画面に並ぶダッシュボード、ファイルを壊さず存在しないモデルも割り当てない保存処理、そしてClaude Code CLIを無料ローカルモデル・格安DeepSeek・本物のAnthropic課金へポチッと切り替えるスイッチ。
手に入るもの
まずスクリーンショットから。これは使い捨ての HOME にダミー設定を置いたサンドボックス環境で撮ったものです。アプリは本物、データは偽物、私のAPIキーはゼロ。
メインウィンドウが答えてくれるのは、以前はJSONをgrepして調べていた問い、つまり「どこでどのモデルが動いていて、いくらかかるのか?」です。各エージェント、スタック全体のデフォルト、サブエージェントのオーバーライド、cronジョブ、さらには隣で動くメールエージェントのモデルまで。各エントリには色つきバッジが付きます:Local(このPC)、Remote(2台目のPC)、Cloud(請求書に載るやつ)。
なぜ作ったか
OpenClawは自宅で動かしているマルチエージェントスタックです。複数のAIエージェントがそれぞれモデルに向いていて、ローカルで無料のものもあれば、クラウドで課金されるものもあります。ルーティングは全部1つのファイル ~/.openclaw/openclaw.json に載っています:モデルカタログ、エージェントごとのプライマリ/フォールバック割り当て、プロバイダ設定、そしてゲートウェイ自身の認証トークン。これを手で編集していると、決まって2通りの事故が起きました。
まず、間違ったモデルIDは静かに失敗します。古いデフォルト設定が、プロバイダが一度も提供したことのないモデル vllm/google/gemma-4-31b-qat をエージェントに割り当てていたことがありました。何もクラッシュしません。エージェントはただ座り込んでいるだけ。保存に失敗して壊れたファイルはもっとひどくて、悪い編集1回でゲートウェイ全体がクラッシュループに入ります。
次に、Claude Code CLIのバックエンド切り替えは、目に見えない環境変数の外科手術です。OpenClawはコーディングタスクにClaude Codeを起動しますが、そのリクエストがどこへ行くか(=誰に請求が行くか)は、ゲートウェイのsystemdユニットに載る ANTHROPIC_* 環境変数で決まります。無料ローカル・格安DeepSeek・本物のAnthropicを行き来するたびに、systemdドロップインを手書きしていました。夜11時に確実に間違えるタイプの作業です。
保存の流れ
いちばん信頼したいのは、Saveを押したときに何が起きるかです。順番はこう:
重みを支えているのは2つのステップです。検証は、プロバイダが公開していないモデルIDを一切拒否します。冒頭のタイポバグは「気をつけて確認するもの」ではなく、構造的に起こりえないものになりました。アトミック書き込みがあるのは、openclaw.json がゲートウェイの認証トークンを含んでいて chmod 600 を維持しなければならないから。一時ファイルには内容を書く前に元ファイルのパーミッションを付け、fsync してから元ファイルの上にrenameします。保存の途中でクラッシュしても、元のファイルは無傷です。
バックアップは古いものから順に回します。.bak.4 が .bak.5 になり、以下同様、最新のコピーが .bak に入ります。失敗した保存はrename1回で巻き戻せて、履歴は1世代ではなく5世代残ります。
Coding Helperのドロップイン
Claude Code CLIの向き先変更は別のフローです。openclaw.json には一切触れず、ゲートウェイがClaude Codeを起動する前に環境を上書きするsystemdドロップインを書き込みます。
モードは4つ、ドロップダウンは1つ。LM Studio(無料・ローカル)、Anthropic互換エンドポイント経由のDeepSeek(安い)、Anthropic Cloud(デフォルト:ドロップインなし、何も上書きしない)、そしてDisabled。最後のはCLIを http://127.0.0.1:9/blocked に向けるので、すべての呼び出しがハングせず即失敗します。ワンクリックのライブテストもあって、本物のAnthropic形式の ping をLM StudioかDeepSeekに投げ、実際にどのモデルが答えたかを報告してくれます。信じるのは設定画面ではなく、たった今起きたリクエストです。
APIキーをユニットファイルに書かない
DeepSeekモードにはAPIキーが必要ですが、systemdユニットファイルはキーの置き場所として最悪です。直接書けば、ディスク上でも systemctl show の出力でも平文で丸見えになります。なのでドロップインにはキーを含めず、代わりにこう書きます:
ExecStart=/usr/bin/bash -c 'export ANTHROPIC_API_KEY="$$DEEPSEEK_API_KEY"; exec <gateway cmd>'
ミソは $$ です。ユニットファイルの中では、$$ はリテラルの $ のエスケープになります。これがないと、systemdがコマンドライン組み立ての時点で自分で変数を展開してしまい、本物のキーがプロセスのargvに載って ps で読めてしまう。ドルを2つにすれば、bashはリテラルの $DEEPSEEK_API_KEY を受け取り、実行時にゲートウェイの EnvironmentFile(~/.openclaw/gateway.systemd.env、chmod 600)から展開します。秘密はユニットファイルにも systemctl show にもプロセス一覧にも現れません。存在するのはそのプロセスのbash環境の中だけです。zipの examples/ フォルダに、CHANGE_ME プレースホルダ付きでこのパターンの解説が入っています。
セットアップ
zipに同梱のREADMEから:
# 1. Install GTK4 + libadwaita + PyGObject from your distro's packages
# (one dnf/apt line — see README-SETUP.md for the exact package names)
# 2. Install the app and its launcher
install -Dm755 openclaw-model-manager ~/.local/bin/openclaw-model-manager
# .desktop file goes to ~/.local/share/applications/
# 3. If you don't already have an OpenClaw config:
cp examples/openclaw.json.example ~/.openclaw/openclaw.json
chmod 600 ~/.openclaw/openclaw.json
# then replace every CHANGE_ME placeholder inside it
# 4. Optional — API keys, both chmod 600, examples provided:
# ~/.openclaw/.env
# ~/.openclaw/gateway.systemd.env
pipで入れるのはPyGObjectだけで、あとはPython 3.11+の標準ライブラリです(tomllib 込み)。中身は実行ファイル1本(164KB、3,570行)、.desktop ランチャー、README、MITライセンス、サンプル設定4つ。zipにして49KBです。
ハマりどころ
- Cloudモードは「ドロップインなし」であって「確実に自分のAnthropicアカウント」ではありません。何も上書きしないので、ユニットに元から設定されていたものがそのまま動き続けます。選んだモードに有効なキーがないとアプリが警告しますが、念のため自分でも確認を。
- ドロップインは本物のAnthropicキーを意図的に隠します。Localモードは、ゲートウェイが起動するすべてに
ANTHROPIC_API_KEY=lm-studioを設定します。うちのマシンでは、これが対話用のclaudeCLIエイリアスまで気づかぬうちにLM Studioへ振り替えていました。Claude Codeは「動いている」ように見えて、答えだけローカルモデル製。Claudeの様子がおかしいと感じたら、モデルを疑う前にsystemctl --user cat openclaw-gateway.serviceでドロップインを探してください。 openclaw updateでゲートウェイのExecStartが変わったら、DeepSeekモードを一度選び直して新しいコマンドをラップし直すこと。アプリはユニットフラグメントから正規のExecStartを読み、自分のラッパーを自力で見分けるので(index.jsがあって$$DEEPSEEK_API_KEYがないことで判定)、二重ラップは起きません。ただし、見ろと言われていないコマンドを勝手に直すこともしません。- ローカルモデルは
reasoning: trueが安全なデフォルトです。reasoning_contentを出すモデルをreasoning: falseのまま設定すると、ゲートウェイからはストールに見えます。約390秒の沈黙、そしてkill。思考しないモデルでオンのままでも無害なので、モデル追加ダイアログはデフォルトでオンにしています。これは本当にデバッグ時間を溶かしたやつです。 - 空でない
plugins.allowは厳格な許可リストです。プラグインエントリのenabled: trueは、そのidがallowにも載っていない限り何もしません。アプリはこれを正しく読みますが、あえてplugins.*には一切書き込みません。プラグインの挙動がおかしいとき、原因を教えてくれるツールではないということです。 - ゲートウェイは自分でも
openclaw.jsonを書き換えます(identityの再調整やopenclaw update)。アプリはファイルのmtimeを追跡していて、外部の編集を上書きする前に警告します。保存前バックアップは、実際にディスクにあった内容を保全します。 - モデルIDは
provider/raw-id形式です。スラッシュのない裸のIDは、ローカルのLM Studioエンドポイント経由で解決されます。エラーではなくただの慣習ですが、存在しないproviderフィールドを探しに行く前に知っておくと得です。
ダウンロード
個人利用は無料です。役に立ったら、コーヒーをおごってもらえると嬉しいです。