反代后的 OpenCode 为什么比 Codex 慢这么多?性能差异深度解析
最近在圈子里看到个挺有意思的技术吐槽,说是自己弄的 Pro 20x 反代服务,在不同平台上表现天差地别。
图中展示了 Pro 20x 反代服务在 OpenCode(流式)和 Codex(WS)下的速度差异,OpenCode 处理一个请求时,Codex 已完成三个。
事情是这样的:同一个反代源,在 OpenCode 里用流式(Stream)调用,慢得令人发指;而切到 Codex 用 WebSocket(WS)调用,速度快得飞起。肉眼可见的速度差异是——OpenCode 还在吭哧吭哧跑完第一个请求,Codex 那边三个请求都已经处理完了。
这种“同源不同命”的情况,很容易让人怀疑是不是反代配置跪了,或者是某个平台在偷偷限速。今天咱们就抛开焦虑,纯技术角度聊聊,这中间到底是哪个环节掉链子了,以及遇到这种情况该怎么排查。
一、别急着怪反代,先看协议差异
首先,很多人遇到速度问题第一反应是“是不是我的 Nginx/Caddy 配置不对?”或者是“上游是不是抽风了?”。但在这个案例里,既然 Codex 跑得飞快,说明你的反代节点本身和上游源大概率是没问题的。
核心差别在于调用方式:流式传输 vs WebSocket。
- OpenCode(流式/HTTP SSE): 普通的流式请求通常是基于 HTTP 长连接或者 SSE(Server-Sent Events)。这种方式虽然能逐字输出,但在高并发或网络环境复杂时,TCP 握手、HTTP 头部的开销以及缓冲策略,都可能引入额外的延迟。如果 OpenCode 的后端在实现流式输出时缓冲区设置得比较大(比如积攒了一定字节数才发一次),那你感知到的“首字延迟”和“整体卡顿”就会非常明显。
- Codex(WebSocket): WS 是全双工通信,握手一次之后,数据通道就彻底打通了。它的帧结构更轻量,而且没有 HTTP 那些繁琐的头部开销。对于这种需要频繁、实时交互的场景,WebSocket 的底层效率天生就比 HTTP 流式要高。
结论: 并不是 Codex 神奇,而是 WebSocket 协议在这种实时性要求极高的场景下,确实比 HTTP 流式更有优势。
二、反代配置的“隐形杀手”
虽然协议差异是主要原因,但如果你发现慢得离谱(比如几十倍的差距),那就得检查一下反代的配置细节了。很多默认配置在本地跑得欢,一上公网反代就拉胯。
这里有几个常见的坑,大家可以对号入座:
-
缓冲区设置过大: 如果你在 Nginx 里用了
proxy_buffering on;并且没有针对流式接口做特殊处理,Nginx 可能会先把上游的数据攒够了再一股脑发给客户端。这直接导致“看起来没有任何输出,然后突然一段一段蹦出来”。- 解决思路: 针对流式接口路径,强制关闭缓冲:
location /your-stream-endpoint { proxy_buffering off; proxy_cache off; # ... 其他配置 }
- 解决思路: 针对流式接口路径,强制关闭缓冲:
-
gzip 压缩的副作用: 反代开启了 gzip,上游是小数据包流式吐出来,反代为了压缩,得等数据攒够了才能开始压。这又引入了延迟。
- 解决思路: 针对这类实时性要求高的 API,建议在反代层关闭 gzip 压缩,或者只对静态资源开启压缩。
-
超时与 Keepalive: WebSocket 对连接的稳定性要求极高。如果你的反代(尤其是经过多层 CDN 转发时)没有正确配置
Upgrade头部,或者proxy_read_timeout设置得太短,WS 连接可能会频繁重连,但 Codex 这类客户端通常重连机制做得好,你看不出来而已。而 OpenCode 的流式接口如果遇到超时,可能会直接卡死。
三、OpenCode 特有的性能损耗
除了网络层面,OpenCode 自身的实现逻辑也值得怀疑。
有些平台为了“渲染效果”或者兼容性,会在前端做一层额外的处理。比如,为了防止 Markdown 渲染闪烁,可能会等待后端吐出完整的代码块才进行渲染。这种“前端缓冲”会给你一种后端很慢的错觉。
另外,如果 OpenCode 后端做了额外的日志记录、鉴权验证或者敏感词过滤,每一段流式数据到达时都要过一遍逻辑,那累加起来的延迟也是不可忽视的。
四、实战优化建议
既然找到了病根,咱们就得对症下药。如果你也遇到了类似的痛点,可以按这个顺序排查:
-
A/B 测试定罪源: 不要只靠肉眼观察。用
curl或者Postman直接请求你的反代接口,关掉渲染,只看纯文本的 TTFB(首字节时间)和下载速度。如果 curl 也慢,那是反代/网络的问题;如果 curl 秒速,那是 OpenCode 平台前端的问题。 -
针对流式优化 Nginx/Caddy: 确保反向代理软件知道你在处理流。
- Nginx 用户记得加
X-Accel-Buffering: no;的响应头,或者在 location 里关 buffer。 - Caddy 用户通常不需要额外配置,但如果用了 CDN 回源,检查 CDN 是否开启了边缘缓存。
- Nginx 用户记得加
-
检查 CDN 节点: 很多人图省事,反代前面套了一层 Cloudflare 免费版。CF 的免费版有时候会把 WebSocket 连接当成普通 HTTP 处理,或者在某些节点上对流式转发做了优化策略变更。尝试找个 IP 直连你的反代,看看是不是 CDN 的锅。
-
拥抱 WebSocket: 如果你的业务允许,尽量优先使用支持 WebSocket 的客户端(如 Codex)。对于 AI 对话这种场景,WS 的低延迟体验是 HTTP 流式很难比拟的。
写在最后
技术圈里,“慢”永远不是单一因素造成的。在这个案例里,协议特性的差异是底色,而反代缓冲策略和平台前端处理则是加剧差异的催化剂。
别因为一次卡顿就否定自己的搭建成果,多一层抓包,多看一眼日志,往往就能找到那个让你提速 10 倍的配置项。希望这篇排查思路能帮你把这个“慢吞吞”的 OpenCode 拯救回来,或者至少让你在换用 Codex 时更加理直气壮。
评论已关闭