CPA 代理 Codex 卡在"正在思考"的排查与 WebSocket 解决方案(都是自己遇到的真实情况,拜托管理员放过哈)

CPA 代理 Codex 卡在"正在思考"的排查与 WebSocket 解决方案 使用 CPA 代理 Codex / Codex CLI / Codex Desktop 时,可能会遇到这些现象: 卡在"正在思考",长时间没有输出。 请求反复失败,偶发超时。 CPA 代理下 HTTPS / SSE 转...
CPA 代理 Codex 卡在"正在思考"的排查与 WebSocket 解决方案(都是自己遇到的真实情况,拜托管理员放过哈)
CPA 代理 Codex 卡在"正在思考"的排查与 WebSocket 解决方案(都是自己遇到的真实情况,拜托管理员放过哈)

CPA 代理 Codex 卡在"正在思考"的排查与 WebSocket 解决方案

使用 CPA 代理 Codex / Codex CLI / Codex Desktop 时,可能会遇到这些现象:

  • 卡在"正在思考",长时间没有输出。
  • 请求反复失败,偶发超时。
  • CPA 代理下 HTTPS / SSE 转发不稳定。
  • codex doctor 显示 WebSocket 失败,随后 fallback 到 HTTPS。

这类问题不一定和出口 IP 区域有关,更常见的关键点是 Codex 到 CPA、CPA 到 OpenAI 这两段是否真的走了 WebSocket。本文整理完整配置方式,以及如何确认链路是否已经变成全程 WebSocket。

目标链路

理想的全程 WebSocket 链路是:

Codex ---ws---> CPA ---wss---> OpenAI / ChatGPT Codex backend

也就是:

Codex -> ws://localhost:8317/v1/responses
CPA   -> wss://chatgpt.com/backend-api/codex/responses

注意,这里有两段链路:

  • Codex -> CPA:由 Codex provider 配置决定。
  • CPA -> OpenAI:由 CPA 当前选中的 Codex OAuth auth 文件决定。

只配置其中一段,可能只能得到半程 WebSocket。

解决方案:开启全程 WebSocket

目标是让 Codex 到 CPA 使用 WebSocket,同时 CPA 到 OpenAI 也使用 WSS。

1. 修改 Codex 配置

编辑 Codex 配置文件:

~/.codex/config.toml

找到 CPA 对应的 provider,例如:

[model_providers.cliproxyapi]
base_url = "http://localhost:8317/v1"

在这个 provider 下添加:

supports_websockets = true

完整示例:

[model_providers.cliproxyapi]
name = "cliproxyapi"
base_url = "http://localhost:8317/v1"
wire_api = "responses"
supports_websockets = true

这个配置必须放在 [model_providers.cliproxyapi] 下面,不要放到 [features] 下面。

2. 不要乱配 feature flag

不要盲目在 [features] 下添加:

responses_websockets_v2 = true

部分 Codex 版本中相关 feature flag 已经被移除或默认内置。可以用下面命令确认:

macOS:

/Applications/Codex.app/Contents/Resources/codex debug features

Windows 示例:

codex debug features

如果输出里显示类似:

responses_websockets: removed
responses_websockets_v2: removed

说明这个开关已经不再需要,也不应该再配。关键配置是 provider 里的 supports_websockets = true

3. 修改 CPA 的 Codex auth 文件

只改 Codex 配置,通常只能保证:

Codex ---ws---> CPA

要实现:

CPA ---wss---> OpenAI

还需要让 CPA 当前使用的 Codex OAuth auth 开启 WebSocket。

CPA 的 Codex OAuth auth 文件一般在:

macOS 常见位置:

~/.cli-proxy-api/

Windows 运行包常见位置示例:

<CPA_RUNTIME_DIR>\auth\

文件名通常类似:

codex-your-email@example.com-plus.json
codex-your-email@example.com-free.json

编辑 CPA 实际选中的 Codex auth 文件,在 JSON 顶层添加:

"websockets": true

示例结构:

{
  "websockets": true,
  "access_token": "...",
  "account_id": "...",
  "email": "...",
  "refresh_token": "...",
  "type": "codex"
}

注意:

  • websockets 是 JSON 顶层字段。
  • 不要放进 metadataattributes 或其他嵌套对象里。
  • 如果有多个 Codex auth 文件,要改 CPA 实际选中的那个。
  • CPA 日志中的 Use OAuth provider=codex auth_file=... 会显示当前使用的是哪个 auth 文件。

