macOS 实测:Codex 桌面版双开,官方账号与第三方 API 独立使用

日常使用 Codex 时,我遇到了一个需求:保留官方账号登录的桌面版,同时再开一个接入第三方 API 的 Codex,两边的配置、登录凭据和任务记录分别保存。

一开始想到的是复制应用、改个名字。但实际排查后发现,关键在于启动时指定独立的数据目录。本文记录一次 macOS 上的实际配置过程,包括启动入口、API 配置、验证和错误排查。

验证环境:macOS,应用版本 26.908.40834,本机应用路径为 /Applications/ChatGPT.app,使用其中的 Codex 功能。本文方案依赖该版本的桌面启动实现,后续版本升级后建议重新验证。第三方接口仅作为配置示例,不代表官方支持或服务推荐。

一、最终实现了什么

配置完成后,保留原来的官方应用,新增一个"Codex 代理版"启动入口。

项目 官方版 代理版
启动入口 原来的 ChatGPT/Codex 应用 Codex 代理版.app
模型认证 原有官方账号登录 第三方 API Key
Codex 配置与本地状态 原来的 ~/.codex ~/.codex-proxy
桌面应用数据 原来的默认目录 ~/Library/Application Support/Codex-Proxy
程序文件 已安装的官方应用 复用同一份官方应用

这里创建的是两个独立运行的实例和两个启动入口,程序本体仍然只有一份。因此无需复制整个应用,也无需修改官方应用的签名或内部代码。

这个方案隔离的是本地配置、凭据和应用状态。两个实例仍然运行在同一个 macOS 用户下,可以访问相同的项目文件。如果它们同时修改同一个仓库,仍可能产生文件冲突;需要并行开发时,可以分别使用独立工作目录或 Git worktree。

二、为什么只复制 App 或传一个参数不够

Codex 的配置和本地状态默认保存在 ~/.codex。如果两个实例都使用这个目录,即使应用名称不同,也可能读取同一份模型配置和登录信息。

本次排查还遇到了一个旧启动脚本,它只传了:

bash 复制代码
--user-data-dir="$HOME/.codex-proxy"

这个参数没有明确隔离 Codex 自身的配置目录。而且在本次验证版本中,桌面程序会在启动时设置自己的 Electron userData 路径,因此不能只靠这个参数判断隔离成功。

实际使用的关键设置是:

设置 作用
CODEX_HOME 指定 Codex 配置、文件凭据和本地状态目录
CODEX_ELECTRON_USER_DATA_PATH 指定当前版本的桌面应用数据目录
open -n 请求启动一个新的应用实例
--user-data-dir 与上述桌面数据目录保持一致的启动参数

官方文档说明了 CODEX_HOME 的作用。CODEX_ELECTRON_USER_DATA_PATH 则是本次检查已安装应用代码时确认的实现入口,不应当把它视为永久稳定的公开接口。

在当前版本中,还能看到程序在显式指定桌面数据目录时保留传入的 CODEX_HOME,避免加载登录 Shell 环境后丢失这个设置。

三、创建独立的代理配置目录

以下命令以首次配置为例。如果目录中已经有配置,先备份,并按现有内容合并,不要直接覆盖。

bash 复制代码
mkdir -p "$HOME/.codex-proxy"
mkdir -p "$HOME/Library/Application Support/Codex-Proxy"

chmod 700 "$HOME/.codex-proxy"
chmod 700 "$HOME/Library/Application Support/Codex-Proxy"

代理版的配置文件为:

text 复制代码
~/.codex-proxy/config.toml

首次创建可以执行:

bash 复制代码
cat > "$HOME/.codex-proxy/config.toml" <<'EOF'
model_provider = "aicoding"
model = "gpt-5.5"
model_reasoning_effort = "high"
cli_auth_credentials_store = "file"

[model_providers.aicoding]
name = "AI Proxy"
base_url = "https://aicoding.com/v1"
wire_api = "responses"
requires_openai_auth = true
EOF

chmod 600 "$HOME/.codex-proxy/config.toml"

这里有几个容易混淆的地方:

  • model_provider 必须与下面 [model_providers.aicoding] 的标识一致。
  • base_url 是 API 服务地址,本例最终请求的是 /v1/responses
  • wire_api = "responses" 要求服务商兼容 Responses API,不能仅凭"兼容 OpenAI"几个字判断兼容性。
  • cli_auth_credentials_store = "file" 明确使用文件凭据,代理 Key 保存在独立目录内。
  • requires_openai_auth = true 沿用服务商的认证配置,在本例中使用 auth.json 中的 API Key,不需要复制官方账号的登录令牌。

