主题
OpenAI Codex CLI 学习指南
1. 概述
1.1 项目定位
OpenAI Codex CLI 是一个运行在终端中的轻量级 AI 编码代理(Coding Agent),由 OpenAI 官方开源。它让开发者在终端中与 AI 模型(默认 o4-mini)对话,AI 可以读取文件、执行 Shell 命令、编写/修改代码,所有操作均在沙盒环境中运行,确保安全性。
- 仓库地址:
https://github.com/openai/codex - 开源协议: Apache-2.0
- npm 包名:
@openai/codex - 当前版本:
0.1.2504251709
1.2 核心目标与解决的问题
| 问题 | Codex CLI 的解决方案 |
|---|---|
| AI 对话工具无法直接操作文件和执行命令 | 集成 Shell 执行和文件修改能力,AI 可以直接在终端中运行代码 |
| 自动化代码生成/修改的安全风险 | 三级审批策略 + 多平台沙盒(Seatbelt/Landlock/Docker) |
| 依赖 Web UI,不适合终端开发者 | 纯终端界面,基于 Ink(React 终端 UI 框架) |
| 编码代理需要复杂配置 | 零配置上手,只需 API Key 即可运行 |
1.3 适用场景与优势
适用场景:
- 代码重构、Bug 修复、自动生成测试
- 批量文件操作(重命名、格式转换)
- 代码审查和安全检查
- CI/CD 自动化(非交互模式)
- 项目理解与文档生成
对比同类工具:
| 特性 | Codex CLI | Claude Code | Cursor | GitHub Copilot Chat |
|---|---|---|---|---|
| 运行环境 | 终端 | 终端 | IDE | IDE |
| 命令执行 | ✅ 沙盒内 | ✅ | ❌ | ❌ |
| 文件修改 | ✅ | ✅ | ✅ | ✅ |
| 多模型支持 | ✅ 8+ 供应商 | ❌ 仅 Claude | ❌ | ❌ |
| 安全沙盒 | ✅ 内核级 | ✅ | N/A | N/A |
| 开源 | ✅ Apache-2.0 | ❌ | ❌ | ❌ |
1.4 依赖环境与安装方式
| 依赖 | 版本要求 |
|---|---|
| 操作系统 | macOS 12+, Ubuntu 20.04+/Debian 10+, Windows 11 (WSL2) |
| Node.js | ≥ 22(LTS 推荐) |
| Git | ≥ 2.23(可选,推荐) |
| RAM | 4GB 最低,8GB 推荐 |
bash
# 安装
npm install -g @openai/codex
# 设置 API Key
export OPENAI_API_KEY="your-api-key-here"
# 运行
codex "explain this codebase to me"2. 目录结构与模块划分
2.1 完整目录树
trpc-codex/ # Monorepo 根目录
├── codex-cli/ # ★ TypeScript CLI(当前生产版本)
│ ├── bin/
│ │ └── codex.js # 可执行入口脚本
│ ├── src/ # 源代码
│ │ ├── cli.tsx # ★ CLI 主入口(参数解析、启动逻辑)
│ │ ├── app.tsx # React 应用根组件
│ │ ├── approvals.ts # ★ 审批策略引擎
│ │ ├── text-buffer.ts # 多行文本缓冲区
│ │ ├── components/ # UI 组件
│ │ │ ├── chat/ # ★ 聊天界面核心组件
│ │ │ │ ├── terminal-chat.tsx # 主聊天界面
│ │ │ │ ├── terminal-chat-input.tsx # 输入框(28KB,复杂多行编辑器)
│ │ │ │ ├── terminal-chat-command-review.tsx # 命令审查 UI
│ │ │ │ └── ...
│ │ │ ├── onboarding/ # 首次使用引导
│ │ │ └── vendor/ # 第三方组件内置
│ │ ├── hooks/ # React Hooks
│ │ └── utils/ # 工具函数
│ │ ├── agent/ # ★ Agent 核心逻辑
│ │ │ ├── agent-loop.ts # ★★★ 核心循环(61KB,最重要的文件)
│ │ │ ├── handle-exec-command.ts # 命令执行处理
│ │ │ ├── apply-patch.ts # 代码补丁应用
│ │ │ ├── exec.ts # Shell 执行器
│ │ │ └── sandbox/ # 沙盒实现
│ │ │ ├── macos-seatbelt.ts # macOS Seatbelt 沙盒
│ │ │ ├── raw-exec.ts # 原始执行
│ │ │ └── interface.ts # 沙盒接口
│ │ ├── config.ts # ★ 配置管理(多源合并)
│ │ ├── responses.ts # ★ OpenAI API 适配层
│ │ ├── model-utils.ts # 模型验证
│ │ ├── providers.ts # 多供应商支持
│ │ ├── singlepass/ # 全量上下文模式
│ │ └── storage/ # 会话持久化
│ ├── tests/ # 50+ 测试文件
│ ├── build.mjs # esbuild 构建脚本
│ ├── package.json # NPM 配置
│ └── Dockerfile # 容器化
│
├── codex-rs/ # ★ Rust 重写版本(开发中)
│ ├── core/ # ★ 核心业务逻辑库
│ │ └── src/
│ │ ├── codex.rs # ★★ 核心引擎(SQ/EQ 队列模型)
│ │ ├── protocol.rs # ★ 通信协议定义
│ │ ├── client.rs # OpenAI API 客户端
│ │ ├── safety.rs # 安全评估
│ │ ├── exec.rs # 命令执行
│ │ ├── config.rs # 配置管理
│ │ └── linux.rs # Linux 沙盒(Landlock + seccomp)
│ ├── cli/ # 多工具 CLI 入口
│ │ └── src/main.rs # 子命令分发(tui/repl/exec/proto)
│ ├── tui/ # Ratatui 全屏 TUI
│ ├── repl/ # 轻量 REPL
│ ├── exec/ # 无头模式(CI/自动化)
│ ├── execpolicy/ # 命令安全策略(基于 Starlark)
│ ├── apply-patch/ # 补丁应用(tree-sitter 语法感知)
│ ├── ansi-escape/ # ANSI → Ratatui 转换
│ ├── docs/protocol_v1.md # 协议规范
│ └── Cargo.toml # Workspace 配置
│
├── package.json # Monorepo 根配置
├── pnpm-workspace.yaml # pnpm Workspace
├── README.md # 项目主文档(26KB)
└── CHANGELOG.md # 变更日志2.2 核心模块与辅助模块
核心模块(必须深入理解):
| 模块 | 路径 | 核心职责 |
|---|---|---|
| Agent 循环 | codex-cli/src/utils/agent/agent-loop.ts | AI 对话主循环:发 prompt → 收 response → 执行 tool calls → 反馈结果 |
| 审批引擎 | codex-cli/src/approvals.ts | 三级审批策略,命令安全性评估 |
| 命令执行 | codex-cli/src/utils/agent/handle-exec-command.ts | 处理 AI 发出的 Shell 命令,含沙盒路由 |
| 配置管理 | codex-cli/src/utils/config.ts | 多源配置合并:CLI flags → config.yaml → 环境变量 → 默认值 |
| API 适配 | codex-cli/src/utils/responses.ts | 适配 OpenAI Responses API 和 Chat Completions API |
| Rust 引擎 | codex-rs/core/src/codex.rs | SQ/EQ 异步队列模型,Rust 版核心 |
| 协议定义 | codex-rs/core/src/protocol.rs | Submission/Event 协议规范 |
辅助模块:
| 模块 | 路径 | 用途 |
|---|---|---|
| 沙盒层 | codex-cli/src/utils/agent/sandbox/ | macOS Seatbelt 和原始执行 |
| UI 组件 | codex-cli/src/components/ | Ink 终端 UI 组件 |
| 单次模式 | codex-cli/src/utils/singlepass/ | 全量上下文一次性编辑 |
| 命令策略 | codex-rs/execpolicy/ | 基于 Starlark 的命令安全策略 |
2.3 模块依赖关系
┌─────────────────────────────────────────────┐
│ CLI 入口 │
│ cli.tsx → meow(参数解析)→ loadConfig() │
└──────────┬──────────────────────────────┬────┘
│ 交互模式 │ 静默模式
▼ ▼
┌──────────────┐ ┌─────────────────┐
│ app.tsx │ │ runQuietMode() │
│ (React Root) │ │ (无 UI 运行) │
└──────┬───────┘ └──────┬──────────┘
│ │
▼ ▼
┌──────────────────────────────────────────┐
│ AgentLoop (agent-loop.ts) │
│ ┌──────────┐ ┌──────────┐ │
│ │ OpenAI │→│ 响应解析 │→ tool calls │
│ │ SDK │ │(responses)│ │
│ └──────────┘ └──────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────┐ │
│ │ handleExecCommand │ │
│ │ ┌───────────────┐ │ │
│ │ │ canAutoApprove │ │ ← approvals.ts │
│ │ └──────┬────────┘ │ │
│ │ ▼ │ │
│ │ ┌───────────────┐ │ │
│ │ │ exec / sandbox│ │ ← sandbox/ │
│ │ └───────────────┘ │ │
│ └─────────────────────┘ │
└──────────────────────────────────────────┘3. 核心架构与设计理念
3.1 架构流程图
3.2 核心设计模式
3.2.1 Agent 循环模式(TypeScript 版)
AgentLoop 类是整个系统的心脏,采用迭代式 Agent 模式:
用户输入 → [Turn 1: API 调用 → Tool Call → 执行 → 反馈] → [Turn 2: ...] → ... → 完成关键设计决策:
- 流式处理:使用 SSE(Server-Sent Events)实时接收 AI 响应
- Generation 计数:通过
generation字段防止取消后的过期事件干扰 - 对话上下文管理:支持
previous_response_id(服务端存储)或本地transcript(ZDR 模式)
typescript
// codex-cli/src/utils/agent/agent-loop.ts(核心片段)
export class AgentLoop {
private generation = 0; // 防止过期事件的代计数器
private transcript: Array<ResponseInputItem> = []; // ZDR 本地上下文
private pendingAborts: Set<string> = new Set(); // 取消后待处理的 Tool Calls
public async run(input: Array<ResponseInputItem>): Promise<void> {
this.generation++; // 每次 run 递增,旧事件自动失效
// ... 发送请求 → 接收流式响应 → 处理 Tool Calls → 循环
}
public cancel(): void {
this.currentStream = null;
this.canceled = true;
this.execAbortController?.abort(); // 中断正在执行的命令
}
}3.2.2 SQ/EQ 队列模式(Rust 版)
Rust 版采用更优雅的 Submission Queue / Event Queue 异步通信模型,将 UI 和核心逻辑完全解耦:
rust
// codex-rs/core/src/codex.rs(核心结构)
pub struct Codex {
tx_sub: Sender<Submission>, // 提交队列发送端
rx_event: Receiver<Event>, // 事件队列接收端
recorder: Recorder, // 调试记录器
}
impl Codex {
// UI → Codex:提交操作
pub async fn submit(&self, sub: Submission) -> CodexResult<()> { ... }
// Codex → UI:接收事件
pub async fn next_event(&self) -> CodexResult<Event> { ... }
}这种设计的好处:
- 传输层无关:可以跑在线程通道、IPC、stdin/stdout、TCP 上
- UI 可插拔:TUI/REPL/Exec 模式共享同一 Core
- 天然支持并发:SQ/EQ 都是 bounded channel
3.2.3 策略模式(审批系统)
审批系统采用策略模式,通过 ApprovalPolicy 类型参数化安全行为:
| 策略 | 只读操作 | 文件写入 | Shell 命令 |
|---|---|---|---|
suggest | ✅ 自动 | ❌ 需审批 | ❌ 需审批 |
auto-edit | ✅ 自动 | ✅ 自动 | ❌ 需审批 |
full-auto | ✅ 自动 | ✅ 自动 | ✅ 沙盒内自动 |
3.2.4 Builder 模式(Rust 版 Codex)
rust
// codex-rs/core/src/codex.rs
pub struct CodexBuilder {
record_submissions: Option<PathBuf>,
record_events: Option<PathBuf>,
}
// 使用方式
let codex = Codex::builder()
.record_submissions("subs.json")
.record_events("events.json")
.spawn(ctrl_c)?;4. 关键功能解析
4.1 功能一:Agent 循环(agent-loop.ts)
作用:这是最核心的文件(61KB),实现了 AI 对话-执行-反馈的完整循环。
使用场景:每次用户输入后,AgentLoop 接管所有与 AI 模型的交互。
核心逻辑:
typescript
// 文件: codex-cli/src/utils/agent/agent-loop.ts
// 1. 工具定义:告诉模型可以调用 shell 命令
const shellTool: FunctionTool = {
type: "function",
name: "shell",
description: "Runs a shell command, and returns its output.",
parameters: {
type: "object",
properties: {
command: { type: "array", items: { type: "string" } }, // 命令参数数组
workdir: { type: "string" }, // 工作目录
timeout: { type: "number" }, // 超时时间
},
required: ["command"],
},
};
// 2. AgentLoop 类核心属性
export class AgentLoop {
private model: string; // 使用的模型名
private oai: OpenAI; // OpenAI SDK 实例
private generation = 0; // 代计数器(防止取消后的过期事件)
private disableResponseStorage: boolean; // 是否禁用服务端存储(ZDR 模式)
private transcript: Array<ResponseInputItem> = []; // 本地对话上下文
// 3. 核心运行方法
public async run(input: Array<ResponseInputItem>): Promise<void> {
this.generation++;
const myGeneration = this.generation;
// 构建请求参数
const params: ResponseCreateParams = {
model: this.model,
instructions: this.instructions,
input: this.disableResponseStorage
? [...this.transcript, ...input] // ZDR: 发送完整上下文
: input, // 正常: 仅发送新输入
tools: [shellTool],
// ...
};
// 流式调用 API
const stream = this.oai.responses.create({ ...params, stream: true });
// 处理流式事件
for await (const event of stream) {
if (this.generation !== myGeneration) break; // 代已过期,退出
// 解析 response_item → 提取 tool_calls → 执行命令 → 循环
}
}
}技术亮点:
- Generation 计数防竞态:每次
run()递增 generation,取消后旧事件自动被忽略 - 双模式上下文管理:正常模式用
previous_response_id(省带宽),ZDR 模式用本地transcript(满足合规) - 优雅取消:
cancel()方法可中断正在进行的 API 调用和命令执行
4.2 功能二:审批策略引擎(approvals.ts)
作用:评估 AI 发出的命令是否安全,决定自动执行还是请求用户确认。
使用场景:每当 AI 想执行一个 Shell 命令或修改文件时调用。
核心逻辑:
typescript
// 文件: codex-cli/src/approvals.ts
// 审批结果类型
export type SafetyAssessment = {
applyPatch?: ApplyPatchCommand; // 如果是补丁操作
} & (
| { type: "auto-approve"; runInSandbox: boolean; reason: string; group: string }
| { type: "ask-user" }
| { type: "reject"; reason: string }
);
// 核心评估函数
export function canAutoApprove(
command: ReadonlyArray<string>, // 命令参数数组
workdir: string | undefined, // 工作目录
policy: ApprovalPolicy, // 审批策略
writableRoots: ReadonlyArray<string>, // 可写路径白名单
): SafetyAssessment {
// 1. 处理 apply_patch 命令
if (command[0] === "apply_patch") {
return canAutoApproveApplyPatch(command[1], workdir, writableRoots, policy);
}
// 2. 检查是否为已知安全命令(如 ls, cat, grep 等只读命令)
const isSafe = isSafeCommand(command);
if (isSafe != null) {
return { type: "auto-approve", runInSandbox: false, ...isSafe };
}
// 3. 解析 bash -lc "..." 格式的命令
if (command[0] === "bash" && command[1] === "-lc") {
const bashCmd = parse(command[2], env); // shell-quote 解析
const shellSafe = isEntireShellExpressionSafe(bashCmd);
// ...
}
// 4. 根据策略决定
switch (policy) {
case "full-auto":
return { type: "auto-approve", runInSandbox: true, ... }; // 沙盒内执行
case "suggest":
case "auto-edit":
return { type: "ask-user" }; // 请求用户确认
}
}技术亮点:
- Shell 表达式解析:使用
shell-quote库解析管道、逻辑运算符组合的复杂命令 - 路径限制检查:检查写入操作是否在允许的可写路径内
- 递归安全检查:对
cmd1 && cmd2 | cmd3这样的组合命令逐段检查
4.3 功能三:多平台沙盒执行
作用:在安全的沙盒环境中执行 AI 生成的命令,防止恶意操作。
核心实现:
macOS Seatbelt(TypeScript 版):
typescript
// 文件: codex-cli/src/utils/agent/sandbox/macos-seatbelt.ts
// 利用 macOS 内置的 sandbox-exec 命令,通过 .sbpl 策略文件限制进程行为
// 关键:生成 Seatbelt 策略
// - 文件系统只读(除了指定的可写目录)
// - 网络完全禁用
// - 只允许执行少量系统工具Linux Landlock + seccomp(Rust 版):
rust
// 文件: codex-rs/core/src/linux.rs
// 使用 Linux 内核级安全机制:
// - Landlock: 限制文件系统访问权限
// - seccomp: 限制可用的系统调用
// 双重防护,即使应用有漏洞也无法逃逸Docker 容器(Linux TypeScript 版):
dockerfile
# 文件: codex-cli/Dockerfile
# - 最小化容器镜像
# - iptables/ipset 防火墙只允许访问 OpenAI API
# - 环境变量 CODEX_UNSAFE_ALLOW_NO_SANDBOX=1 标记容器已受限4.4 功能四:多供应商模型支持
作用:支持 OpenAI 之外的多个 AI 模型供应商。
typescript
// 文件: codex-cli/src/utils/providers.ts
// 预定义 8 个供应商的 baseURL 和 API Key 环境变量名
// 支持的供应商:
// openai, openrouter, gemini, ollama, mistral, deepseek, xai, groq
// 以及任何兼容 OpenAI API 的自定义供应商typescript
// 文件: codex-cli/src/utils/responses.ts
// 关键适配:将 Responses API(OpenAI 专有)转换为 Chat Completions API(通用)
// 当使用非 OpenAI 供应商时,自动切换到 Chat Completions 格式
export async function* responsesCreateViaChatCompletions(...) {
// Responses API 格式 → Chat Completions 格式
// 处理流式响应差异
// 统一 Tool Call 格式
}4.5 功能五:SQ/EQ 协议架构(Rust 版)
作用:定义 UI 和 Codex 核心之间的异步通信协议,支持多种传输层。
rust
// 文件: codex-rs/core/src/protocol.rs
// Submission(UI → Codex):用户操作
pub enum Op {
ConfigureSession { model, instructions, approval_policy, sandbox_policy, ... },
UserInput { items: Vec<InputItem> },
Interrupt,
ExecApproval { id, decision },
PatchApproval { id, decision },
}
// Event(Codex → UI):系统事件
pub enum EventMsg {
SessionConfigured { ... },
TaskStarted { ... },
AgentMessage { items },
ExecApprovalRequest { id, command },
ExecStart { call_id },
ExecOutput { call_id, data },
TurnComplete { response_id },
TaskComplete,
Error { message, detail },
}协议设计的优势:
- 解耦 UI 和逻辑:TUI、REPL、Exec 模式共享同一个 Core
- 传输无关:支持线程通道、IPC、stdin/stdout(NDJSON)、TCP
- 可扩展:
#[non_exhaustive]标记允许未来添加新变体而不破坏兼容
5. 快速上手示例
5.1 示例一:交互式代码修改
bash
# 安装
npm install -g @openai/codex
# 设置 API Key
export OPENAI_API_KEY="sk-..."
# 在项目目录中运行
cd my-project
codex "refactor the Dashboard component to use React Hooks"
# Codex 会:
# 1. 读取项目文件,理解代码结构
# 2. 生成重构方案
# 3. 提示你审查每个文件改动
# 4. 审批后应用修改预期输出:
● OpenAI Codex (research preview) v0.1.2504251709
Session: abc123 | Model: o4-mini
> refactor the Dashboard component to use React Hooks
I'll refactor the Dashboard component from a class component to
use React Hooks. Let me first read the current implementation...
$ cat src/components/Dashboard.tsx
[output truncated]
I'll now create the refactored version:
apply_patch <<'EOF'
--- a/src/components/Dashboard.tsx
+++ b/src/components/Dashboard.tsx
...
EOF
[y] approve [n] deny [e] edit5.2 示例二:非交互式 CI 集成
bash
# 在 GitHub Actions 中使用
- name: Auto-fix lint errors
run: |
npm install -g @openai/codex
export OPENAI_API_KEY="${{ secrets.OPENAI_KEY }}"
codex -q -a full-auto "fix all ESLint errors in src/"
# 参数说明:
# -q 静默模式(无交互 UI)
# -a full-auto 全自动审批(在沙盒中)预期输出:
assistant: I'll scan the source files for ESLint errors and fix them.
$ npx eslint src/ --format json
command.stdout (code: 1, duration: 3.2s)
[ESLint output...]
$ apply_patch <<'EOF'
...fixes...
EOF
assistant: Fixed 12 ESLint errors across 5 files.6. 进阶扩展与注意事项
6.1 二次开发指南
添加新的 AI 供应商:
typescript
// 1. 在 codex-cli/src/utils/providers.ts 添加供应商配置
export const providers = {
// ...existing
"my-provider": {
name: "MyProvider",
baseURL: "https://api.my-provider.com/v1",
envKey: "MY_PROVIDER_API_KEY",
},
};
// 2. 如果 API 不兼容 OpenAI Chat Completions,需在 responses.ts 添加适配自定义命令安全策略(Rust 版):
python
# 在 .policy 文件中定义规则(Starlark 语法)
define_program(
program="my-tool",
options=[flag("--safe-flag")],
args=[ARG_RFILE],
system_path=["/usr/local/bin/my-tool"],
should_match=[["--safe-flag", "file.txt"]],
)开发调试:
bash
# TypeScript 开发
cd codex-cli
pnpm install
pnpm run build:dev # 带 source map 的开发构建
# 调试:附加 Node Inspector
node --inspect-brk ./dist/cli.js
# Rust 开发
cd codex-rs
cargo run --bin codex -- tui # 运行 TUI
RUST_LOG=codex_core=debug cargo run -- tui # 带日志6.2 常见问题与解决方案
| 问题 | 原因 | 解决方案 |
|---|---|---|
Missing OpenAI API key | 未设置环境变量 | export OPENAI_API_KEY="sk-..." |
model does not appear in the list | 模型不可用或拼写错误 | 运行 openai models list 检查 |
| Linux 无沙盒警告 | Linux 默认不启用沙盒 | 使用 Docker 方式运行或 Rust 版 |
| 非 Git 仓库警告 | Codex 建议在 Git 仓库中运行 | git init 或确认继续 |
| ZDR 报错 | 服务端存储与 ZDR 策略冲突 | 升级到最新版或添加 --disable-response-storage |
6.3 性能优化点
- Token 使用优化:
approximate-tokens-used.ts估算 token 用量,避免超限 - 输出截断:
create-truncating-collector.ts限制命令输出大小,防止上下文爆炸 - 构建优化:esbuild 将整个 TypeScript CLI 打包成单文件 ESM bundle,启动极快
- Rust 重写:无 GC、原生编译、更低内存占用,是项目的性能优化方向
6.4 潜在风险
- 安全风险:
--dangerously-auto-approve-everything标志跳过所有安全检查,仅用于测试 - Linux 沙盒缺失:TypeScript 版在 Linux 默认无沙盒,需手动使用 Docker
- API 成本:长对话的 token 消耗可能很高,特别是 ZDR 模式(每次发送完整上下文)
- 模型幻觉:AI 可能生成不正确的命令,审批策略是最后防线
6.5 设计优缺点总结
✅ 优点:
- 安全第一:多层沙盒 + 三级审批,安全设计非常扎实
- 架构清晰:TypeScript 版逻辑集中,Rust 版 SQ/EQ 解耦优雅
- 可扩展性强:多供应商支持、配置灵活、协议可扩展
- 测试完善:50+ 测试覆盖核心逻辑
- 双语言策略:TypeScript 快速迭代 + Rust 性能优化,各取所长
❌ 可优化点:
agent-loop.ts有 61KB/1500+ 行,职责过重,建议拆分- Rust 版尚未功能对齐 TypeScript 版
- 缺少 Windows 原生支持(需 WSL2)
- 配置文件同时支持 JSON/YAML/YML 三种格式,略显冗余
7. 深度学习计划
总时长估算:约 6~8 周(每天投入 1~2 小时),分 5 个阶段递进。 前置要求:熟悉 TypeScript/Node.js 基础,了解 CLI 工具使用,有基本的 LLM API 调用经验。
阶段一:环境搭建与全局认知(第 1 周)
目标:能本地构建运行项目,建立整体架构的直觉认知。
| 天数 | 任务 | 关键文件/命令 | 产出 |
|---|---|---|---|
| Day 1 | 克隆仓库,阅读 README.md 全文 | README.md, CONTRIBUTING.md | 手绘/Mermaid 架构草图 |
| Day 2 | 搭建开发环境,pnpm install + build | package.json, pnpm-workspace.yaml, codex-cli/build.mjs | 成功本地构建并运行 codex --help |
| Day 3 | 实际体验三种审批模式 | 运行 codex -a suggest/auto-edit/full-auto "..." | 记录交互日志,理解三级审批的区别 |
| Day 4 | 阅读目录结构,标注核心/辅助模块 | 本文档第 2 章 | 在笔记中画出模块依赖关系图 |
| Day 5 | 跑通所有测试用例 | pnpm test(50+ 测试文件) | 确认测试全绿,了解测试覆盖范围 |
阶段检查点:能用自己的话向他人解释 "Codex CLI 是什么、怎么用、大致分哪些模块"。
阶段二:核心主循环精读(第 2~3 周)
目标:深入理解 Agent Loop —— 整个 CLI 的心脏。
Week 2:入口到主循环
| 天数 | 任务 | 关键文件 | 学习要点 |
|---|---|---|---|
| Day 1 | 精读 CLI 入口 | codex-cli/src/cli.tsx | meow 参数解析 → 配置加载 → Ink render 启动流程 |
| Day 2 | 精读配置管理 | codex-cli/src/utils/config.ts | 多源配置合并优先级:CLI flags > config.yaml > 环境变量 > 默认值 |
| Day 3 | 精读 Agent 循环(上):初始化与消息发送 | agent-loop.ts 第 1~500 行 | AgentLoop 类结构、OpenAI SDK 初始化、run() 方法 |
| Day 4 | 精读 Agent 循环(中):响应处理 | agent-loop.ts 第 500~1000 行 | 流式响应处理、tool call 解析、ResponseEvent 枚举 |
| Day 5 | 精读 Agent 循环(下):工具调用与重试 | agent-loop.ts 第 1000~1500 行 | 错误处理/重试机制、速率限制、取消逻辑 |
Week 3:工具调用与 API 适配
| 天数 | 任务 | 关键文件 | 学习要点 |
|---|---|---|---|
| Day 1 | 精读命令执行处理 | handle-exec-command.ts | tool call → 安全评估 → 沙盒路由 → 结果收集的完整链路 |
| Day 2 | 精读 Shell 执行器 | exec.ts, sandbox/raw-exec.ts | 进程 spawn、stdout/stderr 收集、超时处理、进程组管理 |
| Day 3 | 精读 API 适配层 | utils/responses.ts | Responses API vs Chat Completions API 双协议适配机制 |
| Day 4 | 精读多供应商支持 | utils/providers.ts, utils/model-utils.ts | 8 种供应商配置、模型验证、context window 计算 |
| Day 5 | 用调试器单步跟踪一次完整对话 | 设置 DEBUG=1,阅读日志 | 实操验证:prompt → API 调用 → 流式响应 → tool call → 执行 → 反馈结果 |
阶段检查点:能画出完整的 Agent Loop 时序图,标注每一步的数据流和关键判断分支。
推荐产出:撰写 1_agent_loop_deep_dive.md 笔记。
阶段三:安全与审批体系(第 4 周)
目标:掌握"安全第一"设计哲学的完整实现。
| 天数 | 任务 | 关键文件 | 学习要点 |
|---|---|---|---|
| Day 1 | 精读审批引擎 | approvals.ts | 三种策略(suggest/auto-edit/full-auto)的判定逻辑 |
| Day 2 | 精读安全命令白名单 | approvals.ts 中的 isSafeCommand() | shell-quote 解析、命令白名单匹配、管道/重定向处理 |
| Day 3 | 精读 macOS 沙盒 | sandbox/macos-seatbelt.ts | Seatbelt profile 生成、可写路径参数化、sandbox-exec 调用 |
| Day 4 | 精读 apply_patch 机制 | apply-patch.ts, parse-apply-patch.ts | 补丁格式解析、文件变更检测、安全写入逻辑 |
| Day 5 | 读相关测试理解边界情况 | tests/approvals.test.ts, tests/apply-patch.test.ts | 安全边界用例:恶意命令、路径穿越、权限绕过等 |
阶段检查点:能解释清楚 "一个 rm -rf / 命令从 AI 输出到被拦截的全过程"。
推荐产出:撰写 2_safety_approval_system.md 笔记。
阶段四:终端 UI 与用户体验(第 5 周)
目标:理解基于 React/Ink 的终端 UI 架构和交互设计。
| 天数 | 任务 | 关键文件 | 学习要点 |
|---|---|---|---|
| Day 1 | 学习 Ink 框架基础 | Ink 官方文档 | React 在终端中的渲染原理、Box/Text 组件、useInput Hook |
| Day 2 | 精读 App 根组件 | app.tsx, terminal-chat.tsx | 应用状态管理、overlay 模式切换(help/history/model/diff) |
| Day 3 | 精读多行编辑器 | terminal-chat-input.tsx(28KB) | 光标控制、多行编辑、快捷键绑定、Ctrl+Enter 提交 |
| Day 4 | 精读命令审查 UI | terminal-chat-command-review.tsx, terminal-chat-tool-call-command.tsx | 审批 UI 交互、命令高亮显示、diff 预览 |
| Day 5 | 精读 TextBuffer 实现 | text-buffer.ts + 5 个 text-buffer 测试文件 | 高性能文本缓冲区:光标移动、选区、复制粘贴、CRLF 处理 |
阶段检查点:能独立修改 UI 组件(例如:给命令审查界面新增一个 "编辑后执行" 按钮)。
推荐产出:撰写 3_terminal_ui_architecture.md 笔记。
阶段五:Rust 版本与高级主题(第 6~8 周)
目标:理解 Rust 重写版的架构差异和高级设计模式。
Week 6:Rust 核心引擎
| 天数 | 任务 | 关键文件 | 学习要点 |
|---|---|---|---|
| Day 1 | 搭建 Rust 开发环境 | codex-rs/Cargo.toml, justfile | cargo build、just 构建系统、Workspace 结构 |
| Day 2 | 精读 SQ/EQ 协议 | core/src/protocol.rs | Submission/Event 定义、AskForApproval/SandboxPolicy 枚举 |
| Day 3 | 精读核心引擎 | core/src/codex.rs | Codex struct、CodexBuilder 模式、async_channel 队列 |
| Day 4 | 精读命令执行与安全 | core/src/exec.rs, core/src/safety.rs | Rust 版沙盒实现、安全评估逻辑 |
| Day 5 | 精读 Linux 沙盒 | core/src/linux.rs | Landlock LSM + seccomp-bpf 内核级沙盒实现 |
Week 7:Rust 前端与策略
| 天数 | 任务 | 关键文件 | 学习要点 |
|---|---|---|---|
| Day 1 | 精读 TUI 前端 | codex-rs/tui/src/ | Ratatui 框架、全屏 TUI 渲染、事件循环 |
| Day 2 | 精读 REPL 前端 | codex-rs/repl/src/ | 轻量 REPL 模式、readline 交互 |
| Day 3 | 精读 Exec 无头模式 | codex-rs/exec/src/ | CI/自动化场景、非交互执行 |
| Day 4 | 精读执行策略引擎 | codex-rs/execpolicy/ | 基于 Starlark 的策略配置、自定义安全规则 |
| Day 5 | 精读补丁应用 | codex-rs/apply-patch/ | tree-sitter 语法感知补丁、语义级别的代码修改 |
Week 8:对比分析与实战
| 天数 | 任务 | 学习要点 |
|---|---|---|
| Day 1 | TypeScript vs Rust 版本架构对比 | 同一功能的两种实现思路差异(回调 vs 队列、GC vs 手动内存) |
| Day 2 | 阅读 codex-rs/docs/protocol_v1.md 协议规范 | 理解 UI 与核心引擎的通信契约 |
| Day 3 | 自选一个 feature 做实践 | 例如:新增一个 provider 支持、添加自定义 slash command |
| Day 4 | 阅读 CHANGELOG.md,理解演进路线 | 版本迭代中的设计决策和重构脉络 |
| Day 5 | 整理完整学习笔记,画全局架构图 | 将零散知识串成体系 |
阶段检查点:能向他人对比讲解 TypeScript 版和 Rust 版的架构差异及各自优势。
推荐产出:撰写 4_rust_rewrite_analysis.md 和 5_full_architecture_summary.md 笔记。
学习路线图(Mermaid)
附录:技术栈速查
TypeScript 技术栈
| 技术 | 用途 | 版本 |
|---|---|---|
| Node.js | 运行时 | ≥ 22 |
| TypeScript | 开发语言 | ^5.0.3 |
| React + Ink | 终端 UI 框架 | ^18.2.0 / ^5.2.0 |
| OpenAI SDK | API 调用 | ^4.95.1 |
| esbuild | 构建打包 | ^0.25.2 |
| Vitest | 测试框架 | ^3.0.9 |
| Zod | Schema 验证 | ^3.24.3 |
| meow | CLI 参数 | ^13.2.0 |
| pnpm | 包管理 | 10.8.1 |
Rust 技术栈
| 技术 | 用途 | 版本 |
|---|---|---|
| Tokio | 异步运行时 | 1.x |
| Ratatui | TUI 框架 | 0.29.0 |
| reqwest | HTTP 客户端 | 0.12 |
| serde | 序列化 | 1.x |
| clap | CLI 参数 | 4.x |
| tree-sitter | 语法分析 | 0.25.3 |
| Landlock | Linux 沙盒 | 0.4.1 |
| Starlark | 策略配置 | 0.13.0 |
QA
codex-cli目录和codex-rs目录的区别
一句话总结
codex-cli 是 TypeScript 原版(成熟、功能完整),codex-rs 是 Rust 重写版(追求性能和原生沙盒,功能尚在追赶中)。两者实现同一套产品逻辑,但语言、架构、UI 框架和安全沙箱实现完全不同。
项目定位对比
| 维度 | codex-cli (TypeScript) | codex-rs (Rust) |
|---|---|---|
| 定位 | 当前正式版本,功能完整 | 性能优化重写版,追赶功能中 |
| 启动时间 | 2024 年 | 2025年4月24日 |
| 状态 | 生产可用 | 研究预览(materially behind) |
| 运行方式 | 需要 Node.js 22+ 运行时 | 编译为独立二进制,无运行时依赖 |
| 发布方式 | npm publish (@openai/codex) | 未来通过 GitHub Releases 发布 |
技术栈对比
| 维度 | codex-cli | codex-rs |
|---|---|---|
| 语言 | TypeScript + JSX/TSX | Rust (Edition 2021) |
| UI 框架 | React/Ink (终端中的 React) | Ratatui (Rust TUI 框架) |
| CLI 参数 | meow | clap (derive 模式) |
| 构建工具 | esbuild (build.mjs) | Cargo + just |
| 测试框架 | Vitest | cargo test |
| 包管理 | pnpm | Cargo workspace |
| 模块系统 | ESM | Cargo crate |
| API 客户端 | openai SDK (npm) | reqwest + 手写 SSE 解析 |
| 配置格式 | YAML/JSON (~/.codex/config.yaml) | TOML (~/.codex/config.toml) |
| 配置校验 | Zod schema | serde + derive |
| Markdown 渲染 | marked + marked-terminal | — (TUI 直接渲染) |
| Shell 解析 | shell-quote (npm) | tree-sitter-bash |
| 日志 | 自定义 AsyncLogger | tracing + tracing-subscriber |
架构模型对比
codex-cli:回调驱动,UI 与逻辑耦合
用户输入 → cli.tsx (meow) → App.tsx (React/Ink)
↓
TerminalChat (Ink组件)
↓
AgentLoop (核心类)
┌─────────┼──────────┐
│ │ │
OpenAI SDK 工具调用 沙盒执行
(responses.ts) (apply- (seatbelt/
patch.ts) raw-exec.ts)- 单进程:UI 和 Agent 逻辑在同一个 Node.js 进程中
- 回调/事件驱动:
AgentLoop类通过回调函数通知 UI - OpenAI SDK:直接使用官方
openainpm 包 - 双 API 协议:同时支持 Responses API 和 Chat Completions API(通过
responses.ts适配)
codex-rs:队列驱动,UI 与核心解耦
用户输入 → cli/main.rs (clap子命令)
↓
┌──────────┼──────────┬──────────┐
│ │ │ │
TUI REPL Exec Proto
(ratatui) (readline) (headless) (JSON行)
│ │ │ │
└──────────┴──────────┴──────────┘
↓
SQ (Submission Queue)
↓
Codex (核心引擎)
Session → Task → Turn
↓
EQ (Event Queue)
↓
UI 消费事件- SQ/EQ 双队列:UI 和核心引擎通过 Submission Queue / Event Queue 解耦
- 多前端支持:同一个
core库支持 TUI、REPL、Exec(无头)、Proto(JSON行协议)四种前端 - 跨进程能力:SQ/EQ 可运行在不同传输层(channel、stdin/stdout、TCP、gRPC)
- Session/Task/Turn 三级状态机:比 TS 版更清晰的生命周期管理
代码规模对比
| 指标 | codex-cli | codex-rs |
|---|---|---|
| 源文件数 | ~87 个 (src/) | ~75 个 (.rs) |
| 测试文件数 | 69 个 | ~14 个(含集成测试) |
| 最大文件 | agent-loop.ts (~62KB, ~1500行) | codex.rs (~51KB, ~1500行) |
| 估算总代码量 | ~15,000-18,000 行 | ~8,000-10,000 行 |
| Crate/模块数 | 1 个 npm 包 | 8 个 Cargo crate |
| 供应商支持 | 8 个 (OpenAI/Gemini/Ollama等) | 仅 OpenAI(通过环境变量) |
目录结构对比
codex-cli 目录结构
codex-cli/
├── bin/codex.js # CLI 可执行入口
├── build.mjs # esbuild 构建脚本
├── package.json # NPM 包配置
├── src/
│ ├── cli.tsx # ★ 主入口 (meow参数解析 + Ink渲染)
│ ├── app.tsx # 根组件 (Git检查 + 路由)
│ ├── approvals.ts # ★ 审批引擎 (三级策略)
│ ├── text-buffer.ts # 多行文本编辑器核心
│ ├── components/ # UI 组件 (chat/ + overlay + vendor/)
│ ├── hooks/ # React Hooks
│ └── utils/
│ ├── agent/ # ★ Agent 核心 (agent-loop.ts 62KB)
│ │ └── sandbox/ # 沙盒 (seatbelt + raw-exec)
│ ├── config.ts # 配置管理 (YAML/JSON/env)
│ ├── responses.ts # ★ 双API协议适配
│ ├── providers.ts # 8种供应商注册表
│ ├── singlepass/ # 单次执行模式
│ └── storage/ # 持久化 (历史/回放)
├── tests/ # 69 个测试文件
├── scripts/ # Docker 容器脚本
└── examples/ # 使用示例codex-rs 目录结构
codex-rs/
├── Cargo.toml # Workspace 根配置 (8个成员)
├── justfile # 构建快捷命令
├── docs/protocol_v1.md # ★ 协议 v1 规范
│
├── core/ # ★ 核心引擎库 (可被任意前端复用)
│ └── src/
│ ├── codex.rs # ★ 主引擎 (SQ/EQ + Session/Task/Turn)
│ ├── protocol.rs # ★ 协议定义 (Op/EventMsg/Submission/Event)
│ ├── client.rs # HTTP/SSE 客户端 (手写)
│ ├── safety.rs # 安全评估
│ ├── exec.rs # 命令执行 + Seatbelt
│ ├── linux.rs # Landlock + seccomp 沙盒
│ ├── config.rs # TOML 配置
│ └── is_safe_command.rs # 安全命令白名单
│
├── cli/ # 统一二进制入口 (codex)
│ └── src/main.rs # clap子命令分派 (tui/exec/repl/proto)
├── tui/ # 全屏 TUI (Ratatui)
├── repl/ # 轻量 REPL
├── exec/ # 无头模式 (CI/自动化)
├── apply-patch/ # 补丁解析库 (tree-sitter)
├── execpolicy/ # ★ Starlark 策略引擎
└── ansi-escape/ # ANSI 转义辅助库安全沙盒对比
| 维度 | codex-cli | codex-rs |
|---|---|---|
| macOS 沙盒 | Seatbelt (sandbox-exec) | Seatbelt (sandbox-exec),实现基本一致 |
| Linux 沙盒 | ❌ 不支持 | ✅ Landlock (文件系统) + seccomp (系统调用) |
| Windows 沙盒 | ❌ 不支持 | ❌ 不支持 |
| Docker 沙盒 | ✅ Dockerfile + iptables | ❌ 未实现 |
| 安全命令判断 | isSafeCommand() (shell-quote解析) | is_known_safe_command() (tree-sitter-bash解析) |
| 策略引擎 | 硬编码白名单 | ✅ Starlark 策略文件 (default.policy),可自定义规则 |
| 沙盒策略粒度 | 3种模式 (suggest/auto-edit/full-auto) | 4种审批 × 4种沙盒,更细粒度组合 |
审批策略映射关系
| codex-cli 术语 | codex-rs 术语 | 行为 |
|---|---|---|
suggest | unless-allow-listed | 仅白名单命令自动执行 |
auto-edit | auto-edit | 白名单 + 可写路径内的文件修改自动执行 |
full-auto | on-failure | 全部自动执行(沙盒内),失败时才询问用户 |
| — | never | 完全不询问,失败直接返回模型(CI模式) |
API 调用方式对比
| 维度 | codex-cli | codex-rs |
|---|---|---|
| SDK | 使用 openai npm SDK | 手写 HTTP + SSE 解析 |
| API 协议 | Responses API + Chat Completions API 双协议 | 仅 Responses API |
| 流式处理 | SDK 内置流式处理 | reqwest + eventsource-stream |
| 重试机制 | 自定义重试 + 指数退避 | 自定义重试 + 带抖动的指数退避 |
| ZDR 支持 | ✅ 通过 disableResponseStorage | ✅ 通过 disable_response_storage + ZdrTranscript |
| previous_response_id | ✅ 支持 | ✅ 支持 |
配置管理对比
| 维度 | codex-cli | codex-rs |
|---|---|---|
| 配置文件 | ~/.codex/config.yaml 或 .json | ~/.codex/config.toml |
| 指令文件 | ~/.codex/instructions.md | ~/.codex/instructions.md |
| API Key 来源 | 环境变量 > .env > ~/.codex.env | 环境变量 (OPENAI_API_KEY) |
| 多供应商 | ✅ 8种 provider 配置 | ❌ 仅 OpenAI |
| 默认模型 | o4-mini | o3 |
| 配置优先级 | CLI flags > config file > env > 默认值 | CLI flags > config.toml > env flags > 默认值 |
前端模式对比
| codex-cli 模式 | codex-rs 等价物 | 说明 |
|---|---|---|
| 交互模式(默认) | codex tui | 全屏交互界面 |
| — | codex repl | 轻量 REPL(TS 版无此模式) |
| — | codex exec | 无头执行模式(TS 版通过 --quiet 实现类似效果) |
| — | codex proto | JSON 行协议(供外部 UI 集成) |
单次执行模式 (-q) | codex exec | 执行一次后退出 |
补丁应用对比
| 维度 | codex-cli | codex-rs |
|---|---|---|
| 实现 | apply-patch.ts (22KB) | apply-patch/ crate (34KB lib.rs + 16KB parser.rs) |
| 解析器 | 正则 + 手写解析 | tree-sitter + 手写解析 |
| Bash 解析 | shell-quote (npm) | tree-sitter-bash |
| Diff 生成 | diff (npm) | similar (Rust) |
| 错误处理 | try/catch | thiserror 类型化错误 |
关键设计差异总结
| 设计决策 | codex-cli 的选择 | codex-rs 的选择 | 分析 |
|---|---|---|---|
| UI 与核心耦合 | 紧耦合(同一进程) | 解耦(SQ/EQ 队列) | Rust 版更有利于多前端和跨进程部署 |
| 内存管理 | GC(V8引擎) | 手动(Rust 所有权) | Rust 更低内存、更可预测 |
| 并发模型 | 事件循环(单线程) | Tokio 多线程异步 | Rust 版可更好利用多核 |
| 沙盒深度 | 应用层(macOS only) | 内核层(Linux seccomp/landlock) | Rust 版安全边界更强 |
| 可扩展性 | 供应商丰富(8种) | 仅 OpenAI | TS 版更适合多供应商场景 |
| 启动速度 | 需加载 Node.js + 解释 JS | 原生二进制直接执行 | Rust 版启动更快 |
| 分发方式 | npm install 需要 Node 22+ | 独立二进制,零依赖 | Rust 版部署更简单 |
什么时候该看哪个目录?
| 你的目标 | 建议看 | 原因 |
|---|---|---|
| 理解完整功能和最佳实践 | codex-cli | 功能最完整,代码注释充分 |
| 学习 Agent Loop 核心逻辑 | codex-cli (agent-loop.ts) | 最详细的实现,1500行注释丰富 |
| 学习 React/Ink 终端 UI | codex-cli | 唯一使用此技术栈的 |
| 学习 SQ/EQ 协议架构 | codex-rs (core/) | 有正式协议文档 |
| 学习内核级沙盒(seccomp/landlock) | codex-rs (core/src/linux.rs) | TS 版不支持 Linux 沙盒 |
| 学习 Starlark 策略引擎 | codex-rs (execpolicy/) | TS 版仅有硬编码白名单 |
| 学习 Rust 异步编程实战 | codex-rs | Tokio + async_channel 真实项目 |
| 学习 Ratatui TUI 开发 | codex-rs (tui/) | 完整的全屏 TUI 实现 |
| 学习多前端架构设计 | codex-rs | TUI/REPL/Exec/Proto 四种前端共享一个核心 |
演进趋势
根据 codex-rs/README.md 的描述:
Currently, the Rust implementation is materially behind the TypeScript implementation in functionality, so continue to use the TypeScript implementation for the time being. We will publish native executables via GitHub Releases as soon as we feel the Rust version is usable.
长期方向:Rust 版将逐步取代 TypeScript 版成为主要发行版本。建议同时学习两个版本,以 TS 版理解完整功能,以 Rust 版理解架构演进方向。