OpenAI Codex

Devin
Githubcodex

OpenAI Codex 完整架构分析与实现指南

OpenAI Codex 完整架构分析与实现指南

📋 目录

  1. 项目概述
  2. 核心架构设计
  3. 技术栈与实现
  4. Agent 设计模式
  5. 工具系统
  6. 安全沙箱机制
  7. 执行流程详解
  8. 配置系统
  9. MCP 集成
  10. 如何实现类似的 Agent
  11. 架构图

项目概述

什么是 Codex CLI?

OpenAI Codex CLI 是一个开源的终端编码代理,它能在本地运行,读取、修改和执行代码。它是 OpenAI 为开发者提供的 AI 编程助手,可以:

  • ✅ 自动编写和重构代码
  • ✅ 执行 shell 命令
  • ✅ 运行测试和调试
  • ✅ 生成 Pull Request
  • ✅ 代码审查和分析
  • ✅ 支持多模态输入(文本+图像)

核心特点

  1. 开源 - Apache 2.0 许可证
  2. 本地运行 - 代码不上传云端
  3. 用 Rust 重写 - 从 TypeScript/Node.js 迁移到 Rust,获得更高性能和安全性
  4. 沙箱隔离 - 多层安全机制保护系统
  5. MCP 支持 - 可作为 MCP 客户端或服务器

核心架构设计

整体架构

Codex CLI 采用分层架构,将用户界面、核心引擎和工具执行分离:

┌─────────────────────────────────────────────────────────┐
│                    用户界面层                              │
│  ┌──────────┐  ┌──────────┐  ┌─────────────────┐        │
│  │   TUI    │  │   Exec   │  │   MCP Server    │        │
│  │ (终端UI)  │  │ (无头模式) │  │  (协议服务器)    │        │
│  └──────────┘  └──────────┘  └─────────────────┘        │
└─────────────────────────────────────────────────────────┘
                        ↓
┌─────────────────────────────────────────────────────────┐
│                  提交/事件协议层                           │
│           Submission Queue / Event Queue                │
│         (异步双向通信,解耦请求和处理)                        │
└─────────────────────────────────────────────────────────┘
                        ↓
┌─────────────────────────────────────────────────────────┐
│                    核心引擎层                              │
│  ┌──────────────────────────────────────────────┐       │
│  │          codex-core (Rust Workspace)         │       │
│  │                                              │       │
│  │  • Session 管理(会话状态)                      │       │
│  │  • TurnContext(单轮上下文)                     │       │
│  │  • Agent Loop(主循环逻辑)                      │       │
│  │  • Model Integration(模型交互)                 │       │
│  │  • Tool Execution(工具执行)                    │       │
│  └──────────────────────────────────────────────┘       │
└─────────────────────────────────────────────────────────┘
                        ↓
┌─────────────────────────────────────────────────────────┐
│                    工具与服务层                            │
│  ┌────────────┐  ┌──────────┐  ┌──────────────┐        │
│  │  Sandbox   │  │   MCP    │  │  File Ops    │        │
│  │  (沙箱)     │  │ (协议)    │  │  (文件操作)   │        │
│  └────────────┘  └──────────┘  └──────────────┘        │
│                                                         │
│  ┌────────────┐  ┌──────────┐  ┌──────────────┐        │
│  │   Auth     │  │  Config  │  │  Responses   │        │
│  │  (认证)     │  │  (配置)   │  │  API         │        │
│  └────────────┘  └──────────┘  └──────────────┘        │
└─────────────────────────────────────────────────────────┘

Rust Workspace 结构

Codex CLI 使用 Cargo Workspace 组织多个 crate:

codex-rs/
├── cli/                 # CLI 入口和命令分发
├── core/                # 核心引擎(Session, Agent Loop)
├── tui/                 # 终端 UI (使用 Ratatui)
├── exec/                # 无头执行模式
├── mcp-server/          # MCP 服务器实现
├── protocol/            # 通信协议定义
├── login/               # 认证系统
├── sandbox/             # 沙箱抽象层
├── macos-seatbelt/      # macOS 沙箱实现
├── linux-sandbox/       # Linux Landlock + seccomp
├── responses-api-proxy/ # API 代理服务器
├── process-hardening/   # 进程加固
└── config/              # 配置管理

技术栈与实现

为什么从 TypeScript 迁移到 Rust?

OpenAI 团队列出了以下原因:

  1. 零依赖安装 - 不再需要 Node.js v22+
  2. 原生安全绑定 - Rust 可直接使用 OS 级沙箱 API
  3. 优化性能 - 无 GC,内存占用更低
  4. 可扩展协议 - 支持其他语言扩展(TypeScript, Python)

核心技术

组件技术选型
CLI 框架clap (命令行解析)
异步运行时tokio (异步 I/O)
终端 UIratatui (原 tui-rs)
HTTP 客户端reqwest
序列化serde + serde_json
配置管理toml
macOS 沙箱Apple Seatbelt (sandbox-exec)
Linux 沙箱Landlock + seccomp
MCP 实现自定义 stdio 协议

