拆开ChatGPT的Linux桌面壳:272MB Rust二进制与两条控制通道

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

评论0

请先
显示验证码
没有账号?注册  忘记密码?