Appearance
Codex、Claude Code、Gemini CLI 代理和环境变量怎么配:Mac 与 Windows 统一整理
如果你同时在终端里使用:
codexclaudegemini
很快就会遇到一个共同问题:
- 浏览器能访问
- 代理工具也开着
- 但 CLI 客户端还是会超时、连不上、卡在请求阶段
这类问题表面看像是不同客户端各自有问题,实际上很多时候它们的根因是同一个:
- 终端进程没有拿到代理环境变量
也就是说,真正要整理的不是“某一个客户端怎么配”,而是:
- 终端里的 AI CLI 工具,应该怎么统一管理代理和启动方式
先说结论
如果你是长期同时使用 Codex、Claude Code、Gemini CLI 的开发者,更推荐的做法是:
- 不要默认相信系统图形代理一定能覆盖终端
- 把代理配置收敛到 shell 函数里
- 给不同客户端分别做一个带代理的启动入口
- 只在需要时显式使用代理版本
这样做的好处是:
- 问题定位更快
- 改代理端口更集中
- 不容易影响其他终端命令
- 三个工具的使用习惯也能统一下来
一、为什么同样开着代理,CLI 还是会超时
这个问题的关键不在模型,而在运行环境。
浏览器、桌面 App、终端进程,虽然都在同一台机器上,但它们的网络配置继承方式并不完全一样。
所以你经常会看到:
- Chrome 可以打开网页
- 代理工具状态正常
- 终端里的 Node、Python、CLI 请求却没有走代理
而 Codex、Claude Code、Gemini CLI 这类工具,很多场景下本质都是:
- 在终端里发起网络请求的 CLI 程序
只要当前 shell 没带上代理变量,它们就可能表现为:
- 登录慢
- 请求超时
- 首次启动一直卡住
- 某些命令能用,某些命令不通
二、三者的共性是什么
从“终端代理”这个问题看,三者的共性远大于差异。
共同点可以先记住这几个:
- 都跑在终端环境里
- 都可能受当前 shell 的环境变量影响
- 都不值得为了它们去全局污染整个终端环境
- 都更适合单独包一层启动函数
也就是说,从工程习惯上看,它们都适合用下面这套思路:
- 普通命令保留原样
- 额外提供
xxx-proxy入口
三、三者的差异主要体现在哪
虽然代理处理思路相似,但三者在日常使用里,关注重点并不完全一样。
Codex
更偏终端协作、任务推进、目录边界和执行闭环。
如果你给 Codex 配代理,重点通常不是“只让它能连上”,而是:
- 在稳定联网前提下继续保持任务节奏可控
- 不要让全局代理影响你本地仓库操作和其他命令
Claude Code
更偏讨论、规划、澄清、长链路理解。
如果你给 Claude Code 配代理,更关注的通常是:
- 启动稳定
- 长轮对话不中断
- shell 环境切换时行为一致
Gemini CLI
更容易暴露“终端代理没继承”的问题,尤其是在:
- Node 请求直接超时
- 浏览器可用但 CLI 不通
所以 Gemini CLI 往往最先把这个问题暴露出来,但这并不代表只有它会受影响。
四、最推荐的统一做法:每个客户端都包一层代理函数
相比全局代理,更推荐的方式是:
codex-proxyclaude-proxygemini-proxy
这样你一眼就知道:
- 当前是普通启动
- 还是显式走代理启动
五、Mac:写进 .zshrc
如果你是 macOS + zsh,可以把下面这组函数写进 ~/.zshrc。
如果你的代理端口不是 7897,记得替换成自己的端口。
bash
function codex-proxy() {
export HTTP_PROXY="http://127.0.0.1:7897"
export HTTPS_PROXY="http://127.0.0.1:7897"
export ALL_PROXY="socks5://127.0.0.1:7897"
export NO_PROXY="localhost,127.0.0.1,::1"
codex "$@"
}
function claude-proxy() {
export HTTP_PROXY="http://127.0.0.1:7897"
export HTTPS_PROXY="http://127.0.0.1:7897"
export ALL_PROXY="socks5://127.0.0.1:7897"
export NO_PROXY="localhost,127.0.0.1,::1"
claude "$@"
}
function gemini-proxy() {
export HTTP_PROXY="http://127.0.0.1:7897"
export HTTPS_PROXY="http://127.0.0.1:7897"
export ALL_PROXY="socks5://127.0.0.1:7897"
export NO_PROXY="localhost,127.0.0.1,::1"
gemini "$@"
}生效步骤
bash
vim ~/.zshrc
source ~/.zshrc日常使用方式
bash
codex-proxy
claude-proxy
gemini-proxy如果要带参数,也一样:
bash
codex-proxy --help
claude-proxy --help
gemini-proxy --help六、Windows:写进 PowerShell Profile
如果你是在 Windows PowerShell 里使用这些 CLI,推荐写进 $PROFILE。
powershell
function codex-proxy {
$env:HTTP_PROXY="http://127.0.0.1:7897"
$env:HTTPS_PROXY="http://127.0.0.1:7897"
$env:ALL_PROXY="socks5://127.0.0.1:7897"
$env:NO_PROXY="localhost,127.0.0.1,::1"
codex @args
}
function claude-proxy {
$env:HTTP_PROXY="http://127.0.0.1:7897"
$env:HTTPS_PROXY="http://127.0.0.1:7897"
$env:ALL_PROXY="socks5://127.0.0.1:7897"
$env:NO_PROXY="localhost,127.0.0.1,::1"
claude @args
}
function gemini-proxy {
$env:HTTP_PROXY="http://127.0.0.1:7897"
$env:HTTPS_PROXY="http://127.0.0.1:7897"
$env:ALL_PROXY="socks5://127.0.0.1:7897"
$env:NO_PROXY="localhost,127.0.0.1,::1"
gemini @args
}生效步骤
powershell
if (!(Test-Path $PROFILE)) {
New-Item -Path $PROFILE -ItemType File -Force
}
notepad $PROFILE
. $PROFILE日常使用方式
powershell
codex-proxy
claude-proxy
gemini-proxy七、这几个环境变量为什么值得统一
这套做法里真正有价值的,不是函数名,而是把下面这几个变量统一起来:
HTTP_PROXY
给 HTTP 请求指定代理。
HTTPS_PROXY
给 HTTPS 请求指定代理。
对 AI CLI 工具来说,这个变量通常最关键。
ALL_PROXY
给更通用的代理链路兜底,尤其是某些支持 socks5 的底层请求。
NO_PROXY
明确告诉程序:
- 本机地址不要走代理
否则你本地开发服务、内网回环地址有时也会被错误带到代理里。
八、为什么我不建议你直接全局导出这些变量
因为全局代理虽然省事,但问题也最多。
常见副作用包括:
- 其他 Node 命令也被迫走代理
- 本地联调链路被污染
- 内网地址访问变慢
- 你忘了自己当前终端到底是不是挂着代理
所以更稳的习惯是:
- 日常终端保持干净
- 需要时显式执行
codex-proxy、claude-proxy、gemini-proxy
九、如果你只想维护一套公共代理变量怎么办
如果你不想三段函数里都重复写一遍,也可以拆成一个公共函数。
Mac
bash
function use-ai-proxy() {
export HTTP_PROXY="http://127.0.0.1:7897"
export HTTPS_PROXY="http://127.0.0.1:7897"
export ALL_PROXY="socks5://127.0.0.1:7897"
export NO_PROXY="localhost,127.0.0.1,::1"
}
function codex-proxy() {
use-ai-proxy
codex "$@"
}
function claude-proxy() {
use-ai-proxy
claude "$@"
}
function gemini-proxy() {
use-ai-proxy
gemini "$@"
}Windows PowerShell
powershell
function Use-AiProxy {
$env:HTTP_PROXY="http://127.0.0.1:7897"
$env:HTTPS_PROXY="http://127.0.0.1:7897"
$env:ALL_PROXY="socks5://127.0.0.1:7897"
$env:NO_PROXY="localhost,127.0.0.1,::1"
}
function codex-proxy {
Use-AiProxy
codex @args
}
function claude-proxy {
Use-AiProxy
claude @args
}
function gemini-proxy {
Use-AiProxy
gemini @args
}如果你后面改端口,只用改一处。
十、怎么判断是“代理问题”还是“客户端本身问题”
一个很实用的判断顺序是:
- 先确认代理工具本身能不能用
- 再确认当前 shell 里有没有代理变量
- 再确认 CLI 命令是不是当前终端能识别
- 最后再怀疑客户端本身
Mac
bash
echo $HTTP_PROXY
which codex
which claude
which geminiWindows PowerShell
powershell
echo $env:HTTP_PROXY
Get-Command codex
Get-Command claude
Get-Command gemini如果你发现:
- 浏览器正常
- 代理软件正常
- 但 shell 里变量是空的
那基本就不是客户端的锅,而是终端环境没配置好。
十一、三者在日常使用上怎么分工更顺
如果你已经同时装了这三个工具,一个更实用的分工方式是:
codex-proxy:更适合进仓库、改代码、跑命令、做验证claude-proxy:更适合做需求澄清、方案梳理、重构讨论gemini-proxy:更适合做补充视角、摘要整理、文档对照和备用工作流
这样做的价值不在“谁更强”,而在:
- 三者的代理启动方式统一了
- 你的心智负担更低
- 切换工具时不会总怀疑是不是网络环境没配好
十二、什么时候该进一步升级成 launcher
如果你后面已经不满足于几个 shell 函数,而是希望:
- 切换不同模型入口
- 统一更多环境变量
- 集中维护代理地址
- 给团队共享同一套启动方式
那下一步更适合升级成一层 launcher,比如:
- 统一
bin/xxx - 统一模型路由
- 统一代理与状态文件
这也是为什么单人使用时函数足够,长期多工具协同时 launcher 更稳。
一句话总结
Codex、Claude Code、Gemini CLI 在“终端代理”这个问题上的本质差异并不大,真正影响稳定性的往往不是客户端本身,而是当前 shell 有没有把代理环境变量带进去。
更适合长期使用的方式,不是全局把终端都挂上代理,而是在 Mac 的 .zshrc 或 Windows 的 PowerShell Profile 里为它们分别提供 codex-proxy、claude-proxy、gemini-proxy 这类显式入口。