設定 Clash初心者 VPNとの違い プロキシ入門

Clash APIで最適ノードを自動選択する高度な設定方法

2026年9月4日 更新日:2026年9月4日 読了目安:約10分

はじめに

Clash を常用していると、時間帯や接続先によってノードの品質が変化し、毎回手動で切り替える作業が発生します。特にリモート開発、動画会議、パッケージのダウンロードなどでは、数十ミリ秒の遅延差や一時的なパケットロスが操作性に大きく影響します。しかし、単純に「最も遅延が低いノード」を選べば、常に快適になるとは限りません。応答は速くても、帯域が狭い、接続が不安定、特定のサイトだけ失敗するといったケースがあるためです。

そこで本記事では、Clash API と YAML 設定を組み合わせ、ノードの遅延を検査し、条件に合うプロキシを自動選択する方法を解説します。Mihomo の External Controller を利用できる環境であれば、Clash Verge Rev、Mihomo を利用するデスクトップクライアント、サーバー上の自動処理などに応用できます。単なる速度測定だけでなく、グループの確認、定期実行、失敗時の再試行、ログの確認までを一つの運用として設計することが重要です。

この記事の目標

API で利用可能なノードを検査し、指定した遅延条件を満たすノードへ自動的に切り替える安全な構成を作成します。

利用前の注意

External Controller は Clash の操作権限を持つ管理 API です。LAN 全体へ無制限に公開せず、可能な限り 127.0.0.1 で待ち受け、認証用の Secret を設定してください。

1External Controller の準備

自動選択の最初の条件は、スクリプトから Clash の API に接続できることです。Mihomo の設定ファイルに external-controller と secret を追加します。ポート番号は他のアプリケーションと重ならないものを選び、ローカル環境だけで操作する場合は、外部の IP アドレスではなく 127.0.0.1 を指定します。

基本的な API 設定 (YAML)
external-controller: 127.0.0.1:9090 secret: "change-this-to-a-long-random-secret" mode: rule log-level: info unified-delay: true

クライアントによっては GUI の設定画面から External Controller を有効にできます。設定を変更した後は、コアを再起動するかプロファイルを再読み込みしてください。API が動作しているかは、次のようなリクエストで確認できます。

curl -H "Authorization: Bearer change-this-to-a-long-random-secret" \ http://127.0.0.1:9090/proxies

レスポンスに proxies の一覧が返れば、接続は成功です。返答がない場合は、ポート番号、Secret の綴り、ファイアウォール、現在使用しているコアが External Controller に対応しているかを確認します。Clash Verge Rev で設定を適用する場合、GUI が生成した設定と手動編集した YAML の優先順位にも注意してください。

利用する主な API エンドポイント

  • GET /proxies:プロキシグループと各ノードの状態を取得します。
  • GET /proxies/{name}:指定したグループの現在の選択状態や候補を確認します。
  • PUT /proxies/{name}:プロキシグループの選択ノードを変更します。
  • GET /proxies/{name}/delay:URL に対する遅延を測定します。コアのバージョンによって利用可能なパラメーターが異なる場合があります。

2自動選択に適した YAML グループを作る

スクリプトを作る前に、API が操作するプロキシグループを整理します。実際のノード名を直接ルールへ書き込むのではなく、対象ノードを一つのグループにまとめると、サブスクリプション更新後も構成を維持しやすくなります。ノード名に含まれる地域や用途を基準に filter を使い、テスト対象から明らかに不要なノードを除外します。

自動切り替え用プロキシグループ
proxy-groups: - name: Auto-Best type: select proxies: - URL-Test - DIRECT - name: URL-Test type: url-test include-all: true filter: "(?i)(JP|SG|US|東京|大阪|Singapore)" url: https://www.gstatic.com/generate_204 interval: 300 tolerance: 80

url-test は、指定した URL への応答時間を基準に候補を評価します。interval は測定間隔、tolerance は現在のノードから切り替える際に許容する差です。値を小さくしすぎると頻繁な切り替えが起き、大きくしすぎると混雑したノードに長く留まる可能性があります。まずは 300 秒と 50〜100 ミリ秒程度から始め、実際の通信状況に合わせて調整してください。

YAML の自動機能だけで十分な場合もありますが、API スクリプトを併用すると、複数 URL の結果を比較したり、特定のノードを除外したり、業務時間だけ判定したりできます。ただし、Clash 内蔵の url-test と外部スクリプトが同じグループを同時に変更すると競合しやすいため、役割を分けることを推奨します。

グループ名を固定する

スクリプトは表示名を手掛かりに API を呼び出します。プロファイルを更新しても Auto-Best のようなグループ名が変わらないようにし、見つからない場合は安全に終了する処理を入れてください。

3遅延検査とノード切り替えを自動化する

次の Python 例は、API からグループ内の候補を取得し、複数のテスト URL で遅延を確認して、条件を満たす最速のノードを選択します。Clash のコアやバージョンによってレスポンスの項目名が異なる可能性があるため、まずは実際の JSON を表示して構造を確認してください。