Agent 设计模式

核心理念
ReAct 模式

Codex 采用单线程 Agent Loop,避免多 Agent 并发的复杂性:

┌─────────────────────────────────────────────────────────┐
│                  Agent Loop (单循环)                       │
│                                                           │
│  1. 接收用户输入                                           │
│  2. 构建上下文(System Prompt + 历史 + 用户消息)              │
│  3. 调用 Responses API (流式响应)                          │
│  4. 处理模型输出:                                          │
│     ├─ reasoning (推理过程)                                │
│     ├─ message (文本消息)                                  │
│     └─ function_call (工具调用)                            │
│  5. 执行工具 → 获取结果 → 追加到历史                         │
│  6. 回到步骤 2,继续循环                                     │
│  7. 直到任务完成或用户中断                                  │
└─────────────────────────────────────────────────────────┘

System Prompt 设计

Codex 的 System Prompt 非常关键,它定义了 Agent 的"操作系统":

You are Codex, based on GPT-5. You are running as a coding agent
in the Codex CLI on a user's computer.

## General

- The arguments to `shell` will be passed to execvp()
- Most terminal commands should be prefixed with ["bash", "-lc"]
- Always set the `workdir` param when using the shell function
- When searching, prefer `rg` over `grep` (faster)

## Tools

1. **shell** - Execute shell commands
2. **apply_patch** - Apply unified diffs to files

## Coding Guidelines

- Minimal, surgical diffs (avoid full file rewrites)
- Run tests to verify changes
- Use project's existing patterns
- Check linter/formatter output

## Workflow

1. Read files to understand context (cat, rg, find)
2. Make minimal changes (apply_patch)
3. Verify changes (run tests, linters)
4. Iterate until success

关键点:

  • ✅ 简洁明了 - GPT-5-Codex 提示词比 GPT-5 少 60% token
  • ✅ 工具优先 - 教会模型"shell-first"思维
  • ✅ 安全默认 - 明确沙箱和网络限制
  • ✅ 验证驱动 - 强调测试和验证

工具系统

主要工具

Codex 暴露给模型的工具非常简洁:

1. shell 工具

// 工具定义
{
  "name": "shell",
  "description": "Execute shell command in sandbox",
  "parameters": {
    "cmd": ["string"],      // 命令数组
    "workdir": "string",    // 工作目录
    "env": {"key": "value"} // 环境变量(可选)
  }
}

执行流程:

  1. 模型生成 function_call: {"name": "shell", "arguments": {"cmd": ["ls", "-la"]}}
  2. CLI 拦截调用 → 检查审批策略
  3. 根据策略决定是否需要用户确认
  4. 在沙箱中执行命令
  5. 返回 stdout/stderr 给模型

2. apply_patch 工具

