Codex 源码解析 · 第 3 讲
Codex 源码解析系列 第 3 讲:Protocol 协议层——SQ/EQ 双队列与权限模型 基于 OpenAI Codex 源码 · 2026-09-27 💡 本讲一句话: Codex 的客户端和 agent 之间没有直接函数调用,全靠 protocol crate 定义的两条队列通信——请求收敛成 29 种 Op、响应展开成 83 种 EventMsg;沙箱策略、审批决策这些"安全语义"也长在协议层里。读完这一讲,你就拿到了后面所有讲的"词汇表"。 一、protocol crate:客户端与 agent 之间的"合同层" 第 2 讲我们看了 CLI 怎么把命令分发出去。但真正让 TUI、app-server、CLI 这些不同前端都能驱动同一个 agent 的,是中间这层"合同"—— codex-protocol crate。它不执行任何逻辑,只回答一个问题: 客户端能对 agent 说什么?agent 能向客户端报什么? 这个 crate 的规模本身就说明问题:protocol.rs 单文件 6335 行、models.rs 4419 行、permissions.rs 4468 行,lib.rs 里挂了 50 多个模块。它同时是 Rust 类型定义、JSON wire format(serde)、TypeScript 代码生成源(ts-rs)和 JSON Schema(schemars)——一份定义,四端消费。 📄 codex-rs/protocol/src/protocol.rs (第 1-4 行) //! Defines the protocol for a Codex session between a client and an agent. // 定位:客户端与 agent 之间的会话协议,整个 crate 的总纲 //! Uses a SQ (Submission Queue) / EQ (Event Queue) pattern to asynchronously communicate // 核心模式:SQ/EQ 双队列——请求走提交队列、响应走事件队列,异步解耦 //! between user and agent. // 用户与 agent 之间不再直接函数调用,而是"发消息" 为什么这样设计: 把协议独立成 crate,意味着 TUI、app-server(RPC 网关)、CLI exec 模式可以各自实现传输层,但共享同一套语义。SQ/EQ 这个命名直接来自 OpenAI 内部对 agent 会话的抽象:Submission Queue 是"用户说的话",Event Queue 是"agent 做的事"——两个方向完全解耦,agent 可以在处理一条提交时连续吐出几百个事件。 二、请求方向:Submission 与 Op 枚举(29 种变体) 客户端的每一次动作都被包进一个 Submission 。注意它只有五个字段——协议层刻意保持"信封"极简,所有差异都塞进 op 载荷里: 📄 codex-rs/protocol/src/protocol.rs (第 190-205 行) /// Submission Queue Entry - requests from user // SQE:提交队列条目,方向是"用户 → agent" #\[derive(Debug)] // 派生 Debug:提交对象可直接打印进日志,排障时看得到完整载荷 pub struct Submission { // 信封结构体开始——刻意保持极简,差异全塞进 op 载荷里 /// Unique id for this Submission to correlate with Events // 唯一 ID(UUIDv7):后续事件靠它和这次请求对上号 pub id: String, // 字符串而非数字——跨进程传输不丢精度,日志里也直观 /// Payload // 操作载荷:Op 枚举的某个变体,"能做什么"全在这里表达 pub op: Op, // 不拆成多个字段——新增操作只需加变体,信封结构永远不变 /// Optional W3C trace carrier propagated across async submiss…
阅读全文:Codex 源码解析 第 3 讲