137 个 crate 造出「敢在你电脑上动手」的 AI:我把 OpenAI Codex 源码拆了一遍
从源码看终端 AI 编程智能体的设计哲学
本文基于 openai/codex 官方仓库(codex-rs 分支)的 Rust 源码进行逐层拆解, 梳理其「入口 → 会话核心 → 协议 → 客户端 → 沙箱执行 → 状态持久化 → 基础设施」的七层架构, 并深入解析 Session / Turn / Step 三级交互模型、Responses API 代理循环与工具路由机制。
|
摘要:openai/codex 是 OpenAI 开源的「终端原生」AI 编程智能体,其核心是一个庞大的 Rust workspace( |
01项目概览与代码规模
openai/codex 于 2025 年 5 月随 ChatGPT Codex 的发布正式开源,仓库同时包含 Rust 核心(codex-rs/) 与 TypeScript 前端(sdk/、codex-cli/)。其中 codex-rs 是整个系统的工程主体, 由 Cargo workspace 统一管理 137 个独立 crate,构成一个高度模块化的单体(modular monolith)。
从仓库结构可以直接读出它的分层意图——crate 命名即架构目录:
codex-rs/
├── core/ # 582 个 .rs 文件 · 智能体大脑(会话/轮次/工具/钩子/MCP)
├── tui/ # 终端交互界面(基于 ratatui 的富 TUI)
├── cli/ # headless 命令行入口(--json / --full-auto)
├── exec/ exec-server/ # 单次执行与远程执行服务器
├── protocol/ # Responses API 协议类型、事件流、items
├── client/ http-client/ # Responses API HTTP 客户端与连接池
├── model-provider/ # 模型提供方抽象(OpenAI / Ollama / LM Studio / ChatGPT)
├── sandboxing/ # Linux bwrap+landlock / macOS seatbelt / Windows 受限令牌
├── state/ thread-store/ # SQLite 状态管理、线程历史持久化
├── config/ login/ keyring-store/ # 配置、认证与密钥
├── tools/ # 工具契约(DiscoverableTool / ToolName)
├── mcp/ mcp-server/ rmcp-client/ # MCP 协议集成
├── skills/ plugins/ hooks/ connectors/ # 扩展体系
├── analytics/ otel/ features/ utils/ # 遥测与基础设施
└── linux-sandbox/ windows-sandbox-rs/ # 平台沙箱实现
技术选型
|
维度 |
选型 |
架构意义 |
|---|---|---|
|
核心语言 |
Rust(edition 2021) |
无 GC 的内存安全、单二进制分发、对进程/沙箱的精细控制 |
|
异步运行时 |
tokio + async-stream |
支撑 Responses API 长连接流式事件处理 |
|
协议基准 |
OpenAI Responses API |
统一的「事件流 + 工具调用」抽象,天然适配代理循环 |
|
终端 UI |
ratatui(tui 模块) |
富文本终端界面,模型文本与工具事件实时渲染 |
|
持久化 |
SQLite(rusqlite + 异步封装) |
会话/线程历史落盘,支持断点续跑与多前端共享 |
|
进程隔离 |
Bubblewrap / Landlock / Seatbelt |
平台原生沙箱,限制命令执行的文件系统与网络访问 |
从工程演进看,core 中的 session/、agent/、tools/ 等目录均超过千行且仍在快速增长, 说明 Codex 正从「单线程命令行工具」向「多代理、可扩展、服务化的智能体运行时」演进——例如新增的 multi_agents、 agent-graph-store、code-mode(多代理协议)与 app-server(守护进程模式)都是这一趋势的直接证据。
02整体架构:七层分层设计
Codex 的架构可以概括为一条「从用户指尖到模型云端的单向数据流」,外加一条「从模型返回机器的执行回流」。 两条流交汇于 codex-core 的会话层。整体自上而下分为七层:

图 1 · openai/codex 七层架构总览:数据上行(用户指令 → 会话 → 协议 → 云端)与执行回流(工具 → 沙箱 → 结果反馈)
各层职责
|
层级 |
代表 crate / 目录 |
核心职责 |
|---|---|---|
|
L0 入口 |
tui
· |
收集用户输入、渲染输出、进程生命周期管理;不承载业务逻辑 |
|
L1 核心会话 |
core |
会话编排、代理循环、工具路由、钩子/MCP/技能集成——系统的大脑 |
|
L2 协议 |
protocol |
与模型对话的「语言」:请求/响应类型、事件流、权限与安全风险模型 |
|
L3 客户端 |
client
· |
与云端/本地推理的传输层:HTTP 池、重试、流式解析、多供应商抽象 |
|
L4 执行沙箱 |
sandboxing
· |
把模型的「动作」翻译为受限的真实命令执行,并施加文件/网络策略 |
|
L5 状态持久化 |
state
· |
会话历史、线程状态、记忆的落盘与恢复 |
|
L6 基础设施 |
config
· |
配置、认证、密钥、遥测、特性开关等横切能力 |
设计要点:七层之间遵循严格的单向依赖——入口依赖核心,核心依赖协议,协议与客户端不反向依赖上层。 这保证了 codex-core 可以脱离具体 UI 运行(headless 模式),也让 TUI、CLI、exec、daemon 四种前端共享同一套会话引擎。
03核心交互:Session / Turn / Step 三级模型
Codex 的交互语义建立在三级递进的时间尺度上,这一模型贯穿了状态存储、事件协议与遥测的全部设计。从 session/session.rs 的 Session 结构可以直观看到:一个会话拥有唯一的 thread_id、一个事件通道 tx_event、 一个状态互斥锁 state: Mutex<SessionState>,且「一个会话同时最多运行一个任务,可被用户输入中断」。
// core/src/session/session.rs(节选)
pub structSession {
pub(crate) thread_id: ThreadId, // 会话唯一标识,落盘为 thread
pub(super) tx_event: Sender<Event>, // 事件总线:向 UI/订阅者推送状态变化
pub(super) agent_status: watch::Sender<AgentStatus>, // 可观察的代理状态
pub(super) state: Mutex<SessionState>, // 会话状态(受锁保护)
pub(crate) active_turn: Mutex<Option<ActiveTurn>>, // 当前活动轮次
pub(crate) input_queue: InputQueue, // 用户输入队列(可中断/追加)
pub(crate) conversation: Arc<RealtimeConversationManager>, // 实时会话
pub(crate) services: SessionServices, // 注入的服务集合
pub(super) multi_agent_version: OnceLock<MultiAgentVersion>,
}
三级模型的语义
|
层级 |
时间尺度 |
内容 |
关键代码 |
|---|---|---|---|
| Session
(会话) |
一次对话的完整生命周期 |
绑定 |
Session::new
/ |
| Turn
(轮次) |
一次用户输入 → 最终回复 |
包含多轮「模型采样 + 工具执行」的循环;中途可被用户消息打断并插入新轮次 |
session/turn.rs
/ |
| Step
(步骤) |
一次模型采样请求 |
持有该次请求的模型、推理强度、审批策略、工具路由、MCP 绑定等「请求级快照」 |
session/step_context.rs
/ |
StepContext 的注释点明了它的设计定位——「request-scoped state that may change between model sampling requests」:
// core/src/session/step_context.rs(节选)
pub structStepContext {
pub(crate) turn: Arc<TurnContext>, // 回指所属轮次
pub(crate) model_info: Arc<ModelInfo>, // 本次采样的具体模型
pub(crate) reasoning_effort: Option<ReasoningEffort>,
pub(crate) approval_policy: AskForApproval, // 工具动作的审批策略
pub(crate) tool_router: Arc<ToolRouter>, // 本次请求最终化的工具路由
pub(crate) mcp: Arc<McpBinding>, // 本次请求的 MCP 连接与目录
pub(crate) environments: TurnEnvironmentSnapshot, // 环境快照
}
将「请求级」状态抽离成 StepContext 是一个非常关键的设计决策:它使 模型切换(同一轮次内中途更换模型)、 审批策略动态调整 与 工具集动态变更 成为可能——因为这些变化都只影响下一个 Step,而不会污染 Turn 与 Session 的语义

图 2 ·Session / Turn / Step 三级层级关系:Step 为请求级最小单元,支持模型切换与增量持久化
04代理循环:Responses API 流式驱动
Codex 的本质是一个 ReAct 风格(推理-行动)的代理循环,但它与大多数「JSON 往返」式 agent 框架的关键区别在于: 模型交互基于 Responses API 的服务端事件流(server-side streaming)——模型推理、推理过程文本、工具调用意图、 最终回复都作为流式事件逐个到达,而非一次性 JSON。这为 TUI 的「打字机」渲染和「边推理边行动」提供了底层支撑。
session/turn.rs(超过 1200 行)承载了循环主体。从它的 import 列表可以还原出每一轮次发生的事: hooks(run_pending_session_start_hooks、run_turn_stop_hooks)、上下文压缩(run_inline_auto_compact_task)、 工具路由(ToolRouter)、MCP 技能依赖(maybe_prompt_and_install_mcp_dependencies)、 重试(ResponsesStreamRetryState)、事件流工具函数(stream_events_utils)等。

图 3 · 代理循环交互流程:Turn 内「采样 → 分流 → 工具执行 → 回注」闭环,直到生成最终文本回复
流式事件处理管线
事件流处理被集中在 stream_events_utils.rs,其职责划分非常清晰:handle_non_tool_response_item(非工具文本/推理)、 handle_output_item_done(item 完成终态)、finalize_non_tool_response_item(收尾)与 last_assistant_message_from_item(提取助手消息)。这种「增量事件 → 累积 item → 终态定型」的三段式处理, 使 UI 渲染、持久化、遥测与钩子都能挂接到统一的 item 生命周期上。
05工具系统:路由、注册与处理器
Codex 的工具系统遵循「契约与实现分离」:契约层在 codex-tools crate(定义 DiscoverableTool trait、 ToolName 等),实现层在 core/src/tools/(router.rs、registry.rs、handlers/)。
// codex-rs/core/src/tools/ 目录结构
tools/
├── router.rs # ToolRouter:工具选路、上下文候选、提示注入
├── registry.rs # 工具注册表:名称 → 处理器绑定
├── handlers/ # 20+ 具体工具处理器(68 个文件)
│ ├── apply_patch.rs # 补丁应用(Lark 语法解析补丁格式)
│ ├── shell.rs # shell 命令执行(沙箱内)
│ ├── unified_exec.rs # 统一执行器(命令/脚本)
│ ├── plan.rs # 规划工具(多步计划)
│ ├── multi_agents.rs # 多代理派生/协作
│ ├── mcp_resource.rs # MCP 资源读取
│ ├── view_image.rs # 查看图片(视觉输入)
│ ├── request_permissions.rs # 权限审批请求
│ ├── request_user_input.rs # 向用户提问
│ ├── tool_search.rs # 工具自搜索(工具数量庞大时)
│ ├── get_context_remaining.rs # 查询剩余上下文
│ ├── new_context_window.rs # 新开上下文窗口
│ ├── send_user_message_async.rs # 异步消息推送
│ └── ... current_time / sleep / test_sync / dynamic / extension_tools / wait_for_environment
工具路由的执行链路
- 模型发出
function_call:事件流解析出工具调用意图,携带工具名与参数。 - 审批检查:根据 approval_policy(AskForApproval)判断是自动放行、询问用户,还是拒绝。
- ToolRouter 分派:按工具名 + 上下文(MCP 目录、环境快照、能力根)找到可执行的处理器。
- Handler 执行:在沙箱内执行(shell/unified_exec),或执行本地逻辑(plan、tool_search、view_image 等)。
- 结果回注:执行结果封装为 tool output item 追加到对话,触发下一轮采样。

图 4 · 工具调用时序:审批 → 路由 → 沙箱执行 → 结果回注,构成代理循环的最小闭环
06沙箱与安全模型
「敢在你的机器上动手」的前提是「不会乱动」。Codex 的沙箱设计采用平台原生能力 + 统一抽象的策略: sandboxing/src/lib.rs 以 SandboxManager 为统一入口(spawn_process、SandboxType、 SandboxTransformRequest),底层按平台分流:
|
平台 |
技术 |
隔离能力 |
|---|---|---|
|
Linux |
Bubblewrap( |
用户态命名空间 + 内核级文件系统沙箱(路径读/写白名单) |
|
macOS |
Seatbelt( |
系统级沙箱配置文件,限制文件/网络/进程能力 |
|
Windows |
受限 Token / 提升后端( |
降权令牌 + 文件系统覆盖( |
沙箱策略与「权限画像」(PermissionProfile)联动:compatibility_sandbox_policy_for_permission_profile 把用户配置的权限画像翻译成对应平台的沙箱策略。而 violation.rs 记录两类关键违规—— FileSystemSandboxViolation(越权读写文件)与 NetworkSandboxViolation(越权网络访问), 通过 record_sandbox_violation 统一上报,构成「策略 → 执行 → 审计」的闭环。
在权限模型之上还有一层审批(approval):AskForApproval 决定工具动作是「自动放行(沙箱内)」「询问用户」还是「拒绝」, 并且可以通过 request_permissions 工具让模型主动申请提权——这是 agent 类产品中典型的「最小权限 + 按需提升」模式。
07状态管理与上下文压缩
长时间运行的 agent 有两个持久化诉求:会话可恢复(断电/断网后续跑)与上下文不失控(token 窗口有限)。 Codex 用一套 SQLite 为中心的存储体系解决前者,用多层「压缩(Compaction)」机制解决后者。
存储体系
codex-state:SQLite 核心状态库,管理会话、线程、角色状态(如ActiveTurn)、环境选择等。codex-thread-store:线程历史持久化,PersistContext记录每一步落盘的上下文;支持 fork(forked_from_thread_id)与 resume。codex-message-history:消息级历史,供 UI 回看与断点续传。codex-memories:长期记忆管理,跨会话复用用户偏好与项目事实。agent-graph-store:多代理协作时的图结构存储(代理、任务、依赖关系)。
上下文压缩(Compaction)
当会话累积超出模型上下文窗口时,Codex 不会简单截断,而是执行「压缩」——把早期对话提炼为摘要再替换进上下文。 turn.rs 中可见多条压缩路径:本地内联压缩(run_inline_auto_compact_task)、 远端压缩(run_inline_remote_auto_compact_task)、以及 v2 版本(compact_remote_v2)。 配合 AutoCompactTokenLimitScope(按请求/按轮次统计 token 上限)与 get_context_remaining 工具, 模型可以在上下文逼近上限时主动触发压缩,实现「自适应上下文管理」。
08扩展体系:MCP、插件、技能与钩子
Codex 的扩展体系遵循「模型先觉 → 运行时装载 → 动态注入」的思路:模型在对话中发现需要的能力,运行时按需加载并注入提示词与工具定义。
|
机制 |
载体 |
交互方式 |
|---|---|---|
| MCP
(Model Context Protocol) |
codex-mcp
· |
动态连接外部工具/资源服务器; |
| Skills(技能) | codex-skills
· AGENTS.md |
从 AGENTS.md / skills 目录发现技能清单,模型通过 |
| Plugins(插件) | codex-plugin
· |
request_plugin_install
/ |
| Hooks(钩子) | codex-hooks
· |
生命周期事件:session 启动、turn 开始/停止、after agent 等;可与 MCP 组合实现自定义审查逻辑 |
| Connectors(连接器) | codex-connectors |
第三方应用集成(如桌面 App、Web 端),以 |
统一抽象:无论工具来自内置 handlers、MCP 服务器、插件还是技能,最终都以「DiscoverableTool」的统一接口暴露给模型, 由 ToolRouter 在运行时按需装载。这解释了为什么模型既能用 apply_patch 改代码,又能通过 MCP 读数据库—— 在模型眼里它们只是不同的工具条目。
09多前端入口与多代理协作
四种入口共享同一会话引擎
|
入口 |
形态 |
典型场景 |
|---|---|---|
codex-tui |
ratatui 富终端界面 |
日常交互开发,逐 token 渲染推理与工具事件 |
codex-cli --headless |
一次性命令 + |
CI/CD、脚本编排、自动化测试 |
codex-exec |
单次执行(类似「干一件事」) |
非交互任务、定时任务 |
app-server |
守护进程(stdio/unix socket) |
桌面 App、IDE 扩展等常驻客户端接入 |
入口层的统一性在 tui/src/main.rs 中有直接体现:入口通过 arg0_dispatch_or_else 按 argv[0] 分发到不同子命令, 而真正的会话逻辑统一收敛到 codex_tui::run_main。也就是说,「交互 TUI」与「headless CLI」只是同一运行时外壳的不同参数形态。
多代理协作
最新代码已出现完整的多代理基础设施:multi_agents(v1/v2 两代协议)、agent-graph-store(代理关系图)、 code-mode(多代理通信协议)、external-agent-migration(外部代理迁移)。模型可以通过 multi_agents 工具 派生子代理处理子任务,子代理运行在独立的线程(thread)中,通过 parent_thread_id 建立父子关系—— 这是从「单代理对话」向「多代理协作系统」演进的关键一步。
10设计理念总结
从源码层面回看,openai/codex 的架构设计可以提炼为五条核心理念:
|
理念 |
体现 |
|---|---|
| 1. 一切皆工具调用 |
写文件、跑命令、读资源、问用户、派生子代理……所有真实世界动作统一收敛为 tool call,从而获得统一的审批、审计与 UI 呈现。 |
| 2. 请求级快照与分层上下文 |
Session → Turn → Step 三级上下文,Step 持有请求级快照,使模型切换、策略调整、工具变更都能在「下一次采样」干净生效。 |
| 3. 事件驱动而非请求响应 |
SSE 事件流驱动 UI 渲染、持久化、遥测与钩子,让「边推理边行动」成为可能。 |
| 4. 平台原生沙箱 + 策略翻译 |
统一 SandboxManager 抽象下,Linux/macOS/Windows 各用原生能力;权限画像在运行时翻译为平台策略,越权行为记录为 violation 事件。 |
| 5. 可插拔扩展与模型引导装载 |
MCP / 技能 / 插件 / 钩子全部以 DiscoverableTool 统一暴露;模型在对话中按需发现并请求安装,运行时动态注入。 |
「Codex 的架构核心不在于某一个炫技的模块,而在于把『模型推理』与『本地执行』两条流,通过事件驱动的会话层稳定地咬合在一起—— 上行是清晰的意图,下行是受控的动作。」
演进方向观察
从 multi_agents、agent-graph-store、app-server、code-mode 等新增模块看, Codex 正从「终端单代理工具」演进为「可服务化的多代理运行时」。对工程团队而言,最值得借鉴的并非某个具体功能, 而是它以协议为轴、以事件为血脉、以工具为边界的模块化组织方式——这让一个 137 crate 的巨型系统依然保持了清晰的演进能力。
参考资料
-
openai/codex 官方仓库:
https://github.com/openai/codex(codex-rs workspace 结构、core/src/session/、core/src/tools/、sandboxing/等源码) -
OpenAI Responses API 文档:
https://platform.openai.com/docs/api-reference/responses -
Model Context Protocol 规范:
https://modelcontextprotocol.io
葡萄城是专业的软件开发技术和低代码平台提供商,聚焦软件开发技术,以“赋能开发者”为使命,致力于通过表格控件、低代码和BI等各类软件开发工具和服务,一站式满足开发者需求,帮助企业提升开发效率并创新开发模式。
更多推荐

所有评论(0)