使用教程 精选 Clash 入门 VPN 区别 新手指南

Clash API自动切换节点:YAML配置与脚本实战

2026年9月4日 更新于 2026年9月4日 约 12 分钟阅读

前言:为什么要用 API 自动切换节点?

在日常使用 Clash 或 Mihomo 时,手动切换节点并不困难,但当节点数量较多、网络质量变化频繁,或者你需要长期运行下载、服务监控和远程办公任务时,单纯依靠手动操作就容易出现问题。某个节点可能在白天延迟很低,晚高峰却发生丢包;某个节点虽然能够连通目标网站,但实际吞吐量不足;还有一些节点会突然失效,导致应用长时间停留在重试状态。

Clash 提供的 external-controller 接口,可以让脚本读取代理组、检测节点延迟,并通过 HTTP API 修改当前策略组的选择结果。配合 YAML 配置、定时任务和日志记录,我们就能构建一个轻量的节点自动管理流程:先确认控制接口安全可用,再获取指定代理组中的节点,逐个测试延迟,最后将表现较好的节点切换为当前使用节点。

本文以 Mihomo 兼容的 Clash 配置为例,重点讲解三个部分:external-controller 的配置方式、代理组与延迟检测的设计,以及使用 Python 脚本调用 API 完成自动切换。Clash Verge、Clash Verge Rev、Clash for Windows 和其他支持 Mihomo 内核的客户端,配置入口可能略有不同,但核心 API 思路基本一致。

最终目标

让脚本只在节点确实可用、延迟达到要求时执行切换,并通过超时、失败重试和日志机制避免频繁抖动。

1配置 external-controller 与访问密钥

external-controller 是 Clash API 的监听地址,通常写成 127.0.0.1:9090。其中 127.0.0.1 表示只允许本机访问,适合在个人电脑上运行自动化脚本;如果写成 0.0.0.0:9090,则可能让局域网甚至更大范围内的设备访问接口,除非你非常清楚防火墙和访问控制策略,否则不建议这样配置。

在配置文件的顶层加入以下内容。YAML 缩进必须使用空格,不能混用 Tab;修改后需要在客户端中重新加载配置,部分客户端还需要重启内核才能使控制器端口生效。

external-controller: 127.0.0.1:9090 secret: "change-this-to-a-long-random-token" external-ui: "dashboard"

secret 是 API 访问密钥。脚本请求时需要在 HTTP 请求头中加入 Authorization: Bearer,后面跟上配置文件中的密钥。不要把真实密钥直接提交到公开代码仓库,也不要在截图、工单或聊天记录中暴露完整的控制地址与密钥。

先用 curl 检查接口是否可用

启动 Clash 内核后,可以用下面的命令读取版本信息。如果返回 JSON,说明端口监听和认证基本正常;如果出现连接失败,应先检查客户端是否真的使用了这份配置,以及端口是否被其他程序占用。

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

在 Windows PowerShell 中,也可以执行:

$headers = @{ Authorization = "Bearer change-this-to-a-long-random-token" } Invoke-RestMethod -Headers $headers ` -Uri "http://127.0.0.1:9090/version"

安全提醒

不要为了方便把 secret 删除,也不要将 external-controller 绑定到公网地址。若确实需要远程管理,应使用防火墙白名单、VPN 或 SSH 隧道,而不是直接开放 9090 端口。

2设计可检测的代理组与 YAML 配置

自动切换的基础是一个明确的代理组。脚本不能凭空判断“哪个节点属于日常使用组”,因此建议为需要自动管理的节点单独创建一个策略组,例如 Auto-Select。代理组中的名称必须与 proxies 列表里的节点名称完全一致,包含空格、括号和地区后缀时也不能随意改写。

下面是一个简化示例。真实使用时,节点通常由订阅文件生成,节点名称和协议参数不需要手动填写;你只需要在策略组中引用这些节点,并设置测速参数。

proxy-groups: - name: Auto-Select type: url-test url: https://www.gstatic.com/generate_204 interval: 300 tolerance: 80 timeout: 5000 lazy: false proxies: - Japan-01 - Japan-02 - Singapore-01 - United-States-01 - DIRECT rules: - DOMAIN-SUFFIX,example.com,Auto-Select - MATCH,Auto-Select

url-test 适合让 Clash 内核自行按照测试结果选择节点;select 更适合交给外部脚本控制,因为脚本可以根据自定义条件选择节点。若你希望观察脚本的决策过程,推荐使用 select 类型,并让脚本通过 API 写入当前选择结果。

proxy-groups: - name: Script-Managed type: select proxies: - Japan-01 - Japan-02 - Singapore-01 - United-States-01 - DIRECT

url-test 与脚本测速如何选择?

  • 只需要自动选最快节点:优先使用 url-test,配置简单,测速和切换由内核完成。
  • 需要排除特定地区或节点:使用脚本,在测速前过滤名称,例如排除包含“过期”“倍率”或“备用”的节点。
  • 需要结合失败次数、最低延迟和固定时段:使用脚本,将延迟、HTTP 状态和历史失败记录一起纳入判断。
  • 需要尽量减少切换:增加切换阈值,只有新节点比当前节点快出一定数值,或者当前节点连续失败时才切换。

配置建议

测速地址应尽量稳定,并与实际业务场景接近。公共检测地址只能代表连通性,不能完全代表视频、代码仓库或企业服务的真实访问质量。

3使用 Python API 检测延迟并切换节点

Clash API 中,GET /proxies 可以读取当前所有代理和代理组信息;GET /proxies/{name}/delay 用于测试某个代理的延迟;向 PUT /proxies/{name} 发送 JSON 请求,则可以修改 select 代理组的当前选择。代理组名称需要进行 URL 编码,因此脚本不应直接拼接未经处理的名称。

下面的脚本使用 Python 标准库,不依赖第三方包,适合放在 Windows、macOS 或 Linux 上运行。执行前请把 API_SECRET、GROUP_NAME 和节点列表按自己的配置修改。

import json import os import time from urllib.error import HTTPError, URLError from urllib.parse import quote from urllib.request import Request, urlopen API_BASE = "http://127.0.0.1:9090" API_SECRET = os.environ.get("CLASH_SECRET", "change-this-to-a-long-random-token") GROUP_NAME = "Script-Managed" TEST_URL = "https://www.gstatic.com/generate_204" TIMEOUT_MS = 5000 MIN_DELAY = 450 SWITCH_MARGIN = 30 HEADERS = { "Authorization": f"Bearer {API_SECRET}", "Content-Type": "application/json", } def api_request(method, path, data=None): body = None if data is None else json.dumps(data).encode("utf-8") request = Request(API_BASE + path, data=body, headers=HEADERS, method=method) with urlopen(request, timeout=8) as response: return json.loads(response.read().decode("utf-8")) def get_group(): payload = api_request("GET", "/proxies") return payload["proxies"][GROUP_NAME] def test_delay(proxy_name): group = quote(proxy_name, safe="") url = quote(TEST_URL, safe="") path = f"/proxies/{group}/delay?timeout={TIMEOUT_MS}&url={url}" try: result = api_request("GET", path) return int(result["delay"]) except (HTTPError, URLError, ValueError, KeyError): return None def select_proxy(proxy_name): group = quote(GROUP_NAME, safe="") api_request("PUT", f"/proxies/{group}", {"name": proxy_name}) def main(): group = get_group() candidates = [ name for name in group.get("all", []) if name not in {"DIRECT", "REJECT"} ] current = group.get("now") results = {} for name in candidates: delay = test_delay(name) if delay is not None and delay <= MIN_DELAY: results[name] = delay print(f"{name}: {delay if delay is not None else 'failed'} ms") if not results: print("没有找到满足条件的节点,保持当前选择") return best_name = min(results, key=results.get) best_delay = results[best_name] current_delay = test_delay(current) if current else None should_switch = ( current not in results or current_delay is None or best_delay + SWITCH_MARGIN < current_delay ) if should_switch and best_name != current: select_proxy(best_name) print(f"已切换到 {best_name}: {best_delay} ms") else: print(f"保持当前节点 {current}") if __name__ == "__main__": main()

这段脚本包含几个重要的保护条件。第一,测速失败的节点不会被加入候选结果;第二,只有延迟不超过 MIN_DELAY 的节点才会进入比较;第三,SWITCH_MARGIN 要求新节点至少明显优于当前节点,避免两个节点延迟相近时来回切换。实际网络中延迟可能上下波动,因此不要把切换条件设置得过于敏感。

处理节点名称和 API 错误

节点名称可能包含中文、斜杠、括号或空格,必须使用 quote 进行 URL 编码。常见错误包括 401 Unauthorized,通常代表密钥错误;404 Not Found 可能是代理组名称不匹配;408 或连接超时,则多半是目标地址不可达或节点响应过慢。

如果使用的是 Mihomo,部分版本还支持更丰富的健康检查和连接信息接口,但不同客户端的内核版本可能存在差异。建议先通过 GET /version 确认内核版本,再以当前版本的 API 行为为准,不要直接复制其他项目中针对旧版 Clash 的接口代码。

4定时运行、日志记录与稳定性优化

脚本能够完成一次切换,但要实现长期自动管理,还需要一个可靠的运行方式。最简单的做法是每隔几分钟执行一次脚本;不过频率过高会产生额外测速流量,也可能让节点频繁变更。因此,普通使用场景建议每 5 到 15 分钟运行一次,远程办公或长时间下载场景则可以根据业务重要性调整。

Linux 与 macOS:使用 cron

先给脚本执行权限,并设置密钥环境变量。不要把密钥直接写入公开脚本;如果系统只有自己使用,也应限制环境文件的权限。

chmod 700 /opt/clash/auto_switch.py export CLASH_SECRET="change-this-to-a-long-random-token" crontab -e */10 * * * * /usr/bin/python3 /opt/clash/auto_switch.py >> /var/log/clash-auto-switch.log 2>&1

Windows:使用任务计划程序

在“任务计划程序”中创建基本任务,触发器设置为“每天”,并将重复间隔调整为 10 分钟。操作项选择启动程序,程序填写 python.exe,参数填写脚本完整路径。若脚本依赖环境变量,建议在一个受保护的启动脚本中设置 CLASH_SECRET 后再调用 Python。

避免频繁切换的四个方法

  1. 设置延迟余量:新节点必须比当前节点快至少 30 至 80 毫秒才切换。
  2. 设置连续失败阈值:当前节点一次测速失败不代表完全不可用,连续两到三次失败后再切换更稳妥。
  3. 保存最近结果:将节点延迟和切换时间写入 JSON 或文本日志,排查问题时可以判断是节点异常还是检测地址异常。
  4. 保留 DIRECT 作为兜底:如果所有代理节点都失败,脚本不应盲目选择一个未知节点,可保持当前选择或切换到明确的备用策略。
推荐的排查顺序

遇到自动切换不生效时,按下面顺序检查:

  1. 确认 Clash 内核正在运行,并监听 127.0.0.1:9090。
  2. 使用 /version 检查密钥是否正确。
  3. 使用 /proxies 查看代理组名称、候选节点和当前选择。
  4. 手动调用 /delay 接口,确认检测地址能被节点访问。
  5. 检查脚本运行用户是否有权限读取日志和执行 Python。
  6. 最后再检查定时任务是否按预期触发。

需要注意的是,API 自动切换只能优化“节点选择”,不能解决订阅失效、节点服务器宕机、DNS 污染或本地 TUN 配置错误。若所有节点的测速结果都异常,应先在 Clash 客户端中手动验证代理、DNS 和规则模式,再继续调整脚本。对于生产环境或团队使用,还应加入日志轮转、异常告警和密钥管理,避免日志无限增长或凭据泄露。

实践总结

稳定的自动切换不是“测到最快就立刻切换”,而是将安全认证、合理阈值、失败回退、定时执行和可追踪日志组合起来。先让 API 可控,再让脚本可观测,最后才适合长期自动运行。

如果你还没有适合当前系统的 Clash 客户端,可以先选择支持 Mihomo 内核的版本,再按照本文配置控制接口和策略组。

立即免费下载 Clash,开启流畅上网新体验 →