OpenAI Codex 源码的原理、架构与未来

发布时间:2026/6/29 18:54:16

OpenAI Codex 源码的原理、架构与未来 如果你第一次打开codex-main这个源码目录很容易被它的规模吓住顶层有 npm 包、Rust workspace、SDK、app-server、MCP、插件、技能、沙箱、TUI、云任务、线程存储、模型提供商、登录认证等大量模块。它不像一个传统命令行工具也不像一个简单的 ChatGPT 包装器。更准确地说Codex CLI 是一个“本地运行的智能软件工程代理”它能理解用户目标读取项目上下文调用模型推理决定是否执行命令或修改文件把工具结果回传给模型再持续推进任务直到给出最终结果。本文基于当前工作区的codex-main源码目录进行分析目标是让初学者也能看懂 Codex 的基本原理同时给有工程背景的读者足够的架构细节。文章会围绕四个问题展开第一Codex 到底是什么它和普通命令行工具、普通聊天机器人有什么区别第二Codex 的源码是如何组织的哪些 crate 或目录承担核心职责第三Codex 的核心执行原理是什么从用户输入一条需求到模型调用 shell、修改文件、读取 MCP 资源、输出最终答案中间经过了哪些关键步骤第四从工程实践角度看我们可以怎样使用 Codex、扩展 Codex或者从它的架构中学习如何设计自己的 AI Agent先给出一句通俗但准确的定义Codex 是一个以 Rust 为核心实现的本地软件工程 Agent 运行时它通过协议层连接 UI、CLI、App Server 和无交互执行入口通过 core 会话循环连接模型和工具通过沙箱、审批、配置、MCP、技能、插件等机制把“模型会想”变成“系统能安全地做事”。从源码看Codex 并不是把用户问题直接发给模型然后打印模型回答这么简单。它更像一个小型操作系统里面有输入队列、事件队列、会话状态、权限系统、工具注册表、上下文管理器、模型客户端、执行沙箱、插件系统和持久化存储。模型只是决策核心之一真正把 Agent 做成产品的是围绕模型的一整套工程系统。为了帮助初学者建立直觉我们先用一个简化流程表示 Codex 的工作方式普通回复工具调用用户输入任务CLI/TUI/App Server 接收请求加载配置、权限、AGENTS.md、技能和插件构建模型可见上下文向模型发起 Responses API 请求模型输出什么记录消息并展示给用户ToolRouter 匹配工具审批与沙箱检查执行 shell、apply_patch、MCP、web、子代理等工具工具结果写回会话历史结束当前 turn这个循环是理解 Codex 的关键。传统 CLI 往往是“一条命令 - 一个结果”聊天机器人往往是“一段上下文 - 一段文本”。Codex 则是“一段目标 - 多轮推理 - 多次工具调用 - 状态更新 - 最终交付”。它的源码复杂度主要来自三个方面模型需要看到足够上下文但上下文窗口有限所以需要压缩、裁剪和结构化注入。模型需要调用真实工具但工具可能读写文件、联网、执行命令所以必须有权限、沙箱和审批。Codex 要服务多种入口包括交互式 TUI、无交互exec、IDE/桌面 App、MCP Server、Cloud 任务等所以需要稳定协议和分层架构。接下来进入源码层面的系统拆解。2. 内容简要介绍codex-main是一个多语言单仓库外层 npm 包负责分发和启动核心能力集中在codex-rsRust workspace。最重要的主线是codex-cli/bin/codex.js找到对应平台的原生二进制Rustcli解析命令tui或exec或app-server建立会话core运行 Agent 主循环protocol定义客户端与 Agent 之间的操作和事件tools负责把模型输出映射成真实工具调用sandboxing和权限系统负责限制风险。2.1 Codex 不是“聊天壳”而是 Agent Runtime很多初学者第一次理解 AI 编程工具时会把它想成用户帮我修 bug程序把问题发给模型模型返回一段代码程序显示代码这只是最早期的代码助手形态。Codex 源码展示的是更成熟的 Agent 形态用户帮我修 bugCodex读取项目规则搜索相关文件运行测试分析失败修改代码再运行测试汇总结论这个过程中模型需要不断“看见”外部世界。它不能只凭训练记忆回答因为当前项目的代码、测试失败、用户本地环境、未提交变更、配置文件和工具输出都在实时变化。Codex 的核心价值就在于把这些外部信息纳入一个受控循环。在codex-rs/core/src/session/turn.rs中源码对run_turn的注释已经把核心机制讲得很清楚每一次 sampling request模型可能返回函数调用也可能返回助手消息。如果返回工具调用Codex 执行工具并把工具输出作为下一次请求的输入如果返回普通助手消息就记录进历史并认为当前 turn 完成。也就是说Codex 的“智能”不只是模型能力还包括它周围的运行时能力它能把模型输出解析成结构化工具调用。它能把工具调用映射到本地实现。它能在执行前检查权限与审批策略。它能把执行结果转换成模型能理解的ResponseInputItem。它能维护线程、turn、上下文窗口、token 预算和持久化记录。如果我们把 Codex 当成一个系统来观察可以把它拆成五层用户入口层CLI / TUI / exec / App Server / MCP Server协议层Op / Event / Thread / Turn核心层Session / Turn / Context / ModelClient工具层ToolRouter / ToolRegistry / ToolRuntime执行与安全层sandbox / approval / permission profile模型与外部服务OpenAI Responses API / WebSocket / HTTP / MCP其中最重要的源码目录如下codex-main/ ├── README.md # 项目入口说明介绍安装方式和产品形态 ├── codex-cli/ │ └── bin/codex.js # npm 包入口定位并启动平台原生二进制 ├── codex-rs/ │ ├── Cargo.toml # Rust workspace列出大量内部 crate │ ├── cli/ # 顶层命令行解析与子命令分发 │ ├── tui/ # 交互式终端 UI │ ├── exec/ # 非交互执行入口适合脚本和 CI │ ├── core/ # Agent 核心会话、turn、工具、上下文、模型调用 │ ├── protocol/ # 核心协议类型Op、Event、SandboxPolicy 等 │ ├── app-server/ # App/IDE 等宿主形态可复用的服务端 │ ├── app-server-protocol/ # App Server v1/v2 JSON-RPC 协议 │ ├── codex-api/ # OpenAI API / Responses API 访问层 │ ├── codex-client/ # HTTP/SSE/WebSocket 客户端基础能力 │ ├── model-provider/ # 模型提供商抽象 │ ├── mcp-server/、codex-mcp/ # MCP 相关能力 │ ├── core-skills/、skills/ # 技能加载与注入 │ ├── core-plugins/、plugin/ # 插件 manifest、市场和本地插件 │ ├── sandboxing/ # 跨平台沙箱抽象 │ ├── linux-sandbox/ # Linux Landlock / bubblewrap 支持 │ ├── windows-sandbox-rs/ # Windows 受限 token、ACL、WFP 等 │ ├── thread-store/ # 线程持久化抽象 │ ├── rollout/、rollout-trace/ # 会话记录、回放和调试 │ └── tools/ # 工具规范和共享工具定义 └── sdk/ ├── python/ # Python SDK └── typescript/ # TypeScript SDK从这个目录可以看出Codex 的核心不是某一个巨大文件而是一组职责明确的 crate。core是大脑和调度中心但它并不直接承担所有事情协议在protocolUI 在tui无交互运行在execApp 集成在app-server沙箱在sandboxing插件和技能也拆成独立模块。这正是大型 Agent 工程的第一条经验不要把“模型调用、工具实现、UI 展示、权限控制、配置读取、状态存储”塞进一个文件。它们变化频率不同风险边界不同测试方式也不同。2.2 从安装启动看 Codex 的第一层架构Codex 可以通过npm install -g openai/codex、Homebrew 或安装脚本安装。源码中的codex-cli/package.json定义了 npm 包名和可执行入口{ name: openai/codex, bin: { codex: bin/codex.js }, type: module }但codex.js并不实现 Agent 本身。它做的是平台适配根据process.platform和process.arch判断目标三元组例如 macOS arm64 对应aarch64-apple-darwinLinux x64 对应x86_64-unknown-linux-muslWindows x64 对应x86_64-pc-windows-msvc。然后它到对应平台包的vendor/target/bin/codex下寻找真正的原生二进制最后用spawn把参数原样转发过去。简化版代码可以这样理解// 简化示例根据平台选择原生 Codex 二进制 const targetMap { darwin-arm64: aarch64-apple-darwin, darwin-x64: x86_64-apple-darwin, linux-x64: x86_64-unknown-linux-musl, win32-x64: x86_64-pc-windows-msvc, }; const key ${process.platform}-${process.arch}; const targetTriple targetMap[key]; // 真实源码会处理更多平台、包管理器提示和信号转发 const binaryPath vendor/${targetTriple}/bin/codex; // 关键逻辑Node 只负责启动Agent 主体在 Rust 二进制里 spawn(binaryPath, process.argv.slice(2), { stdio: inherit, env: process.env, });这个设计有几个好处npm 生态用户安装方便不需要自己编译 Rust。真正运行时代码是原生二进制启动快资源控制强。平台差异被集中处理Rust 侧可以根据目标平台启用不同沙箱实现。Node 入口保留了信号转发能力用户按 Ctrl-C 时能把信号传给子进程。初学者可以把codex-cli/bin/codex.js理解为“门卫”它不负责推理只负责把你带到真正的入口。进入 Rust 之后codex-rs/cli/src/main.rs使用clap定义了顶层命令。源码里的Subcommand很能说明 Codex 的产品边界Exec非交互运行 Codex。Review无交互代码审查。Login/Logout认证管理。Mcp管理外部 MCP server。Plugin管理 Codex 插件。McpServer把 Codex 作为 MCP server 运行。AppServer运行 app server 或相关工具。App启动桌面 App。Doctor诊断本地安装、配置、认证和运行环境。Sandbox在 Codex 提供的沙箱里运行命令。

相关新闻