Codex 与 AI Coding 实践

解决 Codex `Reconnecting 5/5` 与 `stream disconnected`:从代理配置到固定 HTTPS Streaming

用分层诊断定位代理节点、Streaming 与连接复用导致的 Codex 断联。

Codex网络诊断Streaming

本文记录一次特定 Windows、代理与 Codex 配置环境下的实际排查过程。配置项和本地数据结构可能随 Codex 版本变化,修改前请先备份,并以当前版本的官方文档为准。

每次重新启动 Codex,第一次发送消息都要经历 Reconnecting 1/5Reconnecting 5/5,等重试结束后才能正常回答。

我最初以为只是代理没有配置好。补充 .env 后,启动时连续重连的问题确实消失了,但随后又出现了更频繁的对话中断:

stream disconnected before completion: Transport error: network error: error decoding response body

最终,我保留了 .env 中的代理和本机地址绕过配置,同时在 config.toml 中禁用 WebSocket,让 Codex 固定使用 HTTPS Streaming。调整后,连接问题得到大幅改善。

本文记录完整的排查过程,并说明两个容易混淆的问题:

  • .env 到底解决什么?
  • 为什么配置了代理以后仍然可能断流?

一、最初的现象:每次重启都要 Reconnect 5 次

问题最早出现在 Codex 重启后的第一次对话。

每次重新打开 Codex 并发送消息,客户端都会连续显示:

Reconnecting 1/5
Reconnecting 2/5
...
Reconnecting 5/5

奇怪的是,五次重连结束后,Codex 通常又能继续回答,同一会话中的后续提问也可能恢复正常。

这个现象说明网络并非完全不可用,更像是某种连接方式建立失败,经过多次重试后才切换到另一条可用路径。

结合当时的现象,可以将可能的过程理解为:

新会话发送消息
      ↓
客户端尝试建立 WebSocket
      ↓
连接没有成功建立
      ↓
触发多次 Reconnecting
      ↓
改用可用的 HTTPS 流式路径
      ↓
对话恢复

这段流程是根据现象作出的排查推断,并不代表所有版本和网络环境都一定采用相同的回退机制。

二、第一次处理:从没有 .env 到配置代理

检查后发现,本机原本没有 Codex 使用的 .env 文件。因此,这一步不是修改旧配置,而是在下面的位置新建文件:

%USERPROFILE%\.codex\.env

文件内容如下:

HTTP_PROXY=http://127.0.0.1:7897
HTTPS_PROXY=http://127.0.0.1:7897

http_proxy=http://127.0.0.1:7897
https_proxy=http://127.0.0.1:7897

NO_PROXY=localhost,127.0.0.1,::1
no_proxy=localhost,127.0.0.1,::1

其中,7897 是我本机代理软件提供的 HTTP 代理端口,需要根据自己的实际端口修改。

这份 .env 做了什么?

它实际上划分了两类连接:

访问远程服务
      ↓
通过 127.0.0.1:7897 代理转发

访问 localhost / 127.0.0.1 / ::1
      ↓
绕过代理,直接连接本机服务

HTTP_PROXYHTTPS_PROXY 指定远程 HTTP/HTTPS 请求使用的代理。大写和小写各写一组,是为了兼容不同程序和网络库读取环境变量时的差异。

真正容易被忽略的是:

NO_PROXY=localhost,127.0.0.1,::1
no_proxy=localhost,127.0.0.1,::1

Codex 启动时不仅需要访问远程服务,也可能需要与本机组件通信。如果访问本机地址的请求也被送进代理,就可能干扰本地连接。NO_PROXY 的作用就是为本机通信划出一条不经过代理的直连路径。

这里还要纠正一个容易产生的误解:

.env 不是用来“开启 WebSocket”的。

它配置的是代理路径和绕过规则。WebSocket 是否被采用,是 Codex 传输层的选择;.env 只是让相关网络请求通过正确的路径连接。

完全退出并重新启动 Codex 后,原来每次启动固定出现的 Reconnecting 5/5 消失了。至此,第一层问题看起来已经解决。

三、新的问题:响应还没完成,连接就断了

然而,使用一段时间后,新的错误开始频繁出现:

stream disconnected before completion: Transport error: network error: error decoding response body

这条错误可以分成三层理解:

错误片段表示的现象
stream disconnected before completion流式响应尚未完成,连接已经断开
Transport error: network error失败发生在网络传输层
error decoding response body客户端没有获得可供正常继续解析的完整响应数据

这里的 error decoding response body 不一定表示服务器返回了格式错误的正文。结合前面的 stream disconnectednetwork error,更合理的理解是:响应体仍在传输过程中,底层连接却已经中断,客户端因此无法继续读取和解析。