模型名称应按自己的服务商和 Key 权限设置。本次最终使用 gpt-5.5,原因是它实际调用成功;这不代表所有账号、分组或时间段都支持该模型。

四、在本地输入 API Key

API Key 写入:

text 复制代码
~/.codex-proxy/auth.json

文件结构如下,示例不含真实密钥:

json 复制代码
{
  "OPENAI_API_KEY": "YOUR_API_KEY"
}

为了避免将 Key 直接写进 Shell 命令历史,可以在终端通过 Python 的隐藏输入保存。需要本机已安装 Python 3。

bash 复制代码
python3 - <<'PY'
import getpass
import json
import os
import tempfile
from pathlib import Path

profile = Path.home() / ".codex-proxy"
profile.mkdir(mode=0o700, exist_ok=True)

key = getpass.getpass("请输入代理 API Key(输入不显示): ").strip()
if not key:
    raise SystemExit("未输入 Key,配置未修改。")

fd, temporary = tempfile.mkstemp(dir=profile)
with os.fdopen(fd, "w") as file:
    json.dump({"OPENAI_API_KEY": key}, file)

os.chmod(temporary, 0o600)
os.replace(temporary, profile / "auth.json")
print("已保存到代理版独立目录。")
PY

这个步骤只负责保存,还没有验证 Key 是否有效。不要把真实 Key 放进博客正文、截图或代码仓库,也不要将官方版的整个 auth.json 复制过来。

五、启动第二个 Codex 实例

确认应用实际安装路径后,在终端执行:

bash 复制代码
/usr/bin/open -n \
  --env "CODEX_HOME=$HOME/.codex-proxy" \
  --env "CODEX_ELECTRON_USER_DATA_PATH=$HOME/Library/Application Support/Codex-Proxy" \
  /Applications/ChatGPT.app \
  --args \
  "--user-data-dir=$HOME/Library/Application Support/Codex-Proxy"

如果你的应用叫 Codex.app,将命令中的应用路径换成实际路径。旧版本是否支持同样的环境变量,需要单独验证。

这里的环境变量只传给新启动的应用,不需要写入 .zshrc,也不需要修改系统全局环境。官方版继续从原入口启动。

六、做成可以双击的桌面入口

每次复制终端命令不够方便,可以用 macOS 自带的"脚本编辑器"创建启动应用。

打开"脚本编辑器",粘贴以下 AppleScript:

applescript 复制代码
on run
    set userHome to POSIX path of (path to home folder)
    set profilePath to userHome & ".codex-proxy"
    set desktopDataPath to userHome & "Library/Application Support/Codex-Proxy"
    set appPath to "/Applications/ChatGPT.app"

    set launchCommand to "/usr/bin/open -n --env " & ¬
        quoted form of ("CODEX_HOME=" & profilePath) & ¬
        " --env " & quoted form of ("CODEX_ELECTRON_USER_DATA_PATH=" & desktopDataPath) & ¬
        " " & quoted form of appPath & ¬
        " --args " & quoted form of ("--user-data-dir=" & desktopDataPath)

    do shell script launchCommand
end run

选择"文件 → 导出":

  1. 文件格式选择"应用程序"。
  2. 名称填写"Codex 代理版"。
  3. 保存到"应用程序"目录或自己的 ~/Applications 目录。

以后通过这个入口打开代理版。它是一个启动器,启动后实际运行的仍是官方程序,因此运行窗口、菜单或 Dock 图标可能仍显示官方应用名称。不要只根据窗口外观判断当前使用的是哪套配置。

重复点击启动入口是否复用窗口,取决于应用版本的单实例处理;建议先确认代理版是否已经运行。

七、怎么验证隔离真的生效

1. 检查两个主进程

在终端执行:

bash 复制代码
ps -axo pid=,command= | grep '[C]hatGPT.app/Contents/MacOS/ChatGPT'

本次实测可以看到两个主进程:原来的官方进程,以及带有以下参数的代理进程:

text 复制代码
--user-data-dir=.../Library/Application Support/Codex-Proxy

进程存在只能证明启动成功,还需要继续验证目录和接口。

2. 检查独立目录

