# 读完之后

> 全书收尾，不讲新代码：按兴趣分出七条重读路线；在自己机器上构建、调试与读测试的入口；Codex 不接受外部代码贡献，想参与要走 issue，动手前该读 docs/contributing.md 与 AGENTS.md；以及几条可以带回你自己 agent 的设计。

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

# 读完之后

这是全书的最后一篇。从[一条消息的生命周期](https://daiw.net/manual/codex-source/message-lifecycle)出发，我们沿着 app-server、内核、工具、安全、扩展、终端界面与运行形态，一路拆到了[测试、构建与发布](https://daiw.net/manual/codex-source/engineering)。这一篇不讲新代码，只回答四个问题：接下来读什么；怎么在自己机器上把它跑起来、调起来；想参与 Codex 该走哪扇门；哪些设计值得带回你自己的 agent。

## 接着读：挑一条线

全书按“一条消息穿过的层次”排序，第二遍不妨按兴趣挑一条线读。每条线都从[一条消息的生命周期](https://daiw.net/manual/codex-source/message-lifecycle)出发：

```mermaid
flowchart LR
  L[一条消息的生命周期] --> A[服务化<br/>app-server、协议、守护进程]
  L --> K[内核<br/>run_turn、上下文、压缩]
  L --> T[工具<br/>工具表、命令、补丁、MCP]
  L --> S[安全<br/>权限、审批、三平台沙箱]
  L --> E[扩展<br/>配置、Skills、Hooks、插件、多 agent]
  L --> U[界面<br/>TUI]
  L --> G[工程<br/>workspace、约定、CI 与发布]
  A & K & T & S & E & U & G --> D[动手<br/>构建、调试、读测试]
  D --> Y[带回自己的 agent]
```

| 路线 | 适合谁 | 建议顺序 |
| --- | --- | --- |
| 服务化 | 想让一个内核服务多个前端，或要接 IDE、写 SDK | [app-server](https://daiw.net/manual/codex-source/app-server-architecture) → [v2 协议](https://daiw.net/manual/codex-source/app-server-protocol) → [守护进程与传输](https://daiw.net/manual/codex-source/daemon-and-transport) → [ThreadManager](https://daiw.net/manual/codex-source/thread-manager) → [codex exec 与 SDK](https://daiw.net/manual/codex-source/exec-and-sdk) → [exec-server](https://daiw.net/manual/codex-source/exec-server) |
| 内核 | 想写自己的 agent 循环与上下文管理 | [Session 与 TurnContext](https://daiw.net/manual/codex-source/session-and-turn-context) → [run_turn](https://daiw.net/manual/codex-source/turn-loop) → [模型客户端](https://daiw.net/manual/codex-source/model-client) → [上下文与历史](https://daiw.net/manual/codex-source/context-history) → [上下文压缩](https://daiw.net/manual/codex-source/compaction) → [指令从哪来](https://daiw.net/manual/codex-source/instructions) → [任务类型与 Plan 模式](https://daiw.net/manual/codex-source/tasks-and-plan-mode) |
| 工具 | 想设计工具接口、命令执行与文件编辑 | [工具系统总览](https://daiw.net/manual/codex-source/tool-architecture) → [执行命令](https://daiw.net/manual/codex-source/unified-exec) → [读懂一条命令](https://daiw.net/manual/codex-source/shell-command-analysis) → [apply_patch](https://daiw.net/manual/codex-source/apply-patch) → [MCP 工具调用](https://daiw.net/manual/codex-source/mcp-tool-calls) → [其它内置工具](https://daiw.net/manual/codex-source/builtin-tools) → [Code mode](https://daiw.net/manual/codex-source/code-mode) |
| 安全 | 关心“放手让它干”的边界在哪 | [权限模型](https://daiw.net/manual/codex-source/permissions-model) → [审批流程](https://daiw.net/manual/codex-source/approvals-flow) → [执行策略](https://daiw.net/manual/codex-source/execpolicy) → 自己平台的沙箱（[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/network-proxy) → [自动审查](https://daiw.net/manual/codex-source/guardian) |
| 扩展 | 想写 skills、hooks、插件，或让几个 agent 协作 | [配置系统](https://daiw.net/manual/codex-source/config-system) → [Skills](https://daiw.net/manual/codex-source/skills) → [Hooks](https://daiw.net/manual/codex-source/hooks) → [插件](https://daiw.net/manual/codex-source/plugins) → [MCP 客户端](https://daiw.net/manual/codex-source/mcp-client-oauth) → [多 agent](https://daiw.net/manual/codex-source/multi-agent) → [扩展 API](https://daiw.net/manual/codex-source/extension-api) → [记忆](https://daiw.net/manual/codex-source/memories) |
| 界面 | 想做终端 UI | [TUI 架构](https://daiw.net/manual/codex-source/tui-architecture) → [输入框](https://daiw.net/manual/codex-source/chat-composer) → [历史记录单元](https://daiw.net/manual/codex-source/history-cells) → [全屏对话记录](https://daiw.net/manual/codex-source/fullscreen-transcript) → [其它界面](https://daiw.net/manual/codex-source/tui-surfaces) |
| 工程 | 想学大型 Rust 仓库怎么组织、怎么守规矩 | [从源码构建与运行](https://daiw.net/manual/codex-source/build-and-run) → [workspace 全景](https://daiw.net/manual/codex-source/workspace-map) → [读源码之前](https://daiw.net/manual/codex-source/reading-the-source) → [工程实践](https://daiw.net/manual/codex-source/engineering) → [遥测与分析](https://daiw.net/manual/codex-source/telemetry) |

每条线都可以对照《从 LLM 到 Coding Agent》读，[复盘](https://daiw.net/manual/codex-source/recap)里那张对照表就是索引；想看同一件事在别家怎么做，查[横向对比](https://daiw.net/manual/codex-source/codex-vs-others)。

## 在自己机器上跑起来

从源码构建，`docs/install.md` 给的步骤如下（中间安装 Rust 工具链的几行省略）：

```bash
# Clone the repository and navigate to the root of the Cargo workspace.
git clone https://github.com/openai/codex.git
cd codex/codex-rs
# ...
# Install helper tools used by the workspace justfile:
cargo install --locked just
# DotSlash fetches pinned development tools such as buildifier on first use.
cargo install --locked dotslash
# Install nextest for the `just test` helper.
cargo install --locked cargo-nextest

# Build Codex.
cargo build

# Launch the TUI with a sample prompt.
cargo run --bin codex -- "explain this codebase to me"
```

（`docs/install.md:18`）

工具链不用自己挑，`codex-rs/rust-toolchain.toml` 钉在 1.95.0，并带上 `clippy`、`rustfmt`、`rust-src` 三个组件。日常操作都包在仓库根的 `justfile` 里，它第一行就把工作目录定到 `codex-rs`：`just codex`（别名 `just c`）与 `just exec` 从源码跑 TUI 和 `codex exec`；`just test -p <crate>` 用 nextest 只跑一个 crate 的测试；`just fmt`、`just fix -p <crate>` 负责格式化与 clippy 修复；想走 Bazel，用 `just bazel-codex`。在 Unix 上，`just tui-with-exec-server` 先起一个 `codex exec-server` 再开 TUI，适合试 [exec-server](https://daiw.net/manual/codex-source/exec-server) 那种把“想”和“做”分开的形态。两套构建的分工见[从源码构建与运行](https://daiw.net/manual/codex-source/build-and-run)，CI 的分层与发布流水线见[工程实践](https://daiw.net/manual/codex-source/engineering)。

## 调试与读代码的入口

- **模型到底收到了什么**：`codex debug prompt-input "..."` 把模型可见的输入列表打成 JSON，开头那几条带标记的 developer 与 user 消息，就是[上下文与历史](https://daiw.net/manual/codex-source/context-history)讲的注入片段。
- **协议层怎么往来**：`codex debug app-server send-message-v2 "..."` 起一个 `codex app-server` 子进程，打印 `initialize`、`thread/start`、`turn/start` 的响应和随后的通知（[一条消息的生命周期](https://daiw.net/manual/codex-source/message-lifecycle)）。
- **模型目录里有什么**：`codex debug models` 打印当前目录，加 `--bundled` 只看随二进制分发的那一份（[模型目录与提供方](https://daiw.net/manual/codex-source/models-and-providers)）。
- **沙箱与规则**：`codex sandbox -- <命令>` 在本平台的 Codex 沙箱里单独跑一条命令，macOS 上加 `--log-denials` 会在结束后列出被拦下的操作；隐藏子命令 `codex execpolicy check` 离线检验规则文件（[macOS 沙箱](https://daiw.net/manual/codex-source/seatbelt)、[执行策略](https://daiw.net/manual/codex-source/execpolicy)）。
- **日志**：Rust 侧认 `RUST_LOG`；`codex -c log_dir=<目录>` 让 TUI 另写一份纯文本日志；`just log` 从 SQLite 日志库里跟踪。仓库自带的 `test-tui` 技能就是这样验证界面改动的：设 `RUST_LOG="trace"`，再用 `just codex -c log_dir=<目录>` 启动。
- **把一次会话录下来**：`CODEX_TUI_RECORD_SESSION=1` 让 TUI 把收发的消息记进 `session-*.jsonl`；设了 `CODEX_ROLLOUT_TRACE_ROOT` 才会在本地写 rollout trace，隐藏命令 `codex debug trace-reduce` 把它归约成 `state.json`（[遥测与分析](https://daiw.net/manual/codex-source/telemetry)）。
- **把测试当说明书**：`codex-rs/core/tests/suite/` 下的文件名基本就是功能名，用假的 Responses API 驱动真的 agent；TUI 的 `.snap` 快照是现成的效果图；`codex-rs/thread-manager-sample/src/main.rs` 不到 500 行，不经 app-server 直接驱动 `ThreadManager`（[读源码之前](https://daiw.net/manual/codex-source/reading-the-source)、[工程实践](https://daiw.net/manual/codex-source/engineering)）。

## 想参与 Codex

先说结论：Codex 不接受外部的代码贡献。`docs/contributing.md` 第二段只有一句加粗的话，“We do not accept external code contributions or pull requests.”理由也写在里面：有效的改动需要架构上下文、系统层面的约束和对路线图的了解；外部 PR 往往优先级不高、影响面小，或者要大改才能融进整个系统，审查与来回修改花的时间可能比团队直接修还多；弄清问题、找对方案、排好优先级才是难的部分，借助 Codex 本身，实现反倒相对容易。社区能参与的是 issue：

- 开新 issue 前先搜索，已经有人报过，就往那一条里补信息；
- 报 bug 写清复现步骤、预期与实际行为、Codex 版本与操作系统等环境信息，附上去掉敏感内容的日志与错误信息，能给出根因分析或修复思路更好；
- 功能请求讲清用例与期望的行为，或者给已有的同类请求投票；
- 安全漏洞不要公开提 issue，按根目录 `SECURITY.md` 的说明，走 OpenAI 在 Bugcrowd 上的漏洞披露项目。

读完这本书，最能派上用场的正是根因分析：一份能指到文件与行号的分析，比“某个功能不好用”有用得多。Grok Build 同样不接受外部 PR（见那本专栏的[读完之后](https://daiw.net/manual/grok-build/whats-next)）；对这类项目，开源的意义在于你能读、能在自己的分叉里改、能自己构建。

在分叉里动手，或者想让根因分析说到点子上，根目录的 `AGENTS.md` 值得照着做。它是团队写给所有贡献者（包括 Codex 自己）的规矩，最常用的几条：

- 改完先 `just fmt`；测试用 `just test -p <crate>`，不直接 `cargo test`；改动碰到 common、core 或 protocol 时再跑全量的 `just test`；大改动收尾前跑 `just fix -p <crate>`；
- 用户看得见的界面改动要附 insta 快照；改 agent 行为优先写 `core/suite` 下的集成测试；
- 一次改动一般不超过 800 行，复杂逻辑不超过 500 行；新概念先考虑放进别的 crate 或新开 crate，别往 `codex-core` 里塞；
- 改了配置类型跑 `just write-config-schema`，改了 app-server 协议跑 `just write-app-server-schema`，改了 Rust 依赖跑 `just bazel-lock-update` 并提交 `MODULE.bazel.lock`；
- 往模型上下文里加东西，先过“模型可见上下文”那六条：不改写历史，少让缓存失效，每项有界且不超过 10K token（[读源码之前](https://daiw.net/manual/codex-source/reading-the-source)）。

仓库自带的 `.codex/skills/` 还透露了团队自己怎么审代码：`code-review` 技能为每个 `code-review-*` 技能各派一个子代理，这几个技能分别对应 `AGENTS.md` 里破坏性变更、改动规模、模型可见上下文与测试这几节；`test-tui`、`remote-tests` 则记下了怎么交互式地验证界面，怎么让集成测试跑在远程执行端上。

## 把设计带回你自己的 agent

先说一句别照搬：Codex 的 153 个 crate，是为多个前端、三个操作系统和组织托管长出来的。你的 agent 若只有一个终端界面、只跑在自己机器上，[《从 LLM 到 Coding Agent》](https://daiw.net/manual/llm-to-agent)的最小实现就够起步。下面几条与规模无关，小项目也用得上：

1. **从第一天就把“提交”和“事件”分开。** 界面发出请求后立即返回，进度全走事件，审批做成内核反过来向界面发的请求。哪怕只有一个前端，这道缝也让你以后接 IDE、写 SDK、做无界面模式时不必动内核（[app-server](https://daiw.net/manual/codex-source/app-server-architecture)、[一条消息的生命周期](https://daiw.net/manual/codex-source/message-lifecycle)）。
2. **历史只追加，会变的上下文当成“世界状态”。** 第一轮全量注入，之后只追加差异；换模型、改项目指令都用一条新消息来表达。提示缓存能命中、会话能原样回放，都从这里来（[上下文与历史](https://daiw.net/manual/codex-source/context-history)）。
3. **给每一段注入起名字、设上限。** 注入的文字用具名结构表示，带起止标记与硬上限；回滚与界面展示都靠这些标记认出哪些不是用户说的话（[上下文与历史](https://daiw.net/manual/codex-source/context-history)、[读源码之前](https://daiw.net/manual/codex-source/reading-the-source)）。
4. **每次请求冻结一份快照。** 发给模型的工具清单与执行时查的注册表用同一份，设置在开轮时冻结，中途的改动只影响下一步（[Session 与 TurnContext](https://daiw.net/manual/codex-source/session-and-turn-context)、[工具系统总览](https://daiw.net/manual/codex-source/tool-architecture)）。
5. **把“能不能做”和“要不要问”拆开。** 前者交给操作系统强制，后者交给策略；所有有副作用的动作都走同一个编排器，审批答复出了任何差错都按拒绝处理（[权限模型](https://daiw.net/manual/codex-source/permissions-model)、[审批流程](https://daiw.net/manual/codex-source/approvals-flow)）。
6. **真相写在只追加的日志里，数据库只当投影。** 投影坏了能从日志重建；Codex 的数据库迁移还刻意让旧版本的二进制也能打开被新版本迁移过的库（[会话持久化](https://daiw.net/manual/codex-source/rollout-and-storage)）。
7. **把规矩写成给 agent 读的文档，再用 lint 与 CI 守住。** `AGENTS.md` 定方向，clippy 的 `deny`、自研的参数注释 lint 与一串 CI 自检脚本负责落实，写代码的人与 agent 守同一套规矩（[读源码之前](https://daiw.net/manual/codex-source/reading-the-source)、[工程实践](https://daiw.net/manual/codex-source/engineering)）。

## 用法、原理与同类

- **怎么用**：[《Codex 中文手册》](https://daiw.net/manual/codex)与本专栏用同一个版本基准，常翻的是[安装、登录与升级](https://daiw.net/manual/codex/installation)、[配置项速查](https://daiw.net/manual/codex/config-reference)、[沙箱、审批与安全](https://daiw.net/manual/codex/sandbox-approvals)、[SDK 与 App Server](https://daiw.net/manual/codex/sdk-app-server)，新版本改了什么看[更新日志](https://daiw.net/manual/codex/changelog)。
- **为什么这样做**：[《从 LLM 到 Coding Agent》](https://daiw.net/manual/llm-to-agent)讲一个 agent 在裸 API 之上必须补齐的那一圈，附一个可以运行的最小实现。
- **别家怎么做**：[《Grok Build 源码解读》](https://daiw.net/manual/grok-build)、[《OpenCode 源码解读》](https://daiw.net/manual/opencode)，以及同组的 [Kimi Code](https://daiw.net/manual/kimi-code)、[MiMo Code](https://daiw.net/manual/mimo-code)、[MiniMax Code](https://daiw.net/manual/minimax-code)、[ZCode](https://daiw.net/manual/zcode) 几本。
- **闭源产品的用法**：[《Claude Code 中文手册》](https://daiw.net/manual/claude-code)。

## 最后

本专栏的行号都固定在 `rust-v0.158.0` 上。你读到这里时，HEAD 多半已经往前走了，书里标着“开发中”的那些开关（比如 `token_budget`、`code_mode`、`step_model_switching`）尤其可能变样；想追某一块的变化，拿两个 tag 对相应目录做一次 `git diff` 就能看清。不过这本书梳理的骨架——前端只认 app-server，内核是一对队列，历史只追加，有副作用的动作都走编排器，沙箱与审批各管一件事——通常比任何一个行号都活得久。

从按下回车的那一刻一路读到这里，谢谢。回到[专栏封面](https://daiw.net/manual/codex-source)可以查任意一篇；现在，去读你最感兴趣的那个角落，或者去写你自己的 agent 吧。

---

上一篇：[横向对比 · Codex 与 Grok Build、OpenCode](https://daiw.net/manual/codex-source/codex-vs-others)