与最初的问题相比,故障发生的阶段已经变化:

阶段主要表现发生时机
配置 .envReconnecting 1/5 ... 5/5重启后的首次连接
配置 .envstream disconnected before completion模型正在流式返回内容时

这说明 .env 解决了代理边界和本机通信问题,但不能保证远程长连接在整个响应期间都不会中断。

四、为什么网页能打开,Codex 仍然会断流?

普通网页请求能够成功,并不代表代理链路适合持续传输。

短请求和流式请求对链路的要求并不相同:

短请求:建立连接 → 获取结果 → 很快结束

流式请求:建立连接 → 持续接收数据 → 保持连接 → 响应完成

Codex 的一次回答可能持续较长时间,中间还可能包含推理过程、工具调用及执行结果。如果代理节点发生短暂抖动、连接被中间设备重置,或者线路在任务过程中切换,当前 TCP/TLS 会话就可能失效。

WebSocket 同样依赖长期保持的连接。在我的网络环境中,它虽然不再每次启动都建连失败,却仍然频繁发生传输中断。因此我推测:当前代理链路对 WebSocket 的兼容性或稳定性不足。

这是根据错误现象作出的排查判断,而不是说“WebSocket 在任何网络中都一定比 HTTPS 不稳定”。更准确的结论是:

在我的代理和网络环境下,HTTPS Streaming 的实际稳定性优于 WebSocket。

代理节点本身的稳定性同样会影响结果。排查过程中,我也更换了不稳定的节点,但本文不展开具体代理服务和节点名称。

五、最终处理:禁用 WebSocket,固定使用 HTTPS Streaming

与其等待 WebSocket 失败后再重试或回退,也可以在 Codex 配置中明确禁用 WebSocket。

打开用户级配置文件:

%USERPROFILE%\.codex\config.toml

在保留原有配置的前提下,加入下面的内容:

model_provider = "openai_http"

[model_providers.openai_http]
name = "OpenAI HTTP"
wire_api = "responses"
requires_openai_auth = true
supports_websockets = false

如果文件中已经存在 model_provider,不要重复声明。应修改原来的值,并注意不要破坏已有的 TOML 表结构。修改前最好先备份配置文件。

每一项配置有什么作用?

配置项作用
model_provider = "openai_http"选择下面定义的自定义模型提供方
wire_api = "responses"继续使用 Responses API
requires_openai_auth = true继续使用 OpenAI 身份认证
supports_websockets = false告诉 Codex 该提供方不使用 WebSocket 传输

最关键的是:

supports_websockets = false

修改后,预期的传输流程变成:

Codex 读取 openai_http 配置
            ↓
supports_websockets = false
            ↓
不尝试 Responses WebSocket
            ↓
直接使用 HTTPS Streaming
            ↓
持续接收模型响应

这个方案没有关闭 Responses API,也不会把流式回答变成必须等待全部生成完成的普通请求。它改变的是 Responses API 使用的传输方式:由 WebSocket 改为 HTTPS 流式传输。

修改完成后,需要彻底退出 Codex,包括可能仍在运行的托盘进程,然后重新打开,让用户级配置重新加载。

六、切换 HTTPS 后,历史聊天记录为什么不见了?

固定 HTTPS 后,连接稳定性明显改善,但重启 Codex 时,我又遇到了一个新问题:侧边栏中的历史聊天记录不见了。

这个现象很容易让人误以为修改配置删除了会话。实际检查后发现,大多数情况下聊天内容并没有被删除,问题可能来自 model_provider 的变化。

原来的会话记录使用内置 Provider,例如:

model_provider = "openai"

为了禁用 WebSocket,我把它切换成了新定义的 Provider:

model_provider = "openai_http"

Codex 的本地会话状态不只存在于单一文件中,还可能涉及:

~/.codex/sessions
~/.codex/archived_sessions
~/.codex/state_5.sqlite
.codex-global-state.json

切换 Provider 后,这些位置记录的 Provider、会话索引和项目状态可能没有同步更新,于是出现下面的情况:

历史会话文件仍然存在
          ↓
会话与 SQLite 中的 Provider 元数据不一致
          ↓
Codex Desktop 无法将它们归入当前 Provider
          ↓
侧边栏过滤掉这些会话
          ↓
看起来像历史记录丢失

使用 codex-provider-sync 恢复显示

我参考相关文章,使用了开源工具 codex-provider-sync,把已有会话的相关元数据同步到当前使用的 openai_http Provider。

命令行版本可以通过下面的方式安装:

npm install -g git+https://github.com/Dailin521/codex-provider-sync.git

