Clash API 代理節點自動切換:外部控制器進階設定
進入 2026 年,Perplexity AI 憑藉其強大的實時搜索與生成能力,已成為許多用戶不可或缺的生產力工具。然而,隨著其風控系統的升級,越來越多的用戶在使用 Clash 代理時遇到了「Access Denied」或無限加載的問題。本文將深度解析其背後的技術原因,並提供一套從基礎規則到進階 TUN 模式的完整配置方案,確保您的 AI 搜索體驗穩定無障礙。
外部控制器能做什麼?
Clash API 代理節點自動切換,指的是由另一個程式、腳本或排程服務,透過 Clash 核心提供的外部控制器(External Controller)介面讀取狀態並執行操作。它不是重新建立一條代理連線,而是代替使用者完成「查看節點、測試延遲、選擇策略組、切換出口」等工作。只要 Clash 或 Mihomo 核心仍在運行,外部控制器就能按照固定規則處理節點狀態。
一般圖形化用戶端的自動選擇功能,通常只適合簡單的延遲測試;當您需要排除連續失敗的節點、記錄切換原因、按照不同服務選擇不同策略組,或把切換行為整合到伺服器部署流程時,API 會更有彈性。Clash Verge、Clash Verge Rev、Mihomo 以及部分相容 Clash API 的客戶端,都可能提供相近的控制方式,但實際端點、欄位名稱與權限設定仍應以目前使用的核心文件為準。
本文使用的概念適用於您有權管理的電腦、手機、路由器或測試伺服器。外部控制器具備切換代理與讀取連線資訊的權限,不應直接暴露在公用網路,也不應把密鑰寫入公開程式碼、聊天記錄或版本控制儲存庫。
開始前的設定與安全邊界
設定清單
- 可使用的 Clash 或 Mihomo 核心:確認核心正在運行,並知道它的 API 監聽位址與埠號。
- 控制器密鑰:建議設定足夠複雜的
secret,不要使用空白密鑰。 - 可測試的網址:選擇穩定、合法且適合您網路環境的測試端點。
- 腳本執行環境:例如 Python、Node.js、Shell,或具備 HTTP 請求功能的排程工具。
在 YAML 設定檔中,外部控制器常見的設定形式如下。不同核心可能使用 external-controller 或相容的欄位,若您使用的是 Mihomo,請以該版本的設定說明為準。
external-controller: 127.0.0.1:9090
secret: "replace-with-a-long-random-secret"
127.0.0.1 只允許本機程式連線,對桌面電腦或單機腳本而言通常是最安全的選擇。如果控制器必須由區域網路中的另一台管理主機存取,才考慮監聽區網位址,但必須同時限制防火牆來源、設定密鑰,並避免直接使用 0.0.0.0 對所有網卡開放。即使 API 使用 HTTPS,也不能取代網路層的存取控制。
安全注意
外部控制器不是一般的唯讀監控介面。取得密鑰的程式可以切換策略、重新載入設定,部分核心還能讀取連線與配置資訊。請把密鑰放在環境變數或權限受限的檔案中,並在日誌中遮蔽完整 URL、Authorization 標頭與訂閱內容。
修改設定後,請透過用戶端提供的「重新載入設定」或重啟核心功能套用變更。不要只編輯 YAML 卻期待目前執行中的核心立即更新,因為許多客戶端會先把設定載入記憶體,檔案變更不一定會自動生效。
查詢代理與策略組狀態
自動切換的第一個階段不是立即選節點,而是先取得核心目前知道的代理、代理群組與可用節點。常見的控制器 API 會使用 GET /proxies 取得完整資料,並透過 Authorization: Bearer 標頭傳送密鑰。請注意,API 回傳的代理名稱可能包含表情符號、空格、斜線或非 ASCII 字元,腳本不應假設名稱一定是簡單英文。
curl -s \
-H "Authorization: Bearer ${CLASH_SECRET}" \
"http://127.0.0.1:9090/proxies"
回應通常是一個以代理名稱為鍵的 JSON 物件。單一代理可能包含 type、history、now、all 等欄位;策略群組則常見為 Selector、URLTest、Fallback 或其他核心支援的類型。要自動切換,最重要的是先找到「群組名稱」和「群組可選項目」,再判斷目前選中的節點是否仍在可用清單內。
不要把所有代理都當成實際出口。有些名稱代表策略群組,有些代表 DIRECT、REJECT、DNS 或內部控制器。實作時應先檢查群組的 type,再依照 all 清單篩選真正可測試的節點。若訂閱更新後群組名稱改變,硬編碼名稱的腳本可能完全失效,因此可以採用「優先找指定名稱,找不到時再尋找第一個 Selector 群組」的策略。
| 資料項目 | 用途 | 實務注意 |
|---|---|---|
| 代理名稱 | 作為切換時的選擇值 | 不可只依靠陣列位置,名稱可能隨訂閱更新 |
| 策略群組 | 決定哪一組流量要切換 | 不同群組可使用不同測速網址與容錯門檻 |
| 延遲歷史 | 觀察最近測試結果 | 延遲為零、逾時或缺少資料不等同節點一定可用 |
| 目前選擇 | 避免重複切換與抖動 | 只有在新節點明顯較好或目前節點失效時才切換 |
動手實作:測試節點並切換策略組
一個可靠的控制器腳本至少要分成四個動作:讀取 API、找出候選節點、逐一測試、向策略組送出切換請求。對於支援 Clash API 的核心,常見的測速端點是 /proxies/{name}/delay,而切換策略組則可能使用 PUT /proxies/{group}。由於名稱必須放入 URL,請務必進行 URL 編碼,不要直接拼接含有空格或特殊字元的名稱。
以下是簡化的 Python 範例,重點在於流程與錯誤處理;實際使用前,請依您的核心版本確認測速端點支援的參數,以及回應中的延遲欄位名稱。
import os
import time
import requests
BASE = os.getenv("CLASH_API", "http://127.0.0.1:9090")
SECRET = os.environ["CLASH_SECRET"]
GROUP = os.getenv("CLASH_GROUP", "Proxy")
TEST_URL = os.getenv("CLASH_TEST_URL", "https://www.gstatic.com/generate_204")
headers = {"Authorization": f"Bearer {SECRET}"}
def get_proxies():
response = requests.get(f"{BASE}/proxies", headers=headers, timeout=5)
response.raise_for_status()
return response.json()["proxies"]
def test_proxy(name):
response = requests.get(
f"{BASE}/proxies/{requests.utils.quote(name, safe='')}/delay",
params={"url": TEST_URL, "timeout": 5000},
headers=headers,
timeout=8
)
response.raise_for_status()
return int(response.json().get("delay", 0))
def select_proxy(group, name):
response = requests.put(
f"{BASE}/proxies/{requests.utils.quote(group, safe='')}",
json={"name": name},
headers=headers,
timeout=5
)
response.raise_for_status()
data = get_proxies()
group = data.get(GROUP, {})
candidates = [name for name in group.get("all", []) if name not in ("DIRECT", "REJECT")]
results = []
for name in candidates:
try:
delay = test_proxy(name)
if delay > 0:
results.append((delay, name))
except requests.RequestException:
continue
time.sleep(0.2)
if results:
results.sort()
best_delay, best_name = results[0]
if group.get("now") != best_name:
select_proxy(GROUP, best_name)
print(f"switched to {best_name}: {best_delay} ms")
這段程式可以示範基本邏輯,但不建議直接把「最低延遲」當成唯一選擇條件。某個節點可能只在測速網址上反應很快,實際使用的服務卻頻繁重置;也可能因測試時間太短而誤判。因此可加入最低品質要求,例如連續兩次成功才列入候選、延遲超過門檻就淘汰,或優先選擇最近一段時間成功率較高的節點。
避免頻繁切換
建議設定遲滯條件(hysteresis):只有當新節點比目前節點快至少 20% 或目前節點連續失敗三次,才執行切換。每次切換後至少等待數十秒再重新評估,否則所有節點的短暫波動都可能造成策略組來回跳轉。
如果您使用的是 URLTest 或 Fallback 群組,核心本身可能已經負責測速與容錯,外部腳本不一定需要接管選擇。比較穩妥的做法是讓 API 只負責監控、告警和必要時重設,而不是與核心內建的自動選擇同時競爭。若必須由腳本管理,請把每個群組的責任分清楚,例如「串流」由核心自動測試,「工作服務」由腳本依成功率切換。
排程、重試與長時間運行
自動切換腳本應被視為一個小型服務,而不是只執行一次的命令。API 無法連線時,可能是 Clash 正在重載設定、電腦從睡眠中喚醒,或核心剛好重啟。腳本應使用有限次數的指數退避重試,例如在 1、2、4 秒後重試,超過上限便記錄錯誤並結束本次工作,不要無限迴圈佔用 CPU。
- 鎖定同一時間只有一個執行個體:使用檔案鎖或作業系統服務鎖,避免兩個排程同時切換相同群組。
- 保留目前選擇:切換前先讀取
now,若目標與目前節點相同,就不要再次發送 PUT 請求。 - 設定冷卻時間:成功切換後暫停評估,讓 TCP、TLS 與應用程式連線有時間穩定。
- 輸出可搜尋日誌:至少記錄時間、群組、原節點、新節點、測試結果與錯誤類型,但不要記錄 API 密鑰。
- 區分故障層級:API 失效、測速逾時、節點拒絕連線與目標網站暫時不可用,應使用不同訊息,方便後續排查。
在 Linux 上可使用 systemd timer 或 cron,在 Windows 上可使用工作排程器,在 macOS 上則可使用 launchd。排程間隔要配合節點數量與測速成本:節點很多時,每一輪同時測試會產生大量請求,逐一測試又可能耗時過長。可以先根據上一次成功結果保留前幾名,再定期完整掃描所有節點,降低對網路與 API 的壓力。
部署到伺服器時,建議使用專用的低權限帳號,將密鑰透過環境檔或秘密管理功能注入。若腳本需要在容器中運行,請確認容器能解析宿主機的 API 位址;使用 127.0.0.1 時,容器內的 localhost 通常不是宿主機。這類環境可以改用受限制的內部網路,或透過明確設定的主機閘道連線,但仍要保留防火牆規則。
常見問題與排查方法
為什麼 API 回傳 401 或 403?
先確認請求使用的是目前生效的密鑰,標頭格式通常是 Authorization: Bearer 密鑰,而不是把密鑰放在 URL 查詢參數中。若您剛修改 YAML,請確認核心已重載;若 API 綁定在其他位址,也要檢查腳本中的主機與埠號。部分用戶端會自行管理核心設定,直接修改檔案可能在下次啟動時被覆蓋。
找不到策略群組,該怎麼辦?
不要假設群組一定叫「Proxy」或「🚀 節點選擇」。先呼叫 /proxies 列出所有鍵值,再找出類型為 Selector、URLTest 或核心支援的群組。訂閱更新後名稱可能改變,建議將群組名稱放在環境變數中,並在找不到時發出告警,而不是默默切換到錯誤群組。
測速一直逾時,但手動使用節點正常,原因是什麼?
測速 URL 可能被目前網路阻擋、回應狀態不符合核心要求,或 timeout 太短。請在相同環境用瀏覽器或命令列確認測試網址,並選擇回應穩定且內容簡單的端點。還要注意部分節點需要特定 TLS、SNI 或 UDP 能力,測速成功只代表測試網址可達,不代表所有網站與應用都會正常。
節點為什麼會不斷來回切換?
常見原因是沒有設定遲滯、測速差距太小,或不同輪次使用了不一致的測試網址。請加入最小切換間隔、連續失敗次數與最小改善幅度,並在切換前後保留日誌。若核心本身已啟用 URLTest,則應避免外部腳本再次接管同一個策略組。
把 API 自動化納入穩定的 Clash 工作流程
有些只提供圖形介面的代理工具,節點切換必須依靠人工點選;另一些腳本方案雖然可以測速,卻缺少權限控制、重試、冷卻時間與清楚的錯誤日誌,長時間運行後容易出現頻繁跳轉或失去控制的情況。這正是 Clash API 與成熟核心值得善用的地方:您可以保留熟悉的圖形化介面,同時透過受保護的控制器精確查詢代理、管理策略組、記錄結果,並把自動切換接到排程與部署流程。若您希望在不同平台上以較一致的方式管理節點,不妨前往下載 Clash,先完成基本設定,再逐步加入 API 自動化。
準備好恢復您的 AI 工作流了嗎?
獲取 2026 最新版 Clash,內建優化分流規則,一鍵解決 Perplexity 與 ChatGPT 存取難題。
免費下載 Clash(Windows / macOS)