Codex 架构全景:本地运行、云端长任务与多层 Loop
Codex 的架构需要同时回答两个问题:一次编码请求怎样完成,以及请求结束以后,什么状态还能保留、谁会再次启动工作。前一个问题涉及模型、工具和 Harness;后一个问题涉及会话、目标、执行环境、调度和身份。
“Codex 在本地运行”通常表示工作区和工具在本机,模型推理仍可以发生在 OpenAI 的服务器。“Desktop 连 Remote”通常表示客户端通过 SSH 控制远端 App Server;“Cloud 长期运行”则包含托管执行环境及其生命周期。这些模式可以共享执行框架,却承担着不同的运行责任。
本文以 2026 年 10 月 15 日读取的官方产品文档和 Codex rust-v0.162.1 源码为基线。源码固定在 092d3acd6bec3e3a14bdc7e7a2810ab628ab759d,提交日期为 2026 年 10 月 9 日;本地 codex --version 为 codex-cli 0.162.1。文中的拓扑是根据公开接口整理的解释模型,涉及托管 Cloud 的部分只描述公开契约。云端内部队列、数据库拓扑、VM checkpoint 算法和模型权重结构,没有足够公开证据可以展开。
Codex 这个名字覆盖了哪些东西
Codex 既指产品,也出现在模型名称、命令行工具、SDK 和执行框架的讨论中。架构分析需要先确定对象。
| 对象 | 实际职责 | 不能由名字直接推导的性质 |
|---|---|---|
| 模型与推理服务 | 根据上下文生成文本、工具调用等响应 | 工具一定在模型服务器执行、本机一定运行模型权重 |
| Harness / Core | 管理上下文、模型工具循环、权限、取消、记录和恢复 | 自带完整云调度与永久在线服务 |
| App Server | 向客户端提供认证、thread、turn、事件和审批接口 | 必须独立进程、等同 MCP、只是模型 API 代理 |
| 客户端与 SDK | 提供交互入口,或以程序控制运行时 | 各入口使用完全相同的工具、权限和产品功能 |
| 执行与产品平台 | 提供工作目录、进程、网络、身份和任务生命周期 | 所有产品共用一种 VM、状态或调度策略 |
CLI、核心 Harness、App Server 及部分 SDK 可以检查公开实现;桌面和 IDE 产品的完整实现、托管 Cloud 控制面并不能通过 CLI 仓库全部还原。官方还单独列出了 codex-universal 等开源项目。开源范围是组件范围,不能扩展成整个产品栈都已开源。开源组件说明
站内的《OpenAI Codex Harness 源码解剖》解释过 CLI 与 Harness 的关系。这里使用较新的源码快照:当前核心包装类型是 CodexThread,内部持有 Session 和 SessionIo,由 ThreadManager 管理。旧版本的类型名和调用路径不能直接当成当前实现。
先确定四个位置
理解一种运行模式,先定位控制、推理、执行和状态。
| 位置 | 要问的问题 | 典型内容 |
|---|---|---|
| 控制 | 谁接受请求、安排工作、决定继续或等待? | Desktop、App Server、goal 扩展、云端调度 |
| 推理 | 谁处理模型请求? | OpenAI 推理服务、显式配置的本地模型服务 |
| 执行 | 谁真正读取文件、运行命令、访问服务? | 本机、SSH 主机、云任务 VM、MCP 服务 |
| 状态 | 历史、文件、目标和凭据分别存在哪里? | 本地会话文件与 SQLite、远端目录、云任务状态、身份服务 |
这四个位置可以重合,也可以分离。Desktop 的窗口在本机,不代表命令在本机;工具在本机,不代表模型在本机;UI 经过云端 relay,也不代表工作区已经进入托管 Cloud。运行环境、远程连接
图中箭头表示职责之间的调用或数据关系,不表示每个框都部署为独立服务。尤其是 App Server,可以在客户端进程内运行。
从命令启动到 Core:本地到底运行了什么
一个 Rust 发行物承载多个入口
codex 的顶层命令分发到交互 TUI、非交互 exec、独立 app-server、Cloud 客户端等入口。它们承担不同的输入输出方式,不应按命令名字推断执行地点。例如,codex cloud 是操作云任务的客户端入口,不能据此认为当前终端开始托管云任务。CLI 命令分发源码
在这个源码版本中,TUI 的 AppServerTarget 有 Embedded、LocalDaemon、Remote 三种目标。Embedded 启动进程内 App Server;LocalDaemon 尝试连接本地 daemon,部分失败路径允许回退 Embedded;Remote 连接已有远端服务。因此,“CLI 直接调用 Core”和“CLI 总是另起 App Server 子进程”,都不足以概括当前启动路径。目标类型、连接分支
非交互 codex exec 也调用 InProcessAppServerClient::start。进程内客户端使用带类型的请求和事件通道,启动 App Server 后台 Tokio worker。外部 STDIO / WebSocket 边界使用 JSON 序列化;进程内热路径使用 typed channels,但响应仍保留 JSON-RPC result envelope,并未另造一套协议语义。服务抽象与操作系统进程边界在这里是两个独立选择。exec 初始化、进程内客户端设计
App Server 下面的对象关系
ThreadManager 创建并保有内存中的 thread。创建过程组装认证、模型、执行环境、skills、plugins、MCP 和存储等依赖,再启动 Session。CodexThread 提供线程对象的外部操作面;SessionIo 保存提交操作的 sender、接收事件的 receiver,以及会话循环的终止 future。ThreadManager、CodexThread、SessionIo
可以沿着下面的路径阅读一次普通执行:
1 | |
这里的“thread”是对话状态和执行控制对象,不能直接翻译成“一条操作系统线程”。Tokio task、子进程、终端会话和子 agent thread 是另外的对象。
本地执行与本地推理要分别配置
普通本地模式可以在本机读代码、运行测试,再把必要的代码片段和工具结果发送给远端模型。截图等多模态输入也属于数据流的一部分。本地工作目录并不构成“代码绝不离开机器”的保证。本地执行安全边界
显式使用 OSS provider 是另一种拓扑:CLI 可以连接 Ollama 或 LM Studio 等本地模型服务。这时推理服务的位置改变,模型能力、工具协议兼容性和资源要求也要分别确认。安装 Codex CLI 本身不会把默认托管模型的权重下载到笔记本。本地模型 provider 配置
Desktop 的 Local 与 Worktree 模式仍属于本地执行。Worktree 提供独立 Git 工作目录,减少并行修改同一路径的冲突;它不提供独立操作系统,也不自动隔离网络、凭据和所有进程。
App Server 的协议架构
App Server 提供的是有状态 agent 协议。客户端需要跟踪 thread、turn、item、流式事件、审批请求及连接生命周期,不能只发送一次 prompt,等待一段文本。App Server 协议
传输与连接握手
默认传输是 STDIO:请求与事件按 JSONL 逐行传输。还支持 WebSocket,以及 Unix socket 上的 WebSocket/HTTP Upgrade 等方式。消息采用 JSON-RPC 2.0 的请求、响应和通知结构,但 wire message 省略 jsonrpc 字段。每个连接先完成 initialize 请求,再发送 initialized 通知,随后才进入业务调用。
--listen 决定客户端怎样连接 App Server;--code-mode-host 决定 App Server 怎样连接 Code Mode 执行宿主。这是两条不同方向的连接。同一 App Server 进程内的 threads 共享所选 Code Mode host 连接,并不意味着所有工具都被同一个参数迁移到了远端。App Server 传输与 Code Mode host
当前文档仍将 App Server 命令及 WebSocket transport 标为实验性,并注明不支持 production workloads。用它研究、嵌入和构建原型,与获得托管 Cloud 的生产生命周期承诺,是不同层次的事情。
Thread、Turn、Item
| 协议对象 | 表示什么 | 一个例子 |
|---|---|---|
| Thread | 可持续追加和恢复的对话及其状态 | 围绕某个仓库持续处理问题的 chat |
| Turn | 一次输入所启动的 agent 工作过程 | 接到修复请求后读文件、改代码、测试、回答 |
| Item | turn 中的输入、输出或操作记录 | 用户消息、agent 消息、命令、文件修改、工具调用 |
一个 turn 可以包含多次模型请求和多次工具执行。一个 thread 可以经历多个 turn。产品层的一项任务还可能涉及多个对话或子 agent;不能把所有界面上的 task 都当成一个固定的 thread ID。
典型事件序列如下。工具和审批事件只是示意,实际类型以协议 schema 为准:
1 | |
turn/start 成功只表示工作获准开始。turn/completed 表示该 turn 达到协议终态,不能证明测试通过、PR 合并、线上流量正常,甚至不能单凭 completed 证明业务目标已经实现。验收证据需要来自相应工具、文件或外部系统。
Steering、取消与双向请求
turn/steer 向活动 turn 注入新输入,使用 expectedTurnId 防止输入落到错误的执行过程。它不会新建 turn,也不能借此随意改写活动 turn 的 cwd、模型或权限策略;没有活动 turn 时会失败。turn/interrupt 则请求中断当前执行。
审批让协议具有双向性:服务端也可以发起请求,等待客户端答复。只实现“客户端请求、服务端响应”的单向 RPC 包装,会遗漏命令审批、文件操作审批和用户补充信息等状态。连接中断时,还要处理这些等待者的归属。
历史读取、订阅和执行恢复也需要区分。读取已保存的 thread,不等于让它恢复执行;客户端收到某个 item 的增量,也应以后续完成事件确定最终状态。官方说明还包含无订阅、无活动一段时间后卸载 thread 的行为,这与任务永久驻留是不同概念。Thread 与 Turn 生命周期
Task Loop 与 Turn Loop:先消除同名歧义
“Task loop 是外层,turn loop 是内层”只能作为粗略解释。源码里的 task、产品里的 task、业务工作流里的 task,并不共享同一种生命周期。
| 用法 | 负责的事情 | 是否天然跨 turn |
|---|---|---|
| 产品任务 | 保存一次委托、环境、结果与继续工作的入口 | 可以,具体由产品定义 |
| 目标或工作流循环 | 判断目标是否完成,安排下一轮执行或等待 | 通常可以 |
SessionTask |
驱动 Session turn 的具体执行工作流 | 不能据名字推导;由具体实现决定 |
run_turn 内部循环 |
组织模型、工具、输入与停止条件 | 工作于 turn 执行范围内 |
| 模型请求与响应流 | 完成一次推理请求,处理响应事件 | 单次请求本身不是完整 turn |
在本次固定快照的 Rust 源码中,没有检索到名为 task_loop 或 turn_loop 的精确标识符。可定位的机制是 submission_loop、SessionTask、RegularTask::run、run_turn,以及 goal 扩展的 continuation。文章或演讲使用前两个英文词时,必须补上所指层次。
图中的层级是职责层级。它不是说每层都有一个独立、永不返回的 while 函数,更不是一次函数调用就对应一个新协议 turn。
submission_loop:会话操作分发
Session 启动 submission_loop,等待并分发输入、取消、恢复、关闭等操作。会话可以存活并等待输入,此时模型完全不需要持续生成。服务在线、thread 已加载、turn 活跃、模型正在推理,是四种不同状态。循环启动、操作分发
这层循环解决“运行时收到什么操作、如何改变执行状态”。它本身不负责证明某个长期业务目标完成,也不等于云调度器。
SessionTask:Session 拥有的执行工作流
SessionTask 的注释明确说明:它驱动 Session turn,由 Session 拥有,在后台 Tokio task 中执行。当前 TaskKind 包含 Regular、Review、Compact。这些类型解释运行时如何区分普通工作、审查和压缩等工作流。SessionTask 契约、TaskKind
RegularTask::run 自己还有一个外层循环。它调用 run_turn;遇到 terminal error 则结束;没有 pending input 则结束;如果仍有输入,就以空 initial input 再调用一次,并复用原来的 TurnContext。
因此,同一个协议 turn 的执行过程,可以重新进入 run_turn。拿 run_turn() 的调用次数统计 turn 数量,会把函数实现细节误当成协议生命周期。RegularTask 的循环
run_turn:模型与工具往返
run_turn 的源码注释给出了基本机制:模型提出函数调用,运行时执行工具,再把结果用于下一次采样。实际循环还要处理 pending input、上下文管理、模型是否需要 follow-up,以及 Stop hook 是否允许结束。run_turn 定义与注释
可以把下面的伪代码用作阅读辅助;它省略并发、错误、压缩和事件细节,不能代替实现:
1 | |
follow-up 判断包含 model_needs_follow_up || has_pending_input。模型已经输出一段可见文本,并不意味着 turn 立刻结束;Stop hook 拒绝结束时,还可以注入 continuation prompt,继续同一执行循环。后续请求条件、Stop hook
一次修复请求怎样跨越这些层
假设用户提交“修复登录超时,并用回归测试证明”。一个 turn 中可能依次发生:模型要求读文件、工具返回代码;模型要求运行测试、工具返回失败;模型生成修改、工具更新文件;模型再次测试、工具返回结果;模型提交最终说明。这里包含多个模型请求、多个 items,但仍可能只有一个协议 turn。
用户在执行期间补充“也检查 Windows”,如果通过 turn/steer 接入,可以仍处于该 turn。用户在结束后再发“继续验证集成环境”,则启动后续 turn。若设置了长期 goal,运行时也可以在空闲时自动启动新 turn。产品中的“修复登录超时”这项任务,可能覆盖上述整个过程。
这给出三个不同的计数单位:任务按委托和产品状态计数,turn 按协议执行生命周期计数,模型调用按推理请求计数。它们不能互相代换,token 预算和耗时统计也需要注明口径。
Goal:跨 turn 的目标续跑
当前 /goal 功能把目标及完成条件保存下来,支持继续引导、暂停、恢复和修改。它延长的是目标管理的生命周期;当前 sandbox 和 approval policy 仍然适用。Long-running work
App Server 提供 thread/goal/set、thread/goal/get 和 thread/goal/clear 等接口。goal 状态包含 objective、status、token budget、tokens used 和 time used 等信息。设置新的 objective 与在同一个目标上继续工作,涉及不同的预算记账语义,应按接口契约处理。Goal 协议
源码中的实现已分离到 codex-rs/ext/goal。GoalRuntimeHandle::continue_if_idle 会检查功能是否可用、是否有 continuation deferral、thread 是否仍可用、保存的 goal 是否处于 Active。满足条件后,通过 start_turn_if_idle 提交 continuation,并将 turn_trigger 标为 goal。Goal runtime
这与 Stop hook 的区别是可观察的:Stop hook 可以继续 turn 内循环;goal 的 idle continuation 则尝试启动新的 turn。两者都能产生“回答以后还在继续”的表象,却作用于不同生命周期。
goal 也有停止和记账路径。源码区分 turn error、usage limit、execution unavailable、重复空响应等情况,并通过状态和锁协调外部修改与自动续跑。它不是一个无条件的 while true。Goal 停止处理
本地 goal 仍依赖运行时和工作区可用。官方建议长任务避免主机休眠,并在预计断网前暂停,再恢复执行。保存了目标,并不自动获得离线调度器、常驻云主机或无限资源。
模型连接、上下文与工具路由
ModelClient 与一次模型请求
源码把会话级 ModelClient 与 turn 级 ModelClientSession 分开。前者维护认证、provider、conversation 和连接回退等状态;后者服务于某个 turn,允许在该 turn 内发出多个 Responses 请求。模型客户端设计注释
连接层包含 WebSocket 缓存、路由状态、增量上下文关联和 HTTP 回退等机制。由此不能把“一个 turn”等同一条 HTTP 请求,也不能声称每一步都重新发送一份完全相同的纯文本历史。模型输入包含指令、消息、工具声明、工具结果及多模态内容;具体传输还受 provider 和版本影响。
认证状态、模型选择和计费主体也属于运行架构。使用 ChatGPT 登录、API key 或组织管理的凭据,不能仅因接入同一 CLI 就视为同一种身份和配额。远端主机上的 Codex 还需要自己的可用认证;本机登录不等于给任意 SSH 主机自动授予全部凭据。CLI 使用与认证入口、远程连接
工具声明、选择与执行
模型输出的是工具调用意图,Harness 根据工具名、call ID 和 payload 路由到实现。工具 registry 决定哪些工具可见,参数 schema 决定调用形状,执行器再处理结果、错误和事件。ToolRouter 维护 registry、可见 specs、Code Mode 名称映射等对象。ToolRouter
当前仓库还把共享工具 schema、namespace、延迟发现、MCP 转换和 Code Mode 相关定义整理在 codex-rs/tools。该目录说明部分职责仍在迁移,Core 继续承担具体编排。讨论组件边界时,应该同时看类型定义和实际执行入口。工具层设计说明
普通命令工具还要经过审批、sandbox 选择、执行及必要的升级重试。ToolOrchestrator 的设计注释直接列出这条路径。工具调用成功返回,只证明该工具的结果;一个外部服务返回“已接受”,不等于它的下游副作用已经完成。ToolOrchestrator
Code Mode 与 exec-server
Code Mode 增加了通过代码组合工具调用的执行方式,公开仓库包含基于 V8 的 runtime 和会话实现。它处于工具编排层,不能解释为“模型生成 JavaScript 后就获得不受限制的系统权限”。最终调用仍落到宿主提供的能力与策略。Code Mode runtime
exec-server 则是另一类更窄的服务:启动、控制子进程和 PTY,并提供文件系统相关 handler。它的协议与 App Server 不同。App Server 管 thread 和 turn,exec-server 管执行资源;不能把两个名字都翻译成“远程 Codex 服务”。
公开 exec-server 设计还包含直接 WebSocket 与远端 registry/rendezvous 等连接路径。relay/forwarder 负责转发字节,不持久化、重放完整执行;目标执行端拥有进程及恢复状态。这里能确认执行位置可进一步拆开,却不能据此断言托管 Codex Cloud 就采用同一内部拓扑。exec-server 设计说明
状态架构:上下文、历史、记忆和文件
长期工作至少要区分四类状态。模型当前能看到的上下文,只是其中一类。
| 状态 | 主要用途 | 恢复时需要防止的误解 |
|---|---|---|
| 对话与执行历史 | 记录输入、items、turn 和相关事件 | 能恢复历史,不代表活跃进程仍在 |
| 上下文与压缩结果 | 在有限窗口中保留当前推理所需信息 | 压缩会选择和重写信息,不是无限完整记忆 |
| 工作区与执行状态 | 保存文件、未提交修改、依赖、进程与终端 | 文件、进程、连接可以有不同寿命 |
| 目标、记忆与产品元数据 | 支持跨 turn 目标、偏好和检索 | 持久化文本不等于更新模型权重 |
ThreadStore、Rollout 与 SQLite
当前快照使用 ThreadStore 作为 thread 存储边界,提供本地和内存实现,也允许仓库之外存在其他实现。活动会话优先通过 LiveThread 持久化:应用相应策略、追加规范历史,再显式提交 metadata patch。ThreadManager 统一路由已加载与冷 thread 的元数据修改,Core 不需要假设底层一定是本地文件。Thread Store 设计说明
LocalThreadStore 才进一步使用 rollout JSONL 保存历史,并在 SQLite 可用时维护可查询的元数据。RolloutRecorder 是本地 writer;活动 thread-store append 的元数据更新由上层明确提交,不再由 writer 根据历史内容自行推断。这条边界让“会话怎么运行”与“状态由谁存储”可以独立变化。
公开实现包含 rollout 记录器和状态数据库。rollout 模块负责会话记录的持久化与发现,记录器将事件写入 JSONL;state 模块使用 SQLite 保存和查询结构化状态,部分 thread metadata 与 rollout 对应,并提供 backfill 等机制。goal、队列等新增状态也有自己的表和语义。rollout 模块、记录器、state 模块
不能用“所有状态都在 JSONL”或“SQLite 是全部真相”概括这一组合。具体对象的拥有者、写入时机和恢复路径需要逐项确认。线程历史、Git 修改、云 VM state 和外部服务数据,也不在同一个事务中提交。
Compaction 管理推理窗口
上下文窗口有限,长 turn 和长 thread 都需要控制输入规模。压缩把既有内容整理成继续推理可用的表示;它会影响后续判断,但不会让原始外部系统状态自动变成最新。文件可能被其他进程修改,测试环境可能变化,旧结论需要重新读取对应证据。
Compact 是当前源码中的任务类型之一,配置和模型还可能影响压缩方式。压缩、恢复、记忆维护是相邻机制,不能用“记住了”把它们合成一种能力。
Memories 是独立的维护流程
公开 codex-rs/memories 描述了一个可启用、依赖持久状态的两阶段机制。第一阶段从符合条件、已经空闲的交互会话 rollout 中提取 raw_memory、rollout_summary 等内容,使用有 lease 的任务与并发上限;生成内容会经过秘密信息处理并写入状态。第二阶段选择材料,生成或同步记忆文件,再由受限的内部 consolidation agent 整理。Memories 设计说明
第二阶段还使用记忆目录的 Git baseline 检测变化、清理过期内容,并在成功后更新 baseline。这里发生的是外部状态提取、筛选和重新注入,不是在线训练模型。该机制有功能开关和会话条件,不能写成所有 Codex 入口默认拥有同一套永久记忆。
Trace 与可观测性
rollout-trace 提供可选本地诊断:记录原始事件与 payload,再离线还原 thread、turn、推理调用、工具、Code Mode cells、终端和压缩等节点与关系。这种记录适合解释“为什么继续了三次”“时间花在哪个工具上”,比只保存最终聊天文本更接近实际执行图。Rollout trace 说明
该功能说明它是本地诊断记录,不能当作全部都会上传的遥测。记录可能包含 prompt 和工具结果,使用、保存和共享时需要按内容处理。
权限、身份与扩展分别约束什么
Sandbox 与审批的边界
Sandbox 决定工具在技术上能够访问什么;approval policy 决定何时需要人工或策略授权;auto-review 对符合条件的动作进行自动审批判断;安全监测还可以在执行过程中暂停活动。它们承担不同职责,不能互相替代。Agent approvals and security
典型文件权限模式包括只读、工作区可写和更宽的访问,也可以使用命名 permission profile。即使工作区可写,.git、.agents、.codex、.aws 等敏感路径仍可能受到额外保护。实际能否写入,要以当次生效的 profile、平台和组织要求为准。
当前官方文档列出的实现包括 macOS Seatbelt、Linux 的 bubblewrap 与 seccomp、Windows 的 MXC 及兼容路径;WSL2 使用 Linux 执行环境。早期资料中关于 Linux 单一隔离后端的描述,需要结合版本更新。平台隔离机制
网络也分通道。本地 shell 的网络关闭,并不必然关闭托管网页搜索或远端 MCP 服务的访问;MCP 服务自身的凭据和权限也不由一个本地目录白名单完整决定。需要分别追踪命令执行、模型服务、网页工具和 connector 的调用路径。
Config 与 AGENTS.md
个人配置、profile、项目配置、命令行覆盖和组织管理要求共同决定运行行为。当前配置文档还区分默认配置与强制要求:一个默认值可以被更高优先级配置覆盖,强制约束则不能靠普通项目配置解除。未信任项目不会直接加载其项目配置、hooks 和规则。配置基础
AGENTS.md 是提供给 agent 的指令来源。当前发现规则从全局指令和项目路径逐层组合,每层优先选择 override 等候选文件,并受默认读取大小限制;它不是递归读取仓库所有同名文件。进入某个子目录的工作范围,还可能受到该层指令影响。AGENTS.md 规则
文件里的“只读”“允许联网”属于指令内容。文件系统与网络能力由运行时策略约束。把角色文件命名为 reviewer,不能自动建立只读 sandbox;在仓库里写“允许全部操作”,也不会绕过宿主权限。
Skills、Plugins、MCP、Apps 与 Hooks
| 机制 | 装入什么 | 应当检查的边界 |
|---|---|---|
| Skill | 工作流说明、脚本、参考资料 | 先发现摘要,再按需读取正文;不等于模型微调 |
| Plugin | skills、MCP、hooks 等能力的分发组合 | 安装、启用、认证和使用授权是不同动作 |
| MCP / App connector | 外部服务提供的工具与数据 | 连接方式、凭据主体、服务端权限、数据可见性 |
| Hook | 生命周期事件触发的确定性程序或反馈 | 信任、运行地点、超时和对执行的影响 |
Skills 使用渐进式加载,避免每次把所有操作手册塞进上下文。MCP 支持 STDIO 子进程和 Streamable HTTP 等连接;其服务可能在本机,也可能在其他系统。工具可见,不等于目标服务已经授权当前用户访问全部数据。Skills 与 plugins、MCP 工具接入
Hooks 可覆盖 Session、Turn 周边、工具前后、压缩、Stop、Interrupt 和子 agent 生命周期等事件。它们能在关键位置运行检查或返回继续工作的反馈。当前文档还要求处理 hook 信任;匹配的 hooks 可能并发执行,不能依赖一个未声明的串行短路顺序。Hooks
Hook 的运行位置也取决于编排模式。启用相应企业策略时,Work Cloud local access 与 dots 使用云端协调器上的管理员远程 MCP hooks;本地配置、插件中的 command hooks 不会因为工具在本机执行就自动生效。某些 PreToolUse 回调错误、超时或畸形响应会使 hook 失败,却不阻止工具执行。因此,hook 检查不能一概当作操作系统级强制隔离。云端编排的 hooks 边界
还有一个版本变化:当前官方文档说明 codex mcp-server 和独立 codex-mcp-server 已移除。Codex 仍能消费 MCP 工具,但把 Codex 自身作为服务嵌入时,应区分 App Server 协议与旧 MCP server 路线。MCP server 迁移说明
多 agent:多个执行上下文如何协作
子 agent 拥有独立对话和工作上下文,父 agent 可以分派任务、等待结果和发送后续输入。创建时可以提供或继承初始上下文;后续每一步不会自动共享成一个全局聊天缓冲区。角色配置还能指定模型和行为,但不能仅靠 prompt 获得超出宿主边界的权限。Subagents
多 agent 有两种经常被混淆的并行:多个模型或 agent 同时工作,以及单个 agent 并发调用工具。前者涉及独立上下文、任务归属和结果整合;后者主要涉及工具依赖、并发限制和事件顺序。一个父 turn 可以等待多个子 agent,而子 agent 又有自己的 turns,时间结构并不是一条简单的串行链。
独立上下文不等于独立文件系统。在共享 checkout 上,两个 agent 可以修改同一文件、影响同一个测试进程或覆盖彼此结果。Worktree 能隔离工作目录,却仍需要分配文件归属、集成修改并验证最终组合。只有明确配置的执行环境隔离,才能进一步隔离系统资源。
父 agent 需要为委派设置可检查的目标、范围和完成证据。子 agent 的“完成”消息属于协作结果,不能代替父级集成后的构建、测试或产品验收。并行提高吞吐的前提,是子任务能够独立执行、结果能够被整合。
六种运行模式放在一起比较
以下表格描述产品支持的运行边界。默认模型推理可以在远端发生,因此“执行地点”特指工具和工作区的主要位置。
| 模式 | 交互入口 | Harness / 执行位置 | 状态和依赖由谁维护 | 客户端离线意味着什么 |
|---|---|---|---|---|
| CLI、IDE、本地 Desktop | 终端、编辑器、App | 本机或所连接开发环境 | 用户与本地运行时 | 需要区分 UI 退出、运行时退出和主机休眠 |
| Desktop Worktree | Desktop | 本机的独立 Git 工作目录 | 用户与本地运行时 | Worktree 本身不提供后台在线保证 |
| Desktop → SSH | 本机 Desktop | 用户的 SSH 主机 | 用户维护主机、Codex、仓库与认证 | 不能推导任意断线后所有进程继续 |
| Remote Control | 手机或另一台 Desktop | 被配对主机,可继续连接 SSH | 被控主机及其连接环境 | 主机须醒着、在线、App 运行 |
| Codex Cloud | Web、Mobile、Desktop 等 | 托管的每任务 workspace / VM | 平台管理基础设施,用户配置 environment | 明确支持用户电脑睡眠后继续 |
| Work Cloud + local access | 云端协调入口 | 授权本地执行,也可在规定边界使用云容器 | 云任务与已连接电脑分别承担状态 | 部分既有任务可在新 turn 边界转云执行 |
运行模式、Remote connections、Cloud、Cloud local access
Desktop → SSH:远端 App Server
Desktop 读取 ~/.ssh/config 中可用的具体 host aliases,通过 OpenSSH 连接。远端需要安装并认证 Codex,远端 login shell 的 PATH 能找到 codex。App 通过 SSH 启动、管理远端 App Server,项目命令和文件访问发生在远端主机。SSH 连接机制
这一模式适合已有的远程开发机:代码、依赖、私网和凭据已经在那里,Desktop 提供交互面。用户仍负责主机可用性、磁盘、系统升级、SSH、远端配置及项目环境。
远端服务器一直开机,只满足主机可用性的一部分。App Server 如何被启动、transport 消失时怎样清理、子进程受谁监督、是否保存未处理输入,都影响断连后的行为。官方没有给出覆盖全部 SSH 断线场景的存活保证,不能写成“关掉 Desktop 也一定一直运行”。
Remote Control:远程控制一台仍在运行的电脑
手机或另一台 Desktop 可以经安全 relay 连接已配对的主机。主机继续提供工作目录、凭据、skills、MCP 及其他本地能力。relay 解决连接可达性,任务计算并没有因此自动进入托管 Cloud。Remote Control 条件
该主机需要保持醒着、联网、登录且 App 运行。放一台常开电脑可以改善这条路径的可用性,但生命周期仍由用户维护;手机退出不等于主机退出,主机睡眠则会影响远程访问。
Host handoff:迁移聊天与 Git 状态
host handoff 可以在本机与具有匹配项目的远端主机之间转交 chat 及其 Git 状态。活动 response 会先被中断,再进行转交。它不是迁移正在运行的操作系统进程,也不是把所有内存、终端和网络连接热迁移到新机器;当前该 handoff 路径也不支持将目标设为 Codex Cloud。Host handoff
当前 Codex Cloud:Environment 与 Task VM
新版 Codex Cloud 把可复用的环境准备状态与每次任务分开。Environment 规定仓库、依赖、工具、网络和服务访问;Task 从准备好的起点开始,在自己的 workspace / VM 中工作。Cloud environments
准备、保存与发布
创建或修改 environment 时,Codex 可以检查仓库、安装工具和依赖,并验证准备结果。保存配置与发布 filesystem 不是同一个动作:发布后的准备状态,才构成新任务使用的环境起点。
任务 A 的文件修改,不会直接覆盖共享 environment,也不会自动成为任务 B 的初始目录。需要改变后续任务的起点,就编辑、验证并重新发布 environment。已有任务则保有自己的 saved files,包括未提交修改和在任务中安装的工具。
这可以解释两个看似矛盾的行为:新任务保持隔离,同一个任务又能继续已有工作。隔离作用于任务之间,恢复作用于同一任务的生命周期。
电脑睡眠后还能工作,靠的是托管执行
官方明确说明,Cloud 任务可以在用户电脑睡眠后继续;同一个任务可以从其他入口重开。此时工具执行不依赖用户笔记本上的进程,执行基础设施由平台管理。Codex Cloud
当前文档还给出 saved VM state 的恢复窗口:默认情况下,以最近一次 start turn 或 resume task 为时间锚,最多七天可恢复。这里描述的是已保存 VM 状态的恢复期限,不能解释为一个模型连续推理七天、一条 shell 命令运行七天,或任务永久保留。重要成果仍需要提交或保存到适当的持久位置。任务状态保留
公开文档没有给出内部 scheduler 的队列设计、VM 暂停机制、每个进程的 checkpoint 颗粒度或无期限运行 SLA。能够确认的,是用户可见的任务独立性与恢复契约。
网络、身份与 secrets
当前 Cloud environment 可以配置网络 allowlist、包管理相关预设或更宽的访问。允许目标域名,只解决“能否连到那里”;服务仍可能要求 OAuth、云身份、数据库凭据或其他认证。
普通 environment variables 会向需要读取原始值的程序提供变量。Network secrets 则采用 placeholder 与代理替换机制:程序使用占位值,代理在符合配置的 HTTPS 请求中注入实际凭据。当前支持范围涉及 HTTPS 443 与允许域名;不能把这种 secret 当成程序能直接读出的原始环境变量。Cloud 网络与凭据
私网连接当前支持 Tailscale,访问同时受环境网络规则与 Tailscale 访问规则约束。OIDC 短期云凭据目前面向 Enterprise 按申请开放。共享 environment 的使用权限,不自动授予查看其他用户任务、修改 environment 或访问所有关联服务的权限。
本地能力不会自动复制过去
本地文件、浏览器登录态、VPN、长期运行的进程和个人 skills,不会因为创建 Cloud 任务就全部复制。仓库中的 skills 可以随项目提供;需要的服务访问则要在 Cloud environment 中配置。
截至本文取证日,Cloud environments 尚不支持 Computer Use、browser use、GitLab 与 self-hosted GitHub Enterprise Server。选择执行地点前,需要按实际依赖核对这些能力。Cloud 限制
Legacy Cloud 需要单独解释
官方仍保留明确标记为 Legacy 的 Cloud 文档,覆盖 Code Review、Linear 和 GitHub integrations 等路径。它描述 container checkout、setup、maintenance、agent 执行与产出 diff 的流程。Codex Cloud Legacy
| 方面 | Legacy 文档描述 | 新版 Cloud 文档描述 |
|---|---|---|
| 环境起点 | Container image、checkout、setup / maintenance | 准备并发布的 environment filesystem |
| 隔离对象 | 某次执行的 container | 每个 task 的 workspace / VM |
| 缓存或恢复 | Container cache 最多 12 小时 | Saved VM state 默认最多七天可恢复 |
| Secrets | Setup 阶段提供,agent 阶段移除 | Environment variables 与 network secrets 分开 |
| 网络 | Setup 与 agent 阶段分别处理 | Environment 网络、服务访问与身份配置 |
Legacy 的 setup script 在独立 Bash session 中运行,临时 export 不会自动变成 agent 阶段环境。其 universal image 与最多 12 小时 container cache 也有明确适用范围。把这组规则与新版 VM、published environment、network secrets 拼在一起,会得到一个官方从未描述过的混合系统。
两个时间数字也不能比较成“新版任务比旧版多运行十四倍”:12 小时描述缓存,七天描述 saved state 恢复窗口,计量对象不同。
云端长期运行,到底包含哪些机制
“长期”至少有三种需求:一次工作持续较久,停止以后可以继续,以及隔一段时间或收到事件后再次启动。它们分别需要执行时间、状态恢复和触发机制。
| 机制 | 主要解决什么 | 还依赖什么 |
|---|---|---|
| 长 turn / 长工具执行 | 当前这一轮持续工作 | 运行时、连接、工具和预算 |
| 持久 goal | 跨 turn 保存目标并续跑 | 活跃 runtime、目标状态、权限和资源 |
| 可恢复云任务 | 客户端离开后保存并继续已有任务 | 平台的 workspace 与恢复契约 |
| 定时或事件任务 | 没有新用户输入时再次启动工作 | Scheduler、触发源、身份和可用环境 |
| 上层持续协调 | 跨任务追踪、委派、等待和通知 | 更长寿命的产品状态与授权管理 |
给 codex exec 外面包一个无限循环,只实现了某种重试或续跑策略。它没有自动补齐任务去重、可恢复输入、身份更新、环境供给、结果通知和外部副作用管理。
Desktop 的定时任务
Desktop scheduled tasks 可以在本地项目目录或 worktree 中运行。它们需要电脑开机、App 运行和项目路径可用。Standalone 运行会创建新的 chat;绑定到 chat 的调度可以复用已有上下文。具体调度能力包括间隔和日周计划等。Scheduled tasks
把这种调度设置成每天一次,不会让一台睡眠的电脑具备持续执行能力。它解决“何时开始”,本地环境仍负责“能否执行”。
Web / Mobile 的云端定时与事件任务
当前 Web 和 Mobile 的 scheduled tasks 可以在云端使用上传上下文、connected tools、skills 和 plugins。它们不持有用户本机文件夹或 worktree;长期需要的信息应放入任务指令、项目、上传文件或可访问的数据源。云端 scheduled tasks
当前文档还包含 eligible plans 的 event triggers,例如 Gmail 新消息、所选 Slack channel 的新消息和 GitHub PR 活动。这类事件触发目前只在 Web / Mobile,不能据此说 Desktop、CLI、IDE 都有同一功能。邻近事件可能合并为一次 run,连接了 app 也不等于已经创建监控。
一个 scheduled task 可以配置多个事件触发器,但不能同时混合事件触发与时间计划。触发配置定义的是何时创建 run;一个 run 如何选择上下文、工具和执行环境,则是后续的运行职责。
因此,旧结论“Codex automations 都在本地跑”已经不足以描述当前产品;反过来,也不能把全部云端 scheduled tasks 都写成同一种仓库 VM。上下文来源、工具集合和执行环境,要看具体任务入口。
Team Tasks 与持续协调产品
Team Tasks 使用团队 service account 及配置的 app connections,在云端接受定时或事件触发。它不自动继承创建者的个人记忆、custom instructions 和聊天历史。任务能否在创建者离开后继续,还取决于连接身份是否仍有效。Team Tasks
暂停 Team Task 会阻止未来的定时和事件运行;暂停或删除任务,不能作为中断正在执行 run 的可靠手段。调度状态与活跃执行状态要分别处理。
dots 等上层产品还可以保存持续目标,等待、唤醒并委派本地或 Cloud 编码任务。子任务有自己的 conversation,不会自动获得上层全部聊天内容;选择另一台电脑也不等于迁移已有任务。这属于跨任务协调层,不能全部归入开源 CLI 的 run_turn。Tasks and memory
站内《Personal Agents 的架构演进》讨论了这类长期产品实体。Codex Harness 可以成为其中的执行器,长期身份、触发和跨任务责任则需要额外的产品机制。
Work Cloud 与本地 executor:两个位置分开以后
Work Cloud 使用 Codex task-execution harness,但工具、权限和企业管理控制并不完全相同。开启 local computer access 后,符合条件的新 Work 任务可以由云端协调,连接电脑执行本地步骤。Work Cloud security、Cloud local access
Work Cloud 在 VM-backed sandbox 中运行,可以跨任务复用执行环境,也可以替换环境并保留符合条件的状态。它不保证每个任务都新建一个 container;前文 Codex Cloud 的每任务 workspace 契约,不能直接套用于 Work Cloud。Work Cloud 执行环境
这个模式给出了一个明确的迁移边界:对符合条件的既有任务,如果在新 turn 开始时发现电脑不可用,可以继续到 cloud container;不能在 turn 中途自动切换。转云以后,也不能访问离线电脑里的文件和工具。
开启 sync 之前的既有任务不会因此全部改用新模式,本地 enterprise requirements 也不能直接当成 cloud container 的策略。官方还明确说明,这一功能不改变 Codex mobile host connection 的行为。本地与云执行边界、Codex Remote
这与 Desktop SSH 的区别不在“都能连电脑”,而在控制责任:SSH 把交互面接到远端 runtime;Work Cloud local access 允许云端协调任务使用本地资源,并在产品规定的 turn 边界选择其他执行位置。两者的离线行为不能互相套用。
断线、重启和恢复:需要逐层验收
“可以 resume”仍然没有说明恢复了什么。至少要分别检查历史、输入、执行和副作用。
| 恢复对象 | 能恢复的典型内容 | 不能自动保证的内容 |
|---|---|---|
| Thread 历史 | 已持久化的消息、items 和状态 | 所有尚未落盘的增量与待处理输入 |
| 工作区 | 已保存文件、Git 修改、任务 filesystem | 原来的 PID、网络连接和内存 |
| 活动执行 | 在支持的路径重新建立运行状态 | 任意工具在任意断点无损续跑 |
| 外部副作用 | 通过业务系统查询已发生结果 | 自动 exactly-once、撤回已发送消息或已写数据库 |
App Server 的 thread/resume 让已保存 thread 继续。thread/revert 删除指定 turn 及之后的历史,不撤销文件写入和外部系统动作;旧的 thread/rollback 已被移除。把历史回退当成仓库回滚,会直接造成判断错误。恢复与 revert 协议
公开源码中的 turn suspension 也说明恢复边界很具体:当前路径只支持 Regular task,并检查 live descendants;它会 flush 后取消执行,为另一个 worker 使用原 turn ID 恢复保留条件。但 pending accepted input 和 interactive waiters 属于进程内状态,不能凭这条路径自动持久化重放。挂起约束、进程内状态限制
由这些边界可以得到一个工程推论:自行把 Codex 接入长期工作流时,需要在应用层保存目标、触发事件和外部操作 ID,恢复后先查询现实状态,再决定是否重试。对于创建 PR、发送通知、提交订单或写数据库等动作,应利用目标系统的幂等机制;不能从一次模型回答或会话日志推出恰好执行一次。
取消也要区分层次。中断 turn、杀掉终端进程、暂停 goal、取消未来 schedule、删除任务,是不同操作。已经发生的外部副作用不会因为其中某个状态改成 paused 就自动撤销。
自己嵌入 Codex,应该选择哪个接口
非交互命令与 SDK
codex exec 适合围绕一次非交互执行组织脚本。程序需要可靠处理机器可读事件、退出状态和输出文件,不能只按终端中的最后一句话判断是否成功。要修改工作区,仍需显式配置适用的 sandbox 与权限。CLI
当前 TypeScript SDK 包装本地 CLI 执行路径;在所核查版本中,它通过子进程及 JSONL 事件驱动 codex exec,提供运行、流式消费和恢复 thread 等接口。当前官方还提供稳定 Python SDK,经 JSON-RPC 控制本地 App Server,并绑定 Codex runtime 依赖。因此,“SDK 就是远端 Cloud Job REST API”不符合这些实现。SDK 文档、TypeScript SDK 执行入口
Rich client 与自建常驻服务
需要聊天历史、流式 UI、审批、多个 thread 和中断控制,可以研究 App Server。客户端应使用当前生成的 schema,并把初始化、请求 ID、反向请求、订阅和重连状态纳入设计。App Server
自建常驻服务还要额外承担进程监督、任务排队、持久输入、凭据更新、环境隔离、资源预算和结果验收。这些是服务集成责任。App Server 已提供某些状态与生命周期接口,并不意味着用户只需公开一个端口,就拥有与托管 Cloud 相同的服务。
下面的命令只用于核对本机版本和可用参数,不会创建任务或修改仓库:
1 | |
在本文环境中,四条命令均已执行,版本为 0.162.1。App Server 监听若用于远程实验,应按官方要求保护传输与认证;不要将可操作工作区的接口直接暴露到公共网络。
选择运行方式时,检查任务真正需要什么
| 需求 | 对应的架构选择 | 最先验证的条件 |
|---|---|---|
| 直接使用本机代码、工具与登录态 | Local / Worktree | 本地权限、工作区隔离、主机在线 |
| 使用已准备好的远程开发机 | Desktop → SSH | 远端 Codex、认证、PATH、SSH 和依赖 |
| 手机查看并控制同一台电脑的工作 | Remote Control | 被控主机醒着、在线、App 运行 |
| 电脑睡眠后仍执行独立编码任务 | Codex Cloud | Environment、仓库和服务访问是否齐备 |
| 跨多轮推进、按时间或事件再次启动 | Goal + 对应调度或上层协调 | 目标状态、触发器、身份、执行地点与验收证据 |
设计自有 agent 系统时,Codex 的公开结构还能提供几条可复用的经验。协议对象可以跨进程边界,服务抽象不必固定成独立进程;持久 goal 与 turn 执行分开后,目标管理可以跨越多轮;执行宿主与交互入口分离后,SSH、relay 和混合执行才有清楚的定位;将历史恢复与副作用恢复分开,可以避免把聊天记录误当成业务事务日志。
这些经验能用于其他 Harness,但具体恢复保证仍需要对应实现证明。任务可继续、模型还在回答、命令执行成功和业务目标验收通过,是四种不同结论。
公开组件的源码导航
下表固定到同一 SHA,便于沿实际对象关系继续阅读。目录存在说明公开实现覆盖这项职责,不代表所有产品入口均已启用同一功能。
| 层次 | 路径 | 阅读重点 |
|---|---|---|
| 入口与客户端 | cli、tui、exec |
命令分发、交互与非交互路径 |
| 服务与协议 | app-server、app-server-client、app-server-protocol |
传输、生命周期、请求和事件 |
| 会话与执行循环 | core/src/session、core/src/tasks、ext/goal |
操作分发、turn 内工作、跨 turn 目标 |
| 工具与宿主 | core/src/tools、tools、code-mode-runtime、exec-server |
路由、schema、代码编排与执行资源 |
| 状态与诊断 | thread-store、rollout、state、memories、rollout-trace |
存储抽象、历史、元数据、记忆维护与执行图 |
参考资料与验证范围
产品文档读取日期为 2026 年 10 月 15 日。官方文档索引当时由原 developers.openai.com/codex/llms.txt 指向 learn.chatgpt.com 下的文档。引用以这些具体页面和固定版本源码为依据,产品可用性仍受计划、组织策略与后续更新影响。
| 主题 | 一手资料 |
|---|---|
| 核心协议与本地入口 | App Server、CLI、SDK、开源范围 |
| 部署与执行环境 | 运行模式、Remote、Cloud、新版环境、Legacy 环境 |
| 长期工作与混合模式 | Long-running work、Automations、Cloud local access、Work Cloud security |
| 权限、扩展与协作 | 安全与审批、配置、AGENTS.md、Skills 与 plugins、Hooks、Subagents |
| 源码基线 | Codex 092d3acd,对应 rust-v0.162.1;各关键结论在正文中附具体文件链接 |
本文完成了官方文档与固定源码的交叉阅读,并核对本地 CLI 版本和帮助参数;没有执行托管 Cloud 长时任务、SSH 断线、Desktop 退出、VM 重启恢复或跨主机迁移实验。涉及恢复期限和离线能力的结论属于公开产品契约,不作为端到端实测结果。


