使用教學 精選 Clash 入門 Clash 與 VPN 差異 代理工具新手

Clash API 自動換節點:External Controller 進階設定

2026年9月4日 更新於 2026年9月4日 約 12 分鐘閱讀

前言:為什麼要用 API 自動換節點?

對於只需要偶爾切換代理的使用者來說,在 Clash Verge 或 Mihomo 的介面中手動選擇節點已經足夠。但如果你需要長時間運行下載任務、維護家用伺服器,或希望在不同網絡環境下維持穩定連線,單純依靠人工操作就不太可靠。節點可能在晚間出現高延遲、封包遺失,甚至突然失效;等到應用程式回報錯誤時才切換,往往已經造成請求逾時或工作中斷。

Clash 的 External Controller API 可以把這些操作交給腳本處理。腳本先透過 API 取得代理清單,再逐一測試節點延遲,接著將品質較佳的節點寫入指定的代理群組。配合重試、冷卻時間與排程,就能建立一套不依賴圖形介面的自動換節點流程。本文以 Mihomo 及支援 Clash API 的桌面客戶端為例,示範如何安全地完成這項設定。

本文目標

使用 External Controller 偵測節點品質、切換代理群組、處理失敗重試,並透過本機綁定與 Secret 控制 API 存取權限。

1開啟 External Controller 與驗證 API

External Controller 是 Clash 核心提供的 HTTP 控制介面。它通常監聽在 127.0.0.1:9090,因此只有本機程式可以存取。若你打算讓同一個區域網絡內的其他設備控制 Clash,才需要改用區域網絡 IP 或 0.0.0.0;這種做法會擴大攻擊面,除非有明確需求,否則不建議。

在 YAML 中設定控制器

打開目前正在使用的配置檔案,確認有以下欄位。不同客戶端的介面名稱可能略有不同,但最終都會寫入 Mihomo 的 YAML 配置:

external-controller: 127.0.0.1:9090 secret: "請替換成長且隨機的密碼"

secret 會用來驗證每一次 API 請求。即使控制器只監聽本機,也不應省略它,因為惡意程式一旦能夠連接本機連接埠,就可能讀取節點資訊、切換代理,甚至終止現有連線。修改後請重新載入配置或重啟核心,確保設定真正生效。

先用 curl 測試控制器

在終端機執行版本查詢,確認控制器可以連線。請將 YOUR_SECRET 替換成實際 Secret,並注意不要把包含密碼的指令貼到公開日誌或聊天群組:

curl -H "Authorization: Bearer YOUR_SECRET" \ http://127.0.0.1:9090/version

如果返回 JSON 並包含 version 欄位,代表 API 已正常工作。若出現連線拒絕,通常是控制器沒有開啟、連接埠寫錯,或客戶端使用的核心並非支援該 API 的 Mihomo。若收到 401 Unauthorized,則應檢查 Bearer 格式、Secret 是否正確,以及 YAML 引號中是否多了空白。

安全提醒

不要把 external-controller 綁定到公開網卡,也不要在腳本、Git 儲存庫或截圖中直接保存 Secret。若必須遠端管理,請搭配防火牆、VPN 或 SSH 隧道。

2透過 API 偵測節點品質

自動換節點的核心不是「隨機切換」,而是先定義可量化的品質條件。最常見的指標是延遲,但延遲低不一定代表連線穩定;某些節點在測試網址上反應很快,實際傳輸大型檔案時卻頻繁丟包。因此,建議至少綜合考慮可用性、延遲、連續失敗次數以及節點所在地。

讀取代理與群組資訊

使用以下請求可以取得目前核心中的所有代理、代理群組及其當前選擇。回傳結果通常是一個以代理名稱為鍵的 JSON 物件:

curl -s \ -H "Authorization: Bearer YOUR_SECRET" \ http://127.0.0.1:9090/proxies

在回傳資料中,all 通常代表所有可選節點,select 代表手動選擇群組,url-test、fallback 或 load-balance 則代表不同的自動策略。實作腳本時,不要把所有名稱都當成節點;應先排除群組、DIRECT、REJECT 及其他內建策略,否則測試結果可能無法用來切換目標群組。

測試延遲與可用性

Clash API 提供代理延遲測試端點。常見寫法如下,其中 name 必須進行 URL 編碼,url 則應選擇穩定、回應內容簡單的 HTTPS 網址:

curl -G \ -H "Authorization: Bearer YOUR_SECRET" \ --data-urlencode "url=https://www.gstatic.com/generate_204" \ --data-urlencode "timeout=5000" \ http://127.0.0.1:9090/proxies/節點名稱/delay

回應中的 delay 通常以毫秒表示。若請求逾時、TLS 失敗或節點拒絕連線,腳本應將該節點標記為不可用,而不是把錯誤值當成極低延遲。測試網址最好與實際用途接近:瀏覽國際網站可使用穩定的公共 HTTPS 端點,串流用途則應另外觀察實際播放是否緩衝,不能只依賴一次 API 測試。

  • 可用性: 至少連續兩次測試成功,避免短暫恢復的節點被立即選中。
  • 延遲門檻: 例如只接受低於 300 毫秒的節點,再從中選擇最低值。
  • 失敗懲罰: 連續失敗的節點加入冷卻清單,數分鐘內不重複測試。
  • 地區限制: 對需要固定出口地區的服務,先篩選名稱或標籤,再比較延遲。

小撇步

不要每幾秒測試全部節點。節點數量較多時,可先保留最近一次的結果,只對過期、失敗或延遲大幅上升的節點重新測試,減少控制器與代理伺服器的負擔。

3更新代理群組並自動切換

找到合適節點後,下一步是把它寫入正在使用的代理群組。假設群組名稱為 PROXY,API 的請求方法通常是 PUT,內容使用 JSON 指定要選擇的節點:

curl -X PUT \ -H "Authorization: Bearer YOUR_SECRET" \ -H "Content-Type: application/json" \ -d '{"name":"日本-01"}' \ http://127.0.0.1:9090/proxies/PROXY

節點名稱及群組名稱必須與 /proxies 回傳結果完全一致,包含空格、括號和地區符號。建議腳本先檢查目標群組的 all 陣列是否包含候選節點,再執行切換;這可以避免因訂閱更新、節點改名或配置重新載入而收到錯誤回應。

一個可維護的 Python 範例

以下範例示範基本流程:讀取代理群組、依序測試節點、選擇最低延遲者,最後更新群組。實際使用時請把 Secret 放在環境變數中,不要直接寫在程式碼裡:

import os import time import requests API = "http://127.0.0.1:9090" SECRET = os.environ["CLASH_SECRET"] GROUP = "PROXY" TEST_URL = "https://www.gstatic.com/generate_204" session = requests.Session() session.headers.update({"Authorization": f"Bearer {SECRET}"}) data = session.get(f"{API}/proxies", timeout=5).json() group = data["proxies"][GROUP] candidates = [ name for name in group.get("all", []) if name not in {"DIRECT", "REJECT"} ] results = [] for name in candidates: try: response = session.get( f"{API}/proxies/{name}/delay", params={"url": TEST_URL, "timeout": 5000}, timeout=7, ) delay = response.json().get("delay") if isinstance(delay, int) and delay > 0: results.append((delay, name)) except (requests.RequestException, ValueError): continue if results: delay, selected = min(results) session.put( f"{API}/proxies/{GROUP}", json={"name": selected}, timeout=5, ) print(f"已切換至 {selected},延遲 {delay} ms") else: raise SystemExit("沒有可用節點")

這段程式適合作為起點,但正式環境不應只用單次最低延遲作決策。可以將每個節點測試兩至三次後取中位數,避免某一次偶然的快速回應影響選擇;也可以設定「改善幅度」,只有新節點比目前節點低 20% 以上時才切換,避免兩個相近節點之間反覆跳轉。

避免頻繁換 IP

登入、支付、郵件及長連線服務可能因出口 IP 改變而重新驗證。建議為重要服務建立固定地區的獨立策略群組,不要讓全域代理因一次延遲波動就立即切換。

4加入重試、排程與權限控管

能夠完成一次切換,只代表 API 呼叫成功;要讓流程長期運作,還需要處理網絡暫時中斷、核心重載、訂閱更新以及腳本重複執行等情況。穩定的自動化流程應該具備明確的退出條件,並保留足夠的日誌供日後追查。

設計合理的重試策略

