电影《暗金丑岛君》剧情说明
2026-08-15 3450847
2026-08-15 0
Codex CLI 出现 Reconnecting,不等于已经查明“中转不支持 WebSocket”。它表示 Responses stream 进入了可重试错误路径;实际传输可能是 WebSocket,也可能是 HTTP 流,还可能发生 WebSocket 重试后回退 HTTPS。排查时应先记录版本、错误文本、实际 transport 和重连位置,再确认使用的是内置 OpenAI provider 还是自定义 provider,最后按可回滚方式检查连接、请求、流、企业网络和证书链。

本文配置项与默认值核验于 2026-08-04。Codex CLI 迭代较快,发布或应用配置前应重新查看当前配置参考和目标版本行为。
当前 Codex 配置参考明确区分了几个概念:
model_providers..supports_websockets 表示该自定义 provider 是否支持 Responses API WebSocket transport;request_max_retries 控制发往 provider 的 HTTP 请求重试次数,当前默认值是 4;stream_max_retries 和 stream_idle_timeout_ms 在当前配置参考中分别按 SSE 流中断重试和 SSE 空闲超时描述,默认值是 5 和 300000 毫秒;wire_api 当前只支持 responses。因此,界面上的 Reconnecting 1/5 只能视为 Responses stream 正在重试,不能仅凭数字“5”认定发生了五次 WebSocket 握手,也不能反过来认定一定是 SSE。当前运行时的 retry/fallback 路径会涉及 WebSocket 和 HTTP;这些配置值不是协议探针。
同一句 Reconnecting,出现在不同阶段,排查方向并不相同。
| 重连位置 | 优先核对 | 暂时不能下的结论 |
|---|---|---|
| 提交请求后、正文输出前 | provider 配置、传输能力、TLS 与连接路径 | 一定是中转没有 WebSocket |
| 已经开始输出、随后中断 | 当前实际 transport 的流中断、空闲超时、代&理读超时、上游断流 | 已经输出过正文就一定是 SSE |
| 工具调用前后、工具结果提交后的模型续传 | 先区分工具进程挂起、工具结果未返回和后续 Responses 流断开 | 工具正常执行或等待本身触发了重连 |
| 只在企业网络出现 | 企业代&理、私有 CA、防火墙和出口策略 | 服务端对所有用户都不可用 |
先记录 Codex 版本、发生时间与时区、网络环境、重连阶段以及最终是否完成。版本可用下列命令查看:
codex --version
如果问题不能稳定复现,也应如实写“偶发”,不要把一次恢复当成根因已经确认。
这一步最容易配错。Codex 提供两种不同的配置路径。
如果只是把内置 openai provider 指向代&理,可在用户级 ~/.codex/config.toml 中设置:
openai_base_url = "https://proxy.example.com/v1"
openai_base_url 只覆盖内置 openai provider 的 Base URL。此时不能在根级随手添加 supports_websockets;它不是 openai_base_url 的配套开关。
需要单独声明鉴权、查询参数或传输能力时,可以定义自定义 provider:
model = ""model_provider = "proxy"[model_providers.proxy]name = "Example proxy"base_url = "https://proxy.example.com/v1"env_key = "PROXY_API_KEY"wire_api = "responses"supports_websockets = false
这里的 env_key 是环境变量名称,不是密钥本身。真实 API Key 不应写进配置截图、文章或公开仓库。
supports_websockets = false 适合两类情况:服务端已经明确只支持 Responses HTTP 传输;或者维护者把它作为可回滚的诊断变量。它不是所有重连问题的通用修复项。
还有一个位置边界:openai_base_url、model_provider 和 model_providers 等机器本地 provider 配置写入项目级 .codex/config.toml 时会被忽略,部分版本可能同时给出配置诊断或启动提示。这些字段应放在用户级 ~/.codex/config.toml。修改后启动新的 Codex 进程再观察,避免把旧进程的结果算进新配置。
如果使用自定义 provider,可以先做最小、可回滚的配置对照。不要同时更换模型、Base URL、网络和鉴权方式,否则即使现象消失,也无法判断是哪项变化起作用。
建议记录以下三组:
| 组别 | 唯一配置差异 | 要观察的结果 |
|---|---|---|
| 当前组 | 保留当前配置 | 重连发生阶段、最终是否完成 |
| 对照组 | 只改变 supports_websockets | 输出前重连是否变化,长输出和工具调用是否完整 |
| 回滚组 | 恢复原值 | 原现象是否重新出现 |
如果没有测试环境或无法完成这组对照,也可以先提交阶段、配置类型和网络差异等现有证据,但结论应停留在“待定位”,不能写成已确认的传输根因。
不要把所有 timeout 和 retry 都归到 stream_max_retries。截至本次核验日期,可以按下面的层级理解:
| 配置或实现项 | 作用层 | 当前默认值 | 能否判断 transport |
|---|---|---|---|
websocket_connect_timeout_ms | 等待 WebSocket 连接建立 | 源码为 15000 ms | 只能说明连接阶段;公开配置支持以当前版本参考为准 |
request_max_retries | 发往 provider 的 HTTP 请求失败重试 | 4 | 不能据此判断后续流使用 WS 还是 HTTP |
stream_max_retries | Responses 流中断后的重试 | 5 | 不能;运行时路径可能涉及 WS、HTTP 和 fallback |
stream_idle_timeout_ms | 流长时间无活动时判定连接丢失 | 300000 ms | 不能;“已经输出”也不是协议证据 |
自定义 provider 可以显式记录公开配置参考支持的请求与流参数:
[model_providers.proxy]request_max_retries = 4stream_max_retries = 5stream_idle_timeout_ms = 300000
上面展示的是当前默认值,不是建议所有人照抄的调优值。盲目增加重试次数可能只是让失败更晚暴露;盲目延长空闲超时,也不能修复代&理主动断开、上游异常或证书问题。应先确认实际 transport 和中断层级,再决定是否调整。
这只能证明传输选择与现象相关,属于“相关线索”,还不能仅凭客户端对照定位到上游、中转、反向代&理或 TLS 链中的某一层。若同时观察到 WebSocket 握手错误或 Falling back from WebSockets to HTTPS transport,可把传输路径提高为强线索;只有结合维护者日志、HTTP/WS 状态和实际握手证据,才能确认具体故障层。若 provider 维护者确认服务端不支持 Responses API WebSocket transport,可以让能力声明与服务端保持一致。
优先检查当前实际 transport 的流和长连接:代&理读超时、流空闲时段、企业网络波动或上游断流都可能造成类似现象。此时 supports_websockets 不是唯一变量,更不应只围绕它反复修改。已经出现正文输出不能证明流一定是 SSE。
把企业 TLS 代&理、私有根证书和出口策略列为强线索。当前 Codex 文档说明,CODEX_CA_CERTIFICATE 可为登录、普通 HTTPS 请求和安全 WebSocket 连接指定 PEM CA 包;未设置时回退到 SSL_CERT_FILE。
证书包应由组织的安全或运维团队提供。不要从不可信来源下载根证书,也不要关闭 TLS 校验来换取“临时成功”。
问题已经不是“重连后还能回答”。回到基础项检查鉴权方式、最终请求 URL、模型 ID、限流和脱敏错误体,避免让传输层假设遮住了更早发生的 401、404、429 或其他服务端错误。
Codex 当前公开的 OTel 事件包括 codex.sse_event、codex.websocket_request 和 codex.websocket_event;对应指标使用 codex.sse_event、codex.websocket.request、codex.websocket.event 等名称,另有 transport.fallback_to_http 记录 WebSocket 到 HTTP 的回退次数。事件名和指标名不要混写。这些数据只有在团队主动配置 OTel,并将数据发送到自己控制的采集端后才可使用;默认终端中看不到它们。
启用观测前应确认采集范围、访问权限和保留期限。提示词、工具结果与错误上下文可能包含业务数据,不应为了排障直接发送到未经批准的采集端。还要注意,这里讨论的是 Responses API 的传输,不是 codex app-server --remote 的远程 WebSocket,两者不能混为一谈。
当自己无法继续验证时,下面这组材料通常比整份配置更有用:
Falling back from WebSockets to HTTPS transport,以及已知的实际 transport;不要公开 API Key、完整请求体、真实内部链接、未脱敏日志或完整本机配置。接入方能核对哪些记录取决于链路位置、采集范围和保留策略,不能预设它一定看得到完整请求、上游日志或内部路由。
.codex/config.tomlstream_max_retries 当成 WebSocket 重试参数1.Reconnecting 1/5是否代表 WebSocket 连续失败五次?
不能这样判断。当前官方配置说明 stream_max_retries 的默认值也是 5,但界面计数本身没有完成传输类型归因。需要结合发生阶段、provider 配置和可观测证据判断。
2. 使用openai_base_url后,可以直接加supports_websockets = false吗?
不能把它当成同一层配置。openai_base_url 服务于内置 openai provider;supports_websockets 是 model_providers. 下的自定义 provider 字段。若要改成自定义 provider,还要一并核对鉴权、模型和最终端点。
3. 把stream_max_retries调大,能解决频繁重连吗?
不一定。它改变的是 Responses 流中断后的重试次数;官方配置参考以 SSE 描述该字段,但当前运行时还存在 WebSocket 和 HTTP fallback 路径。它不会修复 TLS、代&理断流或服务端路由问题,也不会自动告诉你实际 transport 和根因。
4. 短回答正常,是否说明配置已经没问题?
不能。短回答覆盖不了长时间流式输出和工具调用。若要评估一条链路是否适合实际任务,至少还要观察长输出是否完整,以及工具调用能否完成请求、结果返回和最终回答。
排查 Codex CLI 重连,关键不是先猜 WebSocket 或 SSE,而是先确定实际 transport、重连阶段和 fallback,再按 provider 类型核对配置。supports_websockets、request_max_retries、stream_max_retries 与 stream_idle_timeout_ms 处理的是不同层的问题。证据不足时保留“待定位”,比把一次恢复写成通用结论更可靠。