验证步骤

1. 用 Codex doctor 验证 Codex 到 CPA

macOS:

/Applications/Codex.app/Contents/Resources/codex doctor

Windows / PATH 已配置时:

codex doctor

成功时应看到类似:

websocket connected (HTTP 101 Switching Protocols)
supports websockets true
endpoint ws://localhost:8317/v1/...

这说明:

Codex ---ws---> CPA

已经成立。

2. 用 CPA Manager 监控辅助判断

CPA Manager 的监控列表也可以作为一个直观信号。开启 WebSocket 后,监控里对应模型的请求方法通常会显示为:

cpa-manager-get-v1-responses

GET /v1/responses

这和普通 HTTP/SSE 请求不一样。之前走 HTTP/SSE fallback 时,请求通常是:

POST /v1/responses
Accept: text/event-stream

原因是 WebSocket 握手本身是 HTTP GET + Upgrade: websocket,成功后才升级成 WebSocket 连接。所以在 CPA Manager 里看到连续成功的 GET /v1/responses,基本可以说明 Codex -> CPA 这一段已经在走 WebSocket 路由。

不过它只能证明下游请求进入了 CPA 的 WebSocket handler。要确认 CPA -> OpenAI 也变成 WSS,还需要继续看 main.log 里是否有 codex websockets: upstream connected ... url=wss://...

3. 打开 CPA 日志验证 CPA 到 OpenAI

这一步不是长期必需,只建议临时打开用于验证。编辑 CPA 配置文件。

macOS Homebrew 常见位置:

/opt/homebrew/etc/cliproxyapi.conf

Windows 运行包示例:

<CPA_RUNTIME_DIR>\config.yaml

临时打开:

debug: true
request-log: true
logging-to-file: true

然后重启 CPA。

日志文件常见位置:

macOS:

~/.cli-proxy-api/logs/main.log

Windows 运行包示例:

<CPA_RUNTIME_DIR>\auth\logs\main.log

rg 检索关键日志:

macOS:

rg -n "codex websockets|upstream connected|wss://|responses websocket|Use OAuth" ~/.cli-proxy-api/logs/main.log

Windows:

rg -n "codex websockets|upstream connected|wss://|responses websocket|Use OAuth" <CPA_RUNTIME_DIR>\auth\logs\main.log

成功时会看到类似:

responses websocket: client connected ... remote=127.0.0.1
Use OAuth provider=codex auth_file=codex-example@example.com-plus.json ...
codex websockets: upstream connected ... url=wss://chatgpt.com/backend-api/codex/responses

这就说明链路已经是:

Codex ---ws---> CPA ---wss---> OpenAI

验证完成后,建议把 CPA 日志开关关回去:

debug: false
request-log: false
logging-to-file: false

然后再次重启 CPA。

原因是 request-log: true 可能记录完整请求 payload,包括对话内容、工具调用参数等,长期打开会增加磁盘占用和敏感信息落盘风险。

常见误区

误区 1:把 supports_websockets 放错位置

错误写法:

[features]
supports_websockets = true

正确写法:

[model_providers.cliproxyapi]
supports_websockets = true

supports_websockets 是 provider 能力配置,不是 feature flag。

误区 2:只开了 Codex 到 CPA

如果 CPA 日志里只有:

responses websocket: client connected

但没有:

codex websockets: upstream connected ... url=wss://...

说明大概率只是:

Codex ---ws---> CPA

还没有实现:

CPA ---wss---> OpenAI

这时继续检查 CPA 当前选中的 Codex auth 文件是否有:

"websockets": true

误区 3:被本机代理环境变量干扰

有时环境里设置了:

HTTP_PROXY
HTTPS_PROXY
http_proxy
https_proxy

NO_PROXY 没包含本地地址,导致 ws://127.0.0.1:8317 也被拿去走外部代理。

典型报错可能是:

HTTP CONNECT failed with status 504
Proxy URL scheme not supported

临时验证时可以设置:

macOS / Linux:

NO_PROXY=127.0.0.1,localhost no_proxy=127.0.0.1,localhost codex doctor

Windows PowerShell:

$env:NO_PROXY = "127.0.0.1,localhost"
$env:no_proxy = "127.0.0.1,localhost"
codex doctor

如果这样就恢复 HTTP 101 Switching Protocols,说明本地代理绕过规则需要补齐。

误区 4:cc-switch 端口能监听但不支持 WebSocket 路由