import time import requests API = "http://127.0.0.1:9090" SECRET = "change-this-to-a-long-random-secret" GROUP = "Auto-Best" TEST_URLS = [ "https://www.gstatic.com/generate_204", "https://cp.cloudflare.com/generate_204", ] TIMEOUT = 5000 MIN_DELAY = 800 HEADERS = {"Authorization": f"Bearer {SECRET}"} def get_group(): response = requests.get( f"{API}/proxies/{GROUP}", headers=HEADERS, timeout=5 ) response.raise_for_status() return response.json() def check_delay(node, url): response = requests.get( f"{API}/proxies/{node}/delay", params={"url": url, "timeout": TIMEOUT}, headers=HEADERS, timeout=8, ) response.raise_for_status() return response.json().get("delay", 99999) def select_node(node): response = requests.put( f"{API}/proxies/{GROUP}", json={"name": node}, headers=HEADERS, timeout=5, ) response.raise_for_status() def main(): group = get_group() candidates = group.get("all", []) best = None for node in candidates: delays = [] for url in TEST_URLS: try: delays.append(check_delay(node, url)) except requests.RequestException: pass if delays: score = sum(delays) / len(delays) if score <= MIN_DELAY and (best is None or score < best[0]): best = (score, node) if best: select_node(best[1]) print(f"selected: {best[1]} ({best[0]:.0f} ms)") else: print("no healthy node found") if __name__ == "__main__": main()

この例では、テスト URL の平均値をスコアにしています。平均値だけでは一度だけ発生した大きな遅延を見落とすため、実運用では最大値も確認し、例えば「平均 500 ミリ秒以下、最大 1200 ミリ秒以下」のように条件を分けると安定します。また、DIRECT や別のプロキシグループを候補に含めないよう、API の一覧から除外してください。

失敗時の再試行とフォールバック

ネットワークが一時的に不安定なとき、1 回の失敗だけでノードを無効と判定すると、不要な切り替えが発生します。各 URL の検査を 2〜3 回行い、少なくとも 1 回成功した場合だけ候補として残す方法が現実的です。API 接続そのものが失敗した場合は、指数バックオフを使って 2 秒、4 秒、8 秒のように待機し、一定回数を超えたら現在の選択を変更せず終了します。

  • 検査失敗:そのノードだけを除外し、次の候補を調べます。
  • API タイムアウト:短時間に繰り返さず、バックオフ後に再試行します。
  • 候補がゼロ:現在のノードを維持し、無条件で DIRECT へ変更しません。
  • 認証エラー:Secret をログへ出力せず、設定ミスとして処理を停止します。

切り替えすぎに注意

遅延が数ミリ秒変わるたびに切り替えると、既存の接続が切断されたり、ストリーミングが不安定になったりします。新しいノードが現在のノードより一定以上速い場合だけ変更する「ヒステリシス」を設けてください。

4定期実行、ログ、トラブルシューティング

スクリプトは常時ループさせるより、5〜15 分間隔の定期ジョブとして実行する方が扱いやすく、Clash API への負荷も抑えられます。Linux では cron や systemd timer、Windows ではタスク スケジューラ、macOS では launchd を利用できます。端末を起動した直後はネットワークが安定していないことがあるため、最初の実行を数十秒遅らせると誤判定を減らせます。

# Linux の cron 例:10 分ごとに実行 */10 * * * * /usr/bin/python3 /home/user/bin/clash_auto_select.py >> /home/user/logs/clash-auto.log 2>&1

ログには実行時刻、候補数、各ノードの遅延、選択結果、エラー種別だけを記録し、Secret やサブスクリプション URL は書き込まないでください。ログが増え続ける場合はローテーションを設定します。GUI で手動選択した直後に自動変更される場合は、ジョブの間隔が短すぎるか、現在の選択を保護する条件が不足しています。

よくある問題と確認方法

  • 404 が返る:グループ名を URL エンコードしていない、または指定した名前が実際のプロキシグループと異なります。
  • 401 が返る:Bearer 認証の Secret が一致していません。ヘッダーの形式も確認します。
  • 遅延が常に大きい:テスト URL がブロックされている可能性があるため、複数の URL を試します。
  • 選択後も通信できない:ルールが別のグループを参照していないか、DNS や TUN モードの状態を確認します。
  • 更新後に候補が消える:サブスクリプションのノード名や filter 条件が変わっていないか確認します。

自動選択は「最速のノードを永遠に固定する」仕組みではありません。接続先、時間帯、テスト URL、利用するプロトコルによって結果は変わります。まずは手動で測定結果と実際の体感を比較し、許容遅延、除外地域、再試行回数、実行間隔を調整してください。安全な Secret 管理とフォールバック設計を優先すれば、手動切り替えの負担を減らしながら、安定した Clash 運用を実現できます。

Clashを無料でダウンロード — 快適なネット体験をはじめよう →