基于 OpenAI
Codex 开源仓库
整理,阅读版本为 commit 7d47056(2026-05-22)。本文是源码导读与工程拆解,不代表官方设计文档。
Runtime Engineering
生产级 Agent 的重点,不在 prompt,而在 runtime
读 Codex 源码最有价值的地方,是看它如何把“会写代码的模型”变成“能在真实机器上协作、执行、受控、可恢复的系统”。 这篇只看四个硬工程问题:沙箱、Subagent 调度、Skill 注册,以及 app-server API。
1. 沙箱:先改文件系统视图,再收紧系统调用
Codex 的执行链路不是简单地“跑一个子进程”。在 Linux 上,它组合了三层保护:进程启动前的 hardening、bubblewrap
构造文件系统视图、再用 no_new_privs 和 seccomp 限制危险 syscall。核心入口可以从
core/src/exec.rs
追到 sandboxing/src/manager.rs
和 linux-sandbox。
进程 main 之前先禁 core dump、ptrace attach,并清理 LD_*/DYLD_* 这类高风险环境变量。
根据平台和权限 profile 选择 macOS seatbelt、Linux seccomp/bubblewrap、Windows restricted token,或不启用沙箱。
默认只读挂载根目录;只把允许写入的 workspace root 重新 bind 成可写;敏感目录可再覆盖成只读或不可读。
执行真正命令前再落下 syscall 过滤器,限制 ptrace、process_vm、io_uring、网络 socket 等能力。
为什么要分两步
文件系统隔离回答“能读写哪里”;seccomp 回答“能向内核请求什么”。只做前者挡不住进程注入和网络请求,只做后者又很难表达 workspace 级别的读写策略。
失败怎么识别
exec.rs 会根据退出码、信号和常见错误文案把失败归因到 sandbox denied、timeout、signal 等类型,让上层能给出更清楚的状态。
2. Subagent:不是递归聊天,而是一棵受控 thread tree
Subagent 相关工具在 multi_agents_v2 目录下:spawn_agent、send_message、
wait_agent、close_agent。真正的调度核心在
agent/control.rs
和 agent/registry.rs。
spawn:解析 agent type、model、reasoning effort、fork mode,发出 spawn begin/end 事件。
registry:检查每个 session 的最大 thread 数,预留 path/nickname,防止同一棵 agent 树里引用冲突。
fork or fresh:可以新建空 thread,也可以从父 thread 历史里 fork,fork 时会过滤未完成和不适合复制的 rollout item。
wait / close:wait_agent 订阅 mailbox 状态,按 deadline 返回;close_agent 会连同 descendants 一起关闭。
3. Skills:能力模块化,关键是发现、过滤、缓存和注入
Skills 的源码在
core-skills/src。
它把能力包装成 SKILL.md,再用不同 scope 的 root 扫描出来:repo、user、system、admin。插件也能贡献 skill roots。
---
name: skill-creator
description: Create or update a Codex skill
metadata:
short-description: Create skills
---
# Instructions
...
一个细节很重要:app-server 的 skills/list 不只是返回名字。协议里会返回每个 cwd 的 skills、errors、enabled 状态和 interface
元数据;本地 skill 文件变化后会发 skills/changed,前端把它当 invalidation signal 再重新 list。
4. App server:前端不是轮询日志,而是订阅状态流
codex app-server 是 Codex 给 VS Code 等富客户端用的接口层。README 明确写了它用 JSON-RPC 2.0 形态通信,传输支持 stdio、
websocket、unix socket;核心状态模型是 Thread、Turn、Item。
连接 gate
ConnectionRpcGate 保证连接关闭后不会再启动新的 handler,但已经拿到 token 的 handler 可以完成,避免半截响应。
请求串行化
RequestSerializationQueues 按 thread、path、process、watch id 等 key 排队;同 key 写操作 FIFO,不同 key 可以并发。
状态同步
服务端 notification 覆盖 thread status、turn started/completed、item started/completed、agent message delta、tool output delta 等事件。
反向请求
服务端也能向客户端发 approval、dynamic tool、auth refresh 这类请求,并在 OutgoingMessageSender 里追踪 callback。
最聪明的读法:让 Agent 读 Agent Runtime
这类仓库适合从“请求进来后去哪了”开始读:前端请求进入 app-server,变成 thread/turn/item;执行命令时进入 exec 和 sandbox; 拆任务时进入 AgentControl 和 Registry;能力扩展时进入 SkillsManager 和 loader。这样读,看到的是工程边界,而不是提示词技巧。
No comments yet