OpenAI Codex 深入剖析:下一代 AI 编程助手的架构与原理

深入剖析 OpenAI Codex:下一代 AI 编程助手的架构与原理

本文将带你深入了解 OpenAI Codex 的内部架构、设计思路和实现原理。无论你是初学者还是有经验的开发者,都能从中获得对 AI 编程助手的深刻理解。

目录

  1. [什么是 Codex?](#什么是 Codex? "#%E4%BB%80%E4%B9%88%E6%98%AF-codex")
  2. 整体架构概览
  3. 核心特性详解
  4. 底层协议与通信机制
  5. 记忆系统:如何记住对话
  6. 上下文工程:智能管理有限的"脑容量"
  7. [工具系统:让 AI 能够"动手"](#工具系统:让 AI 能够"动手" "#%E5%B7%A5%E5%85%B7%E7%B3%BB%E7%BB%9F%E8%AE%A9-ai-%E8%83%BD%E5%A4%9F%E5%8A%A8%E6%89%8B")
  8. [安全沙箱:给 AI 一个安全的"游乐场"](#安全沙箱:给 AI 一个安全的"游乐场" "#%E5%AE%89%E5%85%A8%E6%B2%99%E7%AE%B1%E7%BB%99-ai-%E4%B8%80%E4%B8%AA%E5%AE%89%E5%85%A8%E7%9A%84%E6%B8%B8%E4%B9%90%E5%9C%BA")
  9. [MCP 协议:连接外部世界的桥梁](#MCP 协议:连接外部世界的桥梁 "#mcp-%E5%8D%8F%E8%AE%AE%E8%BF%9E%E6%8E%A5%E5%A4%96%E9%83%A8%E4%B8%96%E7%95%8C%E7%9A%84%E6%A1%A5%E6%A2%81")
  10. 执行策略:智能的权限管理
  11. [如何使用 Codex](#如何使用 Codex "#%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8-codex")
  12. 总结

什么是 Codex?

想象一下,你有一个超级聪明的编程助手,它不仅能理解你的需求,还能直接帮你写代码、运行命令、修改文件。这就是 Codex ------ OpenAI 推出的本地 AI 编程代理。

用大白话解释

如果把编程比作做菜:

  • 普通的 AI 助手(如 ChatGPT)就像一本菜谱,告诉你怎么做,但你需要自己动手
  • Codex 就像一个真正的厨师,不仅告诉你怎么做,还能直接帮你把菜做出来

核心能力

  • Codex 能做什么?
    • 理解代码:阅读和分析你的项目代码
    • 编写代码:自动编写新功能或修复 bug
    • 执行命令:运行测试、构建项目、git 操作等
    • 修改文件:直接编辑、创建、删除文件
    • 搜索信息:在代码库中搜索,甚至进行网络搜索
    • 调用外部工具:通过 MCP 协议连接各种外部服务

整体架构概览

Codex 采用了 Monorepo(单一代码仓库) 的组织方式,主要由 Rust 和 TypeScript 两种语言构建。

为什么选择 Rust?

特性 说明
性能 Rust 编译成机器码,运行速度极快
安全 内存安全保证,避免常见的安全漏洞
并发 优秀的异步编程支持,可同时处理多个任务
跨平台 一套代码可编译到 macOS、Linux、Windows

项目结构图

bash 复制代码
codex/
├── codex-rs/           # Rust 核心代码(45+ 个模块)
│   ├── core/           # 核心引擎 - AI 的"大脑"
│   ├── tui/            # 终端界面 - 用户交互
│   ├── cli/            # 命令行入口
│   ├── exec/           # 非交互式执行
│   ├── mcp-server/     # MCP 服务器
│   └── ...             # 其他支持模块
│
├── sdk/typescript/     # TypeScript SDK(给开发者用的库)
├── shell-tool-mcp/     # Shell 工具 MCP 实现
└── docs/               # 文档

架构分层图

graph TB subgraph UserInterface["用户接口层"] CLI["CLI 命令行"] TUI["TUI 终端界面"] SDK["TypeScript SDK"] end subgraph CoreEngine["核心引擎层"] Codex["Codex 核心引擎"] ModelClient["模型客户端"] ContextMgr["上下文管理器"] ToolRouter["工具路由器"] end subgraph ExecutionLayer["执行层"] ShellExec["Shell 执行器"] FileOps["文件操作"] MCPClient["MCP 客户端"] WebSearch["网络搜索"] end subgraph SecurityLayer["安全层"] Sandbox["沙箱隔离"] ExecPolicy["执行策略"] Approval["审批系统"] end CLI --> Codex TUI --> Codex SDK --> Codex Codex --> ModelClient Codex --> ContextMgr Codex --> ToolRouter ToolRouter --> ShellExec ToolRouter --> FileOps ToolRouter --> MCPClient ToolRouter --> WebSearch ShellExec --> Sandbox ShellExec --> ExecPolicy FileOps --> Sandbox FileOps --> Approval MCPClient --> Approval style UserInterface fill:#E3F2FD,stroke:#1976D2 style CoreEngine fill:#E8F5E9,stroke:#388E3C style ExecutionLayer fill:#FFF3E0,stroke:#F57C00 style SecurityLayer fill:#FCE4EC,stroke:#C2185B

Codex 的架构可以分为四层:

  1. 用户接口层:你与 Codex 交互的入口(CLI、TUI、SDK)
  2. 核心引擎层:处理 AI 推理、工具调用、上下文管理
  3. 执行层:实际执行命令、修改文件、调用外部服务
  4. 安全层:沙箱隔离、权限控制、执行策略

核心特性详解

1. 多模式交互

Codex 支持三种使用模式:

交互式 TUI 非交互式 Exec SDK 集成
实时对话界面 自动化脚本执行 嵌入到你的应用
适合日常开发 适合 CI/CD 适合构建产品

2. 会话管理

每次与 Codex 的对话都是一个"会话"(Session)。Codex 会:

  • 记住你们的对话历史
  • 保存执行过的命令和结果
  • 支持暂停和恢复对话

3. 智能审批

Codex 不会盲目执行所有命令。对于危险操作,它会:

ini 复制代码
你: 帮我删除所有日志文件
Codex: 我需要执行 `rm -rf ./logs/*`,这会删除所有日志。
       [允许执行] [拒绝] [白名单此命令]

底层协议与通信机制

提交队列/事件队列(SQ/EQ)模式

Codex 内部使用了一种高效的异步通信模式:

sequenceDiagram participant User as 用户/TUI participant SQ as 提交队列 (SQ) participant Engine as Codex 核心引擎 participant LLM as 大语言模型 participant Tools as 工具系统 participant EQ as 事件队列 (EQ) User->>SQ: 提交用户输入 Note over SQ: Op::UserTurn SQ->>Engine: 异步接收提交 Engine->>LLM: 调用模型 API LLM-->>Engine: 流式响应 Engine->>EQ: 发送 AgentMessage 事件 EQ-->>User: 实时显示 AI 回复 LLM-->>Engine: 工具调用请求 Engine->>Tools: 执行工具 Engine->>EQ: 发送 ExecApprovalRequest EQ-->>User: 请求用户批准 User->>SQ: 提交批准决定 SQ->>Engine: 接收批准 Tools-->>Engine: 工具执行结果 Engine->>EQ: 发送 ExecCommandOutput EQ-->>User: 显示执行结果 Engine->>LLM: 继续推理 LLM-->>Engine: 最终响应 Engine->>EQ: 发送 TurnCompleted EQ-->>User: 显示完成状态

用大白话解释

想象一家餐厅:

  • 提交队列(SQ) 就像顾客下单的窗口
  • Codex 核心引擎 就像厨房
  • 事件队列(EQ) 就像出餐窗口

顾客下单后不需要等在窗口,可以去座位上等。厨房做好菜后,通过出餐窗口通知顾客取餐。

核心代码结构

rust 复制代码
// 简化版的 Codex 核心结构
pub struct Codex {
    // 提交队列:接收用户输入
    tx_sub: Sender<Submission>,
    // 事件队列:发送处理结果
    rx_event: Receiver<Event>,
}

事件类型

Codex 定义了丰富的事件类型来描述各种操作:

事件类型 说明 示例
AgentMessage AI 的回复 "我来帮你修复这个 bug"
ExecCommandOutput 命令执行结果 测试运行的输出
PatchApprovalRequest 请求批准文件修改 修改 config.js
TokenCount Token 使用统计 输入 1000,输出 500

记忆系统:如何记住对话

问题:AI 的"健忘症"

大语言模型本身是"无状态"的,每次调用都是全新的开始。就像一个失忆的人,每天早上醒来都不记得昨天发生了什么。

解决方案:持久化历史

Codex 通过多层记忆系统解决这个问题:

graph TB subgraph ShortTerm["短期记忆 - 上下文管理器"] CM["ContextManager"] Items["对话项目列表"] TokenInfo["Token 统计"] CM --> Items CM --> TokenInfo end subgraph MediumTerm["中期记忆 - 消息历史"] History["history.jsonl"] Entry1["session_id + timestamp + text"] Entry2["session_id + timestamp + text"] Entry3["..."] History --> Entry1 History --> Entry2 History --> Entry3 end subgraph LongTerm["长期记忆 - 会话持久化"] Sessions["~/.codex/sessions/"] Session1["session_abc.json"] Session2["session_xyz.json"] Sessions --> Session1 Sessions --> Session2 end subgraph ProjectMemory["项目记忆 - AGENTS.md"] AgentsMD["AGENTS.md"] Rules["项目规范"] Constraints["约束条件"] AgentsMD --> Rules AgentsMD --> Constraints end User["用户"] --> CM CM -->|"保存到"| History CM -->|"持久化"| Sessions AgentsMD -->|"加载到"| CM style ShortTerm fill:#E3F2FD,stroke:#1976D2 style MediumTerm fill:#E8F5E9,stroke:#388E3C style LongTerm fill:#FFF3E0,stroke:#F57C00 style ProjectMemory fill:#F3E5F5,stroke:#7B1FA2

三层记忆架构

1. 短期记忆:上下文管理器(ContextManager)
rust 复制代码
pub struct ContextManager {
    // 当前对话的所有项目(从旧到新排序)
    items: Vec<ResponseItem>,
    // Token 使用信息
    token_info: Option<TokenUsageInfo>,
}

作用:管理当前对话中的所有消息、工具调用和结果。

2. 中期记忆:消息历史(Message History)

存储位置:~/.codex/history.jsonl

json 复制代码
{"session_id": "abc123", "ts": 1699123456, "text": "帮我写一个排序函数"}
{"session_id": "abc123", "ts": 1699123460, "text": "好的,这是冒泡排序的实现..."}

特点

  • 使用 JSONL 格式(每行一个 JSON)
  • 原子写入(不会出现写一半的情况)
  • 自动管理大小(超过限制会清理旧记录)
3. 长期记忆:会话持久化

存储位置:~/.codex/sessions/

每个会话保存为独立的 JSON 文件,包含完整的对话状态,支持随时恢复。

项目文档记忆:AGENTS.md

Codex 还会读取项目中的 AGENTS.md 文件,了解项目的特殊规则:

markdown 复制代码
# AGENTS.md

## 项目规范
- 使用 TypeScript 编写
- 所有函数必须有注释
- 测试覆盖率要求 80% 以上

## 禁止操作
- 不要修改 .env 文件
- 不要删除 migrations 文件夹

上下文工程:智能管理有限的"脑容量"

问题:上下文窗口的限制

大语言模型有一个"上下文窗口"限制,就像人的工作记忆一样有限。如果对话太长,模型就会"记不住"前面的内容。

css 复制代码
┌────────────────────────────────────────────────────────────┐
│                    上下文窗口示意图                          │
├────────────────────────────────────────────────────────────┤
│  [系统提示] [用户1] [AI1] [用户2] [AI2] ... [用户N] [AI N]  │
│  ←─────────────── 有限的容量 ──────────────────→           │
│                                                            │
│  超出容量时:旧的内容会被"遗忘"                              │
└────────────────────────────────────────────────────────────┘

解决方案:智能上下文管理

Codex 采用多种策略来最大化利用有限的上下文:

flowchart TD Start["开始新的对话轮次"] --> Check{"检查上下文大小"} Check -->|"< 80% 窗口"| Normal["正常添加内容"] Check -->|">= 80% 窗口"| Strategy["应用优化策略"] Strategy --> S1["策略1: Token 估算"] Strategy --> S2["策略2: 智能截断"] Strategy --> S3["策略3: 对话压缩"] Strategy --> S4["策略4: 环境差异"] S1 --> |"每4字节≈1 token"| Estimate["快速估算大小"] S2 --> |"保留头尾"| Truncate["删除中间内容"] S3 --> |"AI 生成摘要"| Compact["压缩历史对话"] S4 --> |"只发送变化"| Diff["差异化更新"] Estimate --> Optimize["优化后的上下文"] Truncate --> Optimize Compact --> Optimize Diff --> Optimize Normal --> Send["发送给模型"] Optimize --> Send Send --> Response["获取模型响应"] Response --> Update["更新 Token 统计"] Update --> End["完成"] style Start fill:#4CAF50,color:#fff style End fill:#4CAF50,color:#fff style Strategy fill:#FF9800,color:#fff style Check fill:#2196F3,color:#fff

策略 1:Token 估算

不使用精确的 tokenizer(太慢),而是用简单的启发式算法:

rust 复制代码
const APPROX_BYTES_PER_TOKEN: usize = 4;

// 估算 token 数量:每 4 个字节约等于 1 个 token
fn approx_token_count(text: &str) -> usize {
    (text.len() + 3) / 4  // 向上取整
}

策略 2:智能截断

对于过长的输出,保留头尾,删除中间:

css 复制代码
原始输出(10000 字符):
┌─────────────────────────────────────────────────────────────┐
│ [头部 1000 字符] [...中间内容...] [尾部 1000 字符]          │
└─────────────────────────────────────────────────────────────┘

截断后(2500 字符):
┌─────────────────────────────────────────────────────────────┐
│ [头部 1000 字符] ... [省略 7500 字符] ... [尾部 1000 字符]  │
└─────────────────────────────────────────────────────────────┘

策略 3:对话压缩(Compaction)

当上下文接近满时,Codex 会请求 AI 对之前的对话进行"摘要":

makefile 复制代码
压缩前:
用户: 帮我看看为什么测试失败
AI: 好的,让我运行测试... 测试结果是... 问题在于...
用户: 修复它
AI: 我修改了文件... 现在测试通过了
用户: 还有其他问题吗?
...(很多轮对话)

压缩后:
[摘要] 用户请求修复测试失败问题,经过分析发现是类型错误,
已修改 src/utils.ts 第 42 行,测试现已通过。

策略 4:环境上下文差异

只发送变化的部分,而不是每次都发送完整的环境信息:

xml 复制代码
<!-- 首次发送完整上下文 -->
<environment_context>
  <cwd>/path/to/project</cwd>
  <sandbox_mode>workspace-write</sandbox_mode>
  <shell>bash</shell>
</environment_context>

<!-- 之后只发送变化 -->
<environment_context_diff>
  <cwd>/path/to/project/src</cwd>  <!-- 只有工作目录变了 -->
</environment_context_diff>

工具系统:让 AI 能够"动手"

为什么需要工具?

大语言模型本身只能"说",不能"做"。工具系统就是给 AI 装上"手",让它能够:

  • 执行 shell 命令
  • 读写文件
  • 搜索代码
  • 调用外部服务

工具架构

graph LR subgraph AI["AI 模型"] LLM["大语言模型"] Decision["决策: 需要使用工具"] end subgraph Router["工具路由器"] Registry["工具注册表"] Dispatch["分发器"] end subgraph Tools["内置工具"] Shell["Shell 执行器"] ReadFile["文件读取"] ApplyPatch["补丁应用"] GrepFiles["文件搜索"] ListDir["目录列表"] ViewImage["图片查看"] end subgraph External["外部工具"] MCP["MCP 工具"] WebSearch["网络搜索"] end subgraph Security["安全检查"] Policy["执行策略"] Sandbox["沙箱隔离"] Approval["用户审批"] end LLM --> Decision Decision --> Registry Registry --> Dispatch Dispatch --> Shell Dispatch --> ReadFile Dispatch --> ApplyPatch Dispatch --> GrepFiles Dispatch --> ListDir Dispatch --> ViewImage Dispatch --> MCP Dispatch --> WebSearch Shell --> Policy ApplyPatch --> Approval MCP --> Approval Policy --> Sandbox Approval --> Sandbox Sandbox --> Result["执行结果"] Result --> LLM style AI fill:#E3F2FD,stroke:#1976D2 style Router fill:#E8F5E9,stroke:#388E3C style Tools fill:#FFF3E0,stroke:#F57C00 style External fill:#F3E5F5,stroke:#7B1FA2 style Security fill:#FCE4EC,stroke:#C2185B

内置工具列表

工具名称 功能 示例
shell 执行命令 npm test, git status
read_file 读取文件 查看 config.json
list_dir 列出目录 浏览项目结构
apply_patch 修改文件 修复代码 bug
grep_files 搜索文件 查找函数定义
view_image 查看图片 分析截图
web_search 网络搜索 查找文档
mcp_tool 调用 MCP 工具 使用外部服务

工具调用流程

markdown 复制代码
1. AI 决定使用工具
   └── "我需要运行测试来验证修复"

2. 生成工具调用
   └── { tool: "shell", command: "npm test" }

3. 权限检查
   └── 检查执行策略和沙箱规则

4. 执行工具
   └── 在沙箱中运行命令

5. 返回结果
   └── 将输出返回给 AI

6. AI 继续推理
   └── "测试通过了,修复成功!"

工具注册机制

Codex 使用统一的工具注册表来管理所有工具:

rust 复制代码
pub struct ToolRegistry {
    handlers: HashMap<ToolType, Box<dyn ToolHandler>>,
}

pub trait ToolHandler: Send + Sync {
    async fn handle(
        &self,
        invocation: ToolInvocation
    ) -> Result<ToolOutput, ToolError>;
}

安全沙箱:给 AI 一个安全的"游乐场"

为什么需要沙箱?

让 AI 执行命令是危险的。想象一下:

bash 复制代码
用户: 帮我清理项目
AI: 好的,我来执行 rm -rf /  # 危险!会删除整个系统!

沙箱就是为了防止这种灾难性的操作。

沙箱原理

graph TB subgraph Request["命令请求"] Cmd["执行命令: npm test"] end subgraph PolicyCheck["策略检查"] EP["执行策略引擎"] Decision{"决策"} end subgraph SandboxSelect["沙箱选择"] Platform{"操作系统?"} MacOS["macOS: Seatbelt"] Linux["Linux: Landlock + Seccomp"] Windows["Windows: RestrictedToken"] end subgraph Permissions["权限控制"] FS["文件系统访问"] Net["网络访问"] Proc["进程权限"] end subgraph Execution["执行环境"] Isolated["隔离进程"] Result["执行结果"] end Cmd --> EP EP --> Decision Decision -->|"allow"| Platform Decision -->|"prompt"| UserApproval["用户审批"] Decision -->|"forbidden"| Blocked["拒绝执行"] UserApproval -->|"批准"| Platform UserApproval -->|"拒绝"| Blocked Platform -->|"darwin"| MacOS Platform -->|"linux"| Linux Platform -->|"win32"| Windows MacOS --> FS Linux --> FS Windows --> FS FS --> Net Net --> Proc Proc --> Isolated Isolated --> Result style Request fill:#E3F2FD,stroke:#1976D2 style PolicyCheck fill:#FFF3E0,stroke:#F57C00 style SandboxSelect fill:#E8F5E9,stroke:#388E3C style Permissions fill:#FCE4EC,stroke:#C2185B style Execution fill:#F3E5F5,stroke:#7B1FA2 style Blocked fill:#FFCDD2,stroke:#D32F2F

三种沙箱策略

策略 文件权限 网络权限 适用场景
read-only 只读 禁止 代码审查
workspace-write 工作区可写 可配置 日常开发
danger-full-access 完全访问 允许 特殊场景

跨平台沙箱实现

Codex 针对不同操作系统使用不同的沙箱技术:

macOS: Seatbelt
rust 复制代码
// 生成 SBPL(Seatbelt Profile Language)策略
let profile = format!(r#"
    (version 1)
    (deny default)
    (allow file-read* (subpath "{writable_root}"))
    (allow file-write* (subpath "{writable_root}"))
    (deny network*)
"#);
Linux: Landlock + Seccomp
rust 复制代码
// Landlock:限制文件系统访问
let ruleset = Ruleset::new()
    .handle_access(AccessFs::ReadFile)?
    .create()?;

// Seccomp:阻止危险的系统调用
seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM),
    SCMP_SYS(connect), 0)?;  // 禁止网络连接
Windows: RestrictedToken

使用 Windows 的受限令牌和 ACL(访问控制列表)来限制权限。

沙箱绕过机制

有时候确实需要执行受限的操作,Codex 提供了安全的升级路径:

markdown 复制代码
1. AI 请求执行需要额外权限的命令
2. 向用户显示权限提升请求
3. 用户确认后,在沙箱外执行
4. 记录操作日志

MCP 协议:连接外部世界的桥梁

什么是 MCP?

MCP(Model Context Protocol) 是一个开放协议,让 AI 助手能够与外部工具和服务交互。可以把它想象成 AI 世界的"USB 接口"。

graph LR subgraph CodexCore["Codex 核心"] MCPManager["MCP 连接管理器"] ToolRouter["工具路由器"] end subgraph MCPClients["MCP 客户端连接"] Client1["RmcpClient #1"] Client2["RmcpClient #2"] Client3["RmcpClient #3"] end subgraph Transport["传输层"] Stdio["Stdio 传输"] HTTP["HTTP 传输"] OAuth["OAuth 认证"] end subgraph MCPServers["MCP 服务器"] GitHub["GitHub 服务器"] Slack["Slack 服务器"] Custom["自定义服务器"] end subgraph Protocol["协议层"] Init["1. 初始化握手"] ListTools["2. 获取工具列表"] CallTool["3. 调用工具"] Result["4. 返回结果"] end ToolRouter --> MCPManager MCPManager --> Client1 MCPManager --> Client2 MCPManager --> Client3 Client1 --> Stdio Client2 --> HTTP Client3 --> OAuth Stdio --> GitHub HTTP --> Custom OAuth --> Slack GitHub --> Init Init --> ListTools ListTools --> CallTool CallTool --> Result style CodexCore fill:#E3F2FD,stroke:#1976D2 style MCPClients fill:#E8F5E9,stroke:#388E3C style Transport fill:#FFF3E0,stroke:#F57C00 style MCPServers fill:#F3E5F5,stroke:#7B1FA2 style Protocol fill:#E0F7FA,stroke:#00838F

MCP 的角色

Codex 可以同时作为:

  • MCP 客户端:调用其他 MCP 服务器提供的工具
  • MCP 服务器:让其他应用调用 Codex 的能力

连接外部服务示例

toml 复制代码
# ~/.codex/config.toml

[mcp_servers.github]
enabled = true

[mcp_servers.github.transport]
type = "stdio"
command = "npx"
args = ["@modelcontextprotocol/server-github"]

配置后,Codex 就能使用 GitHub 的功能:

less 复制代码
用户: 帮我创建一个 issue 报告这个 bug
Codex: 好的,我来调用 GitHub MCP 服务器创建 issue...
       [调用 mcp__github__create_issue 工具]
       Issue 已创建:https://github.com/xxx/xxx/issues/123

MCP 通信流程

markdown 复制代码
┌─────────────┐     JSON-RPC      ┌─────────────┐
│   Codex     │ ◄──────────────► │  MCP 服务器  │
│  (客户端)   │    over stdio    │  (GitHub)   │
└─────────────┘                   └─────────────┘

1. 初始化握手:交换能力声明
2. 工具列表:获取可用工具
3. 工具调用:执行具体操作
4. 返回结果:获取执行结果

支持的传输方式

传输方式 适用场景 示例
stdio 本地进程 npx 启动的工具
HTTP 远程服务 云端 API
HTTP + OAuth 需要认证的服务 GitHub, Slack

执行策略:智能的权限管理

问题:如何判断命令是否安全?

不是所有命令都同样危险:

  • ls 完全安全
  • npm test 通常安全
  • rm -rf / 绝对危险
  • git push 需要确认

解决方案:执行策略引擎

Codex 使用基于规则的执行策略系统:

flowchart TD Start["命令: git push origin main"] --> Parse["解析命令 tokens"] Parse --> Lookup["查找匹配规则"] subgraph Rules["规则库"] R1["prefix_rule(['ls'], 'allow')"] R2["prefix_rule(['git', 'push'], 'prompt')"] R3["prefix_rule(['rm', '-rf'], 'forbidden')"] end Lookup --> R1 Lookup --> R2 Lookup --> R3 R1 --> Match{"匹配检查"} R2 --> Match R3 --> Match Match -->|"匹配 R2"| Collect["收集匹配结果"] Match -->|"无匹配"| Heuristics["启发式检查"] Heuristics -->|"安全命令"| AllowH["Decision: Allow"] Heuristics -->|"危险命令"| PromptH["Decision: Prompt"] Collect --> MaxDecision["选择最严格决策"] MaxDecision --> FinalAllow["Allow: 直接执行"] MaxDecision --> FinalPrompt["Prompt: 请求用户批准"] MaxDecision --> FinalForbid["Forbidden: 拒绝执行"] AllowH --> FinalAllow PromptH --> FinalPrompt FinalPrompt --> UserChoice{"用户选择"} UserChoice -->|"批准"| Execute["执行命令"] UserChoice -->|"白名单"| Whitelist["添加 allow 规则"] UserChoice -->|"拒绝"| Reject["取消执行"] Whitelist --> Execute style Start fill:#2196F3,color:#fff style FinalAllow fill:#4CAF50,color:#fff style FinalPrompt fill:#FF9800,color:#fff style FinalForbid fill:#F44336,color:#fff style Rules fill:#E8F5E9,stroke:#388E3C

策略文件格式

策略文件使用类 Python 的 Starlark 语言:

bash 复制代码
# ~/.codex/policy/default.codexpolicy

# 允许常见的安全命令
prefix_rule(
    pattern = ["ls"],
    decision = "allow",
)

prefix_rule(
    pattern = ["cat"],
    decision = "allow",
)

# 需要确认的命令
prefix_rule(
    pattern = ["git", ["push", "pull", "fetch"]],
    decision = "prompt",
)

# 禁止危险命令
prefix_rule(
    pattern = ["rm", "-rf"],
    decision = "forbidden",
)

决策优先级

当多个规则匹配时,采用最严格的决策:

复制代码
forbidden(禁止) > prompt(提示) > allow(允许)

内置安全检测

除了显式规则,Codex 还有内置的启发式安全检测:

rust 复制代码
// 已知的安全命令(27个)
const SAFE_COMMANDS: &[&str] = &[
    "cat", "echo", "ls", "pwd", "grep", "head", "tail",
    "wc", "sort", "uniq", "diff", "file", "which", "date",
    "env", "printenv", "hostname", "uname", "whoami",
    // ...
];

// 危险命令检测
fn is_dangerous_command(cmd: &[String]) -> bool {
    matches!(cmd,
        ["rm", "-rf", ..] |
        ["git", "reset", "--hard", ..] |
        ["sudo", ..] |
        // ...
    )
}

动态白名单

当你批准一个命令后,可以选择"白名单此命令",Codex 会自动更新策略文件:

starlark 复制代码
# 自动添加的规则
prefix_rule(pattern=["npm", "test"], decision="allow")

如何使用 Codex

安装方式

bash 复制代码
# 方式 1:通过 npm 安装
npm install -g @openai/codex

# 方式 2:通过 Homebrew 安装(macOS)
brew install --cask codex

登录认证

bash 复制代码
# 使用 ChatGPT 账户登录(推荐)
codex login

# 或者使用 API Key
export CODEX_API_KEY=sk-xxx

基本使用

bash 复制代码
# 启动交互式界面
codex

# 直接执行任务(非交互式)
codex exec "帮我写一个快速排序函数"

# 在特定目录工作
codex --cd /path/to/project

TypeScript SDK 使用

typescript 复制代码
import { Codex } from "@openai/codex-sdk";

const codex = new Codex();
const thread = codex.startThread({
    model: "gpt-4",
    sandboxMode: "workspace-write",
    workingDirectory: "./my-project"
});

// 同步模式:等待完成
const turn = await thread.run("帮我修复所有的 TypeScript 错误");
console.log(turn.finalResponse);

// 流式模式:实时获取事件
const { events } = await thread.runStreamed("运行测试");
for await (const event of events) {
    if (event.type === "item.completed") {
        console.log("完成:", event.item);
    }
}

配置文件

toml 复制代码
# ~/.codex/config.toml

# 默认模型
model = "gpt-4-turbo"

# 沙箱策略
sandbox_policy = "workspace-write"

# 审批策略
approval_policy = "on-request"

# MCP 服务器配置
[mcp_servers.github]
enabled = true
[mcp_servers.github.transport]
type = "stdio"
command = "npx"
args = ["@modelcontextprotocol/server-github"]

总结

Codex 的设计哲学

  1. 安全第一:多层沙箱、执行策略、用户审批
  2. 可扩展性:工具系统、MCP 协议、插件架构
  3. 智能管理:上下文压缩、记忆持久化、Token 优化
  4. 用户体验:交互式界面、流式输出、断点续传

技术亮点

特性 技术实现 优势
性能 Rust 核心 接近原生速度
安全 多平台沙箱 系统级隔离
扩展 MCP 协议 开放生态
智能 上下文工程 高效利用模型能力
体验 SQ/EQ 异步模式 流畅的交互

未来展望

Codex 代表了 AI 编程助手的一个重要方向:从"建议"走向"执行",从"对话"走向"协作"。随着 AI 能力的提升和工具生态的完善,我们可以期待更加智能、安全、高效的编程助手。


附录:关键文件路径速查

组件 路径
核心引擎 codex-rs/core/src/codex.rs
TUI 界面 codex-rs/tui/src/app.rs
工具系统 codex-rs/core/src/tools/
沙箱实现 codex-rs/core/src/sandboxing/
执行策略 codex-rs/execpolicy/src/
MCP 客户端 codex-rs/rmcp-client/src/
上下文管理 codex-rs/core/src/context_manager/
记忆系统 codex-rs/core/src/message_history.rs
TypeScript SDK sdk/typescript/src/

  • 作者【前端领秀】一个喜欢探索前端领域AI赋能的开发者,喜欢我的可以关注我,私信我邀请进入技术群,我会时刻分享最新前沿AI技术;
相关推荐
火星数据-Tina15 小时前
如何构建一个支持多终端同步的体育比分网站?
大数据·前端·数据库·websocket
IT_陈寒15 小时前
React 19 实战:5个新特性让你的开发效率提升50%!
前端·人工智能·后端
GuMoYu15 小时前
el-date-picker限制选择范围
前端·javascript·vue.js
冴羽16 小时前
JavaScript Date 语法要过时了!以后用这个替代!
前端·javascript·node.js
加油乐16 小时前
react使用Ant Design
前端·react.js·ant design
OEC小胖胖16 小时前
05|从 `SuspenseException` 到 `retryTimedOutBoundary`:Suspense 的 Ping 与 Retry 机制
前端·前端框架·react·开源库
攀登的牵牛花16 小时前
前端向架构突围系列 - 框架设计(三):用开闭原则拯救你的组件库
前端·架构
前端小L16 小时前
专题一:搭建测试驱动环境 (TypeScript + Vitest)
前端·javascript·typescript·源码·vue3