Clash 订阅格式科普:YAML、Base64 节点列表与通用格式的区别及转换方法

梳理常见订阅格式的结构差异:Clash YAML 配置、Base64 编码节点列表与各客户端专有格式,说明为什么有的链接导入失败,以及用转换工具在格式之间安全互转的注意事项。

订阅链接背后到底是什么

一条订阅链接本质上只是一个 HTTP/HTTPS 地址,客户端定时请求这个地址,拿到一份文本内容,再按某种约定的格式把文本解析成节点列表和规则。问题在于,「某种约定的格式」并不是唯一的。不同代理生态在各自发展过程中,各自定义了自己的文本结构,于是同一个「订阅」概念下,实际流通的至少有三类主流格式:Clash 系的 YAML 配置、v2ray/Shadowsocks 系的 Base64 节点列表、以及部分面板软件输出的专有 JSON 格式。客户端能不能"认得"这条链接,取决于它是否实现了对应格式的解析器。

这也是为什么同一条订阅链接,在 Clash 客户端里能正常导入,换到另一款基于不同协议栈的客户端里却提示格式错误或者直接空列表——不是链接坏了,是两边说的不是同一种"语言"。

Clash YAML 配置:结构化、可读、承载能力最强

Clash 与 Clash Meta(内核 mihomo)使用的订阅格式是标准 YAML 文本,一份完整配置通常包含几个顶层字段:

port: 7890
socks-port: 7891
mode: rule
proxies:
  - name: "HK-01"
    type: ss
    server: example.com
    port: 443
    cipher: aes-256-gcm
    password: "your-password"
proxy-groups:
  - name: "自动选择"
    type: url-test
    proxies: [HK-01]
    url: "http://www.gstatic.com/generate_204"
    interval: 300
rules:
  - DOMAIN-SUFFIX,google.com,自动选择
  - MATCH,DIRECT

可以看到,YAML 格式不仅描述了节点(proxies),还描述了节点如何分组(proxy-groups)、以及流量按什么规则(rules)分发到哪个分组。这是它区别于其他格式的关键:一份 YAML 订阅是一整套「可运行的策略」,而不只是一串地址列表。也正因为信息量大,YAML 格式对字段拼写、缩进层级要求严格,少一个空格或者把 tab 混进缩进里,都可能导致整份配置解析失败。

注意:YAML 对缩进极度敏感,同一层级的字段前面的空格数量必须完全一致,禁止用 Tab 键缩进。手工编辑配置文件时,建议用支持 YAML 语法高亮的编辑器,肉眼很难发现少一个空格的问题。

Base64 节点列表:轻量,但只是"地址清单"

另一类常见格式来自 Shadowsocks、V2Ray、Trojan、VLESS 等协议各自的客户端生态。这类订阅打开后往往是一整段没有换行、看起来毫无规律的字符串,例如以 c3M6Ly8... 开头。这其实是把多条节点链接(每条形如 ss://…vmess://…trojan://…)用换行拼接后,再整体做一次 Base64 编码,目的是方便在二维码、纯文本环境里传输,避免特殊字符被转义破坏。

解码之后,每一行大致是这样的结构(以 Shadowsocks 为例):

ss://[email protected]:443#HK-01
vmess://eyJ2IjoiMiIsInBzIjoiSEstMDIiLCJhZGQiOiJleGFtcGxlLmNvbSJ9
trojan://[email protected]:443?sni=example.com#HK-03

这类格式的信息密度比 YAML 低得多:它只描述"有哪些节点、地址是什么、用什么加密",不携带分组策略,也不携带分流规则。客户端拿到这份列表后,规则怎么定、节点怎么分组,完全由客户端自己内置的默认策略决定。这就解释了一个常见困惑:同一条 Base64 订阅,在两款客户端里导入后,节点数量一样,但代理模式的分组结构、默认走向却完全不同——因为分组规则从来不是订阅内容的一部分,是客户端自己补上的。

为什么有的链接导入后没有节点或者直接报错

结合上面两种格式的差异,订阅导入失败基本可以归纳为几类原因:

排查思路建议按顺序来:先确认订阅链接能否在浏览器里正常打开并显示内容,再确认返回内容的开头特征(YAML 一般以 port:proxies: 开头,Base64 列表通常是一整段无空格字符),最后再检查客户端本身的日志页,大多数解析错误都会给出具体报错行号。

格式之间怎么互转

如果手上的订阅格式和客户端要求的格式不一致,常见做法是使用转换工具在中间做一次"翻译",而不是手工改写。目前社区广泛使用的是 subconverter 一类的开源转换服务,原理是:输入原始订阅链接,输出目标格式(Clash YAML、通用 Base64 列表等)的新链接,客户端直接订阅这个转换后的新地址即可,后续更新也会自动带过去。

常见的两种转换方向

  1. 从 Base64 节点列表转 Clash YAML:转换服务会把每条 ss:///vmess:///trojan:// 链接解析出协议参数,填入 proxies 字段,再根据目标客户端类型补上一套默认的 proxy-groupsrules(部分服务允许指定规则模板)。
  2. 从 Clash YAML 转通用 Base64 列表:转换服务只保留 proxies 部分的节点信息,重新拼装成对应协议的链接格式并做 Base64 编码,分组与规则信息会在这一步丢失,因为目标格式本身不支持描述规则。

注意:从结构化格式转成节点列表格式是单向信息损耗——分流规则、分组逻辑不会被保留。如果只是临时在另一款客户端上应急使用,这样做没问题;但如果长期依赖这条转换后的链接,建议直接找订阅服务商索要原生对应格式的地址,而不是长期依赖二次转换。

互转时的安全与稳定性注意事项

转换服务本质上是一个中间代理,原始订阅内容会先经过转换服务器再到达客户端,这里有几点需要留意:

导入前的三步自检

不确定一条订阅链接是什么格式时,可以按下面顺序快速判断,免得反复尝试导入报错:

  1. 在浏览器地址栏直接打开订阅链接,看返回内容的开头字符——出现 portproxiesmixed-port 等字段基本可判定是 Clash YAML;一整段无换行字符可判定是 Base64 节点列表。
  2. 确认当前使用的客户端内核类型(Clash Meta / mihomo 内核通常兼容性更全面,支持的协议类型更多),内核版本较旧时优先更新客户端再导入。
  3. 如果格式确实不匹配,再考虑走转换工具,并按上一节的安全建议选择转换后端。

把这三步走完之后,绝大多数"订阅导入失败""节点列表为空"的问题都能定位到具体环节,而不需要反复试错。

下载客户端