重試不等於無限迴圈。建議將 API 連線錯誤與節點測試錯誤分開處理,使用指數退避,例如第一次等待 2 秒、第二次等待 4 秒、第三次等待 8 秒,最多嘗試三次。若控制器持續無法連線,應保留目前正在使用的節點,不要因腳本失敗而強行切換到未知狀態。

  • API 回應為 401 時停止重試,先檢查 Secret。
  • API 回應為 404 時重新讀取群組名稱,可能是節點或群組已被訂閱更新。
  • 逾時或暫時性網絡錯誤可重試,但每次重試要增加等待時間。
  • 切換成功後再次呼叫 /proxies/群組名稱 驗證目前選擇是否符合預期。

使用排程定期執行

Linux 可以使用 cron 或 systemd timer,Windows 可使用工作排程器,macOS 則可使用 launchd。排程頻率應與節點變化速度相符,例如每 10 至 30 分鐘檢查一次通常已經足夠。若每分鐘掃描全部節點,不但浪費流量,也可能造成供應商限制或讓節點服務誤判為異常探測。

# 每 15 分鐘執行一次,並將輸出寫入專用日誌 */15 * * * * CLASH_SECRET='由安全環境提供' \ /usr/bin/python3 /opt/clash/auto_switch.py \ >> /var/log/clash-auto-switch.log 2>&1

更安全的做法是讓排程程序繼承受限權限的環境變數,或使用檔案權限設為僅擁有者可讀的 Secret 檔案。日誌中只記錄時間、群組、節點名稱和延遲,不要輸出完整 Authorization 標頭、訂閱網址或其他敏感資料。

縮小控制器的權限範圍

External Controller 本身擁有相當高的管理能力,因此可以從幾個層面降低風險:

  • 只監聽 127.0.0.1,並以系統防火牆封鎖外部連線。
  • 使用高熵、不可猜測的 Secret,定期更換並避免與訂閱密碼共用。
  • 腳本只執行必要的 GET 與代理群組 PUT,不要把任意 API 路徑暴露給網頁介面。
  • 若要遠端操作,優先透過 SSH 隧道或 VPN,不要直接把 9090 連接埠映射到公網。
  • 在切換前驗證群組名稱與節點名稱,防止未預期的字串被送入 API。

建議的完整流程

讀取群組 → 篩選候選節點 → 多次測試延遲 → 套用門檻與冷卻 → PUT 切換 → GET 驗證 → 記錄結果。任何一步失敗,都保留原節點並寫入可追蹤的錯誤日誌。

5常見問題與實務檢查清單

如果腳本顯示成功,但實際流量沒有改變,首先確認應用程式使用的策略群組是否就是腳本更新的群組。例如規則可能指向 Proxy,而你更新的是 PROXY;Clash 的群組名稱通常區分大小寫。其次,確認客戶端是否在腳本執行後重新載入了另一份配置,或訂閱更新把手動修改的群組狀態覆蓋。

若延遲結果全部失敗,請分別測試控制器、DNS 和實際代理連線。控制器可用不代表節點可用;測試網址無法解析時,也不一定是節點故障,可能是 DNS 模式、TUN 設定或系統防火牆造成。建議先在客戶端介面手動選擇一個節點,確認瀏覽器能正常訪問測試網址,再回頭檢查腳本參數。

  • 找不到群組: 先呼叫 /proxies,複製 JSON 中的實際名稱,不要依賴介面顯示的簡稱。
  • 節點名稱含特殊符號: 使用 Python requests 或其他 HTTP 用戶端的路徑參數功能,避免自行拼接未編碼的 URL。
  • 切換後又跳回原節點: 檢查是否同時啟用了另一個自動策略,或有第二個排程腳本正在執行。
  • 延遲很低但無法使用: 增加實際 HTTPS 請求驗證,並記錄連續成功率,而不是只看單次毫秒數。
  • 重啟後設定消失: 確認修改的是持久化配置,而不是僅存在於當前核心記憶體中的運行狀態。

最後,建議先在測試群組驗證自動切換,再套用到全域代理。設定合理的最低延遲、最大失敗次數和最短切換間隔,通常比追求每一次都選到最快節點更可靠。對需要固定登入狀態的網站,穩定性、地區一致性和連線成功率應優先於幾十毫秒的延遲差距。

如果你尚未安裝支援 External Controller 的 Clash 客戶端,可以先查看適用於不同平台的版本,再依本文設定 Mihomo 核心與 YAML 配置。

立即免費下載 Clash,開啟流暢上網新體驗 →