前日 OpenAI 正式开源 Codex 全量源码,我针对项目完整代码库做了分层拆分、模块梳理与底层逻辑逐段解析。
先说总体判断:
今天的 Codex 已经不能只理解为“LLM + Shell + while 循环”。更准确地说,它是一个智能体调度平台。

Codex 核心运行主链路
外围还接入 MCP、Skills、Plugins、Memory、Multi-Agent、Approval、Telemetry、Persistence。
这是理解整个 Codex 源码最重要的主线。
模型推理核心把下一步动作交给承载执行、状态、权限与扩展能力的智能体调度层。

1. Agent Loop
核心结论
Codex 底层仍保留经典 Agent Loop:

Agent Loop 标准闭环
核心入口:codex-rs/core/src/session/turn.rs
源码注释直接说明了这个循环的设计:
模型每次判断可能返回 function call 或 assistant message;如果返回 function call,就执行并把结果拼接到下一次推理;如果只有 assistant message,则本轮会话完成。
关键源码
以下中文注释均为我追加:
pub(crate) async fn run_turn( // 一个完整 Agent Turn 的主入口 sess: Arc , // 持有整个会话级状态、历史、工具、环境等 turn_context: Arc , // 当前 Turn 固定配置和运行上下文 input: Vec , // 当前用户提交给 Agent 的输入 prewarmed_client_session: Option , // 可复用已经预热的模型连接 cancellation_token: CancellationToken, // 支持用户中断整个 Turn ) -> CodexResult
值得注意的是,在第一次模型推理之前,Codex 会先执行:
drain_async_hook_results(&sess, &turn_context, true).await; // 先吸收上一轮异步 Hook 产生的新上下文 let mut client_session = prewarmed_client_session // 优先使用已经预热的模型连接 .unwrap_or_else(|| sess.services.model_client.new_session()); // 否则创建 Turn 级模型会话 run_pre_sampling_compact(&sess, &turn_context, &mut client_session, &cancellation_token).await; // 推理前先检查是否需要压缩上下文
完成这些准备后,Codex 才进入持续推理。
真正的产品设计
因此,当前 Codex 的 Agent Loop 更接近:

Agent Loop 决策与回流
关键在于:
Codex 不会简单地重复调用模型,而是会在每个推理步骤重新构建模型所见的“世界视图”。
这是一项重要的架构演进。

一个 Turn 容器内,第一次模型判断触发 Tool Call 与执行,Tool Result 返回后重新注入上下文,再次模型判断并产生 Final Answer。
2. Intent Understanding & Task Routing
核心结论
Codex 当前没有设置统一的:

意图理解与任务路由
至少,运行时主路径并不采用这种结构。
它把路由分成两层:
1.第一层:程序确定性路由
客户端明确操作直接映射为 Typed Op。
2.第二层:模型语义路由
进入普通 Turn 后,“要不要查代码、执行 Shell、调用 MCP、启动 Agent”等,交给模型结合 Tool Specs 和 Instructions 判断。
核心文件:codex-rs/core/src/session/handlers.rs
程序级 Routing
match sub.op { // 根据客户端提交的强类型操作进行确定性路由 Op::Interrupt => { // 明确的中断操作,不需要让模型判断 interrupt(&sess).await; // 直接终止当前任务 false // Session 不退出 } // 完成 Interrupt 分支 Op::Compact => { // 用户明确要求进行 Context Compact compact(&sess, sub.id.clone()).await; // 直接进入 CompactTask false // Session 继续运行 } // 完成 Compact 分支 Op::Review { review_request } => { // 明确进入 Code Review 工作流 review(&sess, &config, sub.id.clone(), review_request).await; // 创建 Review 流程 false // Session 继续运行 } // 完成 Review 分支
同一个任务调度器同时还会处理:
•TurnInput
•RecoverTurn
•SuspendTurnAndShutdown
•ThreadSettings
•InterAgentCommunication
•ExecApproval
•PatchApproval
•RequestPermissionsResponse
•DynamicToolResponse
•RefreshMcpServers
•RunUserShellCommand
•Rollback
•Memory Mode
•Shutdown
产品含义
这种划分很明确:
确定性行为
例如:
•/compact
•review
•interrupt
•rollback
•approval
不要浪费 LLM 推理。
程序直接完成 Routing。
模糊语义行为
例如用户说:
帮我看看这个项目登录为什么有问题。
此时:
•是否搜索代码?
•搜哪些文件?
•是否运行测试?
•是否调用 sub-agent?
•是否联网?
这些问题交给 Model 推理。
因此,Codex 的原则是:
能由协议确定的意图,不交给模型;真正需要语义理解的部分,才交给模型。
相比“所有请求先经过 Intent Agent”,这种方式更稳定。
3. Context Engineering
Context Engineering 是 Codex 当前最值得研究的模块之一。
核心结论
Codex 的 Context 已经不再只是:
system prompt + chat history + user message
它至少包括:
Base Instructions + User / Developer Instructions + AGENTS.md + Environment State + Workspace State + Conversation History + World State + Skills + Plugins + Memory + MCP / Connector Context + Current User Input
同时还有:
Compaction + Reinjection + 当前执行上下文快照
3.1 当前执行上下文
run_turn 第一次请求前:
let first_step_context = sess // 从 Session 中开始捕获上下文快照 .capture_step_context_with_required_mcp_servers( // 同时考虑本轮必须启用的 MCP Server Arc::clone(&turn_context), // 保留当前 Turn 固定配置 &cancellation_token, // 捕获过程也支持中断 &required_servers, // 用户输入显式依赖的 MCP Servers ) // 完成参数构造 .await; // 异步等待 Environment/MCP 等状态准备完成
之后每轮推理还会重新 capture。
这表明:
TurnContext ≠ StepContext。
TurnContext 是这一轮的相对稳定配置。
当前执行上下文指:
模型这一次推理真正看到的环境快照。
3.2 Compaction
核心:codex-rs/core/src/compact.rs
Codex 已经明确区分:
•Pre-turn compaction
•Manual compaction
•Mid-turn compaction
更关键的问题是 Compaction 后如何重新注入上下文。
pub(crate) enum InitialContextInjection { // 定义压缩后如何重新恢复基础 Context BeforeLastUserMessage { // Mid-turn compact 使用这种策略 world_state: Arc , // 保留压缩时真实的环境感知 step_context: Arc , // 保留对应推理步骤的运行环境 }, // Mid-turn 模式结束 DoNotInject, // Manual/Pre-turn compact 后先不注入,下一个普通 Turn 再完整注入 } // Context reinjection 策略结束
这一设计已经相当成熟。
Context Compact 最大的风险并不在:
“摘要写得好不好。”
而是:
摘要后模型看到的真实环境是否还和现实一致。
Codex 已经着手处理这个问题。
4. Knowledge & Retrieval
核心结论
Codex 当前没有把 Knowledge 设计为单独的“万能知识库模块”。
它采用:
Knowledge as Tools
不同来源的知识通过以下入口进入:

知识与检索入口
因此:
Retrieval 是多源的,不是一个统一 Vector DB。
Web Search 已被 Extension 化
文件:codex-rs/ext/web-search/src/extension.rs
impl ToolContributor for WebSearchExtension { // Web Search 本质上是一个 Tool Extension fn tools( // Extension 向 Codex 运行时注册可执行工具 &self, // 当前 WebSearch Extension session_store: &ExtensionData, // Session 级扩展数据 thread_store: &ExtensionData, // Thread 级扩展配置 ) -> Vec
Web Search 是否可用,也由系统动态计算:
available: (config.model_provider.is_openai() // 当前 Provider 支持 OpenAI Web Search || config.model_provider.uses_openai_actor_authorization() // 或使用兼容授权 || config.model_provider.supports_standalone_web_search()) // 或 Provider 自己提供 Web Search && web_search_mode != WebSearchMode::Disabled, // 同时配置没有禁用 Web Search
产品含义
Codex 没有将:
“知识检索”
绑定为:
“RAG”。
而是将其抽象为:
Agent 可以访问哪些 Knowledge Interfaces。
这对 Coding Agent 的设计很重要。
5. Workspace & Environment
核心结论
Codex 里的 Workspace 已经不只是:
cwd = /repo
现在有了正式的 Environment 抽象。
核心:codex-rs/core/src/environment_selection.rs
Thread 可以绑定多个 Environment。
每个 Environment 至少可以拥有:
•environment_id
•cwd
•workspace roots
•EnvironmentConfig
•ExecutorFileSystem
•Shell
•Capability Roots
•connection state
默认 Environment 生成
.map(|environment_id| TurnEnvironmentSelection { // 为每个可用 Environment 创建选择对象 environment_id, // 标识具体执行环境,例如 local 或 remote environment cwd: PathUri::from_abs_path(cwd), // 每个环境拥有自己的当前工作目录 workspace_roots: workspace_roots.iter() // 获取允许作为 Workspace 的目录集合 .map(PathUri::from_abs_path).collect(), // 统一转换成跨环境 Path URI config: EnvironmentConfigState::FromThread, // Environment 默认继承 Thread 配置 }) // 一个完整 Environment Selection 构造完成
这里的产品思路很重要
传统 Coding Agent:

业务流程图 · 传统 Coding Agent 执行链
Codex 正在向:

Agent Thread 的多环境绑定
演进。
因此,未来的 Coding Agent Workspace 本质上更接近:
Execution Environment Graph
而非“一个项目目录”。
6. Tool System & Tool Routing
Tool System 是 Codex 运行时的另一个核心模块。
核心文件:codex-rs/core/src/tools/router.rs
6.1 Tool Spec 与工具执行器分离
pub struct ToolRouter { // 当前推理步骤使用的统一工具路由器 registry: ToolRegistry, // 真正能够执行 Tool 的注册表 model_visible_specs: Arc<[ToolSpec]>, // 当前 Model 实际能够看到的 Tool Schema } // ToolRouter 定义结束
这种分离很重要。
因为:
已注册的 Tool ≠ 本轮模型需要看到的 Tool
6.2 Model Response → ToolCall
Codex 会统一转换不同类型的 Tool Call:
ResponseItem::FunctionCall { // 模型返回普通 Function Tool Call name, namespace, arguments, call_id, .. // 提取 Tool 身份、参数以及调用 ID } => { // 开始规范化 Tool Call let tool_name = ToolName::new(namespace, name) // 将 namespace + name 合成为统一 ToolName .with_default_namespace(); // 没有 namespace 时补充默认 namespace Ok(Some(ToolCall { // 转换成 Codex 内部统一 ToolCall
此外还支持:
•FunctionCall
•ToolSearchCall
•CustomToolCall
6.3 最终全部进入 Registry
let invocation = ToolInvocation { // 将一次 Tool Call 包装成完整的执行调用 session, // Session 状态 turn, // Turn 状态 step_context, // 当前推理步骤的环境快照 cancellation_token, // 工具执行支持取消 tracker, // 追踪工具对 Workspace 造成的变化 call_id, // 对应 Model Tool Call ID tool_name, // 要执行的 Tool source, // Tool 调用来源 payload, // Tool 参数 }; // Invocation 构造结束
然后:
self.registry // 进入统一 Tool Registry .dispatch_any_with_terminal_outcome(invocation, terminal_outcome_reached) // 找到具体执行器并执行 .await // 等待 Tool 执行结果
产品设计总结
Codex 的 Tool 架构可以抽象成:

工具调用与执行路由
这个分层值得 Agent 平台借鉴。

左侧 Tool Spec 表示模型可见 Schema,中间 ToolRouter 将其连接到右侧工具执行器与注册表。
7. MCP & External Connectors
Codex 的 MCP 已经不只是:

MCP Server 启动与注册
现在有专门的管理组件:
McpManager
核心文件:codex-rs/core/src/mcp.rs
MCP 运行配置投影
pub(crate) struct McpRuntimeProjection { // 描述当前推理步骤真正有效的 MCP 运行配置 pub(crate) config: McpConfig, // 当前合并完成后的 MCP 配置 pub(crate) plugins_available: bool, // 当前是否存在可用 Plugin pub(crate) selected_plugins: SelectedPluginSnapshot, // 当前实际启用的 Plugin 集合 } // 运行配置投影定义结束
更关键的一点是:
MCP 配置是按推理步骤计算的。
pub(crate) async fn runtime_config_for_step( // 为当前推理步骤构造有效 MCP 配置 &self, // McpManager config: &Config, // Thread/Codex 配置 thread_init: &ExtensionDataInit, // Thread 初始化扩展数据 thread_store: &ExtensionData, // 当前 Thread Extension State identity: McpThreadIdentity<'_>, // 当前 Thread/Originator/Environment 身份
输入来源会融合:
Static MCP Config + Extension Contributions + Hosted Apps + Selected Plugins + Plugin Connector Packages + Environment Policy
它还支持 Contributor:
•Set
•Remove
•HostedApps
•SelectedPlugin
•SelectedPluginPackage
因此,MCP 在 Codex 中已经演变为:
外部能力执行层(External Capability Runtime)
不再只是 Protocol Client。
8. Memory
Memory 值得单独说明,因为 Codex 当前源码里已经有清晰的 Memory 架构。
Memory 被拆成独立 Extension:
•codex-rs/ext/memories
以及:
•codex-rs/memories/read
•codex-rs/memories/write
Memory Root
pub fn memory_root(codex_home: &AbsolutePathBuf) -> AbsolutePathBuf { // 根据 Codex Home 计算 Memory 根目录 codex_home.join("memories") // 默认持久化到 $CODEX_HOME/memories } // Memory Root 计算结束
Memory 是一个 Extension Contributor
enabled: config.features.enabled(Feature::MemoryTool) // Feature Flag 必须开启 && config.memories.use_memories, // 用户配置也必须允许 Memory dedicated_tools: config.memories.dedicated_tools, // 决定是否给模型暴露专门 Memory Tool codex_home: config.codex_home.clone(), // Memory 数据保存位置来源于 Codex Home
Memory 可以作为 Prompt:
build_memory_tool_developer_instructions(&config.codex_home) // 根据 Memory 状态生成使用说明 .await // 异步读取本地 Memory 信息 .map(PromptFragment::developer_policy) // 作为 Developer Policy 注入 Prompt
同时还可以作为 Tool:
tools::memory_tools( // 创建真正可供 Agent 使用的 Memory Tools LocalMemoriesBackend::from_codex_home(&config.codex_home), // 使用本地 Memory Backend self.metrics_client.clone(), // Memory Tool 自己也接入 Metrics ) // 返回 Memory Tool 集合
产品含义
Memory 并非:
每次把所有历史聊天塞给模型。
而是:
Conversation History ≠ Memory
Codex 已经正式拆分二者。
Memory 有自己的:
•lifecycle
•storage
•read path
•write path
•tools
•prompt policy
•citations
•telemetry
这是一套较成熟的 Agent Memory 架构。
9. 智能体调度层
核心结论
Codex 智能体调度中心可以分成三层:

调度引擎分层
核心抽象:SessionTask
文件:codex-rs/core/src/tasks/mod.rs
pub(crate) trait SessionTask: Send + Sync + 'static { // 所有可在 Session 内运行的任务统一实现这个接口 fn kind(&self) -> TaskKind; // 告诉执行器当前是哪一类 Task fn span_name(&self) -> &'static str; // 给 tracing/observability 提供任务名称 fn run( // Task 真正的异步运行入口 self: Arc , // Task 实例 session: Arc , // 共享 Session 运行时
run 这个执行方法同时拿到:
•TurnContext
•TurnInput
•CancellationToken
目前核心 Task Module 中可以看到:
regular review compact user_shell lifecycle
这个抽象为什么重要?
Codex 没有让:
run_turn() 管理所有事情。
而是:

SessionTask 任务分派
Agent Loop 只是运行时中的一类任务。
这样一来:
•Review
•Compact
•Shell
•Regular Agent
能够共享同一套:
•lifecycle
•cancellation
•telemetry
•state
•persistence
10. Sandbox & Isolation
Codex 的安全边界不只依赖 Prompt 中的一句:
“不要访问敏感文件。”
它还通过 OS 机制执行约束。
核心:codex-rs/sandboxing/src/manager.rs
平台 Sandbox
pub enum SandboxType { // Codex 支持的平台级隔离类型 None, // 不启用平台 Sandbox MacosSeatbelt, // macOS 使用 Seatbelt LinuxSeccomp, // Linux 使用 Seccomp/Landlock 等机制 WindowsRestrictedToken, // Windows 使用 Restricted Token Sandbox } // Sandbox 类型结束
平台自动选择:
if cfg!(target_os = "macos") { // 当前运行在 macOS Some(SandboxType::MacosSeatbelt) // 使用 macOS Seatbelt } else if cfg!(target_os = "linux") { // 当前运行在 Linux Some(SandboxType::LinuxSeccomp) // 使用 Linux Sandbox } else if cfg!(target_os = "windows") { // 当前运行在 Windows
Sandbox Request 同时包含:
•cwd
•env
•network
•permission profile
•sandbox policy cwd
•environment id
•managed network
•additional permissions
因此,这不是简单的:
sandbox = true / false
它是一套:
Policy-driven execution sandbox。
11. Task Lifecycle & State
这一部分解释了 Codex 为什么可以被中断、恢复、审批和 Steer。
核心文件:codex-rs/core/src/state/turn.rs
ActiveTurn
pub(crate) struct ActiveTurn { // Session 当前正在运行的 Turn pub(crate) task: Option , // 当前真正执行中的 Task pub(crate) turn_state: Arc
RunningTask
pub(crate) struct RunningTask { // 运行时对正在运行 Task 的完整描述 pub(crate) done: Arc , // Task 完成通知机制 pub(crate) kind: TaskKind, // Regular / Review / Compact pub(crate) task: Arc , // 真正运行的 Task pub(crate) cancellation_token: CancellationToken, // 中断控制 pub(crate) handle: AbortOnDropHandle<()>, // Tokio Task Handle
TurnState 还维护更多运行状态
它里面直接维护:
pending_approvals: HashMap >, // 等待用户审批的 Tool Call pending_request_permissions: HashMap , // 等待权限授予 pending_user_input: HashMap >, // Agent 主动向用户提问后的等待状态 pending_elicitations: HashMap<(String, RequestId), oneshot::Sender >, // MCP elicitation 等待状态 pending_dynamic_tools: HashMap >, // 动态 Tool 的异步返回
这表明 Turn 并非只有:
running / completed
它是一个真正的异步状态机。
当前版本还加入 Suspend + Recovery
最新 main 中已有:
Op::SuspendTurnAndShutdown { reply } => { // 请求暂停当前未完成 Turn 并关闭运行时 let result = super::turn_suspension::suspend_turn_and_shutdown( // 进入 Turn Suspension 流程 &sess, sub.id.clone() // 对当前 Session/Turn 执行挂起 ).await; // 等待 History 持久化和运行时安全关闭
目标是:
未完成 Turn 可以交给另一个运行时恢复,而不把它标记为 Completed 或 Aborted。
这是智能体调度层服务化的明确信号。
12. Multi-Agent Orchestration, Scheduling & Workload
现在,Codex 的 Multi-Agent 已经超出“调用一次 sub-agent”的范围。
核心:
•codex-rs/core/src/session/multi_agents.rs
•codex-rs/core/src/agent/control/
Agent 是层级树结构
内置 instruction 明确告诉 Root:
"You can spawn sub-agents to handle subtasks, // Root Agent 可以创建子 Agent and those sub-agents can spawn their own sub-agents. // 子 Agent 也可以继续创建 Agent All agents ... have access to the same set of tools." // Agent 默认具备同级工具能力
可用协作操作包括:
spawn_agent send_message followup_task wait_agent interrupt_agent list_agents
Context Fork 也是明确设计
fork_turns
决定父 Agent 历史向子 Agent 传播多少。
spawn 源码还会过滤 Fork History:
"system" | "developer" | "user" => true, // 系统、开发者和用户消息允许继承 "assistant" => *phase == Some(MessagePhase::FinalAnswer), // Assistant 只保留已经成为 Final Answer 的内容 _ => false, // 其他角色默认不进入子 Agent History
Tool calls、reasoning 等并不会无脑完整复制。
这相当于:
Sub-Agent Context Isolation。
Workload 也已进入执行层
let max_concurrency = config.max_concurrent_threads_per_session; // 获取当前 Session 最大并发 Agent 数 let mut text = format!( // 将真实执行器容量告知模型 "... {max_concurrency} available concurrency slots ..." // 模型知道自己还剩多少并发槽位 ); // Multi-Agent 使用提示完成
因此,Scheduling 并非完全由模型自由决定。
运行时设有明确的:
concurrency slots。
一项值得注意的设计
源码中:
Some(ReasoningEffort::Ultra) => MultiAgentMode::Proactive, // Ultra 推理级别可自动切换到主动多 Agent _ => ... MultiAgentMode::ExplicitRequestOnly, // 普通模式默认更保守,只在显式需要时启动
这一设计开始将:
推理预算
和:
Agent 并行预算
关联起来。
这一关联值得关注。
13. Model & Inference Layer
Codex 并非只是:
model="xxx" client.responses.create(...)
这样一层简单调用。
它至少有:

模型推理调用链
Codex 将 Session ModelClient 与 Turn ModelClientSession 分离
核心:codex-rs/core/src/client.rs
源码注释明确说明:
ModelClient 是 Session-scoped;ModelClientSession 是 Turn-scoped。
ModelClient 保存:
•Provider
•Auth
•Thread ID
•transport fallback state
•originator
•telemetry config
而 Turn-scoped Session 保存:
•WebSocket
•previous response
•incremental request state
•sticky routing token x-codex-turn-state
这表明:
Inference transport 本身也有生命周期。
Model Metadata 还包含更多调度层信息
codex-rs/models-manager/src/model_info.rs
模型 Metadata 保存的不只是名称。
其中包括:
shell_type: ConfigShellToolType::UnifiedExec, // 模型默认使用哪种 Shell Tool web_search_tool_type: WebSearchToolType::Text, // 模型支持哪种 Web Search truncation_policy: TruncationPolicyConfig::bytes(10_000), // Tool Output 如何截断 context_window: Some(272_000), // 模型 Context Window multi_agent_version: None, // 模型对应哪一版多智能体调度层
因此:
Model Metadata 会反向驱动智能体调度层行为。
这已经超出“模型下拉选择器”的范畴。
14. Prompt & Instruction System
Codex 的 Prompt 体系已经采用层级式 Instruction System。
不能把它简单理解为一个:
SYSTEM_PROMPT.md
第一层:Model Base Instructions
模型自身 metadata 中:
pub const BASE_INSTRUCTIONS: &str = include_str!("../prompt.md"); // 编译时加载模型默认基础指令
同时允许:
if let Some(base_instructions) = &config.base_instructions { // 用户或 Host 显式覆盖基础 Prompt model_messages.instructions_template = Some(base_instructions.clone()); // 替换模型默认 Instructions model_messages.instructions_variables = None; // 自定义模板后清空默认模板变量 } // Base Instructions override 完成
第二层:AGENTS.md
核心文件:codex-rs/core/src/agents_md.rs
它并非只读取 cwd 下的一个文件。
规则是:

AGENTS.md 分层发现与拼接
按层级拼接。
源码说明:
•向上搜索 project root
•默认以 .git 为 marker
•从 root 一直收集到 cwd
•不超过 project root
•有最大 byte budget
•读取还受 Sandbox 限制
一项安全设计
if config.active_project.is_untrusted() { // 当前项目被标记为不可信 return Ok((!loaded.is_empty()).then_some(loaded)); // 不继续读取项目级 AGENTS.md } // 阻止不可信 Repo 注入额外项目 Prompt
这在防范:
Repository Prompt Injection。
Prompt 采用 Layered Prompt
最终 Prompt 可以理解为:

Layered Prompt:指令装配顺序
Codex 的 Prompt Engineering 已经演变为:
Instruction Engineering。
15. Skills, Plugins & Extensions
当前 Codex 源码中,这部分的变化也很明显。
Skill 是可被发现的文件系统能力包
核心:codex-rs/ext/skills/src/loader/host.rs
Skill Root 有:
pub(crate) struct HostSkillRoot { // 一个可以被 Skill Loader 扫描的根目录 pub(crate) path: AbsolutePathBuf, // Skill Root 实际文件路径 pub(crate) scope: SkillScope, // User / Repo / Admin / System Scope pub(crate) file_system: Arc , // Skill 可以来自抽象 Environment FS plugin: Option , // Skill 也可以隶属于某个 Plugin } // Skill Root 定义结束
Skill Discovery 并非简单遍历目录
不同 Scope 甚至有不同 Symlink Policy:
SkillScope::User | SkillScope::Repo | SkillScope::Admin // 用户、Repo、管理员 Skill => DirectorySymlinkPolicy::Follow, // 允许跟随目录 Symlink SkillScope::System // 系统 Skill => DirectorySymlinkPolicy::Ignore, // 系统级 Skill 更严格
Plugin Skill 还会检查:
Canonicalized path 必须仍位于 Plugin Root 内。
防止通过 symlink/path trick 越界。
Extension 是更高一层抽象
Memory Extension 已经展示了 Extension 可以同时贡献:
Thread Lifecycle Config Prompt Context Tools
Web Search Extension 又贡献:
Config Thread Lifecycle Tool
MCP Manager 则允许 Extension:
MCP Server Contribution
由此,Codex 正在形成:

Extension Contributor 能力模型
相较单一 Skill,这套机制更接近:
Agent Plugin Framework。
16. Permission, Approval & Safety Governance
这里需要区分两个概念:
Sandbox
负责:
技术上能不能做。
Approval
负责:
治理上允不允许做。
Codex 已经明确分开两者。
Central Approval Stage
核心:codex-rs/core/src/tools/approvals.rs
pub(crate) enum ApprovalAction { // 所有需要风险治理的动作统一抽象为 ApprovalAction ExecCommand { /* ... */ }, // Shell / Process 执行审批 ApplyPatch { /* ... */ }, // 文件修改审批 McpToolCall { /* ... */ }, // 外部 MCP / App 行为审批 NetworkAccess { /* ... */ }, // 网络访问审批 RequestPermissions { /* ... */ }, // 运行时动态申请更多 Permission } // ApprovalAction 定义结束 ExecCommand { / ... / }, // Shell / Process 执行审批 ApplyPatch { / ... / }, // 文件修改审批 McpToolCall { / ... / }, // 外部 MCP / App 行为审批 NetworkAccess { / ... / }, // 网络访问审批 RequestPermissions { / ... / }, // 运行时动态申请更多 Permission
MCP Approval 甚至携带:
•connector_id
•connector_name
•connected_account_email
•tool_title
•approval policy
•reviewer
•approval mode
因此,审批 客户交互端 可以知道:
哪个外部应用、哪个账号、哪个动作正在被调用。
Guardian
源码还包含:
GuardianReviewContext GuardianReviewOptions review_approval_request routes_approval_policy_to_guardian
这意味着审批方不一定只有:
Human。
系统也可以:

权限审批与安全治理流程
这已经构成:
Agent Governance Layer
而不只是权限弹窗。
17. Protocol & Client Integration
Codex 运行时和 客户交互层 已明显解耦。
直接证据是:
app-server-protocol
TurnStartParams
文件:codex-rs/app-server-protocol/src/protocol/v2/turn.rs
pub struct TurnStartParams { // Client 启动一次 Agent Turn 的正式协议对象 pub thread_id: String, // 指定 Turn 属于哪个 Thread pub input: Vec , // 用户输入,可以包含多模态内容 pub environments: Option
继续还有:
pub sandbox_policy: Option , // 本 Turn 可覆盖 Sandbox Policy pub permissions: Option , // 可选择 Permission Profile pub model: Option , // 可在 Turn 边界切换模型 pub effort: Option , // 可调整 Reasoning Budget pub output_schema: Option , // 可约束最终回答 JSON Schema
由此可见:
Sandbox、Model、Environment、Permissions、Collaboration 并不是 CLI 特性。
它们已经是正式的运行时协议。
TypeScript SDK
sdk/typescript/src/thread.ts
SDK 向用户暴露的接口很简洁:
async run(input: Input, turnOptions: TurnOptions = {}): Promise { // 非流式执行一次 Agent Turn const generator = this.runStreamedInternal(input, turnOptions); // 底层仍然走流式事件执行层 const items: ThreadItem[] = []; // 收集整个 Turn 产生的 Item let finalResponse: string = ""; // 保存最终 Agent Answer let usage: Usage | null = null; // 保存 Token Usage
因此,SDK 是:
运行时协议的高级封装。
当前 Client Surface
从源码可以看到至少包括:
•CLI
•TUI
•VS Code
•Exec
•App Server
•TypeScript SDK
•Python SDK
•MCP
•Custom Client
这说明 Codex 的核心产品正在从:
Codex CLI
转向:
Codex 智能体调度层 + 多个客户端。
18. Observability, Diagnostics & Reliability
Observability 很重要,因为 Agent 面临的一个主要问题是:
“失败时到底哪里出了问题?”
Codex 已经建立了较完整的运行监控体系。
18.1 Telemetry
codex-rs/otel/src/events/session_telemetry.rs
可以看到:
use crate::metrics::API_CALL_DURATION_METRIC; // API 请求耗时 use crate::metrics::TOOL_CALL_DURATION_METRIC; // Tool 执行耗时 use crate::metrics::TURN_TTFT_DURATION_METRIC; // Turn 首 Token 延迟 use crate::metrics::WEBSOCKET_REQUEST_DURATION_METRIC; // WebSocket 请求耗时 use crate::metrics::SSE_EVENT_DURATION_METRIC; // SSE Stream Event 耗时
SessionTelemetry 还携带:
•thread id
•agent name
•session source
•model
•reasoning effort
•service tier
•terminal type
•app version
•auth metadata
18.2 智能体调度层自己也有指标
Tasks 中直接有:
TURN_E2E_DURATION TURN_MEMORY TURN_NETWORK_PROXY TURN_TOKEN_USAGE TURN_TOOL_CALL TURN_UNIFIED_EXEC_RUNNING_PROCESSES
借助这些指标可以分析:
某个 Turn 慢,到底慢在 Model、Tool、Network、Memory 还是 Exec。
18.3 Retry + Transport Fallback
codex-rs/core/src/responses_retry.rs
if retry_state.retries >= max_retries // 当前 Transport 已经达到最大重试次数 && client_session.try_switch_fallback_transport( // 尝试切换备用 Transport &turn_context.session_telemetry, // 同时记录 Transport fallback telemetry &turn_context.model_info, // 根据当前模型能力判断能否 fallback ) // Fallback 判断完成
随后会向用户发送:
message: format!("Falling back from WebSockets to HTTPS transport. {err:#}"), // 明确告知 UI 已从 WebSocket 降级到 HTTPS
连接异常还采用:
5s 10s 20s 40s 60s 60s...
指数退避。
整体架构重新拼起来
Codex 当前的真实架构大致如下:

业务流程图 · Codex 智能体运行平台:整体业务流程
我认为 Codex 源码里最值得产品设计学习的 8 个思想
如果把几万行源码压缩为产品方法论,我认为值得带走的不是某个 Rust 类,而是以下原则。
① Agent Loop 要极简,但 Loop 外围要工程化
Agent 最底层仍然只是:

极简 Agent Loop
复杂能力不应硬塞进这个 Loop,而应放在外围的:
•Context
•Runtime
•Tool
•State
•Governance
由外围层解决。
② Turn 和当前执行的上下文必须分开
这是当前 Codex 一项成熟的设计:

Thread、Turn 与执行步骤
每次模型判断都对应新的执行上下文。
这样,Agent 可以在一个 Turn 中动态感知:
•Workspace 已改变
•MCP 已改变
•Permission 已改变
•Sub-agent 返回结果
•用户新增内容
•Tool 改了文件
③ Tool Schema 和工具执行器必须分开
这对 Agent 平台很有参考价值:

模型可见工具生成流程
不必一次把 100 个 Tool Schema 全部塞给模型。
④ Context 不应该只是 Prompt 拼接
Codex 已经把 Context 构建为:
运行状态投影(Runtime State Projection)
它回答的是:
“在这一时刻,这个 Agent 应该看到的真实环境是什么?”
而不再只是:
“我该往 System Prompt 再拼什么字符串?”
⑤ Approval 和 Sandbox 必须分层
这是安全架构中的关键原则:
Approval = 这件事允不允许做 Sandbox = 就算允许,系统物理上能让它做到什么程度
只有 Approval 没有 Sandbox,不安全。
只有 Sandbox 没有 Approval,不可治理。
⑥ Multi-Agent 的难点在 Context + Scheduling,不只在 Spawn
Codex 已经开始解决:
•Context fork
•Agent Tree
•Message delivery
•Concurrency slots
•Agent persistence
•Agent recovery
•shared workspace
•resident runtime
这些能力共同构成真正的 Multi-Agent Engineering。
⑦ Skills / MCP / Plugins 应该是不同层级
从当前 Codex 架构可以看出,三者正逐步分开:
Skill = 教 Agent 怎么完成一类任务 Tool / MCP = 给 Agent 一个外部执行能力 Plugin / Extension = 给整个调度层安装一整套能力
Plugin 可以同时带:
Skill Tool MCP Prompt Config Lifecycle Connector
相比把所有东西都称为“插件”,这种区分清晰得多。
⑧ Coding Agent 最终会从 工具 演进成智能体调度底座
这是我阅读当前 Codex 源码后看到的最明显趋势。
早期更像:

早期 Coding Agent 模式
现在则越来越像:

从单体应用演进为智能体调度平台
当前版本新加入的:
•Turn Suspension
•Recovery
•App Server Protocol
•Environment abstraction
•Agent persistence/residency
•Multi-Agent scheduling
•Extension system
都表明它正在向:
通用 Coding Agent 调度中心 / Agent Operating Layer
这一方向演进。

最终结论
用一句话定义当前 Codex:
Codex 是一个围绕 LLM 推理构建的、可持久化、可扩展、可治理、支持多执行环境和多 Agent 协作的事件驱动智能体调度平台。
它的技术壁垒已经从:
“会不会调用 Shell。”
转向下面这套完整体系:
Model Intelligence + Agent Loop + Context Engineering + tool call + Execution Environment + State & Lifecycle + Multi-Agent + Extension system + Permission & Sandbox + Protocol + Observability
其中,我认为最值得继续深入源码的 6 个模块是:
Agent Loop → Context Engineering → tool call → Multi-Agent → Permission/Sandbox → Extension System。
这六块构成了 Codex 最核心的“Agent OS”基本骨架。
能看到此处的都是潜心学习、深耕 AI 领域的技术伙伴,给你们个超赞。如果需要 Codex 源码资源的朋友点赞留痕,我私信发送链接。
夜雨聆风