# 复盘 · 对照《从 LLM 到 Coding Agent》

> 把《从 LLM 到 Coding Agent》的二十一个概念逐个对上 Codex 的生产实现与本专栏的篇目，列出 Codex 刻意没照教学建议做的几处，再提炼贯穿全书的几条规律：界面与内核之间隔着一层协议，历史只追加，有副作用的动作都走同一个编排器，沙箱与审批各管一件事。最后是教学实现里没有对应物的那一半。

- 作者：David（道雾轩）
- 专栏：Codex 源码解读（https://daiw.net/manual/codex-source.md）
- 最后更新：2026-09-29
- 原文：https://daiw.net/manual/codex-source/recap
- 转载与引用：请注明出处并附原文链接（https://daiw.net/about/copyright）

# 复盘 · 对照《从 LLM 到 Coding Agent》

前 54 篇把 `codex-rs` 从入口一路拆到了发布。收尾的第一篇回到起点：站里的[《从 LLM 到 Coding Agent》](https://daiw.net/manual/llm-to-agent)用二十篇正文加一篇实战番外，把一块只会输出文本的“裸芯片”焊成了一台能自主干活的机器，每一步都配了一个用 TypeScript 写的最小实现。这一篇把两本书并排摆开：左边是教学最小实现，右边是 Codex 的生产实现，最后一列指向本专栏里讲细节的篇目。

## 教学循环落在 Codex 的哪一层

那本书的内核是一个 `while` 循环：问模型，有 `tool_use` 就执行，把 `tool_result` 喂回去，再问。在 Codex 里，这个循环几乎原样活在 `run_turn` 里，只是上下都多出了好几层：

```mermaid
flowchart TB
  FE[前端：TUI、codex exec、IDE 与 SDK<br/>对应：streaming 的界面一侧、interrupt] --> AS[app-server v2 协议与守护进程<br/>教学实现没有这一层]
  AS --> TM[ThreadManager 与 CodexThread<br/>对应：session-history]
  TM --> RT[RegularTask 反复调用 run_turn<br/>对应：agent-loop]
  RT --> CM[ContextManager 与世界状态<br/>对应：context-injection、prompt-caching]
  RT --> MC[ModelClient 与 codex-api<br/>对应：raw-llm-api、streaming、error-recovery]
  RT --> TR[ToolRouter 与 ToolCallRuntime<br/>对应：tool-use、tool-abstraction、streaming-tool-execution]
  CM --> CP[压缩<br/>对应：auto-compaction、context-compaction]
  TR --> TO[ToolOrchestrator：审批与选沙箱<br/>对应：permissions、hooks]
  TO --> SB[三平台沙箱、网络代理与 exec-server<br/>教学实现没有这一层]
```

上面多出的一层让同一个内核服务多个前端，下面多出的一层让命令在操作系统强制的边界里执行。这两处是教学实现与生产实现距离最远的地方，本文最后一节再回来看。

## 逐概念对照

按那本书的阶段分组。“Codex 的生产实现”一列只写结构上的差别，细节见最后一列。

### 起点与“让模型能做事”

| 概念 | 教学最小实现 | Codex 的生产实现 | 本专栏 |
| --- | --- | --- | --- |
| [裸 LLM API](https://daiw.net/manual/llm-to-agent/raw-llm-api) | 一次 `messages.create`；无状态，每轮重发全部历史；一个 API key | 只说 Responses API；请求带 `store: false`，走 HTTP 时每次带完整历史，走 WebSocket 时只发增量；认证单独成一个子系统，八种凭据统一成 `CodexAuth` | [模型客户端](https://daiw.net/manual/codex-source/model-client)、[登录与认证](https://daiw.net/manual/codex-source/login-and-auth) |
| [工具调用](https://daiw.net/manual/llm-to-agent/tool-use) | 用 JSON Schema 声明工具；模型回 `tool_use`，宿主执行后按 id 回填 `tool_result` | 工具以 `ToolSpec` 发出（`function`、`namespace`、`custom` 等五种）；`ToolRouter::build_tool_call` 把输出项变成 `ToolCall`；缺配对的调用在生成输入时补一条 `aborted` 输出 | [工具系统总览](https://daiw.net/manual/codex-source/tool-architecture)、[上下文与历史](https://daiw.net/manual/codex-source/context-history) |
| [Agent Loop](https://daiw.net/manual/llm-to-agent/agent-loop) | `while (true)`，没有 `tool_use` 就退出 | `RegularTask` 反复调用 `run_turn`；“还要不要再问”就是 `needs_follow_up`（有工具调用，或期间来了新输入）；开轮准备、中途压缩与 Stop hook 都围着它 | [一条消息的生命周期](https://daiw.net/manual/codex-source/message-lifecycle)、[run_turn 主循环](https://daiw.net/manual/codex-source/turn-loop) |
| [工具抽象](https://daiw.net/manual/llm-to-agent/tool-abstraction) | 一个富接口：schema、校验、权限、`isConcurrencySafe` 等元数据与两套渲染，默认值往安全方向兜 | `ToolExecutor` 把 spec 与处理器绑在同一个对象上，`supports_parallel_tool_calls` 默认 `false`；`CoreToolRuntime` 补上 hook 与遥测；工具表每次采样前按开关、模型目录与执行环境重建，暴露方式有六种 | [工具系统总览](https://daiw.net/manual/codex-source/tool-architecture) |

### 流式与并发

| 概念 | 教学最小实现 | Codex 的生产实现 | 本专栏 |
| --- | --- | --- | --- |
| [流式处理](https://daiw.net/manual/llm-to-agent/streaming) | SSE 事件序列；文本来一片打一片，工具参数是攒到块结束才解析的部分 JSON | `codex-api` 把 SSE 与 WebSocket 事件统一翻译成 `ResponseEvent`，函数参数的增量事件直接忽略，调用以完整的输出项为准；app-server 再把消息、命令、补丁、MCP 调用统一成 item，按开始、增量、完成推给前端 | [模型客户端](https://daiw.net/manual/codex-source/model-client)、[v2 协议](https://daiw.net/manual/codex-source/app-server-protocol)、[工程实践](https://daiw.net/manual/codex-source/engineering) |
| [边流边执行](https://daiw.net/manual/llm-to-agent/streaming-tool-execution) | 工具块一结束就派发；并发安全的一起跑，其余串行 | 输出项一完成就 `tokio::spawn`，future 进 `FuturesOrdered`，流结束后 `drain_in_flight` 按调用顺序写回；并发靠一把读写锁，可并行的拿读锁、其余独占写锁，不必事先看到整批调用 | [工具系统总览](https://daiw.net/manual/codex-source/tool-architecture)、[run_turn 主循环](https://daiw.net/manual/codex-source/turn-loop) |

### 安全与控制

| 概念 | 教学最小实现 | Codex 的生产实现 | 本专栏 |
| --- | --- | --- | --- |
| [权限系统](https://daiw.net/manual/llm-to-agent/permissions) | 工具自分类、规则、从 plan 到 bypass 的权限模式；`canUseTool` 返回 allow、deny 或 ask；拒绝要喂回模型 | 拆成两个正交的量：`PermissionProfile` 管技术上能碰什么，由操作系统强制；`AskForApproval` 管越界前问不问。规则是 Starlark 写的执行策略，审批依次经过 hook、自动审查与用户，`Denied` 的理由作为工具结果交还 | [权限模型](https://daiw.net/manual/codex-source/permissions-model)、[审批流程](https://daiw.net/manual/codex-source/approvals-flow)、[执行策略](https://daiw.net/manual/codex-source/execpolicy)、[自动审查](https://daiw.net/manual/codex-source/guardian) |
| [中断与转向](https://daiw.net/manual/llm-to-agent/interrupt) | `AbortSignal` 贯穿到底；给悬空的工具合成“已取消”结果；转向是“打断加追加”，新话接到下一轮 | `Op::Interrupt` 触发取消令牌并以子令牌一路下传，任务有 100 毫秒自行收尾；历史里写一条 `<turn_aborted>` 标记，发出 `TurnAborted` 而不是错误事件；转向走 `turn/steer`，插进正在跑的这一轮 | [任务类型与 Plan 模式](https://daiw.net/manual/codex-source/tasks-and-plan-mode)、[run_turn 主循环](https://daiw.net/manual/codex-source/turn-loop)、[输入框](https://daiw.net/manual/codex-source/chat-composer) |
| [Hooks](https://daiw.net/manual/llm-to-agent/hooks) | PreToolUse、PostToolUse、Stop、UserPromptSubmit；外部命令从 stdin 读事件、用 stdout 表态 | 引擎叫 `ClaudeHooksEngine`，12 个事件，处理器是命令或 MCP 工具；按内容哈希记账，新增或改动的钩子要在 `/hooks` 里审阅信任才运行；goal 扩展相当于编译进来的 Stop 钩子 | [Hooks](https://daiw.net/manual/codex-source/hooks)、[扩展 API](https://daiw.net/manual/codex-source/extension-api) |

### 上下文工程

| 概念 | 教学最小实现 | Codex 的生产实现 | 本专栏 |
| --- | --- | --- | --- |
| [Token 预算](https://daiw.net/manual/llm-to-agent/token-budget) | 字符数除以 4 粗估，以 API 回报的 `input_tokens` 为锚；分级水位线，给抢救操作留余量 | 以上一次响应的 `total_tokens` 为准，加上之后新条目的按字节粗估；自动压缩阈值是窗口的 90%，另有 95% 的硬上限；开发中的 `token_budget` 开关还给模型一个 `get_context_remaining` 工具 | [上下文压缩](https://daiw.net/manual/codex-source/compaction)、[其它内置工具](https://daiw.net/manual/codex-source/builtin-tools) |
| [上下文注入](https://daiw.net/manual/llm-to-agent/context-injection) | 系统提示、环境、项目记忆、历史、动态附件分层拼装；静态放高处，动态放低处 | 系统提示只放基础指令，线程创建时定下；开发者指令、权限、协作模式、AGENTS.md、环境都是历史开头的消息，之后的变化以差异追加；每段注入都是实现 `ContextualUserFragment` 的具名结构体 | [指令从哪来](https://daiw.net/manual/codex-source/instructions)、[上下文与历史](https://daiw.net/manual/codex-source/context-history)、[Skills](https://daiw.net/manual/codex-source/skills) |
| [Prompt 缓存](https://daiw.net/manual/llm-to-agent/prompt-caching) | 显式缓存断点加滚动断点；守住字节稳定，要改先拷贝 | 请求里没有断点，只有默认取根线程 ID 的 `prompt_cache_key`；字节稳定靠只追加的历史、世界状态差分与确定性的合成条目 ID | [模型客户端](https://daiw.net/manual/codex-source/model-client)、[上下文与历史](https://daiw.net/manual/codex-source/context-history) |
| [自动压缩](https://daiw.net/manual/llm-to-agent/auto-compaction) | 保留近期、摘要远古；proactive 为主、reactive 兜底；摘要提示词决定成败 | 四个时机：开轮前、一轮中途、轮末、手动 `/compact`；OpenAI、Azure、Amazon Bedrock 走远程压缩，由服务端返回一个不透明的压缩条目，其余提供方在本地写交接摘要；新历史基本只剩最近的用户消息加上摘要 | [上下文压缩](https://daiw.net/manual/codex-source/compaction) |
| [精细化上下文管理](https://daiw.net/manual/llm-to-agent/context-compaction) | 工具结果超限就外置存盘，按 id 定点掏空，大块内容只留句柄 | 工具输出写进历史时按模型的截断策略截断，rollout 保留全文；命令输出先进 1 MiB 头尾缓冲，再按 token 预算保留头尾、截掉中间；压缩请求超窗时把末尾的工具输出换成占位文字 | [上下文与历史](https://daiw.net/manual/codex-source/context-history)、[执行命令](https://daiw.net/manual/codex-source/unified-exec)、[上下文压缩](https://daiw.net/manual/codex-source/compaction) |

### 健壮性

| 概念 | 教学最小实现 | Codex 的生产实现 | 本专栏 |
| --- | --- | --- | --- |
| [错误恢复](https://daiw.net/manual/llm-to-agent/error-recovery) | 分清可恢复与致命；指数退避加抖动、听 `Retry-After`；过载换模型；清理孤儿消息；每条恢复路径都要硬闸 | `CodexErr::retry_delay` 决定重不重试；流级重试默认 5 次，从 200 毫秒倍增、带 10% 抖动，优先用服务端建议的等待；WebSocket 重试用完退到 HTTPS；只把完整的输出项写进历史，重试接着已有进度做 | [run_turn 主循环](https://daiw.net/manual/codex-source/turn-loop)、[模型客户端](https://daiw.net/manual/codex-source/model-client) |
| [成本追踪](https://daiw.net/manual/llm-to-agent/cost-tracking) | 四类 token 分价目表累加；覆盖所有出口；美元预算做硬闸 | 客户端不计价，`ModelInfo` 没有价格字段；token 用量随 `thread/tokenUsage/updated` 通知到达，额度来自响应头里的限额快照；估算花费由服务端给出，另有 `codex.turn.cost_microusd` 指标 | [模型目录与提供方](https://daiw.net/manual/codex-source/models-and-providers)、[其它界面](https://daiw.net/manual/codex-source/tui-surfaces)、[遥测与分析](https://daiw.net/manual/codex-source/telemetry) |
| [扩展思考](https://daiw.net/manual/llm-to-agent/thinking) | 思考块带签名，必须原样保管；签名与生成它的模型绑定 | 请求的 `include` 固定为 `reasoning.encrypted_content`，推理以密文回到客户端、随历史再发回去；统计用量时先看服务端是否声明已计入推理；TUI 把推理摘要渲染成单独的单元 | [模型客户端](https://daiw.net/manual/codex-source/model-client)、[上下文压缩](https://daiw.net/manual/codex-source/compaction)、[历史记录单元](https://daiw.net/manual/codex-source/history-cells) |

### 扩展、规模与实战

| 概念 | 教学最小实现 | Codex 的生产实现 | 本专栏 |
| --- | --- | --- | --- |
| [子 Agent](https://daiw.net/manual/llm-to-agent/subagents) | 一个工具，内部递归跑 `runAgent`，只带回结论；子 Agent 的工具集里不放 `spawn_agent` | 子代理是同一个 `ThreadManager` 里的另一条线程；V1 按深度限制（`agents.max_depth` 默认 1），V2 限驻留数，结论作为 `FINAL_ANSWER` 投进父线程的信箱；`/review`、自动审查与记忆整合也都是受限的子代理 | [多 agent](https://daiw.net/manual/codex-source/multi-agent)、[自动审查](https://daiw.net/manual/codex-source/guardian)、[Codex Cloud、代码审查与 worktree](https://daiw.net/manual/codex-source/cloud-and-review) |
| [MCP 与懒加载](https://daiw.net/manual/llm-to-agent/mcp) | 外部工具适配成统一的 `Tool`；工具太多时只发简介，靠 `search_tools` 按需加载 | `McpRuntime`、`McpConnectionSet` 与每步冻结的 `McpBinding` 三层；工具改名进 `mcp__服务器` 命名空间，支持工具搜索的模型上默认延迟加载，由 `tool_search`（BM25，默认返回 8 个）取回；传输有 stdio 与可流式 HTTP，带 OAuth 与 elicitation | [MCP 工具调用](https://daiw.net/manual/codex-source/mcp-tool-calls)、[MCP 客户端](https://daiw.net/manual/codex-source/mcp-client-oauth)、[其它内置工具](https://daiw.net/manual/codex-source/builtin-tools) |
| [会话历史](https://daiw.net/manual/llm-to-agent/session-history) | append-only JSONL；抄本即真相，压缩只是运行时视图；恢复就是读回来接着循环 | 每个线程一个只追加的 rollout JSONL，压缩结果以 `compacted` 条目追加；SQLite 里的线程列表与分页历史是可以重建的投影；新建、恢复、分叉都汇入 `spawn_thread` | [会话持久化](https://daiw.net/manual/codex-source/rollout-and-storage)、[ThreadManager 与 CodexThread](https://daiw.net/manual/codex-source/thread-manager) |
| [仓库总结](https://daiw.net/manual/llm-to-agent/repo-summarization) | 六阶段流水线：git 裁剪、确定性骨架、符号地图、重要性排序、分治归并、验证与失效 | 没有专门的流水线：`/init` 把一段固定的提示词当作用户消息发出，让 agent 用平常的工具自己探索，写一份 `AGENTS.md` | [指令从哪来](https://daiw.net/manual/codex-source/instructions) |

最后一行值得多看一眼。`/init` 的实现只有三行：

```rust
            SlashCommand::Init => {
                const INIT_PROMPT: &str = include_str!("../../assets/prompt_for_init_command.md");
                self.submit_user_message(INIT_PROMPT.to_string().into());
            }
```

（`codex-rs/tui/src/chatwidget/slash_dispatch.rs:290`）

提示词 `codex-rs/tui/assets/prompt_for_init_command.md` 要求生成一份标题为 “Repository Guidelines” 的贡献者指南，200 到 400 词为宜，动笔前先看当前目录是否已有 `AGENTS.md`，有就不改。那本书用一整篇讲“注定读不完时怎么画地图”；Codex 把画地图交给模型现场探索，画好的地图再按[指令从哪来](https://daiw.net/manual/codex-source/instructions)的规则注入之后的每个会话，正好是那篇结尾说的分工：一份薄的全局摘要常驻上下文，具体问题靠工具现场去查。

## Codex 没照教学建议做的地方

对照表里有几行，Codex 的做法与那本书的建议不同，而且是有意为之。它们都出自各篇末尾的对照小节：

| 那本书的建议 | Codex 的做法 | 篇目 |
| --- | --- | --- |
| 主模型过载时自动降级到备用模型 | 过载错误不在重试之列，本轮结束并提示换一个模型，换不换交给用户 | [模型目录与提供方](https://daiw.net/manual/codex-source/models-and-providers) |
| 在客户端按价目表把 token 换算成钱 | 没有价格字段，也没有计价代码，花费以服务端给的数为准 | [模型目录与提供方](https://daiw.net/manual/codex-source/models-and-providers)、[其它界面](https://daiw.net/manual/codex-source/tui-surfaces) |
| 在稳定前缀末尾打缓存断点 | 不打断点，靠稳定的缓存键与处处维护的字节稳定 | [模型客户端](https://daiw.net/manual/codex-source/model-client) |
| plan 是最严的权限模式，写操作一律拒绝 | Plan 是协作模式，“不改文件”只写在提示词里，代码只拦下 `update_plan`；要硬性只读得靠沙箱与审批 | [任务类型与 Plan 模式](https://daiw.net/manual/codex-source/tasks-and-plan-mode) |
| Stop 钩子要配最大重试次数 | 不设硬上限，把 `stop_hook_active` 传给钩子，由钩子自己刹车 | [Hooks](https://daiw.net/manual/codex-source/hooks) |
| 超长的工具结果存盘，只给模型预览和路径 | 不存盘，保留头尾、截掉中间 | [执行命令](https://daiw.net/manual/codex-source/unified-exec) |
| 转向时结束当前回合，新消息接到下一轮 | 插话并入正在跑的这一轮，下一次采样就交给模型；想排到下一轮按 `Tab` | [run_turn 主循环](https://daiw.net/manual/codex-source/turn-loop)、[输入框](https://daiw.net/manual/codex-source/chat-composer) |
| 子 Agent 是一次同步的函数调用 | `spawn_agent` 立即返回，结论经通知或信箱回来 | [多 agent](https://daiw.net/manual/codex-source/multi-agent) |

这些差别大致出于两种考虑。一是 Codex 只说 Responses API 这一种协议，服务端能做好的事（计价、远程压缩、提示缓存与粘性路由）就交给服务端；二是能交给模型判断的事（什么时候申请提权、用哪个技能、Plan 模式下别动手），它更愿意写进提示词与工具说明，而不是写死在循环里。

## 贯穿全书的几条规律

- **界面与内核之间隔着一层协议。** TUI 的依赖里没有 `codex-core`，所有前端都经 app-server 的 v2 JSON-RPC 访问同一个服务端：`turn/start` 一启动就返回，进度全靠通知，审批是服务端反过来发给客户端的请求。连进程内嵌的那一份，也刻意保留请求、通知、事件这套模型（[workspace 全景](https://daiw.net/manual/codex-source/workspace-map)、[app-server](https://daiw.net/manual/codex-source/app-server-architecture)）。
- **内核是一对队列。** 一个线程在内核里就是一个 `CodexThread`：一端是提交 `Op` 的队列，一端是吐出 `EventMsg` 的队列，常驻的 `submission_loop` 逐个处理提交；一个会话同一时刻只跑一个任务（[ThreadManager 与 CodexThread](https://daiw.net/manual/codex-source/thread-manager)、[任务类型与 Plan 模式](https://daiw.net/manual/codex-source/tasks-and-plan-mode)）。
- **历史只追加，改写只有两个出口。** 根目录 `AGENTS.md` 把“不改写历史”写成了规矩；会变的上下文建模成世界状态的分区，第一轮全量、之后只追加差异；改写只剩压缩与回滚两处。落盘也一样：rollout 只追加，SQLite 只是它的投影（[上下文与历史](https://daiw.net/manual/codex-source/context-history)、[会话持久化](https://daiw.net/manual/codex-source/rollout-and-storage)）。
- **每次请求冻结一份快照。** 设置在开轮时提交成线程默认值，再冻结成只读的 `TurnContext`；每次采样前还要捕获一个 `StepContext`，发给模型的工具清单与随后执行调用的注册表是同一份（[Session 与 TurnContext](https://daiw.net/manual/codex-source/session-and-turn-context)、[工具系统总览](https://daiw.net/manual/codex-source/tool-architecture)）。
- **有副作用的动作都走同一个编排器。** 命令与补丁都经 `ToolOrchestrator`：审批、选沙箱、执行、被沙箱拒绝时视策略请求提权重试；审批请求先交给 hook，开了自动审查就交给审查模型，最后才轮到你（[审批流程](https://daiw.net/manual/codex-source/approvals-flow)）。
- **沙箱与审批各管一件事，三个平台各自落地。** 一个决定命令技术上能碰什么，一个决定越界前问不问，两者自由组合；macOS 现拼 Seatbelt 策略，Linux 用 bubblewrap 加 seccomp，Windows 用写受限令牌、elevated 模式另建专门的沙箱用户，联网再交给本地代理按名单放行（[权限模型](https://daiw.net/manual/codex-source/permissions-model)、[网络代理](https://daiw.net/manual/codex-source/network-proxy)）。
- **可覆盖的配置与不可越过的约束分成两摞。** config 层逐键合并出生效值，requirements 层合成管理员的约束，再把取值关进 `Constrained` 校验器，会话中途切换也越不过去（[配置系统](https://daiw.net/manual/codex-source/config-system)）。
- **拿不准就拒绝。** 跨进程的审批答复解析失败或客户端报错，一律按拒绝处理；Linux 沙箱遇到 glob 展开过多、残留特权、代理端点解析不出这类情况直接报错，不降级成无沙箱；执行策略多条命中时取最严格的那条（[app-server](https://daiw.net/manual/codex-source/app-server-architecture)、[Linux 沙箱](https://daiw.net/manual/codex-source/linux-sandbox)、[执行策略](https://daiw.net/manual/codex-source/execpolicy)）。

## Codex 独有的那一半

对照表只覆盖两本书都讲到的交集。Codex 作为一个多端产品，还有一大块在教学实现里找不到对应物：

| 方面 | 做什么 | 篇目 |
| --- | --- | --- |
| 服务化 | app-server 守护进程被多个客户端共享，可经 stdio、Unix socket、WebSocket 或远程控制接入；exec-server 把起进程、读写文件、发 HTTP 请求搬到本机或另一台机器 | [守护进程与传输](https://daiw.net/manual/codex-source/daemon-and-transport)、[exec-server](https://daiw.net/manual/codex-source/exec-server) |
| 操作系统级安全 | 三套沙箱、联网代理、Starlark 执行策略，以及让另一个模型替你审批的自动审查 | [macOS 沙箱](https://daiw.net/manual/codex-source/seatbelt)、[Linux 沙箱](https://daiw.net/manual/codex-source/linux-sandbox)、[Windows 沙箱](https://daiw.net/manual/codex-source/windows-sandbox)、[自动审查](https://daiw.net/manual/codex-source/guardian) |
| 组织与分发 | 托管的 requirements、插件与 marketplace、从 Claude Code 与 Cursor 导入配置 | [配置系统](https://daiw.net/manual/codex-source/config-system)、[插件](https://daiw.net/manual/codex-source/plugins)、[从别的 agent 迁移](https://daiw.net/manual/codex-source/external-agent-migration) |
| 跨会话的积累 | 后台把旧会话提炼成记忆；goal 扩展在线程空闲时自动开下一轮，直到目标完成或预算耗尽 | [记忆](https://daiw.net/manual/codex-source/memories)、[扩展 API](https://daiw.net/manual/codex-source/extension-api) |
| 编辑与执行的格式 | 自有的 `apply_patch` 补丁格式、可跨轮续写的命令会话、让模型写 JavaScript 编排工具的 Code mode | [apply_patch](https://daiw.net/manual/codex-source/apply-patch)、[执行命令](https://daiw.net/manual/codex-source/unified-exec)、[Code mode](https://daiw.net/manual/codex-source/code-mode) |
| 产品表面 | 占全仓约四分之一非测试代码的终端界面，以及登录认证、实时语音、遥测、Codex Cloud 与代码审查 | [TUI 架构](https://daiw.net/manual/codex-source/tui-architecture)、[登录与认证](https://daiw.net/manual/codex-source/login-and-auth)、[实时语音](https://daiw.net/manual/codex-source/realtime-voice)、[遥测与分析](https://daiw.net/manual/codex-source/telemetry) |

教学实现回答“为什么要这样做、最少要做什么”；Codex 回答的是“同一个内核要服务多个前端、三个操作系统和一个组织时，还得长出哪些层”。想深挖哪个概念，查上面的表，先读本专栏对应的篇目，再点回那本书看最小版本。

下一篇换个角度，把 Codex 和站里另外两本读得最细的开源实现 Grok Build、OpenCode 放在一起比较。

---

上一篇：[工程实践 · 测试、构建与发布](https://daiw.net/manual/codex-source/engineering) · 下一篇：[横向对比 · Codex 与 Grok Build、OpenCode](https://daiw.net/manual/codex-source/codex-vs-others)