有些情况下 Codex provider 指向了 cc-switch.exe 暴露的端口,例如:

ws://127.0.0.1:15721/v1/...

codex doctor 可能显示:

supports websockets true
Responses WebSocket failed
HTTP 405 Method Not Allowed

这说明:

  • Codex 端已经尝试 WebSocket。
  • 配置也认为 provider 支持 WebSocket。
  • 但本地 cc-switch / COA 的 /v1/... WebSocket 路由没有正确接住。
  • 实际请求会 fallback 到 HTTPS/SSE,仍可能卡在"正在思考"。

实践建议:如果你的目标只是让 Codex 通过 CPA 访问上游,并且 CPA 已经能提供 http://127.0.0.1:8317/v1 这类 OpenAI-compatible provider,那么可以先关掉 cc-switch,让 Codex 直接指向 CPA。这样链路更短,排查也更清楚。除非你明确依赖 cc-switch 做模型切换或其他额外能力,否则它在这条 WebSocket 修复链路里通常不是必需层。

排查方向:

  1. 确认 Codex provider 是否应该指向 CPA,而不是 cc-switch 临时端口。
  2. 确认 base_url 是否为 CPA 端口,例如 http://127.0.0.1:8317/v1
  3. Get-NetTCPConnection / lsof 查监听进程,确认端口背后到底是谁。
  4. 如果必须经过 cc-switch,确认该版本是否支持 Codex Responses WebSocket 路由。

Windows 查看监听进程示例:

Get-NetTCPConnection -LocalPort 8317 | Select-Object LocalAddress,LocalPort,State,OwningProcess
Get-CimInstance Win32_Process | Where-Object { $_.ProcessId -eq <PID> } | Select-Object ProcessId,Name,CommandLine

macOS 查看监听进程示例:

lsof -nP -iTCP:8317 -sTCP:LISTEN

Windows 实测参考

以下是一组 Windows 上验证成功的关键点,路径仅作示例:

Codex 配置:

[model_providers.cliproxyapi]
name = "cliproxyapi"
base_url = "http://127.0.0.1:8317/v1"
supports_websockets = true
wire_api = "responses"

CPA 进程:

<CPA_RUNTIME_DIR>\cli-proxy-api.exe

CPA 配置:

<CPA_RUNTIME_DIR>\config.yaml

CPA auth 目录:

<CPA_RUNTIME_DIR>\auth\

CPA 日志:

<CPA_RUNTIME_DIR>\auth\logs\main.log

成功日志关键行:

responses websocket: client connected ... remote=127.0.0.1
Use OAuth provider=codex auth_file=codex-...-plus.json for model gpt-5.5
codex websockets: upstream connected ... url=wss://chatgpt.com/backend-api/codex/responses

成功后 codex doctor 关键行:

websocket connected (HTTP 101 Switching Protocols)
supports websockets true
endpoint ws://127.0.0.1:8317/v1/<redacted>

快速判断表

现象 含义 下一步 websocket connected (HTTP 101) Codex 到 CPA 已经是 WS 继续看 CPA 日志确认上游 WSS CPA Manager 显示 GET /v1/responses 下游大概率已走 WS upgrade 路由 继续看 main.log 确认上游 WSS responses websocket: client connected CPA 收到了下游 WS 继续找 upstream connected codex websockets: upstream connected ... wss://... CPA 到 OpenAI 已经是 WSS 全程 WebSocket 成功 HTTP 405 Method Not Allowed 本地服务没接住 WS 路由 检查端口背后是不是 cc-switch/旧 COA HTTP CONNECT failed 504 本地 WS 被错误送去代理 设置 NO_PROXY=127.0.0.1,localhost POST /v1/responses + Accept: text/event-stream 可能仍在 HTTP/SSE fallback 检查 Codex provider 与 CPA auth

最终检查清单

  • Codex provider 下有 supports_websockets = true
  • Codex provider 的 base_url 指向 CPA,而不是不支持 WS 的中间服务。
  • CPA 当前使用的 Codex auth JSON 顶层有 "websockets": true
  • codex doctor 显示 HTTP 101 Switching Protocols
  • CPA main.log 显示 responses websocket: client connected
  • CPA main.log 显示 codex websockets: upstream connected ... url=wss://chatgpt.com/backend-api/codex/responses
  • 验证完成后关闭 debugrequest-loglogging-to-file

4 个帖子 - 4 位参与者

阅读完整话题

来源: LinuxDo 最新话题查看原文