适用范围:macOS 与 Windows 双平台。第一步必须识别操作系统,严禁交叉执行命令。
macOS 只使用 Shell、LaunchAgent 和 launchctl;Windows 只使用 PowerShell 与 Windows 计划任务。无法确认系统、Codex 版本、真实 CODEX_HOME 或目标 provider 时,立即停止,不要猜路径,也不要照搬另一平台的命令。
Codex 有时会在更新或配置被自动回写后重新尝试 WebSocket,表现为对话反复显示“重新连接”,最后才回到 HTTP。真正安全的处理方式不是复制一小段 TOML 覆盖配置,而是让本机的 GPT 或 Codex 先识别系统和现状,再做一次可回滚的最小修改。
这篇文章同时提供 macOS 与 Windows 方案。你可以把文章链接和文末提示词一起发给本机 GPT/Codex,让它选择正确分支;不要自己把 macOS 命令翻译成 Windows,也不要反过来。
两个平台都必须先过六道安全门
1. 先确认版本、程序位置和真实配置目录
不要先假定配置一定在默认路径。
macOS 先检查:
uname -s
codex --version
command -v codex
printf 'CODEX_HOME=%s\n' "${CODEX_HOME:-$HOME/.codex}"
Windows 先检查:
$PSVersionTable.Platform
codex --version
Get-Command codex -ErrorAction SilentlyContinue
$CodexHome = if ($env:CODEX_HOME) { $env:CODEX_HOME } else { Join-Path $env:USERPROFILE '.codex' }
"CODEX_HOME=$CodexHome"
OpenAI 官方 Windows 文档明确写明:ChatGPT Windows 应用与 Windows 原生 Codex 默认共用 %USERPROFILE%\.codex。如果设置了 CODEX_HOME,应以实际环境变量为准。
2. 只读核对目标键,不回显秘密
GPT/Codex 可以读取完整文件来判断 TOML 表结构,但对外只应报告:
- 实际
config.toml路径和文件是否存在。 - 根级
model_provider的出现次数与当前 provider id。 - 目标
[model_providers.<id>]表是否恰好存在一次。 - 该表中
supports_websockets的出现次数与布尔值。 - 是否存在重复键、重复表或明显的 TOML 结构错误。
不要回显 token、API key、认证头、完整 auth.json、完整配置或其它 provider 的敏感字段。目标 provider 表若不存在,脚本会拒绝创建;先补齐并验证完整 provider 定义,不能用只有两个键的残缺示例冒充可用配置。
3. 写入前先做时间戳备份
备份名统一为:
config.toml.before-http-YYYYMMDD-HHMMSS.bak
已有 .bak 一律保留。每次真正写入前都先生成新备份;第二次运行若配置已经正确,不应再次改文件或制造无意义备份。
4. 只允许修改两个目标
候选脚本只允许:
- 把根级
model_provider指向已经存在且已经验证的目标 provider。 - 把目标 provider 表里的
supports_websockets设为false。
其它设置、注释、provider 字段、认证文件和会话目录都不能改。脚本遇到重复键、重复表或缺少目标 provider 表时会停止,不会猜测用户意图。
5. 写后要验证完整配置和真实连接
OpenAI 当前 Config Reference 与 config schema 都识别:
model_providermodel_providers.<id>- 布尔型
model_providers.<id>.supports_websockets
所以,supports_websockets = false 本身不是必然语法错误。config_load 只说明整份配置加载失败;具体原因可能是 TOML 表位置、重复键、provider id 不匹配、其它无效字段,或自动回写生成了错误文件。
写入后至少检查四层:
- 用当前 Codex 自带的
--strict-config doctor --json验证完整 TOML 与当前版本 schema,确认checks["config.load"].status为ok。 - 从同一份脱敏报告确认 active provider 是目标 provider。
- 重新打开 ChatGPT/Codex 设置,确认不再出现
config_load。 - 发起一次最小真实请求,并结合应用表现或脱敏日志确认连接成功;不能只看脚本退出码。
6. 任一验证失败,立即恢复并停止自动触发
严格加载、active provider、设置页或真实连接任一失败,都要立刻恢复刚才的备份。一次性验证没有完整通过前,不得安装 LaunchAgent 或 Windows 计划任务;已安装的触发器要先停用,防止它低频但持续地写坏配置。
macOS:幂等 Shell + LaunchAgent
下载候选文件:
先单次运行,不要马上安装 LaunchAgent
chmod 700 force-http-provider.sh install-launch-agent.sh
export CODEX_HOME="${CODEX_HOME:-$HOME/.codex}"
export CODEX_BIN="${CODEX_BIN:-$(command -v codex)}"
./force-http-provider.sh openai_http
把 openai_http 换成本机已经存在、已经验证的目标 provider id。脚本会锁定单次执行、保留非目标行、在写前备份,并调用真实 Codex 做严格配置加载;失败时立即把备份复制回去。
随后重新打开 ChatGPT/Codex,完成一次真实请求。只有设置页、active provider 和真实连接都通过,才安装 LaunchAgent:
CONFIRMED_ONE_TIME_VALIDATION=1 \
CODEX_HOME="${CODEX_HOME:-$HOME/.codex}" \
./install-launch-agent.sh ./force-http-provider.sh openai_http
这个 LaunchAgent 只有两个触发条件:
- 当前用户登录时运行一次。
- 每 30 分钟低频检查一次。
它没有 WatchPaths,不会监听自己刚写过的 config.toml;也不会创建常驻进程或文件监控器。重复安装会更新同一个 label,不会堆出多份任务。
如果后续验证失败,先停用触发器,再恢复备份:
plist="$HOME/Library/LaunchAgents/online.aixiaobai.codex-force-http-provider.plist"
launchctl bootout "gui/$(id -u)" "$plist" 2>/dev/null || true
[[ -f "$plist" ]] && mv "$plist" "$plist.disabled-$(date '+%Y%m%d-%H%M%S')"
: "${BACKUP_FILE:?先把 BACKUP_FILE 设为脚本刚才输出的完整备份路径}"
cp -p -- "$BACKUP_FILE" "$CODEX_HOME/config.toml"
恢复后重新运行严格配置检查和真实连接测试;不要在失败状态下重新加载 LaunchAgent。
Windows:幂等 PowerShell + 最小计划任务
下载候选文件:
先单次运行 PowerShell
在 Windows PowerShell 中先读脚本并确认来源,再运行:
$CodexHome = if ($env:CODEX_HOME) { $env:CODEX_HOME } else { Join-Path $env:USERPROFILE '.codex' }
.\Force-CodexHttpProvider.ps1 `
-ProviderId openai_http `
-CodexHome $CodexHome
如果 codex 不在 PATH,不要猜可执行文件位置。先让本机 GPT/Codex 从 Windows 应用、进程或实际安装目录找到当前 Codex 可执行文件,再显式传入:
.\Force-CodexHttpProvider.ps1 `
-ProviderId openai_http `
-CodexHome $CodexHome `
-CodexExecutable '实际查到的 codex.exe 路径'
PowerShell 脚本与 macOS 版本遵守相同边界:目标 provider 表必须已经存在;只改两个键;写前备份;写后读取 codex --strict-config doctor --json;严格加载或 active provider 不对就自动恢复。
重新启动 ChatGPT Windows 应用,确认设置页正常,再完成一次真实请求。全部通过后才能安装计划任务:
.\Install-CodexHttpProviderTask.ps1 `
-PatchScript (Resolve-Path .\Force-CodexHttpProvider.ps1) `
-ProviderId openai_http `
-ConfirmedOneTimeValidation
计划任务只使用当前用户权限,包含两个简单触发器:当前用户登录时一次,以及每 30 分钟一次。安装器使用固定任务名和 -Force 更新,因此重复执行不会创建多个同名变体。它不创建 Windows 服务,不安装文件监控器,也不需要把 launchctl “翻译”成 Windows。
Windows 已经出现 config_load,怎么恢复
这次真实事故里,Windows App 与原生 Codex 共用了 %USERPROFILE%\.codex。卸载或重装 ChatGPT 通常不会清除这个用户目录,所以错误的 config.toml 仍可能留在原处;重装不能替代配置恢复。
按这个顺序处理:
- 完全退出 ChatGPT Windows 应用。
- 在文件资源管理器的“查看”中开启“文件扩展名”,确认看到的是
config.toml,而不是被隐藏扩展名的同名文件。 - 停用相关计划任务或其它自动回写,防止配置刚重命名就被重新生成。
- 将当前
config.toml重命名停用,不要删除;保留全部config.toml.before-http-*.bak。 - 不要删除
auth.json、sessions或整个.codex。 - 重新启动 ChatGPT,重试 Windows 设置。
本次真实 Windows 现场已经按这条路径恢复:停用旧 config.toml 后,Codex 恢复正常使用。这足以验证“先停用当前配置,再让应用脱离错误文件恢复”的应急路径;但它不等于 Windows 计划任务、active provider 或强制 HTTP 自动化已经完成端到端验证。
恢复脚本会先停用本文的计划任务,再把当前配置改名为 config.toml.disabled-时间戳:
.\Recover-CodexConfigLoad.ps1
如果 config.toml 自动重建,立即停止继续修改,记录新文件的时间和有限的非敏感结构信息,然后排查计划任务、启动脚本、同步工具、旧修补器或应用自身的自动回写。先确认是谁在写,再决定修复;不要让多个自动化互相覆盖。
可直接复制给 GPT/Codex 的统一提示词
请阅读这篇文章,并在这台电脑上按以下安全流程处理 Codex 的 HTTP provider。
第一步只读识别操作系统、ChatGPT/Codex 版本、实际 Codex 可执行文件、
实际 CODEX_HOME 和 config.toml 路径。只允许选择一个平台分支:
- macOS:只用 Shell、LaunchAgent、plutil、launchctl。
- Windows:只用 PowerShell 和 Windows 计划任务。
- 无法确认系统时立即停止。
严禁在 Windows 创建 plist、LaunchAgent、~/Library/LaunchAgents 或运行 launchctl;
严禁在 macOS 创建 Windows 计划任务或把 Windows PowerShell 方案当作系统触发器。
只读检查完整 config.toml 的结构,但对我只回显:
1. 实际路径与文件是否存在
2. 根级 model_provider 的出现次数与当前 provider id
3. 目标 [model_providers.<id>] 是否恰好存在一次
4. 该表 supports_websockets 的出现次数与布尔值
5. 是否有重复键、重复表或结构错误
不要回显 token、API key、auth.json、完整配置或其它敏感字段。
目标 provider id 由本机已有配置和事实确定,不能凭文章猜。
如果目标 provider 表不存在或不完整,停止,不得用两行示例创建残缺 provider。
确认无歧义后:
- 使用文章中当前平台的候选脚本
- 真正写入前创建 config.toml.before-http-时间戳.bak
- 只修改根级 model_provider 与目标 provider 的 supports_websockets=false
- 不改其它设置、认证、会话或 provider 字段
- 第二次运行必须不改文件、不新增无意义备份
写入后依次验证:
1. codex --strict-config doctor --json 中 config.load=ok
2. 脱敏报告中的 active provider 等于目标 provider
3. ChatGPT/Codex 设置页无 config_load
4. 一次最小真实请求成功,并从应用表现或脱敏日志确认真实连接
任一项失败,立即恢复刚才的备份,并停用相关 LaunchAgent/计划任务。
只有四项全部通过,才安装文章中的低频触发器:登录时一次 + 每 30 分钟一次。
不要创建常驻服务、文件监控器、复杂状态机或第二套触发任务。
如果 Windows 已经 config_load:先显示文件扩展名,停用计划任务/自动回写,
把当前 config.toml 重命名为 config.toml.disabled-时间戳,保留已有 .bak、
auth.json、sessions 和整个 .codex;重启 ChatGPT 重试设置。
如果 config.toml 自动重建,停止并查明写入者,不要继续覆盖。
最后只报告:识别的平台、实际 CODEX_HOME、备份路径、改动的两个键、
四项验证结果、是否安装触发器、回滚是否可用。不要输出任何秘密。
当前候选的验证边界
截至 2026 年 8 月 24 日:
- macOS Shell 已通过
zsh -n、首次修改、二次零改动、非目标行不变和验证失败回滚测试。 - plist 已通过
plutil -lint;LaunchAgent 安装器重复运行后仍只有一个固定 label,生成内容一致。 - macOS 临时配置已由真实 Codex 0.149 的
--strict-config doctor --json加载,观察到config.load=ok与目标 active provider。 - 三个 PowerShell 文件已由官方 PowerShell 7.6.5 ARM64 解析;核心 PowerShell 修改器已通过首次修改、二次零改动、非目标行不变和失败回滚测试;恢复脚本第二次运行未新增停用文件。
- Windows 真实事故中,停用旧
config.toml后 Codex 已恢复使用;因此本文的 Windows 应急恢复路径已有真实用户结果。 - Windows 计划任务安装器只在 PowerShell 中以 Windows cmdlet 替身验证了固定任务名、双触发器与重复更新逻辑。当前没有真实 Windows 环境,因此没有声称 Windows Task Scheduler 注册、ChatGPT Windows 设置页或真实 Windows 连接已端到端通过。
也就是说,Windows 应急恢复路径已经得到真实现场验证,Windows 脚本候选也经过语法与核心幂等验证;但在实际启用计划任务或声称“Windows 强制 HTTP 自动化完整可用”之前,仍需要在隔离的真实 Windows 用户环境完成:脚本写入、严格加载、active provider、真实请求、计划任务和失败回滚。这个缺口不能用一次恢复成功或 macOS 上的 PowerShell 测试代替。
参考资料
官方资料核对于 2026 年 8 月 24 日。官方资料证明 Windows 运行环境、Codex 主目录和当前配置 schema;具体事故中的备份文件、重装后残留与自动回写现象来自已核现场,未与官方事实混写。