Claude CLI 配置实战:CC-Switch 代理、系统代理冲突与 NO_PROXY 的坑
一、背景
日常用 Claude Code VSCode 扩展用得好好的,某天突发奇想:能不能在终端里直接用 Claude CLI 命令行?毕竟有时候在终端里快速问一句比打开 IDE 方便。
但启动 Claude CLI 后直接报错:
1 | API Error: 502 status code (no body). If it persists, check your inference gateway (127.0.0.1:12857). |
于是开始了一场长达数小时的排查。
二、环境说明
先说清楚我的环境架构:
| 组件 | 说明 |
|---|---|
| Claude Code VSCode 扩展 | VSCode 内的 Claude 插件模式,运行正常 |
| CC-Switch | 本地代理网关,监听 127.0.0.1:12857,负责将请求转发到各家 API |
| Claude CLI | Anthropic 官方命令行工具 |
| 配置文件 | ~/.claude/settings.json,Claude CLI 读取的全局配置 |
CC-Switch 数据库中配置了多个 provider(Xiaomi MiMo、Kimi、DeepSeek、Claude Official 等),当前活跃的是 Xiaomi MiMo,转发到 token-plan-cn.xiaomimimo.com。
三、排查过程
3.1 第一反应:配置不对?
查看 ~/.claude/settings.json,发现里面的关键配置:
1 | { |
PROXY_MANAGED 是 CC-Switch 的特殊标记,告诉代理由它来管理认证。模型名 claude-sonnet-4-6[1M] 中的 [1M] 后缀是 CC-Switch 注入的 1M 上下文窗口标记。配置看起来没问题,VSCode 扩展用的也是同一套配置。
3.2 第二反应:CC-Switch 代理挂了?
检查代理端口:
1 | netstat -ano | grep 12857 |
端口在监听,cc-switch.exe(PID 31444)正常运行。
用 curl 直接测试:
1 | curl -s -X POST http://127.0.0.1:12857/v1/messages \ |
结果:502 Bad Gateway,空响应体。
但查看 CC-Switch 日志:
1 | tail ~/.cc-switch/logs/cc-switch.log |
日志显示 VSCode 扩展的请求一直在成功转发:
1 | [Claude] >>> 请求 URL: https://token-plan-cn.xiaomimimo.com/anthropic/v1/messages?beta=true (model=mimo-v2.5-pro) |
同一个代理,VSCode 扩展能用,curl 直连 502?这不合理。
3.3 第三反应:上游 API 挂了?
直接测试 MiMo API(绕过 CC-Switch):
1 | curl -s -X POST "https://token-plan-cn.xiaomimimo.com/anthropic/v1/messages" \ |
结果:200 OK,完美返回。API 没问题。
那问题出在哪?
3.4 真相大白:系统代理
重新看 curl 的详细输出(-v 参数),注意到一个可疑的请求头:
1 | > Proxy-Connection: Keep-Alive |
这个 Proxy-Connection 头不是我加的,是 curl 自动加的——说明 curl 走了系统 HTTP 代理!
我的机器上配置了系统级 HTTP 代理(可能是 VPN 或网络工具设置的),所有 HTTP 请求都会先经过这个代理。当我请求 127.0.0.1:12857 时,请求并没有直接到达 CC-Switch,而是被系统代理拦截了,系统代理尝试转发但失败,返回 502。
验证一下:
1 | curl -s --noproxy 127.0.0.1 -X POST http://127.0.0.1:12857/v1/messages \ |
加了 --noproxy 127.0.0.1 后:
1 | {"id":"47dba980...","type":"message","model":"mimo-v2.5-pro","stop_reason":"max_tokens",...} |
200 OK! 问题确认:系统 HTTP 代理拦截了 localhost 请求。
四、解决方案
在 ~/.claude/settings.json 的 env 中添加 NO_PROXY 环境变量:
1 | { |
同时加大小写两个是因为不同程序对环境变量的大小写敏感度不同(Windows 上尤其如此)。
验证:
1 | claude --print "respond with just: hello" |
搞定。
五、为什么 VSCode 扩展不受影响
这是排查过程中最让人困惑的点。Claude Code VSCode 扩展走的也是同一个 CC-Switch 代理,为什么它就没问题?
推测原因:VSCode 扩展运行在 VSCode 进程内部,由 VSCode 框架的 HTTP 客户端发起请求。Electron 底层(Chromium 网络栈)对 localhost 请求有内置的代理豁免逻辑——浏览器规范要求 127.0.0.1 和 localhost 默认不走系统代理。而 Claude CLI 是独立的 Node.js 进程,使用 Node.js 的 HTTP 客户端(如 undici 或 fetch),会老老实实继承系统的 HTTP_PROXY 环境变量,所以中招了。
六、经验总结
- 看到 502 先别急着怀疑上游。502 不一定是服务端问题,也可能是请求压根没到达目标服务
- curl 详细模式(
-v)是排查利器。Proxy-Connection这个头暴露了系统代理的存在 NO_PROXY是常被忽略的环境变量。尤其在有 VPN 或公司网络代理的机器上,本地服务很容易被误拦截- 同一个代理端口,不同客户端行为可能完全不同。区别就在于它们读取的代理配置不一样
- **CC-Switch 会自动覆盖
~/.claude/settings.json**。如果你手动改了配置但发现被改回去,那就是 CC-Switch 在管理它。NO_PROXY这类环境变量不会被覆盖,所以是安全的
如果你也遇到了类似的”本地代理 502”问题,先检查一下系统有没有设 HTTP 代理:
1 | # Windows |
有值的话,把 127.0.0.1 加到 NO_PROXY 里就好了。