每次使用 ChatGPT 都要切换全局模式?手把手教你怎样给 OpenAI 配置 Clash 分流规则【纯小白向】

顺便插一句,其实用了始皇的 oaifree 后我就很少访问 OpenAI 官网了,也就偶尔上去看看我的api使用额度。不过配置分流规则也不止适用于 ChatGPT,方法都是通用的,比如我也给 Claude 配置了一下,最近虽然现在有了 fuclaude,但也要每隔十天上官网去拿一次session key。

使用到的软件:clash verge rev,版本 v1.6.6,即大更新前的最后一个版本,可以使用多个全局配置文件,个人觉得比较方便。

下载地址:Release Clash Verge Rev v1.6.6 · clash-verge-rev/clash-verge-rev · GitHub

了解 Clash 配置文件中的规则的写法

首先,简单科普一下 Clash 系列软件配置文件的写法,

来,上官方文档:配置 - 虚空终端 Docs

文档内容很多,不过不用慌,咱们需要啥就看啥,当字典查就行。

咱们的主要目的是给我们需要的访问的网站单独配置规则,比如 OpenAI 的网站让它访问时美国节点(实际上,日本新加坡也可以,为了叙述方便后面就都说美国),Claude也用美国节点。那么我们就主要看规则部分的文档路由规则 - 虚空终端 Docs

感觉还是很多?那我们就主要看 DOMAIN, DOMAIN-SUFFIX这两个,后面主要就用这些。内容也不多,我直接搬过来好了。

DOMAIN 匹配完整域名
DOMAIN-SUFFIX 匹配域名后缀

再放两个带例子的讲解(Rules 规则 | Clash 知识库 ):

DOMAIN 域名
DOMAIN,www.google.com,policy 将 www.google.com 路由到 policy.

DOMAIN-SUFFIX 域名后缀
DOMAIN-SUFFIX,youtube.com,policy 将任何以 youtube.com 结尾的域名路由到 policy.在这种情况下, www.youtube.comfoo.bar.youtube.com 都将路由到 policy.

那我们现在就会写规则了,比如想给 ChatGPT 配置一个特定的规则,就写 DOMAIN,www.chatgpt.com,policy 就行了,是不是还挺简单的。但这个 policy 又是什么?

翻文档太慢了,反正我们现在大概知道规则怎么写了,不如直接去看看我们自己用的机场的配置文件,说不定就能找到 DOMAIN,www.chatgpt.com,policy 这样的格式。

于是打开配置文件

搜索一下 DOMAIN-SUFFIX,发现搜索结果还挺多的
image

于是我们看到填在 policy 的位置是叫 “节点选择” 的东西,还是不知道是干啥的,那么我们可以再搜索这个“节点选择”。

我们找到“节点选择”第一次出现的位置

再往上看看,proxies后面的那些是一个个位于不同地区的节点,这个我们认识。

再翻一翻,看到上面出现的“香港节点”

proxy-groups,意思是代理组,看了上面这三段配置文件内容,完全不用借助文档,我们大概就可以推测出,“节点选择”是一个代理组的名称,这个代理组可以由一个个具体的节点构成(第2、3张图),也可以由其他代理组(如“香港节点”)构成(第1张图),proxies后面就是这个代理组的构成元素。

现在,我们就可以回答上面的问题了,policy这个地方应该怎么写?policy这里应该填的是代理组的名称(name)。

所以,我们现在就可以,在图中的这些规则中,插入一条我们自己定义的规则
image

比如:DOMAIN,www.chatgpt.com,🇺🇸 美国节点

不过,别忘了文档(路由规则 - 虚空终端 Docs )最开始的那句话

所以我们一般把自定义的规则放在开头,优先级更高。

Merge 和 Script 配置文件

这样,我们就学会了在机场配置文件中添加自己的规则了,但是有一个问题:机场的配置文件每隔一段时间就会自动更新,那么我们自己添加的规则就被覆盖了。

这时,Merge配置文件和 Script配置文件就发挥作用了。Merge,合并,顾名思义,Merge配置文件需要与你自己机场的配置文件共同起作用。具体的,文档(扩展配置/脚本 - Clash Verge Rev Docs )是这样说的:

根据文件类型,扩展可分为 配置脚本配置 使用 yaml 对配置进行覆写/合并, 脚本 使用 javascript 对配置进行更加灵活的调整。

还是来实践一下。



创建好并打开 Merge 文件,可以看到了里面已经有了一些内容:

append学过编程的大家应该很容易猜到,意思就是在后面添加东西,比如

StringBuilder sb = new StringBuilder("Hello ");
sb.append("World!");
System.out.println(sb.toString()); // 输出: Hello World!