// 特殊格式的补丁
*** Begin Patch
*** Update File: src/main.rs
@@
-fn main() {
-    println!("Hello");
+fn main() {
+    println!("Hello, World!");
}
*** End Patch

处理逻辑:

  1. 解析补丁格式
  2. 生成彩色 diff 展示给用户
  3. 根据审批策略决定是否应用
  4. 使用 fs 操作直接修改文件

审批策略

Codex 提供 3 种审批模式:

模式读文件写文件执行命令用例
Suggest (建议模式)✅ 自动❌ 需确认❌ 需确认最安全,适合学习
Auto-Edit (自动编辑)✅ 自动✅ 自动❌ 需确认快速重构
Full-Auto (全自动)✅ 自动✅ 自动✅ 自动CI/CD 管道

工具分类逻辑

fn can_auto_approve(cmd: &[String], policy: ApprovalMode) -> bool {
    match policy {
        ApprovalMode::Suggest => {
            // 只允许读操作
            is_read_only_command(cmd)
        }
        ApprovalMode::AutoEdit => {
            // 允许读操作 + 文件写入
            is_read_only_command(cmd) || is_file_write(cmd)
        }
        ApprovalMode::FullAuto => {
            // 允许所有操作(在沙箱内)
            true
        }
    }
}

fn is_read_only_command(cmd: &[String]) -> bool {
    matches!(cmd[0].as_str(), "cat" | "ls" | "head" | "tail" | "rg" | "find")
}

安全沙箱机制

多层防护

Codex 实现了纵深防御:

┌──────────────────────────────────────────────────┐
│ Layer 1: 审批策略 (Application-Level Controls)    │
│  • 命令分类(读/写/执行)                            │
│  • 用户确认流程                                   │
│  • 命令黑名单                                     │
└──────────────────────────────────────────────────┘
                    ↓
┌──────────────────────────────────────────────────┐
│ Layer 2: OS 级沙箱 (OS-Level Sandboxing)         │
│  macOS:    Apple Seatbelt (sandbox-exec)        │
│  Linux:    Landlock + seccomp-bpf               │
└──────────────────────────────────────────────────┘
                    ↓
┌──────────────────────────────────────────────────┐
│ Layer 3: 网络隔离 (Network Isolation)             │
│  • 默认禁用网络                                   │
│  • 白名单:仅允许 OpenAI API                       │
│  • iptables/ipset 防火墙规则                      │
└──────────────────────────────────────────────────┘
                    ↓
┌──────────────────────────────────────────────────┐
│ Layer 4: 文件系统限制 (Filesystem Restrictions)   │
│  • 只读:系统目录                                  │
│  • 读写:$PWD (项目目录)                           │
│  • 读写:$TMPDIR (临时目录)                        │
└──────────────────────────────────────────────────┘

macOS 实现

// 使用 Apple Seatbelt
fn create_sandbox_profile() -> String {
    r#"
    (version 1)
    (deny default)
    (allow file-read*)
    (allow file-write*
        (subpath (param "PWD"))
        (subpath (param "TMPDIR")))
    (deny network*)
    (allow network-outbound
        (remote ip "api.openai.com:443"))
    "#
}

fn run_in_sandbox(cmd: &[String]) -> Result<Output> {
    Command::new("sandbox-exec")
        .arg("-p")
        .arg(create_sandbox_profile())
        .args(cmd)
        .output()
}

Linux 实现

// 使用 Landlock (Linux 5.13+)
use landlock::*;

fn create_landlock_ruleset() -> Result<Ruleset> {
    Ruleset::default()
        .handle_access(AccessFs::from_all(ABI::V2))?
        .add_rule(PathBeneath::new(&pwd, AccessFs::from_all(ABI::V2)))?
        .add_rule(PathBeneath::new("/tmp", AccessFs::from_all(ABI::V2)))?
        .restrict_self()?
}

// seccomp-bpf 限制系统调用
fn apply_seccomp_filter() {
    let filter = SeccompFilter::new()
        .allow_syscall("read")
        .allow_syscall("write")
        // ... 白名单其他必要系统调用
        .deny_default();
    filter.load().unwrap();
}

执行流程详解

完整的用户请求流程

让我们跟踪一个完整的请求:codex "Add error handling to main.rs"

┌─────────────────────────────────────────────────────────┐
│ Step 1: CLI 入口                                         │
│  • 解析命令行参数                                         │
│  • 加载配置文件 (~/.codex/config.toml)                   │
│  • 检查认证状态                                          │
│  • 初始化 TUI 或 Exec 模式                               │
└─────────────────────────────────────────────────────────┘
                        ↓
┌─────────────────────────────────────────────────────────┐
│ Step 2: 上下文构建                                        │
│  • 读取项目文档 (AGENTS.md, codex.md)                    │
│  • 读取全局指令 (~/.codex/instructions.md)               │
│  • 检查 Git 状态                                         │
│  • 组装 System Prompt                                    │
└─────────────────────────────────────────────────────────┘
                        ↓
┌─────────────────────────────────────────────────────────┐
│ Step 3: 提交到核心引擎                                    │
│  • 创建 Submission: Op::StartTurn { prompt, ... }       │
│  • 发送到 Submission Queue                               │
│  • 核心引擎接收并处理                                     │
└─────────────────────────────────────────────────────────┘
                        ↓
┌─────────────────────────────────────────────────────────┐
│ Step 4: Agent Loop 执行                                  │
│  ┌─────────────────────────────────────────────┐        │
│  │ 4.1 调用 Responses API                       │        │
│  │  POST /v1/responses                         │        │
│  │  {                                          │        │
│  │    "model": "gpt-5-codex",                  │        │
│  │    "messages": [...],                       │        │
│  │    "tools": [{"name": "shell"}, ...],       │        │
│  │    "stream": true                           │        │
│  │  }                                          │        │
│  └─────────────────────────────────────────────┘        │
│                        ↓                                 │
│  ┌─────────────────────────────────────────────┐        │
│  │ 4.2 处理流式响应                              │        │
│  │  • response.reasoning (内部推理)             │        │
│  │  • response.message (文本输出)               │        │
│  │  • response.function_call (工具调用)         │        │
│  └─────────────────────────────────────────────┘        │
│                        ↓                                 │
│  ┌─────────────────────────────────────────────┐        │
│  │ 4.3 执行工具调用                              │        │
│  │  假设模型输出:                                │        │
│  │  {                                          │        │
│  │    "name": "shell",                         │        │
│  │    "arguments": {                           │        │
│  │      "cmd": ["cat", "src/main.rs"]          │        │
│  │    }                                        │        │
│  │  }                                          │        │
│  │                                             │        │
│  │  → 检查审批策略                              │        │
│  │  → 在沙箱中执行 cat src/main.rs              │        │
│  │  → 返回文件内容给模型                         │        │
│  └─────────────────────────────────────────────┘        │
│                        ↓                                 │
│  ┌─────────────────────────────────────────────┐        │
│  │ 4.4 模型生成补丁                              │        │
│  │  {                                          │        │
│  │    "name": "shell",                         │        │
│  │    "arguments": {                           │        │
│  │      "cmd": ["apply_patch", "*** ..."]      │        │
│  │    }                                        │        │
│  │  }                                          │        │
│  │                                             │        │
│  │  → 解析补丁                                  │        │
│  │  → 显示彩色 diff                             │        │
│  │  → 请求用户确认(如果不是 Full-Auto)           │        │
│  │  → 应用补丁到文件                             │        │
│  └─────────────────────────────────────────────┘        │
│                        ↓                                 │
│  ┌─────────────────────────────────────────────┐        │
│  │ 4.5 验证更改                                  │        │
│  │  模型可能执行:                                │        │
│  │  • cargo check (语法检查)                    │        │
│  │  • cargo test (运行测试)                     │        │
│  │  • git diff (查看更改)                       │        │
│  └─────────────────────────────────────────────┘        │
│                        ↓                                 │
│  ┌─────────────────────────────────────────────┐        │
│  │ 4.6 完成或继续迭代                            │        │
│  │  • 如果测试通过 → 输出完成消息                 │        │
│  │  • 如果测试失败 → 继续循环修复                 │        │
│  └─────────────────────────────────────────────┘        │
└─────────────────────────────────────────────────────────┘
                        ↓
┌─────────────────────────────────────────────────────────┐
│ Step 5: 事件返回                                         │
│  • 通过 Event Queue 发送事件给 UI                         │
│  • EventMsg::Reasoning - 显示推理过程                    │
│  • EventMsg::Message - 显示文本输出                      │
│  • EventMsg::ToolCall - 显示工具调用和结果                │
│  • EventMsg::TurnComplete - 任务完成                     │
└─────────────────────────────────────────────────────────┘

Submission/Event 协议

Codex 使用自定义的异步协议解耦请求和响应:

// 提交类型
enum Op {
    StartTurn {
        prompt: String,
        images: Vec<PathBuf>,
        context: TurnContext,
    },
    Cancel {
        submission_id: u64,
    },
    // ...
}

// 事件类型
enum EventMsg {
    Reasoning {
        text: String,
    },
    Message {
        content: String,
    },
    ToolCall {
        tool: String,
        args: serde_json::Value,
    },
    ToolResult {
        output: String,
    },
    TurnComplete,
    Error {
        message: String,
    },
}

// 核心循环
async fn submission_loop(
    mut rx: mpsc::Receiver<Op>,
    tx: mpsc::UnboundedSender<EventMsg>,
) {
    while let Some(op) = rx.recv().await {
        match op {
            Op::StartTurn { prompt, context, .. } => {
                // 调用 Agent Loop
                execute_turn(&prompt, &context, &tx).await;
            }
            Op::Cancel { .. } => {
                // 取消执行
                break;
            }
        }
    }
}

配置系统

五层优先级

Codex 的配置系统支持 5 个优先级层:

1. 命令行参数 (最高优先级)
   codex -c model=gpt-5-codex -c approval_mode=full-auto

2. 环境变量
   export CODEX_MODEL=gpt-5-codex

3. 项目配置 (.codex/config.toml)
   [default]
   model = "gpt-5-codex"
   approval_mode = "auto-edit"

4. 用户全局配置 (~/.codex/config.toml)
   [default]
   model = "gpt-5"

5. 内置默认值 (最低优先级)

配置文件示例

# ~/.codex/config.toml

[default]
model = "gpt-5-codex"
model_provider = "openai"
approval_mode = "auto-edit"
sandbox = "workspace-write"
max_turns = 50

[profiles.strict]
approval_mode = "suggest"
sandbox = "read-only"

[profiles.ci]
approval_mode = "full-auto"
quiet = true

[mcp_servers.filesystem]
command = "mcp-server-filesystem"
args = ["--allowed-dirs", "/home/user/projects"]

[mcp_servers.github]
command = "mcp-server-github"
env = { GITHUB_TOKEN = "ghp_xxx" }

MCP 集成

什么是 MCP?

Model Context Protocol (MCP) 是 OpenAI 定义的标准协议,用于 AI Agent 之间的通信。

Codex 的双重角色

1. 作为 MCP 客户端

Codex 可以连接到其他 MCP 服务器,扩展其能力:

# 配置 MCP 服务器
codex mcp add filesystem --command mcp-server-filesystem
codex mcp add github --command mcp-server-github

流程:

Codex CLI  →  [MCP Protocol]  →  MCP Server (filesystem)
                                   ↓
                              读取文件/目录

2. 作为 MCP 服务器

其他 Agent 可以调用 Codex:

# 启动 MCP 服务器模式
codex mcp

# 或者通过 npx
npx codex mcp

在 Agents SDK 中使用:

from agents import Agent
from agents.mcp import MCPServerStdio

async with MCPServerStdio(
    name="Codex CLI",
    params={
        "command": "npx",
        "args": ["-y", "codex", "mcp"]
    },
    client_session_timeout_seconds=360000
) as codex_mcp_server:

    agent = Agent(
        name="Developer",
        instructions="You are a coding assistant",
        mcp_servers=[codex_mcp_server]
    )

    # Agent 现在可以调用 Codex 的能力
    result = await agent.run("Refactor this code")

MCP 工具定义

Codex 暴露的 MCP 工具:

{
  "tools": [
    {
      "name": "codex_execute",
      "description": "Execute a coding task in Codex CLI",
      "inputSchema": {
        "type": "object",
        "properties": {
          "prompt": {
            "type": "string",
            "description": "Task description"
          },
          "approval-policy": {
            "type": "string",
            "enum": ["suggest", "auto-edit", "full-auto", "never"]
          },
          "sandbox": {
            "type": "string",
            "enum": ["read-only", "workspace-write", "danger-full-access"]
          }
        },
        "required": ["prompt"]
      }
    }
  ]
}

如何实现类似的 Agent

第一步

组件推荐选项
语言Rust (性能) 或 Python (快速开发)
异步运行时Rust: tokio / Python: asyncio
CLI 框架Rust: clap / Python: click
终端 UIRust: ratatui / Python: rich + textual
LLM SDKOpenAI SDK / Anthropic SDK

第二步

# Python 示例
import openai
import asyncio
from typing import List, Dict

class CodingAgent:
    def __init__(self, model="gpt-4"):
        self.model = model
        self.history: List[Dict] = []
        self.system_prompt = """
        You are a coding assistant. You can:
        1. Execute shell commands using the 'shell' tool
        2. Apply patches to files using the 'apply_patch' tool

        Always verify your changes by running tests.
        """

    async def run(self, user_prompt: str):
        # 添加用户消息
        self.history.append({
            "role": "user",
            "content": user_prompt
        })

        # 主循环
        while True:
            # 调用 LLM
            response = await openai.chat.completions.create(
                model=self.model,
                messages=[
                    {"role": "system", "content": self.system_prompt},
                    *self.history
                ],
                tools=[
                    {
                        "type": "function",
                        "function": {
                            "name": "shell",
                            "description": "Execute shell command",
                            "parameters": {
                                "type": "object",
                                "properties": {
                                    "cmd": {
                                        "type": "array",
                                        "items": {"type": "string"}
                                    }
                                },
                                "required": ["cmd"]
                            }
                        }
                    },
                    # ... 其他工具
                ]
            )

            message = response.choices[0].message

            # 处理工具调用
            if message.tool_calls:
                for tool_call in message.tool_calls:
                    result = await self.execute_tool(tool_call)

                    # 添加工具结果到历史
                    self.history.append({
                        "role": "tool",
                        "tool_call_id": tool_call.id,
                        "content": result
                    })

                # 继续循环
                continue
            else:
                # 没有工具调用,任务完成
                print(message.content)
                break

    async def execute_tool(self, tool_call):
        tool_name = tool_call.function.name
        args = json.loads(tool_call.function.arguments)

        if tool_name == "shell":
            return await self.run_shell(args["cmd"])
        elif tool_name == "apply_patch":
            return await self.apply_patch(args["patch"])

    async def run_shell(self, cmd: List[str]):
        # 实现沙箱执行
        import subprocess
        result = subprocess.run(
            cmd,
            capture_output=True,
            text=True,
            timeout=30
        )
        return f"stdout: {result.stdout}\nstderr: {result.stderr}"

第三步

# 简单的 Linux 沙箱示例
import subprocess
import tempfile
import os

class Sandbox:
    def __init__(self, work_dir: str):
        self.work_dir = work_dir

    def run_command(self, cmd: List[str]) -> str:
        # 使用 firejail 作为简单沙箱
        sandbox_cmd = [
            "firejail",
            "--quiet",
            "--private=" + self.work_dir,
            "--net=none",  # 禁用网络
            "--",
            *cmd
        ]

        result = subprocess.run(
            sandbox_cmd,
            capture_output=True,
            text=True,
            timeout=30
        )

        return result.stdout + result.stderr

第四步

class ApprovalPolicy:
    SUGGEST = "suggest"
    AUTO_EDIT = "auto_edit"
    FULL_AUTO = "full_auto"

    def __init__(self, mode: str):
        self.mode = mode

    def should_approve(self, tool: str, args: dict) -> bool:
        if self.mode == self.FULL_AUTO:
            return True

        if self.mode == self.AUTO_EDIT:
            # 自动批准读操作和写文件
            if tool == "shell":
                cmd = args["cmd"][0]
                return cmd in ["cat", "ls", "find", "grep"]
            elif tool == "apply_patch":
                return True

        # Suggest 模式:都需要确认
        return False

    def request_approval(self, tool: str, args: dict) -> bool:
        print(f"\n🔔 Approval needed:")
        print(f"Tool: {tool}")
        print(f"Args: {args}")

        response = input("Approve? (y/n): ")
        return response.lower() == 'y'

第五步
MCP

from mcp import Server, Tool

class CodexMCPServer:
    def __init__(self):
        self.server = Server()
        self.agent = CodingAgent()

        @self.server.tool()
        async def codex_execute(
            prompt: str,
            approval_policy: str = "suggest"
        ) -> str:
            """Execute a coding task"""
            self.agent.approval_mode = approval_policy
            result = await self.agent.run(prompt)
            return result

    async def run(self):
        await self.server.run(transport="stdio")

# 启动 MCP 服务器
if __name__ == "__main__":
    server = CodexMCPServer()
    asyncio.run(server.run())

完整的最小实现框架

my-coding-agent/
├── src/
│   ├── main.py              # CLI 入口
│   ├── agent.py             # Agent Loop
│   ├── tools.py             # 工具实现
│   ├── sandbox.py           # 沙箱封装
│   ├── approval.py          # 审批系统
│   ├── config.py            # 配置管理
│   └── mcp_server.py        # MCP 服务器
├── prompts/
│   └── system_prompt.txt    # System Prompt
├── config.toml              # 默认配置
├── requirements.txt
└── README.md

关键实现要点

  1. System Prompt 设计

    • 简洁明了,定义 Agent 的"操作系统"
    • 明确工具使用规范
    • 包含安全约束和验证要求
  2. 工具系统

    • 保持工具数量少(5 个)
    • 使用 shell 作为通用工具
    • 实现专门的文件编辑工具(diff-based)
  3. 安全机制

    • 多层防护
      + 沙箱 + 网络隔离
    • 默认拒绝,白名单允许
    • 用户可控的安全级别
  4. 用户体验

    • 流式输出,实时反馈
    • 彩色 diff 显示
    • 清晰的审批界面
  5. 可扩展性

    • 支持 MCP 协议
    • 插件化工具系统
    • 配置驱动的行为

架构图

系统架构图

┌────────────────────────────────────────────────────────────────┐
│                         用户层                                   │
│                                                                 │
│    ┌──────────┐      ┌──────────┐      ┌──────────────┐       │
│    │  开发者   │      │   CI/CD  │      │  其他 Agent  │       │
│    └────┬─────┘      └────┬─────┘      └──────┬───────┘       │
│         │                 │                    │                │
│         ↓                 ↓                    ↓                │
└────────────────────────────────────────────────────────────────┘
         │                 │                    │
         ↓                 ↓                    ↓
┌────────────────────────────────────────────────────────────────┐
│                      接口层                                      │
│                                                                 │
│    ┌──────────┐      ┌──────────┐      ┌──────────────┐       │
│    │   TUI    │      │   Exec   │      │  MCP Server  │       │
│    │(终端界面) │      │(无头模式) │      │ (stdio协议)   │       │
│    └────┬─────┘      └────┬─────┘      └──────┬───────┘       │
│         │                 │                    │                │
│         └─────────────────┼────────────────────┘                │
│                           ↓                                     │
└────────────────────────────────────────────────────────────────┘
                            │
                            ↓
┌────────────────────────────────────────────────────────────────┐
│                  异步通信层 (SQ/EQ)                              │
│                                                                 │
│    ┌───────────────────────────────────────────────────┐       │
│    │  Submission Queue  ←→  Event Queue                │       │
│    │  (提交队列)             (事件队列)                  │       │
│    └───────────────────────────────────────────────────┘       │
└────────────────────────────────────────────────────────────────┘
                            │
                            ↓
┌────────────────────────────────────────────────────────────────┐
│                      核心引擎 (codex-core)                       │
│                                                                 │
│    ┌─────────────────────────────────────────────────┐         │
│    │            Agent Loop (主循环)                   │         │
│    │                                                 │         │
│    │  while not done:                                │         │
│    │    1. 调用 Responses API                         │         │
│    │    2. 处理 reasoning/message/function_call      │         │
│    │    3. 执行工具                                   │         │
│    │    4. 追加结果到历史                             │         │
│    │    5. 检查完成条件                               │         │
│    └─────────────────────────────────────────────────┘         │
│                           │                                     │
│    ┌──────────────────────┴─────────────────────────┐          │
│    │                                                │          │
│    ↓                                                ↓          │
│  ┌─────────────┐                          ┌─────────────┐     │
│  │  Session    │                          │ TurnContext │     │
│  │  (会话管理)  │                          │  (单轮上下文) │     │
│  └─────────────┘                          └─────────────┘     │
└────────────────────────────────────────────────────────────────┘
                            │
                            ↓
┌────────────────────────────────────────────────────────────────┐
│                       工具执行层                                 │
│                                                                 │
│    ┌──────────┐    ┌──────────┐    ┌──────────────┐           │
│    │  Shell   │    │  Patch   │    │   MCP 客户端  │           │
│    │  执行器   │    │  应用器   │    │   (外部工具)  │           │
│    └────┬─────┘    └────┬─────┘    └──────┬───────┘           │
│         │               │                  │                   │
│         └───────────────┼──────────────────┘                   │
│                         ↓                                       │
└────────────────────────────────────────────────────────────────┘
                         │
                         ↓
┌────────────────────────────────────────────────────────────────┐
│                      安全沙箱层                                  │
│                                                                 │
│    ┌─────────────────────────────────────────────┐             │
│    │            审批策略检查                       │             │
│    │  • Suggest: 所有写操作需确认                 │             │
│    │  • Auto-Edit: 自动应用文件更改                │             │
│    │  • Full-Auto: 完全自动化                     │             │
│    └─────────────────────────────────────────────┘             │
│                         ↓                                       │
│    ┌─────────────────────────────────────────────┐             │
│    │          OS 级沙箱 (Seatbelt/Landlock)       │             │
│    │  • 文件系统限制: 仅 $PWD + $TMPDIR 可写      │             │
│    │  • 网络隔离: 仅允许 api.openai.com          │             │
│    │  • 系统调用过滤 (Linux seccomp)              │             │
│    └─────────────────────────────────────────────┘             │
└────────────────────────────────────────────────────────────────┘
                         │
                         ↓
┌────────────────────────────────────────────────────────────────┐
│                     外部服务层                                   │
│                                                                 │
│    ┌──────────────┐    ┌──────────────┐    ┌──────────┐       │
│    │ OpenAI API   │    │   文件系统    │    │   Git    │       │
│    │ (Responses)  │    │   (读/写)     │    │  (版本控制)│       │
│    └──────────────┘    └──────────────┘    └──────────┘       │
└────────────────────────────────────────────────────────────────┘

Agent Loop 流程图

        ┌──────────────────────┐
        │    用户输入提示       │
        │  "Add error handling" │
        └──────────┬───────────┘
                   ↓
        ┌──────────────────────┐
        │   构建上下文          │
        │ • System Prompt      │
        │ • 历史消息           │
        │ • 项目文档(AGENTS.md) │
        └──────────┬───────────┘
                   ↓
        ┌──────────────────────┐
        │  调用 Responses API   │
        │  (流式响应)           │
        └──────────┬───────────┘
                   ↓
        ┌──────────────────────┐
        │  解析响应类型         │
        └──────────┬───────────┘
                   ↓
         ┌─────────┴─────────┐
         ↓                   ↓
┌────────────────┐    ┌──────────────┐
│   Reasoning    │    │   Message    │
│   (推理过程)    │    │  (文本输出)   │
└────────────────┘    └──────────────┘
         ↓                   ↓
    (显示推理)           (显示消息)
         ↓                   ↓
         └─────────┬─────────┘
                   ↓
        ┌──────────────────────┐
        │   Function Call?     │
        │   (工具调用)          │
        └──────────┬───────────┘
                   ↓
              ┌────┴────┐
              │  是否?   │
              └────┬────┘
                   ↓
            ┌──────┴──────┐
            ↓             ↓
          【是】         【否】
            ↓             ↓
┌──────────────────┐  ┌──────────────┐
│   解析工具调用    │  │  任务完成     │
│ • shell          │  │  输出结果     │
│ • apply_patch    │  └──────────────┘
└─────────┬────────┘
          ↓
┌──────────────────┐
│  检查审批策略     │
│ • 需要确认?      │
│ • 自动批准?      │
└─────────┬────────┘
          ↓
    ┌─────┴─────┐
    ↓           ↓
【需确认】   【自动批准】
    ↓           ↓
┌─────────┐   │
│ 显示 UI │   │
│ 等待确认│   │
└────┬────┘   │
     ↓        ↓
  ┌──┴────────┴──┐
  │  在沙箱中执行  │
  │  获取输出     │
  └──────┬────────┘
         ↓
  ┌──────────────┐
  │  追加到历史   │
  │ • Tool Call  │
  │ • Tool Result│
  └──────┬───────┘
         ↓
  ┌──────────────┐
  │  继续循环     │
  │  (回到 API)  │
  └──────────────┘
         ↓
    (返回顶部)

工具执行流程

┌─────────────────────────────────────────────────┐
│          模型生成工具调用                         │
│  {                                              │
│    "name": "shell",                            │
│    "arguments": {"cmd": ["cat", "main.rs"]}    │
│  }                                              │
└────────────────────┬────────────────────────────┘
                     ↓
┌─────────────────────────────────────────────────┐
│            工具分发器 (Tool Dispatcher)          │
│  • 识别工具类型                                  │
│  • 解析参数                                      │
└────────────────────┬────────────────────────────┘
                     ↓
              ┌──────┴──────┐
              │   工具类型?  │
              └──────┬──────┘
                     ↓
        ┌────────────┴────────────┐
        ↓                         ↓
  ┌──────────┐            ┌──────────────┐
  │  shell   │            │ apply_patch  │
  └────┬─────┘            └──────┬───────┘
       ↓                         ↓
┌──────────────┐          ┌──────────────┐
│ 分类命令类型  │          │  解析补丁     │
│ • 读操作     │          │  格式         │
│ • 写操作     │          └──────┬───────┘
│ • 危险操作   │                 ↓
└──────┬───────┘          ┌──────────────┐
       ↓                  │  生成 diff   │
┌──────────────┐          │  预览        │
│ 审批策略检查  │          └──────┬───────┘
│              │                 ↓
│ Suggest:     │          ┌──────────────┐
│  所有需确认   │          │  审批检查     │
│              │          └──────┬───────┘
│ Auto-Edit:   │                 ↓
│  读自动批准   │          ┌──────┴───────┐
│  写需确认     │          ↓              ↓
│              │      【需确认】      【自动】
│ Full-Auto:   │          ↓              ↓
│  全自动      │    ┌──────────┐        │
└──────┬───────┘    │ 显示 UI  │        │
       ↓            │ 等待输入 │        │
   ┌───┴───┐        └────┬─────┘        │
   ↓       ↓             ↓              ↓
【需确认】【自动】      ┌─────────────────┴──┐
   ↓       ↓          │   应用文件更改      │
   │       │          │   (fs 操作)        │
   │       │          └─────────┬──────────┘
   ↓       ↓                    ↓
┌──┴───────┴──┐          ┌──────────────┐
│ 显示确认 UI  │          │  返回结果     │
│ • 命令内容   │          │  给模型       │
│ • 风险评估   │          └──────────────┘
└──────┬──────┘
       ↓
  ┌────┴────┐
  │ 用户决定 │
  └────┬────┘
       ↓
   ┌───┴───┐
   ↓       ↓
【批准】  【拒绝】
   ↓       ↓
   │    ┌──────┐
   │    │返回错误│
   │    └──────┘
   ↓
┌──────────────────┐
│  在沙箱中执行     │
│                 │
│ macOS:          │
│  sandbox-exec   │
│                 │
│ Linux:          │
│  Landlock       │
│  + seccomp      │
└────────┬─────────┘
         ↓
┌──────────────────┐
│  捕获输出         │
│ • stdout        │
│ • stderr        │
│ • exit code     │
└────────┬─────────┘
         ↓
┌──────────────────┐
│  格式化结果       │
│  返回给 Agent    │
└──────────────────┘

总结

Codex 的核心设计原则

  1. 简洁性 - 少即是多

    • 最小化工具数量
    • 简化 System Prompt
    • Shell-first 设计哲学
  2. 安全性 - 纵深防御

    • 应用级审批策略
    • OS 级沙箱隔离
    • 网络访问控制
    • 文件系统限制
  3. 可观测性 - 透明执行

    • 流式输出推理过程
    • 彩色 diff 预览
    • 详细的工具调用日志
  4. 可扩展性 - 模块化设计

    • MCP 协议支持
    • 配置驱动行为
    • 插件化工具系统

实现建议

如果你想构建类似的 Coding Agent,关键步骤是:

  1. 从最小 MVP 开始

    • 实现基本的 Agent Loop
    • 支持 1-2 个核心工具
    • 添加简单的沙箱
  2. 迭代改进

    • 优化 System Prompt
    • 增强安全机制
    • 改善用户体验
  3. 集成生态

    • 支持 MCP 协议
    • 连接 IDE/CI/CD
    • 构建工具库
  4. 持续学习

    • 研究开源项目(Codex CLI, Claude Code)
    • 参考最佳实践
    • 收集用户反馈

参考资源


附录

A. Responses API 详解

Codex 使用 OpenAI 的 Responses API(而非标准的 Chat Completions API):

# Responses API 请求
POST /v1/responses
{
  "model": "gpt-5-codex",
  "messages": [...],
  "tools": [...],
  "stream": true,
  "previous_response_id": "resp_abc123"  # 用于续传
}

# 流式响应事件
event: response.output_item.done
data: {
  "type": "reasoning",
  "content": "I need to read the file first..."
}

event: response.output_item.done
data: {
  "type": "function_call",
  "name": "shell",
  "arguments": "{\"cmd\": [\"cat\", \"main.rs\"]}"
}

B. Rust Crate 依赖关系

codex-rs/cli
├── codex-rs/core
│   ├── codex-rs/protocol
│   ├── codex-rs/login
│   ├── codex-rs/config
│   └── codex-rs/sandbox
│       ├── codex-rs/macos-seatbelt
│       └── codex-rs/linux-sandbox
├── codex-rs/tui
└── codex-rs/exec

C. 性能优化点

  1. 静态链接 - 无运行时依赖
  2. 零拷贝 - 使用 bytes crate
  3. 异步 I/O - tokio 运行时
  4. 流式处理 - 增量解析 JSON
  5. 缓存策略 - 缓存模型列表和配置

文档版本: 1.0
最后更新: 2025-11-12
作者: Claude (基于 OpenAI Codex 公开资料整理)