Codex 的账号、模型请求和聊天记录是三套相互关联、但并不等价的状态。很多看似随机的 401、压缩失败或“历史消失”,其实都来自把它们当成了同一件事。
先建立正确的心智模型
| 名称 | 保存位置 | 实际作用 |
|---|---|---|
| OcHub 连接 ID | OcHub 数据库 | 标识一张连接卡片;内部可以继续使用 UUID |
| Codex Provider ID | config.toml 的 model_provider |
选择 [model_providers.<id>],也是 Codex 会话历史的 Provider 分桶 |
| Codex Provider 名称 | [model_providers.<id>].name |
Provider 显示/能力兼容字段;不是历史分桶 |
| ChatGPT 登录 | auth.json 或系统凭据存储 |
保存并刷新 ChatGPT 登录凭据 |
| 模型供应商访问密钥 | 当前 Provider 的认证字段 | 认证发往第三方或 OcHub 本地网关的模型请求 |
因此,修改 OcHub 卡片名称不会迁移聊天记录;修改 model_provider 则可能让旧会话落在另一个
分桶里。OcHub 会把内部连接 UUID 与 Codex Provider ID 分开,新建模型供应商连接默认使用
稳定的 custom,也允许你改成 company_proxy 等明确名称。
同时保留 ChatGPT 登录并走模型供应商
这个模式适合你仍需要 ChatGPT 登录状态,但希望模型推理由第三方 Responses API 或 OcHub 模型供应商承担的场景。
-
先完成 ChatGPT 登录。 在 Codex 中登录,确认账号连接能单独工作。登录凭据可能保存在
~/.codex/auth.json,也可能由系统钥匙串保存。 -
把登录状态保存为连接版本。 保持官方连接为当前连接并切换到其他连接;OcHub 显示
auth.json和config.toml差异时,选择“保存为新版”。 -
新建 Codex 连接并选择“模型供应商”。 选择已经配置好的模型供应商与客户端模型。
-
设置稳定的 Provider ID。 例如
company_proxy。这是聊天记录分桶,不是 OcHub 的 内部连接 ID。 -
选择“ChatGPT 登录 + 第三方 API”。 OcHub 会把登录材料纳入这个连接版本,同时给 本地网关写入独立的客户端密钥。
-
检查预览。
model_provider应是你选择的稳定 ID;base_url应指向 OcHub 本地网关; Provider 中应同时保留 OpenAI 登录要求和网关 bearer token。 -
保存、切换并重开 Codex。 先发一条短请求,再到“用量 → 请求日志”核对请求是否经过
gateway。
典型的生成结果类似下面这样;密钥由 OcHub 生成,不要手工复制到其他机器:
model_provider = "company_proxy"
[model_providers.company_proxy]
name = "Company Proxy"
base_url = "http://127.0.0.1:4180/v1"
wire_api = "responses"
requires_openai_auth = true
experimental_bearer_token = "rd-..."这里有两条独立的认证链:
- ChatGPT 登录仍由 Codex 的登录缓存负责。
- 模型请求到 OcHub 网关时使用
rd-...;网关再使用模型供应商自己的上游密钥。
仅仅保留 auth.json 不会让第三方 API 自动接受 ChatGPT OAuth。反过来,只有网关密钥也
不等于已经登录 ChatGPT。
使用原生 Fast 与 Ultra 启动 Codex
在 macOS 上打开 OcHub 本机的 Codex 应用页面,点击启动 Codex。OcHub 会启动一个 独立的桌面实例,让兼容模型可以直接在 Codex 原生模型选择器中显示并选择 Fast 与 Ultra。 当模型请求经过自定义模型供应商,而 Codex 原本会因账号权益检查隐藏或清除这些选项时, 可以使用这种启动方式。
这个启动器确实会执行内存中的 JavaScript 注入。它开启一个仅监听本机回环地址的 Chrome
DevTools Protocol 端点,在 renderer 的首个应用脚本运行前自动附加,并拦截
app-initial-*.js。补丁解除原生选择器对 Fast、Ultra 的 ChatGPT 账号门禁,同时阻止 Codex
在 thread/start 或 turn/start 前清除已经选择的 Fast service tier。模型选择器、React
组件、设置存储和请求格式仍然全部使用 Codex 自己的实现;已安装的 App 不会被修改或重新签名。
-
配置并切换 Codex 连接。 选择直连或模型供应商,并确保面向客户端的模型使用下表中的 精确模型 ID。
-
打开本机 Codex 页面。 远程节点和非 macOS 版本不会显示这个启动功能。
-
点击“启动 Codex”。 OcHub 会在
/Applications或~/Applications中查找Codex.app或ChatGPT.app,启动独立实例,完成首屏注入后再提示成功。 -
使用输入框下方的原生选择器。 在 Codex 内选择模型、推理强度和 Fast 模式。
-
发送一条短请求并检查“用量 → 请求日志”。 在投入重要工作前,确认模型和上游接受了 所选模式。
当前由 OcHub 生成的模型目录只对精确模型 ID 添加能力:
| 模型 ID | Fast | Max | Ultra |
|---|---|---|---|
gpt-5.6-sol |
支持 | 支持 | 支持 |
gpt-5.6-terra |
支持 | 支持 | 支持 |
gpt-5.6-luna |
支持 | 支持 | 不支持 |
未知模型或名称相似的第三方模型不会自动继承这些能力。若 Codex 已经为精确模型提供目录条目, OcHub 会保留该条目自身的能力元数据。
注入只对 OcHub 启动的实例有效。保持 OcHub 运行,后续新建的 renderer 才能继续被处理;退出
Codex 后,需要再次从 OcHub 启动。调试监听只绑定 127.0.0.1,OcHub 也会拒绝非回环目标。
Codex 更新导致预期的 renderer 门禁结构变化时,补丁会直接停止并报告注入失败。此时请退出 所有 Codex 或 ChatGPT App 窗口,安装更新的 OcHub 版本后再试。不要反复从 Dock 打开失败的 实例,因为这样会绕过 OcHub 启动器。
压缩到底压缩了什么
长对话有两个不同概念:
- 本地 transcript:完整或近完整地保存在磁盘,用于
/resume、会话列表和审计。 - 活动上下文:下一次模型请求实际携带的历史,受模型上下文窗口限制。
/compact 压缩的是活动上下文:Codex 用一份摘要替换较早的对话,使后续请求继续保留关键
决定,又不会无限增长。它不会等价于删除本地聊天记录。Codex 也可以在达到模型默认阈值时
自动压缩;高级用户可通过 model_auto_compact_token_limit 调整触发阈值。
什么是远程压缩
普通压缩可以在客户端完成摘要。远程压缩则把 Responses 专用的压缩请求交给支持该语义的
上游处理。在 OcHub 当前实现中,这类请求包含 Responses 的 compaction_trigger,没有可靠的
Chat Completions 或 Anthropic Messages 等价物。
因此,OcHub 只在所选模型供应商至少有一个原生 Responses 上游时允许开启远程压缩:
- 模型供应商中必须启用 Responses 接口。
- 编辑 Codex 连接,选择该模型供应商。
- 在 Provider 区域开启“远程压缩”。
- 检查预览中 Provider 名称是否被写为精确的
OpenAI。 - 重开 Codex,在长对话中使用
/compact验证。
Provider 名称写成 OpenAI 是当前 Codex/OcHub 的能力兼容约定,不要把它与
model_provider = "openai" 混淆。前者是当前自定义 Provider 的名称;后者会选择 Codex 保留的
内建 OpenAI Provider,不能拿来定义自建转发站。
Responses WebSocket 是什么
supports_websockets = true 告诉 Codex:当前模型 Provider 支持 Responses API 的
WebSocket 传输。它可以让支持方使用持久的双向连接承载 Responses 流,而不是每次都新建普通
HTTP/SSE 请求。
这里最容易混淆的是两种完全不同的 WebSocket:
| WebSocket | 连接谁 | OcHub 中对应什么 |
|---|---|---|
| Responses WebSocket | Codex 模型客户端 ↔ 模型 Provider | supports_websockets = true |
| app-server WebSocket | 外部客户端 ↔ codex app-server |
codex --remote / app-server --listen |
OcHub 的开关是第一种,不会把 Codex CLI 变成远程 app-server。
什么时候开启 WebSocket
只有同时满足这些条件才开启:
- 上游明确支持 Responses WebSocket,而不只是 HTTP streaming。
- 模型供应商中的 Responses 接口已经启用 WebSocket 能力。
- 网络代理、TLS 终止层和企业 CA 允许
wss://握手与长连接。 - 普通 Responses 请求已经验证成功。
在模型供应商编辑器中开启 WebSocket 后,OcHub 会把能力传递给 Codex 连接。检查
config.toml 预览:
[model_providers.company_proxy]
wire_api = "responses"
supports_websockets = trueWebSocket 可能减少重复连接开销,并更适合持续事件流,但不保证任何上游都更快。若握手失败、 连接频繁断开或企业代理只支持普通 HTTPS,请关闭它并使用 HTTP/SSE。不要用这个开关修复模型 不支持、鉴权错误或 Base URL 错误。
聊天记录保存在哪里
官方 Codex 行为是把可恢复的会话 transcript 保存在本机。当前版本通常在
$CODEX_HOME(默认 ~/.codex)下使用:
sessions/:活动会话的 rollout JSONL。archived_sessions/:归档但仍可恢复的会话。state_5.sqlite:线程列表、索引和 Provider 分桶等状态。
这些是当前实现细节,未来 Codex 可能调整文件名或布局。优先使用 /resume、/archive、
codex unarchive 和 OcHub 的会话管理,不要在 Codex 运行时手工批量改文件。
auth.json 不是聊天记录;它包含敏感登录凭据,应像密码一样保护,不要提交到 Git、粘贴到
工单或公开聊天。
Provider ID 为什么会影响历史
Codex 会在会话 session_meta 和线程索引中记录 model_provider。这让它可以区分官方
openai、共享 custom 和其他自定义 Provider,但也意味着修改 Provider ID 会改变会话所属
分桶。
实用规则:
- 只更换上游 URL、模型或 API Key:保留 Provider ID。
- 希望多个第三方连接共享历史:给它们使用同一个稳定 ID,例如
custom。 - 希望不同团队/环境隔离历史:使用不同 ID,例如
team_proxy、personal_proxy。 - 从旧 UUID ID 改成语义化 ID:先退出 Codex,再通过 OcHub 保存,让迁移逻辑处理 JSONL 与 SQLite,并保留备份。
/archive只归档,会话仍在本机;/delete会永久删除当前会话及其派生子会话。
一份排障顺序
遇到组合模式、压缩或 WebSocket 问题时,按层排查:
- 登录层:Codex 是否仍显示已登录?凭据保存在文件还是钥匙串?
- Provider 层:
model_provider是否指向实际存在的[model_providers.<id>]? - 网关层:Base URL 是否是 OcHub 本地地址,
rd-...客户端密钥是否由当前连接生成? - 普通请求层:先关闭远程压缩和 WebSocket,验证一条普通 Responses 请求。
- WebSocket 层:确认上游与网络链路都支持后再开启。
- 压缩层:最后开启远程压缩,并在长对话中单独验证
/compact。 - 历史层:若
/resume列表变化,核对CODEX_HOME与 Provider ID,不要先删除文件。
官方参考与 OcHub 实现说明
- OpenAI Codex 配置参考
定义了
model_provider、requires_openai_auth、supports_websockets和自动压缩阈值。 - OpenAI Codex 认证与会话说明登录缓存和凭据存储。
- OpenAI Codex CLI 命令
说明
/compact、/resume、/archive和/delete。 - OpenAI Codex 模型选择说明模型、推理、Max 与 Ultra。
- OpenAI Codex 速度指南 区分 ChatGPT Fast 模式与 API Priority processing。
- “Provider 名称触发远程压缩”、Responses-only 路由保护、原生选择器注入、UUID 历史迁移和 具体文件扫描范围是 OcHub 针对当前 Codex 行为实现的兼容层,不是 OpenAI 承诺的永久协议。