prepend自然就是在前面添加东西。

rules, proxies, proxy-groups,这些都是在机场的配置文件里出现过的,那么根据上面讲的Merge的作用,大概也可以猜到,我们要添加自定义规则,那肯定是在 append/prepend-rules 里添加了。

前面讲过,一般把自定义的规则放在开头,优先级更高,最终,我们就知道了是添加在 prepend-rules 这里。

后面具体怎样添加就留给读者自己完成吧。或许还会踩一些小坑,不过使用AI大模型也可以辅助完成了。

Script 配置文件是使用 JavaScript 脚本对原有的机场配置文件进行修改,实现的功能和 Merge 差不太多,但更加灵活,其实我也没有系统学过 JavaScript ,我都是直接跟gpt说需求,来让它帮我写 Script配置,所以我也不打算在这里展开讲怎样写 script。我感觉只要大致的原理弄懂了,这些细节可以让AI帮我们去完成。

编写具体的分流规则

编写完 Merge 和 Script 配置并启用后,我们会发现还是不能正常访问 ChatGPT,其实登录的过程中我们就可以发现,实际上网址会跳转,比如跳转到 https://auth0.openai.com/ 。所以我们不止需要配置一个域名。具体需要配置哪些域名呢?参照:ios_rule_script/rule/Clash/OpenAI/OpenAI.list at master · blackmatrix7/ios_rule_script · GitHub

OpenAI更新了怎么办?引入RULE-SET

参照上面的链接,我们编写了 Merge 或 Script 配置文件并正常使用了一段时间,但是过段时间后发现,又没法正常访问 ChatGPT 了,这是怎么回事呢?原来是因为 ChatGPT 新加了几个网址,我们再回头去看 ios_rule_script/rule/Clash/OpenAI/OpenAI.list at master · blackmatrix7/ios_rule_script · GitHub ,发现这里面的域名也确实变多了(以上是我个人的真实经历)。

这时,就该引入 RULE-SET 了。RULE-SET就是规则集,简单来说,就是把上一张图中的那些域名规则全部放到一个文件里,我们不需要再手动复制这些域名规则到自己的Merge 或 Script 配置文件中了,而只需要配置这个规则集合(即那个文件的地址)即可。这样,GitHub仓库中的OpenAI.list更新了,我们实际使用到的规则也会更新。

那么下面就来看看怎么用 RULE-SET。

写到这有点累了,大家就自己看文档吧()

ios_rule_script/rule/Clash/OpenAI/README.md at master · blackmatrix7/ios_rule_script · GitHub
GitHub - Loyalsoldier/clash-rules: 🦄️ 🎃 👻 Clash Premium 规则集(RULE-SET),兼容 ClashX Pro、Clash for Windows 等基于 Clash Premium 内核的客户端。
https://wiki.metacubex.one/config/rule-providers/
规则集合内容 - 虚空终端 Docs

顺便放一下我看完文档后写的

rule-providers:
  OpenAI:
    type: http
    behavior: "classical"
    url: "https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/rule/Clash/OpenAI/OpenAI.yaml"
    path: ./ruleset/OpenAI.yaml
    interval: 86400

rules:
  - RULE-SET,OpenAI,myGPT

本文提到的内容基本上都是我在进入L站后在站内佬友们的提点下,结合自己看文档和借助GPT,逐步学习到的,既算是记录自己的学习历程,也算是回馈新入站的就像和当初啥也不懂的自己一样的小白(顺便骗点赞,维持三级 :tieba_005:)。

附录 自用 Script

最后再附上我自己在用的 Script 配置吧

// Define main function (script entry)

function main(params) {
  const USGroupName = addProxyGroup(params, "🇺🇲 美国节点", /美国|US|United States|America|🇺🇸/);
  const JPGroupName = addProxyGroup(params, "🇯🇵 日本节点", /日本|JP|Japan|🇯🇵/);
  const SGGroupName = addProxyGroup(params, "🇸🇬 新加坡节点", /新加坡|狮城|SG|Singapore|🇸🇬/);
  const HKGroupName = addProxyGroup(params, "🇭🇰 香港节点", /香港|HK|Hong Kong|HongKong|🇭🇰/);

  addGPTProxyGroup(params, USGroupName, JPGroupName, SGGroupName, HKGroupName);
  // 添加规则
  addRules(params, USGroupName, JPGroupName, SGGroupName, HKGroupName);
  // 添加 rule-providers
  addRuleProviders(params);

  return params;
}

