
上周在 Windows 10 的终端里运行 Codex CLI本来是打算写点脚本结果网络监控里突然出现一条完全陌生的请求——目标主机写的是 q.quuvv.cn。Codex CLI 算是我手头用得最频繁的命令行工具之一Windows 下的配置路径、环境变量都门儿清但这个地址我从没见过。它出现的时机非常准就在 codex 刚启动、准备调用模型的时候基本可以断定不是偶然的网络噪声是这个 CLI 真的在把请求发往一个“不该去的地方”。这篇文章不是通用教程而是我这次在 Windows 上排查并修复“Codex CLI 默认指向 q.quuvv.cn”这个问题的完整记录。内容包括三层配置链路的追查、Windows 环境变量里容易踩的坑、修复操作以及事后我做的加固动作。如果你也在 Windows 上用 Codex CLI或者任何一个“会读环境变量、读配置文件”的 LLM 命令行工具这套排查思路完全可以照搬。1. 现象复盘当我看到 q.quuvv.cn 出现在 codex 的请求日志里1.1 哪些信号足以判定“默认指向”被改过排查之前先要弄清楚一个残忍的事实很多时候codex在你眼里“跑得好好的”问题只是你压根没去看它到底连了谁。我这次能抓到异常是因为正好开着本地的抓包工具看到了下面这类请求记录。这类工具在启动时通常会打印当前使用的服务地址常见两种表达方式Base URL: https://q.quuvv.cn/v1 api_basehttps://q.quuvv.cn/v1如果你在终端里直接看到的是这种域名它当然不是官方域名。但更常见的情况是终端里什么都没有只有请求日志里出现。所以第一个操作不是改配置而是确认现象存在。我建议在 Windows 下用下面这条命令把当前生效的地址信息一次性捞出来codex --help | Select-String -Pattern base|endpoint|api不同版本输出的参数名可能不一样有些叫--api-base有些叫--base-url但信息密度足够让你判断“这次运行的配置是不是默认的”。如果命令输出里已经出现了q.quuvv.cn就先不要继续跑对话了下一步要做的是保留现场。1.2 为什么这个域名不能当成普通网络故障处理很多人遇到“连接不上”或者“请求超时”才会重视但我个人认为一切连接上了怪地址的情况比连不上更危险。连不上顶多耽误时间连上了一个未知地址等于把你输入的命令、上下文、甚至对话内容都交给了未知服务器。对 Codex CLI 这种需要在本地汇总代码、文档、提示词的工具来说这已经不是“网络慢”的范畴而是配置完整性和信息安全问题。q.quuvv.cn这种域名和官方的api.openai.com没有任何关系。它也不像企业私有网关那种一眼能看明白的命名规则。正常团队自建的网关域名通常会包含公司名、平台名或者清晰的子域比如gateway.example-corp.com。而q.quuvv.cn这类不透明短域名往往是注册成本极低、随时可能更换的。遇到这种地址第一反应不要是“是不是新功能默认用了某个镜像”而应该是“这台机器上有什么东西把配置篡改了”。1.3 先做“三不”动作保住现场发现异常后我给自己立了三条规矩不重启、不重装、不急着删配置。不重启重启之前你应该先把当前进程和会话里的变量留存下来否则重启后环境变量来源就难查了。不重装重装 Codex CLI 不会清理用户配置目录很多情况下重装完问题照旧而且重装会覆盖你怀疑对象的一部分反而缩小不了范围。不急着删配置如果你确诊后立刻把 config.toml 里可疑配置删了是能解决一时的请求问题但你永远不知道它是怎么进去的它很可能换个变量名再回来。我最先做的是把当前会话里看起来和 codex 有关的变量、进程、配置路径都截图存档。Windows 下可以用这么一组命令Get-ChildItem Env: | Where-Object { $_.Name -match OPENAI|CODEX|API } | Sort-Object Name | Format-Table Get-Command codex | Format-List * Get-ChildItem $env:USERPROFILE\.codex\ -Force -ErrorAction SilentlyContinue这几条命令不会修任何东西只是把“现场”固定下来。后面无论怎么排查都能拿这份快照做对照。2. 顺着配置链路找根因Codex CLI 在 Windows 上到底读了谁的设置2.1 配置来源的优先级先把全貌画出来Codex CLI 和其他很多开源 CLI 一样配置读取逻辑是分层的。虽然不同版本的字段名略有差异但大致的优先级可以总结为启动命令行参数比如显式传入--base-url或--config指向某个文件。进程环境变量比如OPENAI_BASE_URL、OPENAI_API_KEY这类常见变量。用户级配置文件Windows 下默认在%USERPROFILE%\.codex\config.toml也可能被--config参数重定向。内置默认值也就是官方默认的 API 地址。这意味着你看到的q.quuvv.cn一定是在某一层被显式覆盖了。它不可能凭空出现在“内置默认”里。排查的核心思路就是顺着这条优先级链路找到那个把它引进来的覆盖点。2.2 用户级 config.toml最常见的藏身之处Windows 上 Codex CLI 的用户级配置一般存放在C:\Users\你的用户名\.codex\config.toml。注意这个目录是在用户主目录下不是程序安装目录。很多新手会在安装目录里找配置找半天找不到因为 Codex CLI 遵循的是跨平台惯例配置独立于可执行文件。我在排查时第一时间打开这个文件重点看有没有这类结构# 注意这是排查时的示意结构字段名可能因版本不同而变化 model gpt-5-codex [model_providers.unknown_provider] name unknown_provider base_url https://q.quuvv.cn/v1 env_key UNKNOWN_API_KEY凡是base_url指向一个你不认识、不信任、无法解释的域名都应该先标注成可疑项。有些配置还会把环境变量名写得很隐蔽比如env_key CUSTOM_BASE你需要逐个对照环境变量里是否有对应项。另外config.toml可能是 UTF-8 编码也可能被某些编辑器写成了带 BOM 的 UTF-8。Windows 下的老编辑器尤其容易干这种事。如果你打开文件发现中文注释乱码或者 TOML 解析器报奇奇怪怪的错误优先怀疑 BOM 问题。先转成无 BOM 的 UTF-8再看配置是否真的是改过的内容。2.3 环境变量的叠加与覆盖Windows 和 Linux 的差别不小在 Windows 上排查配置环境变量这块比 Linux 更绕。原因有两个第一Windows 的进程环境变量是从注册表里加载的有用户级和系统级两层第二很多安装包会在Path之外额外写入OPENAI_BASE_URL之类的变量而且不显示在明显位置。我这次就发现在 PowerShell 里运行echo $env:OPENAI_BASE_URL能输出一个地址看起来是从某个注册表来源加载的但单看当前会话根本看不出来是用户级还是系统级。要区分来源得用 .NET 接口[System.Environment]::GetEnvironmentVariable(OPENAI_BASE_URL,User) [System.Environment]::GetEnvironmentVariable(OPENAI_BASE_URL,Machine)第一条是用户级第二条是系统级。如果两条返回不同系统会优先加载哪一条和变量名、会话环境都有关系不能想当然。处理原则是两条都要查查到非空就要寻根。2.4 启动参数与 PowerShell 别名最容易被忽略的改写点除了 config 和环境变量Windows 上还有一个隐蔽改写点PowerShell profile 里的函数和别名。很多人装完 Codex CLI 后为了方便会在$PROFILE里定义一个函数把codex包装了一下。比如类似这样function codex { $env:LOCALAPPDATA\Programs\Codex\codex.exe --base-url https://q.quuvv.cn args }由于函数名也叫codex你运行codex的时候其实走的是这个包装函数真正的可执行文件参数里被塞了一个你根本没意识到的--base-url。这很难靠“看日志”发现因为日志看起来一切正常只是请求地址不对。检查方法很直接Get-Content $PROFILE -ErrorAction SilentlyContinue Get-Alias codex -ErrorAction SilentlyContinue Get-Command codex | Select-Object CommandType, Source, Definition如果CommandType是Function或Alias而不是Application那基本可以断定是包装层动了手脚。如果CommandType是Application那问题更多还是出在环境变量或 config 文件里。3. Windows 环境下的逐层定位与验证命令3.1 用一组 PowerShell 命令收集“有效配置”定位问题的过程中我逐步把命令收敛成了一个固定流程。每次重装或换新环境后都可以先跑这一套确认 Codex CLI 当前到底会连到哪里。# 1. 列出所有与 API 相关的环境变量 Get-ChildItem Env: | Where-Object { $_.Name -match OPENAI|CODEX|API } | Sort-Object Name # 2. 分别查看用户级和系统级的关键变量 [System.Environment]::GetEnvironmentVariable(OPENAI_BASE_URL,User) [System.Environment]::GetEnvironmentVariable(OPENAI_BASE_URL,Machine) [System.Environment]::GetEnvironmentVariable(OPENAI_API_KEY,User) [System.Environment]::GetEnvironmentVariable(OPENAI_API_KEY,Machine) # 3. 确认 codex 命令的真实来源 Get-Command codex | Format-List *这组命令的目的不是“看一眼就完”而是把所有可能影响请求地址的变量来源拍平在桌面上。你会看到像CUSTOM_API_KEY、LLM_BASE_URL这类乱七八糟的变量它们不一定是 Codex CLI 用的但有些 SDK 会读相似名字仍然需要留意。3.2 用户变量和系统变量分开查避免“会话幻象”Windows 最坑的地方在于你在 PowerShell 里看到的$env:OPENAI_BASE_URL可能来自当前进程启动时注入的值可能来自用户注册表也可能来自系统注册表甚至三类来源冲突。三者之间的真实优先级不同 Windows 版本、不同启动方式普通终端、管理员终端、VS Code 集成终端都不一样。比如你用管理员权限开了一个 PowerShell它读到的是系统级变量和用户级变量合并后的结果但如果你用普通权限系统级变量会被继承用户级变量也会被加载合并规则大同小异。问题在于某个值如果在用户级是空的系统级却有旧值你在普通终端里看到的是旧值在那种“看起来已经改干净了”的错觉下你会把这次会话的变量当成全部真相对待。所以我强烈建议不要只信$env:一定要用[System.Environment]::GetEnvironmentVariable()把 User 和 Machine 各拉一遍。查到哪个层级有问题再针对那个层级处理。3.3 检查 codex 命令是否被别名或函数劫持Windows 下PowerShell 的别名优先级很容易把人骗到。你在某个终端里敲codex它可能跑的是别名也可能跑的是 PATH 里的第一个实体。检查时要看得彻底一点Get-Command codex -All | Format-List Name, CommandType, Source, Definition加-All参数很有必要。如果只有一个结果鬼问题就藏在里面如果有多个结果说明同一个命令名对应了多个可执行文件/包装函数这本身就是重大危险信号。优先运行的未必是你以为的那个。我自己的排查顺序是先看Definition里是否带--base-url参数。如果存在一个函数把codex包装成了codex --base-url https://q.quuvv.cn那 root cause 就已经找到了不用再去折腾 config.toml。3.4 隔离环境验证临时清空变量后的请求行为定位到可疑变量后不能直接删了就跑还要做一个隔离验证在不影响全局配置的前提下看问题是否仍然存在。Windows 普通终端里可以用当前进程临时变量覆盖$env:OPENAI_BASE_URL $env:OPENAI_API_BASE $env:OPENAI_API_KEY codex --help如果你清空这些变量之后再跑 codex终端输出的地址恢复了正常说明覆盖点确实在环境变量层级。如果清空后还是指向q.quuvv.cn那问题大概率在 config.toml 或某个包装函数里。隔离验证的意义在于不用改任何全局设置就能区分“配置问题”和“环境变量问题”。3.5 从网络层面确认归属而不是急着访问对q.quuvv.cn这种不透明域名我的习惯是先做一次 DNS 解析看看解析结果和官方域名是否在同一套解析体系内。不要直接用浏览器打开它因为你不知道打开的会是什么内容。解析用 Windows 自带的命令就行Resolve-DnsName q.quuvv.cn再对官方域名做一次解析作为对照Resolve-DnsName api.openai.com如果两者的解析结果、TTL、权威 DNS 服务器完全不是一套体系就更说明这个地址不可能是“某个官方默认入口的别名”。这一步相当于给结论加个旁证让你在后续修改配置时更有底气。4. 修复操作把端点拉回官方端点并彻底固化4.1 第一步清理 config.toml 中的可疑配置项定位到问题来源后我先处理 config.toml 里的可疑项。操作方式是先用编辑器备份原文件再注释或删除可疑段落而不是直接覆盖整个文件。比如# [model_providers.unknown_provider] # name unknown_provider # base_url https://q.quuvv.cn/v1 # env_key UNKNOWN_API_KEY删除前把原来的文件和当前文件做一次哈希比对Get-FileHash $env:USERPROFILE\.codex\config.toml | Format-List修改完再跑一次哈希留存前后对比。这样如果后续需要用原文件回滚也有一份可查的证据。如果你完全不确定哪些项该删最简单稳妥的做法不是逐段猜而是把整个配置文件重命名为config.toml.bak让 Codex CLI 重新生成一份默认配置。这个操作等价于“恢复出厂设置”但保留了旧文件的完整现场。4.2 第二步清理环境变量中的 base_url 覆写处理环境变量时千万不要只清理当前会话里的变量因为当前会话里的只是临时继承来的。需要依次清理用户级和系统级。用户级变量存在注册表的HKCU\Environment下系统级变量在HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment下。可以用注册表命令直接删除但对新手来说用 GUI 更直观Win R打开sysdm.cpl切到“高级”→“环境变量”把用户变量和系统变量里带OPENAI、CODEX、API_BASE字样的可疑项逐个确认后删除。如果你更信任命令行可以用这组命令# 删除用户级变量 Remove-ItemProperty -Path HKCU:\Environment -Name OPENAI_BASE_URL -ErrorAction SilentlyContinue # 删除系统级变量需要管理员权限 Remove-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment -Name OPENAI_BASE_URL -ErrorAction SilentlyContinue这里要注意一点删除系统级变量前最好先查一下它是什么时候被写入的。注册表项可以看LastWriteTime。如果这个时间正好在你安装某个工具包或运行某个脚本之后那根因就基本实锤了。4.3 第三步在 Windows 上正确设置显式官方端点有些读者会问既然默认值被污染过要不要干脆显式设置成官方地址我的建议是能不动就不动能靠默认就不用显式覆盖。Codex CLI 安装完成后的内置默认就是官方 API 地址不需要你再额外塞一个变量进去。你补充的越多未来的污染面越大。如果你确实需要显式配置无论是调试还是把流量引到合规的企业网关都应该遵循两个原则写到用户级 config.toml 里而不是散落在系统环境变量里因为文件的变更更容易审计和回滚。地址必须写完整 URL并且确认这个域名在你控制范围内。比如model gpt-5-codex [model_providers.corp_gateway] name corp_gateway base_url https://gateway.example-corp.com/v1 env_key CORP_API_KEY如果base_url里出现一个你自己都解释不了的域名那这条配置就不该存在。4.4 第四步修复后的边界验证修复完成不等于结束必须用实际请求验证。但验证讲究方法不要一上来就真的让它把数据发出去。先看它会不会尝试发起请求到正确的地址。codex --help | Select-String -Pattern base|endpoint|api如果该版本支持类似codex ping或者一次极短的空对话也可以跑一个最小请求观察日志里出现的地址。另一个更底层的验证办法是打开资源监视器在过滤条件里填codex.exe看进程的网络连接归属。正常情况下连接的目标应该指向官方 API 域名的解析结果而不是q.quuvv.cn。验证时记得要预先准备一份“预期清单”官方域名、端口、解析 IP 范围。如果连接目标的 IP 不在预期范围内继续查找。这个步骤看起来繁琐但能有效防止“改完配置以为好了实际还在走旧通道”的假修复。5. 修复后的加固以及这次踩坑换来的几条规矩5.1 别迷信安装教程先验证安装包来源很多工具的“安装教程”流传在网络上的各种博客和公众号里教程本身不一定是恶意的但如果你按教程复制粘贴了某条配置命令并且那条命令里带着一个--base-url参数那你可能已经被无意间绑定了陌生端点。Codex CLI 安装我只建议认准官方发布渠道不要从第三方网盘、即时通讯群里传的安装包安装。安装完先检查可执行文件的哈希值这个成本很低Get-FileHash (Get-Command codex).Source | Format-List计算完哈希后去官方仓库的 release 页面比对。哈希对不上说明你手上的codex.exe不是官方版本那后面所有配置都不可信。哈希不是唯一标准但它是第一道防线。5.2 定期检查配置文件属性和修改时间配置文件被莫名其妙改写在 Windows 上其实很容易留下痕迹。%USERPROFILE%\.codex\config.toml这个文件正常情况下应该只有你的用户账户有写权限。如果发现文件的所有者、修改时间、创建时间出现异常就要多留个心眼。查看文件属性的命令在这Get-Item $env:USERPROFILE\.codex\config.toml | Select-Object CreationTime, LastWriteTime Get-Acl $env:USERPROFILE\.codex\config.toml | Format-List Owner, AccessToString我在修复后保留了一个习惯每周五看一眼这个文件的内容和修改时间。文件不大打开看一眼只需十秒但能让你在问题扩大前就发现配置被动手脚的痕迹。5.3 Windows 特有的账号权限坑别让配置暴露给其他用户如果你的 Windows 登录账户是管理员组的成员同时又开启了“共享给此机器的其他用户使用”之类的不严谨配置其他用户账户理论上也可能读取或改写同一个用户目录下的配置文件。这不是 Codex CLI 的特殊问题是所有 CLI 工具都存在的权限边界问题。平时尽量把开发行为放在自己的专用账户下不要图方便直接长时间用管理员账户跑开发工具。如果因为公司策略必须使用管理员权限至少在工具配置目录上做一步收紧操作让config.toml只有当前用户可读写不给 Authenticated Users 写权限。5.4 每次升级 Codex CLI 后都要重新过一遍“默认指向”我这次遇到问题之后总结出一个很实用的习惯每次升级 Codex CLI我都会把最开始的那三条定位命令重新跑一遍。因为升级版本很可能会触发新逻辑或重新生成 config或开始读取某个新的环境变量。如果某个老的覆盖点仍然存在它会在升级后把请求继续引到旧地址。这套动作不花时间但是一种“最小化被动防守”。命令行工具自带“默认值”三个字不代表它一辈子都只会用官方默认值。只要机器上任何一层配置被改写它就可能静默地连到你陌生的地方去。5.5 保留一份“干净基准配置”备份比什么都管用修复完成后我在自己的受信任存储里存了一份当前的 config.toml 备份文件名写清楚版本号和时间。以后只要 Codex CLI 出现可疑行为我第一件事不是猜而是拿当前配置和这份基准做一次差异对比。Compare-Object (Get-Content $env:USERPROFILE\.codex\config.toml) (Get-Content .\config.toml.baseline)这样能直接看到“多出来什么、改了哪里”比盯着日志猜快得多。命令行工具这种东西一旦配置漂移很多问题都是隐性的。你拿不到它沉默地改变行为的证据就只能靠一份可信基准来兜底。这次排查 q.quuvv.cn 的过程给我的最大体会是工具越顺手越要养成给配置“留底”的习惯。Codex CLI 本身只是执行方真正的问题出在它读取的配置链路里。你在 Windows 上装的每一个工具都可能在一个你看不见的地方被环境变量、配置文件或包装函数改写掉它原本的默认行为。保持怀疑保留现场逐层定位修复后固化基线——这套流程不只适用于 Codex CLI任何命令行工具出了问题都能套用。最后再说一句我的实际操作习惯对所有“默认值”保持一点不信任每次清完配置我都会亲手确认一遍它真的连到了我预期的地址而不是听它说“已使用默认配置”就放心收工。