file /usr/bin/chatgpt——整个故事从这条命令开始。装好 OpenAI 官方的 Linux 版 ChatGPT,随手查主程序,返回的是符号链接,目标 ../lib/chatgpt/codex-launcher,启动器名字里就藏着 codex。把包拆开看,1.5GB 的「ChatGPT」另有真名。
拆解方法先说清:对象是官方 deb(chatgpt 26.924.22138,Linux x64),只做静态检查,不碰混淆代码;每条结论都能在包内元数据、进程列表或目录结构里找到对应实物,动手即可复核。
包内的两份「身份证」
第一份在 app.asar 的 package.json 里:
{
"name": "openai-codex-electron",
"productName": "Codex",
"description": "Codex",
"author": "OpenAI",
"main": ".vite/build/early-bootstrap.js"
}
第二份更实锤,owl-electron-app.json:
{
"packagedFrom": "/home/runner/work/openai/openai/codex/codex-apps/electron/out/ChatGPT-linux-x64",
"runtimeName": "owl"
}
两份文件指向同一个源头:CI 流水线里的 openai/codex 单仓库,子目录 codex/codex-apps/electron,对外发布的名字却是 ChatGPT-linux-x64。一套代码两个招牌——对外叫 ChatGPT,对内叫 Codex,壳层代号 Owl,连 Chromium 的用户数据目录都沿用 ~/.config/Codex。
版本号有三条独立的线,后面会反复出现:应用 26.924.22138、Electron 42.3.0、内置引擎 codex-cli 0.158.0-alpha.2.1。
架构:一台壳,一个引擎
┌──────────────────────────────────────────────────────────────┐
│ deb: chatgpt 26.924.22138 (/usr/lib/chatgpt) │
│ │
│ Electron 42.3.0 壳(代号 Owl) │
│ ┌──────────────────────────┐ ┌──────────────────────────┐│
│ │ 主进程 .vite/build/* │ │ 渲染窗口 + 内嵌浏览器侧栏 ││
│ │ main 4.1MB + 服务级 chunks│◄─►│ browser-page-preload ││
│ │ app-protocol / policy │IPC│ sandbox-preload ││
│ └────────┬─────────────────┘ └──────────────────────────┘│
│ │ spawn + 原生管道 账号 / 云流量 │
│ ┌────────▼─────────────────┐ auth.openai.com │
│ │ codex(272MB Rust 静态) │ wss://codex-cloud- │
│ │ app-server 守护进程 │ backend.chatgpt.com │
│ └────────┬─────────────────┘ │
│ │ 共享 ~/.codex │
│ ┌────────▼───────────────────────────────────────────────┐ │
│ │ 组件: cua_node · code-mode-host · tectonic · rg │ │
│ │ 插件: codex-app-tools · browser · chrome · latex · … │ │
│ └─────────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────┘
主进程被拆成多个职责单一的 chunk(main、app-protocol、policy、service、startup-requirements、shell-env),工具链是 Vite 加 rolldown,外围包着 electron-forge。原生模块屈指可数:HID 拓扑监听、远程控制设备密钥,各一个小文件。外设和远程授权之外的一切都走标准 Electron 能力,原生层越薄,将来跨版本升级踩 ABI 的机会越小。
引擎不是子进程,是常驻服务
位于 resources/codex 的是一个静态链接 ELF,识别出来就是 Codex CLI 本尊。--help 一跑便知,半数子命令天生是给宿主应用当接口用的:app-server(下挂 daemon、proxy、generate-ts),加上 agents、remote-control、queue、resume、apply,全是集成向的入口。
真正的要点在运行形态:codex 不是被临时拉起、用完即弃的子进程,而是以 app-server 守护进程的身份一直活着。主进程源码里 codexHome 出现了 248 次,控制通道是 ~/.codex/ipc/ipc.sock 这个 Unix socket。想通了这层,产品形态就豁然开朗——终端 CLI 和桌面窗口共用一个 daemon,是它的两个客户端。终端里跑过的会话桌面里全能翻到;反过来,装完包跑一句 codex resume,桌面会话直接接得上。
组件清单
| 组件 | 体积 | 说明 |
|---|---|---|
codex |
272MB | Agent 引擎本体(Rust,app-server 形态) |
codex-code-mode-host |
71MB | code-mode 的执行宿主进程 |
cua_node/ |
209MB | OpenAI 定制版 Node 24.21.0-cua.1 及配套 REPL |
tectonic/ |
26MB | LaTeX 排版引擎 |
plugins/openai-bundled/ |
23MB | 七个官方内置插件 |
cua_node 单独说:这是 OpenAI 自建的 Node 分支,给 CUA(Computer Use Agent)当代码执行环境,lib/node_modules 里带着 playwright、sharp 和 @oai 模块,另配一个独立的 node_repl 静态二进制给 agent 写代码跑代码。主进程里有配套的 computer-use-native-pipe-server,审批消息走 computer-use-approval: 前缀的原生管道,单条上限 8MB——鼠标点到屏幕上之前,先过一道人工确认。
内置插件七个:codex-app-tools、browser、chrome(自带扩展宿主)、deep-research、visualize、unified-computer-use、latex。
文档能力的运行时是按需下载的
处理文档类任务时,应用会拉取 codex-primary-runtime 放到 ~/.cache/codex-runtimes/,runtime.json 把家底列得清清楚楚:
{
"bundleVersion": "26.904.11930",
"artifactToolVersion": "2.8.59",
"libreOfficeVersion": "25.2-headless-codex.1",
"nativeDependencies": ["libheif", "jxrlib", "libreoffice-headless", "poppler", "git"],
"nodeVersion": "v24.19.0",
"pythonVersion": "3.12.14"
}
至于 docx、xlsx、slides、PDF 这些格式的处理底气,来源是 LibreOffice headless 搭配 poppler。该工具链与应用主体彼此独立,受 bundle 版本管辖——缓存目录若有损坏,清空重新拉取即可,deb 本体无需重装。
数据层只有一份
要说最能暴露产品意图的一条证据,是数据层:应用没有自建私有格式,Codex CLI 的 home 目录被直接拿来当唯一的数据存放地。
~/.codex/
├── config.toml # CLI 配置 + [desktop] 段(GUI 设置写回这里)
├── auth.json # 登录凭据
├── ipc/ipc.sock # app-server Unix 控制 socket
├── sessions/ + session_index.jsonl
├── logs_2.sqlite goals_1.sqlite memories_1.sqlite queue_1.sqlite
├── skills/ plugins/ pets/ node_repl/ browser/ computer-use/
└── dictation-history/ shell_snapshots/
记忆、目标、跟进队列,各占一张 SQLite 表;GUI 偏好回写到 config.toml 的 [desktop] 段;浏览器侧栏那些东西归另一层标准 Chromium profile,也就是 ~/.config/Codex。
顺带一条安全提示:config.toml 里可以给自定义 model provider 配 experimental_bearer_token,这个 token 是明文写盘的(0600 权限)。用 BYOK 的话,把 ~/.codex 从云备份和同步盘的范围里排除掉,别给泄露留口子。
控制流是双向的
GUI 这条线的走法:主进程负责把 app-server daemon 唤起,线程、回合、审批等交互统统封装在 Unix socket 上的版本化协议中(例如 codexAppsMcp20260728),generate-ts 甚至能产出协议对应的 TypeScript 绑定。把第三方宿主的接入路修得如此平整,官方的用意已经写在明面上。
引擎到 GUI 的方向:内置插件 codex-app-tools(v0.1.5)把桌面应用的能力注册成 MCP 工具:
"tools": {
"automation_update": { "approval_mode": "prompt" },
"create_thread": { "approval_mode": "prompt" },
"send_message_to_thread": { "approval_mode": "prompt" },
"fork_thread": { "approval_mode": "prompt" },
"handoff_thread": { "approval_mode": "prompt" }
}
两股流合到一起,画面就完整了:agent 做任务做到一半,能自己开会话、能移交、能操作界面。桌面程序在这个体系里,只是 agent 手里众多工具中的一件。
装之前先掂量的三件事
一是磁盘。1.5GB 的 deb 加上按需拉取的运行时缓存,实际占用只会更大,装之前用 dpkg -s chatgpt 核对已装版本、du -sh /usr/lib/chatgpt 看清占地,别等磁盘告警才想起来。
二是网络。包内可见 Statsig 全家桶的实验与灰度域名(ab.chatgpt.com、api.oaistatsig.com),状态缓存在 ~/.config/Codex/statsig-state.json。企业内网部署时,这些遥测域名是放行还是阻断,得提前写进出口策略——阻断不影响核心功能,但灰度特性会拿不到。
三是账号边界。账号与支付走 auth.openai.com、pay.openai.com,云端任务同步走 wss://codex-cloud-backend.chatgpt.com,本地与 chatgpt.com/codex 之间还能通过 <codex_delegation> 标签互相委托任务。个人用顺手,企业用就得先想清楚哪些任务允许出本地。
给自研团队的借鉴
行业惯性是把引擎塞进应用里,OpenAI 偏偏倒过来做:引擎独立为系统级常驻服务,应用退居客户端之一。这笔交易换回三样好处——会话与凭据在 CLI、桌面乃至将来的 IDE 插件之间天然通用,「从哪开始、到哪继续」不再是问题;Rust 引擎同 Electron 壳完全解耦,三条版本线互不牵制;审批与安全模型统一收口在 daemon 层,外层随便换皮,闸门纹丝不动。
代价也摆在明面上:1.5GB 的安装体积(其中引擎、CUA、文档运行时合计约 600MB),加上桌面与 CLI 之间的兼容完全押在 bundle 协议和版本协商上。抄这套架构之前,先确认自己的用户接得住这个体积。
收尾送个彩蛋:翻目录时在 ~/.codex 下撞见 pets/,对应的内置技能名叫 hatch-pet——一本正经的 1.5GB 工程包里,居然藏着一只等你来孵的电子宠物。

评论0