function addProxyGroup(params, groupName, regex) {
  // 判断是否已经存在某个代理组(如"美国节点")的名称
  const group = params["proxy-groups"].find((e) => regex.test(e.name) || e.name === groupName);
  if (group === undefined) {
    const proxiesByRegex = params.proxies.filter((e) => regex.test(e.name)).map((e) => e.name);
    // 判断proxiesByRegex是否为空数组
    if (proxiesByRegex.length === 0) {
      return null; // 没有匹配的代理,直接返回
    }
    params["proxy-groups"].push({
      name: groupName,
      type: "url-test",
      url: "http://www.gstatic.com/generate_204",
      interval: 86400,
      proxies: proxiesByRegex,
    });
    return groupName; // 没有的话就创建一个新的代理组
  }
  // 有了的话直接返回这个代理组的名称
  return group.name;
}

function addGPTProxyGroup(params, USGroupName, JPGroupName, SGGroupName, HKGroupName){
  // 创建一个名为"myGPT"的代理组
  params["proxy-groups"].push({
    name: "myGPT",
    type: "select",
    proxies: [],
  });

  // 找到新创建的代理组
  const myGPTGroup = params["proxy-groups"].find(group => group.name === "myGPT");

  // 为名为myGPT的代理组添加代理
  if (HKGroupName !== null)
    myGPTGroup.proxies.push(HKGroupName);
  if (SGGroupName !== null)
    myGPTGroup.proxies.push(SGGroupName);
  if (JPGroupName !== null)
    myGPTGroup.proxies.push(JPGroupName);
  if (USGroupName !== null)
    myGPTGroup.proxies.push(USGroupName);
}

function addRuleProviders(params) {
  // 如果 params 中没有 rule-providers,则创建它
  if (!params["rule-providers"]) {
    params["rule-providers"] = {};
  }

  // 添加 OpenAI rule provider
  params["rule-providers"]["OpenAI"] = {
    type: "http",
    behavior: "classical",
    url: "https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/rule/Clash/OpenAI/OpenAI.yaml",
    path: "./ruleset/OpenAI.yaml",
    interval: 86400
  };
}

function addRules(params, USGroupName, JPGroupName, SGGroupName, HKGroupName) {
  // 设置openai用哪个节点访问
  const forOpenai = "myGPT";

  // 创建一个规则数组
  const rules = [
    // 微软中国
    "GEOSITE,microsoft@cn,DIRECT",

    // openai
    "GEOSITE,openai," + forOpenai,
    "RULE-SET,OpenAI," + forOpenai,
    // claude
    "DOMAIN,servd-anthropic-website.b-cdn.net," + USGroupName,
    "DOMAIN,cdn.usefathom.com," + USGroupName,
    "DOMAIN-SUFFIX,anthropic.com," + USGroupName,
    "DOMAIN-SUFFIX,claude.ai," + USGroupName,
    // gemini api
    "DOMAIN-SUFFIX,generativelanguage.googleapis.com," + USGroupName,

    // linux.do
    "DOMAIN-SUFFIX,linux.do,DIRECT",
    // fuclaude.com
    "DOMAIN-SUFFIX,fuclaude.com,DIRECT",
    // oaifree
    "DOMAIN-SUFFIX,oaifree.com,DIRECT",

  ];

  // 把rules中的规则全部添加到params.rules中
  params["rules"] = rules.concat(params["rules"]);
}

60 个赞

很强

感谢分享,适合小白

1 个赞

细致

好的,我明天正好也写个分流规则相关的教程

哈哈不是大佬,跟佬友们在L站学到了点东西而已 :tieba_024:

啊?有人的gpt不走规则吗?

用心了

我用geosite,因为不用写那么多rule-providers
再结合proxy-providers,filter,exclude-filter,只用yaml就能搞定,不需要script

谢谢太有心了

我也用了geosite,但是geosite好像覆盖得不全

感谢分享,作为小白,之前摸索了很久,花费了很多精力才整明白配置语句

感谢大佬

1 个赞

感谢大佬,很有帮助

啊 不是直连的嘛

看了一下blackmatrix7/ios_rule_script,有些规则在geosite确实没有,不过geosite是基于v2fly/domain-list-community的,用着也还行

插眼

非常好教程,使我节点旋转

1 个赞

From 软件开发 to 开发调优

感谢分享!之前就这个问题困扰了很久,先mark一下

另外我还想问个可能有点傻的问题。我订阅了两个机场,其中一个给的订阅链接是正常的url,我也按规则正常的加了parser(老版的CFW,premium内核的),也可以正常使用。但是另一个机场给的订阅链接是.yaml的格式,规则相同的parser就一直识别不出来,自定义规则自然也无法生效了。这种情况是因为机场给的订阅链接的问题还是CFW的问题啊?Clash verge rev会遇到这种情况吗?