Codex CLI 是什么 · 开源的是哪一部分

Codex CLI 是 OpenAI 在你本机运行的编码 agent,仓库 openai/codex 以 Apache-2.0 开源。开源的是本地这一侧:Rust 写的 CLI、TUI、app-server、agent 内核、工具与三套沙箱,外加 npm 启动器和 TypeScript、Python 两个 SDK;模型、ChatGPT 后端、IDE 扩展与桌面应用都不在仓库里。npm 包里的 codex.js 只是一个挑平台二进制、转发信号的启动器。

作者 David更新于 第 1 篇(共 57 篇)

Codex CLI 是什么 · 开源的是哪一部分

仓库根目录 README.md 的第一句是:Codex CLI is a coding agent from OpenAI that runs locally on your computer——OpenAI 出品、在你本机运行的编码 agent。它读你的代码、改文件、跑命令、调 MCP 工具:模型推理在云端,这些动作都在你的机器上执行。

本专栏读的就是这份代码:github.com/openai/codex,Apache-2.0 许可,2025-04-13 建仓,基准 tag rust-v0.158.0(版本、commit 与统计口径见专栏封面)。这一篇先回答两个问题:这个仓库里到底有什么,没有什么。

先看它怎么用

README.md 给了四种安装方式:官方安装脚本(install.sh、install.ps1)、npm 包 @openai/codex、Homebrew 的 codex cask,以及 GitHub Release 里的单文件二进制(Linux 版用 musl 目标构建,文件名形如 codex-x86_64-unknown-linux-musl)。装好之后:

  • 直接敲 codex,进入全屏终端界面(TUI),也就是日常用的交互模式;
  • codex exec "..." 非交互地跑完一个任务,适合脚本和 CI;
  • codex app-server 把同一套 agent 以 JSON-RPC 服务的形式开放出去,IDE 扩展、Python SDK 等都通过它接入。

codex-rs/cli/src/main.rs:143 的 Subcommand 枚举一共 30 个变体,其中 4 个标了 hide = true(tcp-tunnel、execpolicy、responses-api-proxy、stdio-to-uds),属于内部工具。各命令的用法、登录方式与配置,见《Codex 中文手册》的安装、登录与升级和启动命令行选项,这里不重复。

仓库里有什么

git 跟踪的 8,670 个文件里,8,145 个在 codex-rs/ 下。顶层目录的分工如下:

目录内容
codex-rs/Rust Cargo workspace,members 共 153 个:CLI、TUI、app-server、内核 codex-core、工具、沙箱、MCP、登录、持久化……发布出去的 codex 二进制全部出自这里
codex-cli/npm 包 @openai/codex 的外壳,运行时只有 bin/codex.js 一个文件,另有打包脚本
sdk/typescript/@openai/codex-sdk:启动 codex exec --experimental-json,经 stdin、stdout 交换 JSONL 事件
sdk/python/openai-codex:以 codex app-server --listen stdio:// 启动子进程,走 JSON-RPC
sdk/python-runtime/openai-codex-cli-bin:给 Python SDK 带上对应平台的 Codex 二进制,只发 wheel
docs/多数页面只剩一句指向 developers.openai.com 的链接,install.md、contributing.md 等少数几篇有正文
MODULE.bazel、defs.bzl、bazel/、patches/Bazel 构建(下一篇细讲)
scripts/、.github/打包发布脚本与 CI 工作流
.codex/skills/仓库自带的 Codex skills:代码审查、PR 描述、远程测试等,供在这个仓库里干活的 Codex 使用
third_party/、tools/第三方资源(v8、wezterm 等)与自有工具(argument-comment-lint、buildifier)

docs/ 几乎是空壳并非疏忽。根目录 AGENTS.md 明确要求不要往 docs/ 里写面向用户的产品文档,官方文档另有去处,唯一的例外是 app-server 的 API 文档。

NOTICE 里还有一条值得一提:仓库包含从 Ratatui(MIT 许可)派生的代码,TUI 的终端渲染就建在 ratatui 之上。

不在仓库里的

开源的是“本机这一侧”。下图把仓库内外画在一起:

图表加载中…

逐项看:

  • 模型:仓库里只有调用方。模型提供方的线协议枚举 WireApi 只剩一个变体 Responses(codex-rs/model-provider-info/src/lib.rs:103),注释写明是 OpenAI 在 /v1/responses 暴露的 Responses API;HTTP 与 WebSocket 客户端在 codex-api,怎么调用见模型客户端。
  • Codex Cloud:codex cloud 子命令(crate codex-cloud-tasks)只是一个浏览云端任务、把 diff 应用到本地的客户端,默认后端地址是 https://chatgpt.com/backend-api(codex-rs/cloud-tasks/src/lib.rs:55)。后端接口的数据类型放在 codex-backend-openapi-models,它的 lib.rs 注明其中没有手写类型,全部由脚本从 OpenAPI 生成。
  • IDE 扩展:源码不在这里,但留下了接入痕迹。codex app-server 以 SessionSource::VSCode 作为会话来源启动(codex-rs/cli/src/main.rs:1270),参数 --analytics-default-enabled 的注释说,这是给 VS Code 扩展这类第一方用例准备的(codex-rs/cli/src/main.rs:591)。扩展与 app-server 之间怎么通信,见 app-server。
  • 桌面应用:codex app(只在 macOS 与 Windows 上编译)负责打开或安装它,macOS 从 persistent.oaistatic.com 下载 DMG,Windows 走 Microsoft Store(codex-rs/cli/src/desktop_app/),应用本身不开源。

