真实 Agent 系统源码巡礼
前十章给了你词汇和判断框架,这一章把它们在一个真实的、今天还在被工程师 commit 的生产级 agent 系统里一个个指出来。走开源的 OpenAI Codex(Rust),看 loop、工具、沙盒、权限、压缩、状态、子 agent 各自长在哪个模块、对应你学过的哪一章;顺带看清为什么同一个抽象在不同系统里只是换了名字。读完你能拿走一套读法和纪律,面对任何真实 agent 系统都能自己对号入座。前置:Ch2-10。
这是 Agent 工程路书的第 11 章,约 2.5 小时,纯 Mode A,第四站「运维」的第三章。前面十章给了你词汇和判断框架:agent loop、工具与 MCP、沙盒、对抗安全、context 工程、memory、multi-agent、评测、失败 taxonomy。这一章不教任何新概念,它做一件别的事:把这些抽象,在一个真实的、今天还在被工程师 commit 的生产级 agent 系统里,一个一个指出来。
读这一章的姿势和前面都不一样。前面是「学会一个抽象」,这一章是「指着真代码说出它对应你学过的哪个抽象、为什么这么设计、trade-off 在哪」。我们走的是一套三段读法:先说这一段对应前面哪一章,再看真实系统里它长什么样、在哪个 crate,最后停下来想一个判断力训练点。读完后,你拿到的不是「看过一遍源码」,而是一种可迁移的能力:面对任何一个真实 agent 系统(Cursor、Devin、Aider、还没出现的下一个),你能自己 clone 下来,把它的子系统一个个对到你脑子里的抽象上。
主走读系统是 OpenAI 开源的 Codex,一个用 Rust 写的真实 code agent。为什么是它而不是别的,本身就是这一章第一个判断题,答案牵出一条 Ch5 的合规素养,下一节就讲。
7 节:0 怎么读 + 为什么是 Codex · 1 八子系统总览 · 2 形态与循环 · 3 工具、权限、沙盒 · 4 长任务三件套 · 5 拦截与失败 · 6 换名同抽象 + pin-commit。
边界:这一章只做映射,不重讲概念。每个子系统的「是什么 + 怎么工程化」已经分别由前十章讲完,这里看到一个抽象就指回它的那一章。所有行级引用都钉在一个 commit 快照上(Codex HEAD 462deb0,2026-05-28),因为这是个活仓库、代码会漂;你真正要带走的是「子系统对到抽象」的映射,那个不漂。
0. 这一章怎么读,以及为什么主走读是 Codex
先把读法说清。这是一章 capstone,它的载荷不是让你「看过源码」,而是让抽象有形、具象有名。前十章你学的每一个词,都是一个抽象;抽象的麻烦在于它飘在半空,你能复述却未必能在真代码里认出来。这一章把每个抽象钉到一行真实代码上,钉完之后,抽象就有了形状,代码里那些原本陌生的模块就有了你熟悉的名字。具体读法是三段:对应前面哪一章,真实系统怎么做(具体到 crate 和文件,带 commit 快照),以及一个判断力训练点。这套读法不是这一章发明的,它继承自架构师课里那一章被验证有效的源码走读法,只是这次走的是一个真正能合法逐行读的系统。
而「能合法逐行读」恰恰是这一章第一个、也是最重要的判断。巡礼的前提是源码真的摆在那、你能引、能 pin 到某个版本。这件事在 2026 年不是理所当然的。
OpenAI 的 Codex 是真开源的,Apache-2.0 许可,你可以合法地逐行引用,它的 HEAD 今天还在 commit、可以钉到一个具体的 commit SHA,而且 OpenAI 自己写了一个官方的源码走读博客系列,把 Rust 的阅读门槛大幅压低,你不必会写 Rust,跟着走读理解工程语义就够了。Claude Code 则相反,它是闭源的,发行物是一个压缩成一行、约 12MB、变量名全是乱码的 cli.js。2026 年 3 月它确实误发过一次 source map、把内部源码泄露了出来,但有一件事必须说清楚:泄露不等于开源,它的许可证一个字没改、仍然不允许再分发或修改,Anthropic 随后还发了 DMCA。把一份 DMCA 在追的泄露源码当一手引用,既不合法也不可复核,而这件事本身就是 Ch5 教的合规素养的活教材。所以这一章的选择是:主走读交给真开源的 Codex,Claude Code 只用它的公开行为、官方文档、以及它体系里唯一真开源的那个沙盒组件来做架构对照。
这个选择把这一章从「引一份来路不正的泄露代码」升级成了「引一份今天还在 commit、有官方走读、可以合法 pin 的真仓库」。值得一提的是,这恰好也是一个 why-now:agent 工程到 2026 年才成熟到有这样一个生产级、真开源、子系统清晰的 harness 可供逐行巡礼,Codex 在 2025 年 4 月从 TypeScript 全量重写为 Rust 开源,正是这门学科长大的一个标志。
1. 八个子系统,在一个真系统里对号入座
Codex 有一个对这一章特别友好的性质:它的子系统几乎一对一地对应到一个个可读的 crate。这种整齐的对应,正是 capstone 对号入座最需要的脚手架。
这张图是这一章的骨架,接下来四节就是沿着它走。每一个子系统,你都会看到它在 Codex 里的真实位置、它对应你学过的哪一章、以及一个判断点。这里先立一个总的判断框架,它本身就是这一章想给你的可迁移能力:面对任何一个 code agent,你都该能问出同一组问题——它的 loop 在哪、什么时候停?权限怎么设、谁来批?沙盒在哪、能炸多大?context 怎么压?状态能不能 resume?子 agent 怎么派?能问出这组问题,说明前十章的抽象已经长进了你的判断里,而不只是停在术语层。
2. 形态与循环:agent 长什么样,循环怎么转
先看整体形态,对应 Ch1 那条 Model + Harness = Agent 的命题。Codex 作为一个 code agent,形态是一个跑在你机器上的命令行程序:cli crate 用一个 MultitoolCli 路由各种子命令,tui 是全屏交互界面,exec 和 exec-server 提供无界面的 headless 模式。关键的判断点是,CLI、云端、VSCode 扩展这三个产品,共用同一个 core crate 里的 loop 和执行逻辑——读懂一处,等于理解了一整个产品族的地基。这正是 Ch1 那个命题的实物:模型是同一个,真正区分出不同产品形态的,是外面那层 harness。
再看循环,对应 Ch2 的 loop 作为状态机。Codex 把一次执行叫一个 thread,核心在 core/src/codex_thread.rs 和 thread_manager.rs,后者是所有执行模式的汇聚点,而 tasks/ 下面按 turn 的类型分成了 regular、compact、review 几种。一个 turn 是从一次用户输入到一次回复,内部可以包含多次模型和工具的来回迭代,而这个 turn 以一条 assistant message 终止,这就是 loop 的终止信号,正好对照 Ch2 讲的状态机和终止条件。这里有一个绝佳的对照素材:Claude 的 Agent SDK 用一个 query() 异步生成器替你把这个 loop 跑了,你看不见里面;而 Codex 把这个内核打开摊在你面前。同一个抽象,一边是替你跑的黑箱、一边是打开看的实现,Ch2 讲「harness 是什么」时立的那个点,在这里有了两个可对照的实物。判断点是 loop 的流式可中断性:tui 怎么在模型还在吐字时让你能打断它,这是 Ch2 留的判断题。
3. 工具、权限、沙盒:伸手做事的三道关
工具调度对应 Ch3 的工具与 MCP 工程。Codex 的 tools/ crate 里,tool_executor、tool_router、tool_definition 是工具的统一接口和分发,而 tool_discovery 正是 Ch3 讲的「工具多了怎么发现、怎么选」的实物。MCP 在这里尤其有看头:Codex 既有 mcp-server(它自己作为 server 被别人调)又有 rmcp-client(它作为 client 调别人),是双向的;还有一个 code-mode crate,正是 Ch3 讲的那个正在收敛的范式——让 agent 写代码来调工具,而不是一个个 function call。判断点还是 Ch3 那张工具设计清单:名字、描述、schema、权限、并发,每一项在 tool_definition 里都能找到对应。
权限门对应 Ch5 的对抗安全里那道 permission gate。Codex 把它独立成了一个 execpolicy crate,里面 policy、rule、decision 各司其职:已知安全的读操作自动跑,会改变状态的命令需要审批。还有一个很关键的 core/src/command_canonicalization.rs,它在判断一条命令该不该批之前,先把外面包的 wrapper 和环境变量层层剥掉再看,这正是 Ch4 讲的那条「剥安全 wrapper 必须是迭代的、否则会被绕过」。这里要立一个这一章反复出现的正交关系:审批和沙盒是两根独立的轴。execpolicy 管的是要不要先问人,是 autonomy 轴;沙盒管的是真跑起来能炸多大,是 containment 轴。两者正交,这是 Ch4 和 Ch5 一起立的点。
沙盒对应 Ch4 的隔离机制阶梯。Codex 的 sandboxing/ crate 把 Ch4 那道阶梯落成了真代码:macOS 用 seatbelt.rs 加一个 deny default 的 SBPL profile,Linux 用 landlock.rs 加 bwrap.rs 加 seccomp,还有独立的 network-proxy 管网络出口,正是 Ch4 那个连向 Ch5 的 egress 桥。判断点是 Ch4 那条第一分水岭:共享内核还是独立内核,Codex 这些机制全都落在共享内核那一档。这里有一个干净的跨厂商对照:Claude 体系里唯一真开源的核心组件 @anthropic-ai/sandbox-runtime,把 macOS 的 Seatbelt 和 Linux 的 bwrap 封装成了一个统一的管理器 API,你可以拿它和 Codex 的 sandboxing crate 对照着看两家怎么解同一个隔离问题。
4. 长任务三件套:压缩、状态、子 agent
context 压缩对应 Ch6 的 context 策略。Codex 的 core/src/compact.rs 加上 compact_remote_v2.rs 和 context_manager/,实现了「prompt 随对话深度线性增长,到一定程度自动 compaction」。这里有个 Codex 特有的工程分野值得注意:它区分本地 compact 和远程 compact,compact_remote 是把压缩这件事放到服务端做。判断点是 Ch6 那条:压缩不是「满了才压」,而是一套策略,你在 context_manager 里能看到它怎么决定压什么、什么时候压。
状态持久对应 Ch7,也回扣 Ch2 的 durable execution。Codex 的 rollout/ crate 有一个 RolloutRecorder,在后台异步把每一步写成 JSONL,而 state/ 用一个 SQLite 索引存 thread 的元数据。这套设计撑起了 codex resume 和 codex fork——你可以恢复一个中断的会话,或从某个点分叉。这正是 Ch2 讲的 durable execution 在 agent loop 语义上的实物;而那份 JSONL 的 rollout,同时又是一条可审计的 trajectory,正好对照 Ch9 讲的评测可观测性——状态持久和可观测性,在这里是同一份数据的两个用途。
memory 和子 agent 分别对应 Ch7 和 Ch8。memory 这一侧,Codex 用 skills 和 core-skills 实现了文件系统形态的 skill,配的是一个 AGENTS.md 文件,正好和 Claude 体系的 CLAUDE.md 加 .claude/skills 形成跨厂商对照——又是换了名字的同一个抽象。子 agent 这一侧,core/src/agent/ 里有 registry 和 role,还内置了 explorer、awaiter 这样的具名子 agent,配合 codex_delegate 做委派,还有一个 agent-graph-store 存多 agent 的关系图,正好对照 Ch8 讲的 orchestrator-worker 和 handoff 拓扑。判断点是 Ch7 和 Ch8 的选型题:什么时候用具名 memory、什么时候真该上 multi-agent。
5. 拦截与失败:harness 的拦截层和它怎么扛错
还有两类子系统值得单独点出来,它们对应 Ch2、Ch5 和 Ch10 的失败 taxonomy。一类是 hooks:Codex 有一个 hooks/ crate,带 engine、events、registry,加上 core/src/hook_runtime.rs,实现了 PreToolUse、PostToolUse 这类拦截点,可以在工具执行前后 deny、log、或者改写。这正是 harness 的拦截层,和 Claude Agent SDK 暴露的 hooks 一一对应,也是 Ch5 讲的「在动作执行前评估」那道门的实物。另一类是错误处理:retry 和 backoff 散落在 core/src/client 相关的几个文件里,错误分类决定了哪些重试、哪些放弃,这直接对照 Ch10 的失败 taxonomy。这里可以保留架构师课那个被匿名化的洞察:任何自动重试都必须有熔断器,因为真实系统因为缺熔断器吃过「一天浪费几十万次 API 调用」的亏——这是 Ch2 的终止与预算、也是 Ch10 的成本崩溃,在真代码里你能看到熔断逻辑长在哪。
6. 换了名字,同一个抽象,以及读活仓库的纪律
走完八个子系统,你应该已经感觉到一件事:同一个抽象,在不同的系统里只是换了名字。
loop,Codex 是打开看的内核、Claude SDK 是替你跑的 query();权限,Codex 叫 execpolicy 引擎、Claude 是三级权限级联、行为上是 deny 到 ask 到 allow;沙盒,Codex 在 sandboxing crate、Claude 在 sandbox-runtime;连 context 配置文件,Codex 叫 AGENTS.md、Claude 叫 CLAUDE.md。这件事的意义不只是趣闻:它证明了 Ch2 到 Ch10 教的那些抽象是跨系统的不变量,不是某一家的术语。你学的不是 Codex 怎么做,你学的是 agent harness 这件事本身怎么做,Codex 只是它在 2026 年的一个具体长相。
最后是一条这一章不能省的方法论:pin-commit 纪律。这一章和前面所有章不一样,前面引的是论文和博客,基本是静态的;这一章引的是一个今天还在 commit 的活仓库,Codex 的 HEAD 在我写下这句话的当天还在动,那个沙盒组件昨天还在加 Windows 支持。所以这一章的每一个行级引用都钉在一个 commit SHA 加日期上,而不是写一个裸的文件名加行号——明年那一行可能指到完全不同的代码。纪律有几条:优先引 crate 名和模块名,它们比行号稳得多;优先引官方的源码走读而不是自己逐行猜;闭源系统只引公开可复核的行为和文档,绝不引泄露或逆向重构的文件名,这一条本身就是 Ch5 的合规素养。但最重要的一条是:这一章真正训练你的,不是背下这一版 Codex 的代码,而是自己去 gh api 或者 clone 下来、pin 到当下的版本、挑一个子系统对号入座。因为读完这一章半年后,代码已经变了,但「子系统对到抽象」的映射不会变——那才是 capstone 给你的、能带走的能力。
综合 · 抽象有形,具象有名
回头看这一章。它没教你任何新概念,它做的是把前十章飘在半空的抽象,一个一个钉到一个真实系统的真代码上。你看到了 agent 的整体形态长在 cli 和 core、loop 长在 codex_thread、工具和 MCP 长在 tools 和双向 MCP、权限长在 execpolicy、沙盒长在 sandboxing、压缩长在 compact、状态长在 rollout 和 state、子 agent 长在 core/agent。你也看到了同一个抽象在 Codex 和 Claude 体系里只是换了名字,从而确认了你学的是跨系统的不变量。最重要的是,你拿到了一套读法和一条纪律,下次面对任何一个真实 agent 系统,你都能自己 pin 一个版本、对号入座。
把这一章放进整条路书,它是倒数第二章,位置很讲究:它在 Ch10 之后,因为你得先有失败坐标系,才能看懂一个真实系统的每一处设计在防哪一族失败;它在收官的 Ch12 之前,因为只有当所有抽象都被钉在真代码上、变得有形可触之后,你才有资格站到一个制高点上,回望整套 harness 工程、再向未来外推。合上书,去做一件事:打开 Codex 的仓库,gh api 看一眼今天的 HEAD 是哪个 commit,挑一个你最感兴趣的子系统,顺着这一章的映射进去读几个文件,看你能不能指着某一行说出它对应你学过的哪个抽象。能,这一章的目的就达到了。带着这份「抽象有形、具象有名」的踏实,进 Ch12,我们收官。
本章关键术语
下面是这一章引入的少数几个新词;这一章本质上是把前面学过的术语在真实系统里又见了一遍,所以新词很少。加粗是术语,带链接的词可点进术语表。
- 源码巡礼读法(source walkthrough) capstone 读法:对应前面哪一章 → 真实系统怎么做(crate / 文件 + pin)→ 判断力训练点;目标是「抽象有形、具象有名」,不教新概念
- 运行时(runtime) agent harness 实际执行的那一层(Codex 的
corecrate);区别于评测的 eval harness,也区别于暴露接口的 SDK wrapper - pin-commit 纪律(pin-commit discipline) 引活仓库的代码必须钉到一个 commit SHA + 日期、优先引 crate 名和官方走读、闭源只引公开行为;因为代码会漂,而「子系统对到抽象」的映射不漂
这一章看到的其余概念(loop / 工具 / MCP / 权限 / 沙盒 / context / memory / 子 agent / 失败)都来自前十章,完整术语见术语表 /glossary。
参考文献
Mode A · 引用出处(正文 inline,集中列在此)
- OpenAI Codex(开源仓库)· 全章主走读 —— Rust ·
codex-rs/约 80 个 crate · Apache-2.0 · HEAD462deb0(2026-05-28,活仓库,引用前重新 pin SHA) - Unrolling the Codex Agent Loop(OpenAI)· 第 2 节 —— 官方源码走读系列:turn=thread、终止信号、prompt 线性增长、自动 compaction
- Claude Agent SDK(Anthropic)· 第 2 节 / 第 6 节 —— harness 接口层对照(
query()替你跑 loop · 真 loop 在捆绑的闭源二进制里,wrapper 只教接口词汇) - @anthropic-ai/sandbox-runtime(Anthropic)· 第 3 节 / 第 6 节 —— Claude 体系唯一真开源的核心件,统一封装 macOS Seatbelt 与 Linux bwrap,作跨厂商隔离对照
- OpenHands· 第 2 节 第三方对照 —— MIT · CodeAct + event-stream loop 的另一种干净实现
深 dive 资源(可选 · 想往下走再看)
- Codex 安全与审批文档(OpenAI dev-docs)· 第 3 节 —— sandbox + approval 的 canonical 说明(repo 内
docs/sandbox.md是重定向 stub,引这里) - DeepWiki · openai/codex· crate / file 级地图(ThreadManager / RolloutRecorder / 双向 MCP);二手但维护好,行级数据 pin 原文
说明:本章纯 Mode A,主走读是真开源、可合法逐行引、当天仍在 commit 的 OpenAI Codex;Claude Code 本体闭源(2026-03 source-map 泄露但 license 未变 + 已 DMCA),只用其公开行为 / 官方文档 / 真开源的
sandbox-runtime作对照,绝不引泄露或逆向重构的文件名——这条线本身是 Ch5 合规素养。所有 crate / 文件路径是 HEAD462deb0(2026-05-28)快照、模块边界 release 间会漂,引用前必重新 pin SHA。继承架构师课源码走读章的三段读法与「抽象有形」pedagogy;其 Claude Code 行号引用因闭源 / 逆向不可一手核实,已弃。
下一章
下一章(Ch12)是整条 Agent 工程路书的收官:Harness Engineering 综合 + 向未来外推。它会把前十一章拼成一张完整的 Harness Stack 图、算一算生产经济学的账(prompt caching 为什么是头号杠杆)、看异步与后台 agent 怎么部署,最后复用 Ch1 那把「墙与轴」的尺子,识别 agent 工程当前撞着哪几堵墙、向未来外推,收口到这条路书一开始就承诺的那件事:让你为前沿研究和前沿岗位做好准备。