原文所参考的资料称 CLI 依赖 Node.js 24 或更高版本;较旧版本可能因为 node:sqlite 支持问题而无法运行。工具要求可能变化,请以仓库当前说明为准。安装第三方工具前,应自行核对仓库地址、源码、许可证和依赖。

同步前先彻底关闭 Codex、Codex Desktop 和相关 app-server 进程,避免 state_5.sqlite 正在使用而出现:

database locked

然后先检查状态:

codex-provider status

确认当前 Provider 后执行同步:

codex-provider sync --provider openai_http

也可以直接运行:

codex-provider sync

后者不会切换 Provider,只同步当前 Provider 对应的历史会话元数据。完成后重新启动 Codex,原来的历史会话重新出现在侧边栏中。

该工具修复的主要内容包括:

同步对象作用
sessions普通会话文件中的 Provider 元数据
archived_sessions已归档会话的相关元数据
state_5.sqliteCodex 的本地会话状态和索引
项目缓存让桌面端重新识别会话与项目的关联

它不会重写聊天内容,也不会处理登录状态或重新加密历史消息。根据原文所用版本,同步前会自动在下面的位置生成备份:

~/.codex/backups_state/provider-sync/<timestamp>

如果处理后出现异常,可以使用工具提供的 restore 命令恢复相应备份。

还要注意:恢复列表显示并不保证跨账号或跨 Provider 的旧会话一定能够继续对话。如果历史内容包含与原账号或 Provider 相关的加密数据,仍可能遇到:

invalid_encrypted_content

因此,这个工具解决的是“会话明明存在但桌面端不可见”,而不是所有跨 Provider 会话兼容问题。

七、最终生效的完整配置思路

最终方案不是用 config.toml 替代 .env,而是让两个文件分别解决不同层面的问题。

.env:处理代理路径

HTTP_PROXY=http://127.0.0.1:7897
HTTPS_PROXY=http://127.0.0.1:7897
http_proxy=http://127.0.0.1:7897
https_proxy=http://127.0.0.1:7897
NO_PROXY=localhost,127.0.0.1,::1
no_proxy=localhost,127.0.0.1,::1

它负责:

  • 让远程请求经过本机代理;
  • localhost 等本机地址绕过代理。

config.toml:处理传输方式

model_provider = "openai_http"

[model_providers.openai_http]
name = "OpenAI HTTP"
wire_api = "responses"
requires_openai_auth = true
supports_websockets = false

它负责:

  • 保留 Responses API;
  • 禁用 WebSocket;
  • 固定使用 HTTPS Streaming。

完整排查流程

每次重启都 Reconnecting 5/5
              ↓
发现没有 Codex .env
              ↓
配置代理变量和 NO_PROXY
              ↓
启动时五次重连消失
              ↓
频繁出现 stream disconnected before completion
              ↓
判断远程长连接仍不稳定
              ↓
更换不稳定节点,并禁用 WebSocket
              ↓
固定使用 HTTPS Streaming
              ↓
连接问题得到大幅改善
              ↓
切换 model_provider 后历史会话不可见
              ↓
使用 codex-provider-sync 同步到 openai_http
              ↓
历史会话恢复显示

总结

这次问题并不是一个配置就能解释,而是三个阶段连续出现:

  1. Codex 没有正确区分远程代理流量与本机通信,导致重启后反复出现 Reconnecting 5/5
  2. 补充 .env 后,WebSocket 路径仍然无法在当前代理环境中稳定维持,导致流式响应中断。
  3. 禁用 WebSocket 时新增了 openai_http Provider,原有会话的 Provider 元数据与当前配置不一致,因此历史记录暂时不可见。

最终的解决思路可以概括为:

用 .env 配置正确的代理边界
                  +
用 config.toml 固定 HTTPS Streaming
                  +
使用相对稳定的代理节点
                  +
同步切换 Provider 后的本地会话元数据
                  ↓
Codex 连接稳定性得到改善,历史会话恢复显示

这套方案来自特定环境下的实际排查结果,并不意味着所有 Reconnecting 或断流问题都有相同原因。遇到类似问题时,建议先区分故障发生在首次建连、流式传输期间,还是切换 Provider 之后,再针对对应层次处理。

参考资料

原文提及以下资料,但未提供完整 URL:

  • 知乎:Codex 代理与 WebSocket 相关配置
  • CSDN:修复 Codex Reconnecting 5/5
  • 腾讯云:Codex 历史会话消失?一键恢复可见
  • GitHub:codex-provider-sync
  • OpenAI:Codex Configuration Reference
  • OpenAI:Responses API Streaming
  • OpenAI:Responses API WebSocket Mode

陈涛 · Agent Application Developer

杭州 · 2026