代理版启动后,~/.codex-proxy 中会生成数据库、缓存和其他本地状态文件;桌面数据则写入指定的 Codex-Proxy 目录。

本次配置过程中,还比较了官方 config.tomlauth.json 修改前后的 SHA-256,确认它们没有被本次操作改变。

需要注意:应用正常运行时也可能刷新认证文件,因此未来校验值变化本身不能直接证明发生了串用,应结合时间和实际修改内容判断。

3. 验证代理模型调用

在代理版中新建任务,选择配置好的模型,发送一条简单测试消息,例如:

text 复制代码
请只回复 OK。

如果失败,重点看请求地址、HTTP 状态和错误正文。请求确实到达代理域名、认证通过、模型完整返回结果,是不同层次的验证。

本次通过独立的最小 Responses API 请求,观察到 gpt-5.5 返回 OK,并收到 response.completed 事件。随后保存配置并重新启动了代理版。

如需重启,请退出对应的代理实例,而不是只关闭窗口;关闭窗口可能仍保留后台进程。不要使用 killall ChatGPT,它可能把官方版一起退出。

八、这次遇到的两个错误

401 Unauthorized:INVALID_API_KEY

最初复用本机已有的代理 Key,服务端返回:

json 复制代码
{
  "code": "INVALID_API_KEY",
  "message": "Invalid API key"
}

这说明该次请求已到达代理服务,但服务端不接受提交的凭据。排查时应确认:

  • Key 是否完整、有效,是否被撤销。
  • Key 是否属于当前接口服务。
  • 分组是否用于 Codex/GPT,而不是其他客户端或产品。
  • 应用是否仍使用缓存中的旧凭据,或启动到了另一套配置目录。

本次更换 Key 后错误发生变化,后续使用 gpt-5.5 成功返回结果,说明新 Key 能用于这条已验证的调用路径。

Key 更新后,gpt-5.4 返回上游错误

新 Key 调用 gpt-5.4 时,代理返回了 upstream_error。错误文字还提到了与请求模型不一致的其他模型名。

这类信息不能简单理解成"客户端填写的模型一定错误"。也可能涉及服务商路由、上游可用性或参数兼容问题。

本次改用 gpt-5.5 后成功,所以将它设为默认模型。这里只能得出"当次测试成功"的结论,不能据此断言 gpt-5.4 永久不可用。

九、实测结论与边界

本次已经确认:

  • 两个 Codex 桌面进程可以同时运行。
  • 代理实例使用独立的 Codex 状态目录和桌面数据目录。
  • 官方配置和登录文件没有被本次操作修改。
  • 代理 Key 与 gpt-5.5 的最小 Responses API 调用成功。

本次未通过自动化工具完成代理桌面内的完整对话操作验证:电脑控制工具禁止读取 Codex 自身界面。因此,进程、目录隔离和 API 验证已经完成,实际桌面交互仍应按前面的步骤手动确认。也没有验证所有插件、系统权限和全局快捷键在双实例下的行为。

官方程序升级后,两个入口会共同使用升级后的程序文件。由于本方案包含版本相关的桌面启动设置,升级后应再次检查双实例启动、独立目录和代理调用。

相关推荐
全栈弄潮儿1 小时前
周复盘:这一周最值得保存的 7 条 AI 编程原则
aigc·openai·ai编程
m0_734571761 小时前
深入理解人工智能 chatGPT 核心协调与调度层 (Core Orchestration Layer)
人工智能·chatgpt
VIP_CQCRE1 小时前
在 OpenCode IDE 里接入 Ace Data Cloud:把多模型 AI 能力带进开发工作流
大模型·ai编程·开发工具·opencode·ace data cloud
楚国的小隐士9 小时前
在生产环境中和AI协作编程
ai·大模型·编程·软件工程·ai编程·软件架构
wangruofeng10 小时前
一个 Markdown 文件攒下 37k 星,i-have-adhd 给 AI 输出立了 10 条规矩
github·aigc·ai编程
全栈弄潮儿12 小时前
需求不清时,如何让 AI 帮你补全问题,而不是瞎写代码
aigc·openai·ai编程
一航jason13 小时前
Android平台推理框架及试用场景模型对比
android·人工智能·ai·架构·ai编程·llama
一航jason13 小时前
Android 端侧大模型推理框架对比
android·人工智能·ai·ai编程·llama·ai-native