npm 包里的 codex.js:一个启动器

很多人是 npm install -g @openai/codex 装上的,于是以为 Codex 是个 Node 程序。其实 codex-cli/bin/codex.js 不到 300 行,只做四件事:

  1. 按 process.platform 和 process.arch 算出目标三元组,一共六种:Linux 的 x64 与 arm64(都用 musl)、macOS 的 x64 与 arm64、Windows 的 x64 与 arm64,找到对应的平台包;
  2. 在平台包的 vendor/<三元组>/bin/ 下找 codex(Windows 上是 codex.exe),找不到就按探测到的包管理器提示一条重装命令;
  3. 探测是被 npm、bun、pnpm 还是 Vite+ 装上的,把结果写进环境变量;
  4. 启动原生二进制,stdio 直通,转发终止信号,最后照搬子进程的退出方式。

第 3、4 步是这一段:

const env = {
  ...process.env,
  CODEX_MANAGED_PACKAGE_ROOT: codexPackageRoot,
};
delete env.CODEX_MANAGED_BY_NPM;
delete env.CODEX_MANAGED_BY_BUN;
delete env.CODEX_MANAGED_BY_PNPM;
delete env.CODEX_MANAGED_BY_VITE_PLUS;
env[packageManagerEnvVar] = "1";

const child = spawn(binaryPath, process.argv.slice(2), {
  stdio: "inherit",
  env,
});

(codex-cli/bin/codex.js:231)

CODEX_MANAGED_BY_* 是写给 Rust 侧看的:codex-install-context crate 据此判断安装方式(codex-rs/install-context/src/lib.rs:121 的 InstallContext::current),升级提示才能给出对的命令。信号方面,SIGINT、SIGTERM、SIGHUP 原样转给子进程;子进程若被信号杀死,父进程用同一个信号结束自己,这样 shell 看到的退出码(128 加信号编号)与直接运行二进制时一致。平台包是怎么被挑中、装进 node_modules 的,留到下一篇讲。

读之前知道的两件事

不收外部代码贡献。 docs/contributing.md 开宗明义:We do not accept external code contributions or pull requests。社区的参与方式是提 issue、给复现步骤和根因分析,代码由 Codex 团队来改。团队内部遵循的工程约定集中写在根目录 AGENTS.md 里,读代码前值得先过一遍,见读源码之前。

它也是写给 AI 看的。 AGENTS.md 里有这样的话:你在沙箱里运行,用 shell 工具时会设置 CODEX_SANDBOX_NETWORK_DISABLED=1(AGENTS.md:9)。这份开发规范的读者包括 Codex 自己,仓库的 .codex/skills/ 也是为它准备的。

另外说一句版本:发布工作流 .github/workflows/rust-release.yml 只认 rust-v*.*.* 形式的 tag,CHANGELOG.md 第一句就把人指向 GitHub Releases 页面。本专栏的行号都固定在 rust-v0.158.0 上,你手上的版本若更新,细节可能已经变了。

和《Codex 中文手册》的分工

两本书读同一个版本,分工不同:

  • 《Codex 中文手册》依据官方文档整理,讲怎么用:命令、参数、配置项、斜杠命令、沙箱与审批的选项;
  • 本专栏读 rust-v0.158.0 的源码,讲怎么实现:一个功能经过哪些 crate、数据怎么流、边界契约是什么。

所以每一篇都先用一两段交代“用户看到的样子”,并链接到手册的对应页面,然后翻进源码。遇到手册与代码对不上的地方,以代码为准并在文中点明。

和《从 LLM 到 Coding Agent》对照

《从 LLM 到 Coding Agent》从裸 API 调用起步,手搓了一个最小的 agent 循环:问模型、执行工具、把结果喂回去、再问。Codex 的内核做的是同一件事,只是外面多了几层:一个所有前端共用的 app-server,三个操作系统各自的沙箱,一套审批与执行策略,以及会话持久化、上下文压缩和扩展机制。读完这一部分的消息生命周期,你会在代码里认出那个最小循环的每一步。


上一篇:专栏封面 · 下一篇:从源码构建与运行 · Cargo、Bazel 与 npm 包装

本页目录