在这里插入图片描述

目前没有公开、统一的 Cowork MAU 统计。开头这张 AICPB 榜单适合观察单品分布,本文不把它加总成市场规模。CNNIC 给出的基线更稳:截至 2025 年 12 月,中国生成式 AI 用户达到 6.02 亿,普及率为 42.8%。[1] 这个口径比 Cowork 宽,但至少说明 AI 已经成为大规模软件入口。

QuestMobile 进一步拆到了终端形态:截至 2026 年 5 月,PC 网页端 AI 应用 MAU 为 1.72 亿,PC 客户端为 1800 万,后者同比增长 20.1%。[2] 它仍然没有单列 Cowork,却更接近本文关心的问题:用户入口正在 Web、Desktop 与 Mobile 之间分化,客户端开始承接更复杂的生产力任务。

本文用 Cowork 指一类能直接推进工作的 Agent:人给出目标,它拆步骤、读取文件、调用工具和跨应用执行,最后交回可以检查的结果。Coding 是最早跑通的场景,现在正在外溢到更一般的知识工作。

IDC 2026 年对中国企业的调查显示,60% 仍处于了解、评估或试点 Agent 的阶段,只有 18% 已经把 Agent 纳入核心业务流。[3] 这个落差比一个巨大的 TAM 预测更有用:产品已经进入企业,距离大规模接管工作流还有很长一段路。从对话走向执行、从单机走向跨端、从个人工具走向企业工作流,这三条演进已经开始,我预估未来两三年还会继续加速。

Agent 在哪里运行,能访问哪些文件和凭据;用户换一台设备后,任务和状态怎样继续;本地与云端分别记住了什么,也随之成为产品必须解决的问题。Codex 同时覆盖 Desktop、CLI、IDE、Remote 和 Cloud,本地还可以检查进程、协议和 sandbox,比较适合拿来拆解。

这篇文章我想搞清楚四件事。

  1. Desktop、CLI、IDE、Remote 和 Cloud 的 Agent loop、Shell 与代码分别跑在哪里?

  2. 一次消息中,模型、App Server、工具和 sandbox 怎么配合?Worktree 与 sandbox 有什么区别?

  3. Cloud Work 跨端同步与 Mobile Remote 分别传递了什么,状态放在哪里?

  4. ChatGPT Memory 与 ~/.codex 中的 local memory 会不会同步?切换 host 后哪些信息还在?

我会先用五个组件建立最小模型,再逐端比较。Desktop 部分做本机进程、协议和 sandbox 实验;Cloud 后端只写公开证据能够覆盖的部分。

1. 理解 Codex 所需的五个组件

Codex 经常被称为 coding agent。这个说法容易让人把模型和 Agent 混成一个东西。实际运行时至少有五个组件。

组件 负责什么 常见位置
Client 接收输入、显示消息、diff 和审批 Desktop、CLI、IDE、Web、Mobile
Agent runtime 组织上下文、调用模型、调度工具、维护 Agent loop 本机 host、SSH host 或云端环境
Model 根据上下文生成回答或下一步动作 模型服务(本文讨论 OpenAI 托管路径)
Execution environment 真正运行 Shell、测试、浏览器和其他工具 本机目录、Git worktree、SSH host、云容器
State store 保存聊天、任务进度、配置和可选 memory 本机 ~/.codex 或云服务

表格先给职责,不太容易形成运行时的画面。先把 Worktree、Remote 和 Cloud 放到一边,只看我在 Mac 上打开 Codex Desktop,选择 Local,然后让它执行一次 pytest。五个组件与 App Server 的关系如下。

1.1 Desktop Local 中的五个组件与 App Server

在这里插入图片描述

图中五个大块分别对应表格中的五行。App Server 被画成 Client 与 Agent runtime 之间的一条窄接口,因为它不是第六套执行系统,只是 runtime 暴露给 Client 的协议入口。沿着一次本机任务看,每个对象负责的事情很具体。

  • Client 是我看到的 Codex Desktop 界面。它接收 prompt,展示模型输出、命令日志、diff 和审批按钮。Client 解决的是人怎样操作任务,界面运行在 Mac 上不等于模型和命令都由这个界面进程执行。
  • App Server 承载 Client 与 Agent runtime 之间的双向协议。Client 通过它创建或继续任务,runtime 通过它持续返回消息、工具进度和审批请求。App Server 不负责模型推理,也不亲自运行 pytest;把它单独画出来,是为了说明 UI 与 runtime 可以解耦,Desktop 和 IDE 也可以复用同一套 runtime 能力。
  • Agent runtime 负责把任务跑起来。它组织当前上下文,调用模型,接收模型提出的工具调用,检查 approval policy,然后调度工具并把结果送回模型。这就是 Agent loop。一次简单请求可能只循环一轮,修改代码、运行测试的任务通常会循环多轮。
  • Model 根据 runtime 提交的上下文生成回答或下一步动作。它运行在模型服务中,不在这台 Mac 上直接读取仓库,也不会自己启动 gitpytest 或浏览器。模型能够看到本地执行结果,是因为 runtime 把工具返回的 observation 再放进下一轮上下文。
  • Execution environment 是命令和文件修改真正发生的位置。在这个例子中,它就是当前 Mac 上的工具进程与项目 checkout。Sandbox 是 execution environment 的权限边界,限制工具能读写哪些路径、能不能访问网络;Worktree 则是另一份独立 checkout,解决多个任务同时改代码时的工作区冲突。
  • State store 保存一次模型调用结束后仍要存在的信息。本机 Codex 会在 ~/.codex 下保存 thread、rollout、配置和可选 local memory,runtime 后续才能继续同一条任务或取回本地记忆。它保存的是交互与任务状态,项目源码和 Git 状态仍然属于 execution environment 中的 checkout。

本文用 host 指承载 Agent runtime、execution environment 与本地 state store 的机器或容器。在这个例子中 host 就是当前 Mac,只有 Model 位于外部模型服务。App Server 没有改变执行位置,它让 Client 能够通过一套协议控制这个 host 上的 runtime。

后面的多端比较,本质上是在移动这些组件。Desktop Worktree 只更换 checkout;SSH 把 runtime、工具和本地状态放到远端 host;Remote 主要把 Client 与 host 分开;Cloud 则把 runtime、execution environment 和任务状态放到云端。官方将 Desktop 的执行模式分为 Local、Worktree 和 Cloud,Local 与 Worktree 都在用户自己的计算机运行。[4]

2. 多端执行架构的差异

在这里插入图片描述

图 1:Codex 的五种常见运行路径。每个子图只回答三个问题:Agent loop 在哪里、命令在哪里执行、代码状态归谁。实线表示官方文档或本地实验明确验证的关系,虚线表示根据外部行为做出的架构推断。

把上一节的五个组件放进多端场景,Model 可以先拿掉:五种路径调用的都是托管模型服务,真正发生位置变化的是 Client、Agent runtime、Execution environment 和 State store。

使用方式 Client 在哪里 Agent runtime 在哪里 Execution environment 在哪里 State store 在哪里
Desktop / CLI / IDE Local 当前电脑 当前电脑 当前电脑 · 当前 checkout 当前电脑 · ~/.codex
Desktop Worktree 当前电脑 当前电脑 当前电脑 · 独立 worktree 当前电脑 · ~/.codex
Desktop 连接 SSH 当前电脑 SSH host SSH host · 远端 checkout SSH host · ~/.codex
Mobile Remote 手机 connected host connected host connected host
Cloud 用户设备(Desktop / Web / Mobile) OpenAI 云端 云端 sandbox OpenAI 云端

Local 与 Worktree 的四个组件都在当前电脑上,变化的只有 Execution environment 使用当前 checkout 还是独立 worktree。SSH 把 runtime、执行环境和状态都移到 SSH host,当前电脑只保留 Desktop Client。Mobile Remote 更直接:Client 换成手机,另外三个组件继续留在 connected host。Cloud 则把 runtime、云端 sandbox 和任务状态都放到 OpenAI 云端,用户设备只负责显示和控制。

App Server 也没有单列。它仍然是 Client 与 Agent runtime 之间的协议入口,位置跟随 runtime:Local 在当前电脑,SSH 在 SSH host,Cloud 由云端服务提供。CLI 和 IDE 也不需要拆成新的执行架构;在本地模式下,它们只是位于当前电脑上的不同 Client。

2.1 Local 与 Worktree

Local 最直接。Desktop 或 CLI 把当前目录交给 Codex,命令、测试、文件修改都发生在这台机器上。它可以看到未提交的修改,也能使用本机已经登录的 Git、数据库客户端、MCP server 和其他工具。

Worktree 没有搬走 Agent loop。它仍在当前 host,只把工作目录换成一个独立的 Git worktree。Codex-managed worktree 默认放在 $CODEX_HOME/worktrees,一个聊天会持续绑定同一个 worktree。[5] 因此,开三个 Worktree 聊天相当于在同一台机器上准备三个互不覆盖的 checkout,CPU、内存、网络和本机凭据仍然来自同一台 host。

这里有一个实际成本。Worktree 创建独立 checkout,但共享 Git metadata;tracked files 会进入新 checkout,ignored 和 untracked files 不会默认全部复制。依赖与构建缓存往往要在新目录重新生成,仍可能占用不少磁盘。它适合并行改代码,不等于获得了三个独立虚拟机。

2.2 Remote 与 SSH

Remote 的典型入口是手机。手机发 prompt、审批和追问,任务继续在 connected Mac 或 Windows host 上运行。仓库、Shell、本机凭据、浏览器和其他本地扩展工具都由 host 提供。[6]

手机没有挂载这台电脑的文件系统,也没有通过一套远程文件 API 直接读取文件。官方公开的链路是:手机与电脑完成设备配对后,prompt 和控制事件经过 secure relay 到达 connected host;relay 让电脑保持可达,但不要求把它直接暴露到公网。真正打开文件、运行 git 和修改代码的仍然是 host 上的 Codex runtime 与工具进程,结果、diff 和审批请求再沿连接返回手机。[6]

App Server 位于这条链路的后半段。当前 Mac 上的 ChatGPT Desktop 会启动 codex ... app-server 子进程;App Server 协议也正好覆盖创建或继续 thread、发起 turn、传递审批,以及流式返回命令输出和文件 diff。[8] 因此我认为,Remote 请求到达 Desktop 后仍会进入本机的 App Server 与 Agent runtime,再由 runtime 调用受 sandbox 约束的工具访问文件。官方没有公开 secure relay 与 Desktop 内部 App Server 的具体桥接协议,也没有说手机直接连接 App Server。更准确的路径是:

Mobile Remote Client
  → secure relay
  → ChatGPT Desktop remote connection layer
  → local App Server / Agent runtime
  → sandboxed tool process
  → local files

这里的 App Server 是任务控制接口,不是文件服务器。它传递 turn、工具进度、审批和 diff;文件内容由 host 上的工具进程读取,能够访问哪些目录仍由该 host 的 sandbox 与 approval policy 决定。

SSH 又多了一跳。Desktop 会通过 SSH 在远端机器启动 Codex App Server,这一段是官方明确披露的。Agent loop、文件读写和 Shell 随之落到 SSH host。手机如果再 Remote 到这条聊天,实际路径是:

Mobile → secure relay → Desktop → SSH → remote App Server / runtime → remote files

这个链路听起来绕,状态归属却不难判断:项目在哪台 host 上执行,代码、本地工具和文件权限就归哪台 host。手机始终只是 Client,没有得到仓库副本。

2.3 Cloud

Cloud 从 Git 仓库开始。Codex 创建隔离容器,checkout 指定 branch 或 commit SHA,运行 setup script,应用网络策略,然后在容器里进入 Agent loop。Agent 会反复运行终端命令、修改文件和执行检查,完成后返回回答与 diff。[7]

还有就是云端 Agent 系统自身的成本问题。OpenAI 没有公开 Codex Cloud 的沙箱调度、状态数据库与对象存储实现,下面是我按照这类系统的常见做法做的架构分析。

如果只看执行基础设施,云端任务最重的成本通常是 sandbox。一个活跃 task 或 session 一般会绑定一个逻辑 sandbox,里面有 checkout、依赖、工具进程、构建缓存以及本轮命令生成的文件。这样做容易保证文件系统一致性,也避免不同用户的执行环境互相污染。代价是 CPU、内存和临时磁盘会随着 sandbox 的存活时间持续占用;用户停下来阅读结果或隔几个小时再追问时,继续养着原来的容器很贵。

因此,云端系统会尽量缩短 sandbox 的实际使用时间,任务完成或长时间空闲后将其休眠、回收,再在下一次执行时拉起新的 sandbox。这里直接产生一个约束:对话和任务状态不能只放在 sandbox 中。否则容器一旦回收,thread、turn、审批记录和任务进度也会一起消失,多端继续同一任务更无从谈起。

更合理的分层是把持久状态放进独立的云端 State store。它保存对话事件、任务状态、基础 commit、环境配置以及制品索引;sandbox 只保留 Agent loop 当前需要的运行时工作集。代码修改、测试报告和其他制品在执行时仍然首先产生于 sandbox,读取和继续加工都很快。需要跨越 sandbox 生命周期保留的部分,则在回收前将 diff、快照或制品上传到对象存储,并在 State store 中记录引用。

下一次继续任务时,控制面先从 State store 取回任务元数据,再分配一个新 sandbox,重新 checkout 基础代码,并从对象存储恢复需要的快照或制品,最后继续 Agent loop。这个过程会增加冷启动与数据搬运成本,却把昂贵的计算环境和需要长期保留的状态拆开了。按照这个模型看,表格中 Cloud 的 Execution environment 是云端 sandbox,State store 则是位于 sandbox 之外的云端持久化服务。这个分层是架构推断,不代表 OpenAI 已经公开确认了内部实现。

3. Desktop 本地实验与 Agent loop

这次写作前,我让 Codex 对当前 macOS Desktop 做了三组实验。完整结果和可复现脚本放在 Desktop 本地实验记录。实验使用 ChatGPT Desktop 26.803.61601,内置 Codex 0.147.0-alpha.6.5。版本号很重要:bundle 布局和 SQLite schema 都是当前实现,不是稳定 API。

3.1 Desktop 进程拆分

当前 App bundle 里同时存在 app.asar、Chromium Framework、codexcodex-code-mode-host。运行时的进程关系可以压成下面这棵树:

ChatGPT Desktop
├── renderer / GPU / network / storage processes
├── codex ... app-server
│   ├── tool processes
│   ├── code-mode host
│   └── terminal / computer-use helpers
└── Remote / SSH helpers(需要时)

实际启动参数中能直接看到:

Resources/codex -c features.code_mode_host=true app-server --analytics-default-enabled

这至少确认了一件事:当前 Desktop 的 UI shell 和 Codex Agent runtime 是不同进程。结合启动参数,以及 App Server 对外提供的 conversation、approval 与事件流接口,我判断 Desktop UI 主要通过这层 runtime 使用相关能力;具体内部 IPC 没有公开。

OpenAI 对外公开的 App Server 正是这层接口。它使用双向 JSON-RPC,默认 transport 是 JSONL/stdin。协议把一次编码任务拆成三个对象:[8]

  • Thread 是一条可恢复或分叉的聊天。
  • Turn 是用户的一次请求以及 Agent 为它完成的工作。
  • Item 是一条消息、一次命令、一组文件修改或一次工具调用。

为了验证这不是文档里的孤立接口,我在临时 CODEX_HOME 中启动 Desktop 内置 runtime,只发送 initialize → initialized → thread/list,没有发起模型请求。App Server 正常完成握手并返回空的 thread list,也没有读取现有 ~/.codex 会话。实验脚本在 app_server_握手实验.py

3.2 一次请求的循环

在这里插入图片描述

图 2:一次 Codex Turn 的 Agent loop。上半部分表示顺序,下半部分比较 Local 与 Cloud 中每个组件的位置。模型提出动作,Agent runtime 驱动循环并检查 approval policy;工具进程在 sandbox 的约束内执行。

一次 Turn 可以按下面的顺序理解。

  1. Client 把用户消息和当前项目位置交给 Agent runtime。
  2. Runtime 读取 thread history、AGENTS.md、可用工具以及必要的本地 memory,组装本轮上下文。
  3. Runtime 调用模型。模型可能直接回答,也可能请求读取文件、运行命令或调用工具。
  4. Runtime 检查 approval policy。需要用户确认时,App Server 把 approval request 发回 Client;拒绝后不会执行动作。
  5. 获准的动作由 execution environment 中的工具进程运行,sandbox 在执行时施加文件、网络和系统权限。Local 使用本机进程,Cloud 使用容器中的进程。
  6. 命令输出、文件变化和工具结果作为 Item 写回 Thread,再进入下一次模型调用。
  7. 模型给出最终消息,或者 Runtime 收到 interrupt、失败或超时,Turn 结束。

这就是 Agent loop。模型参与每次决策,循环本身由 runtime 驱动。把它画清楚以后,很多产品差异都可以转化成同一个问题:第 5 步在哪台机器运行,第 2、6 步的状态又存在哪里。

当前构建把追加式任务事件写进 rollout JSONL,用 SQLite 保存可检索的 thread 元数据。前者更接近任务发生的过程,后者更像目录;具体字段与版本观察放在实验记录里。这个判断只针对当前构建。

3.3 Sandbox 与 approval

Sandbox 决定命令实际拥有什么权限。Approval 决定某个越界或敏感动作是否需要人同意。一个动作即使逻辑上被模型选择,也要经过这两层。

当前 Codex 还提供 Beta 版 permission profile,内置 :read-only:workspace:danger-full-access。本文验证的是这套 profile 的文件写入边界,它与旧 sandbox 配置是两套入口。:workspace 允许写 workspace roots 和系统临时目录;macOS 使用 Seatbelt 执行文件与进程限制。[9]

我在自动删除的临时目录里跑了三次命令:

:read-only  写工作区内文件     → denied
:workspace  写工作区内文件     → allowed
:workspace  写工作区外文件     → denied

实验脚本在 sandbox_边界实验.py。第一次对照把工作区外目录也放在 /tmp,结果写入成功,因为 system temp 本来就在 :workspace 的可写范围内。这个小坑很典型:看到一个命令写到了 cwd 外面,不能马上得出 sandbox 失效的结论,先看 permission profile 对临时目录的定义。

4. 多端消息的三种连续性

多端消息同步是这篇文章最容易混淆的地方。用户在另一台设备上看到相似的“继续聊天”体验,底层机制并不相同。Cloud sync 类似多个 Client 打开同一份云端会话。Remote 类似手机远程控制原来的电脑,文件和任务仍留在原 host。Handoff 更接近搬家:把笔记本上做到一半的任务搬到一台常开的工作站,聊天记录和当前 Git 状态随任务过去,后面的 Agent loop、Shell 和文件修改都改在新 host 上运行。严格说,Handoff 属于任务迁移,不是后台消息同步。

在这里插入图片描述

图 3:a,Cloud sync、Remote 和 Handoff 的消息路径;b,本地/云端任务状态、Local Memory、ChatGPT Memory 和 AGENTS.md 的作用域。红色阻断符号只表示两套 memory 之间没有公开的自动同步关系,不代表 thread、Handoff 或项目文件不能跨边界。

4.1 Cloud Work conversation 的跨端同步

这里先用两个具体场景把名字拆开。

先以 Desktop 发起任务为例。我在左上角的产品选择器中选择 ChatGPT,把输入框的模式从 Chat 切到 Work,再把运行位置从 Work locally 切到 Cloud,然后让它根据一组资料生成报告。这条任务对应一条 Cloud Work conversation,消息、执行进度和结果由云端保存,之后可以在 Web、Mobile 或另一台 Desktop 上继续。这里的 Mobile 指从手机查看和继续这条云端任务,不是说这个例子从手机发起。Web 上的 Work 默认运行在云端;Desktop 如果选择 Work locally,conversation 则留在当前电脑。[10][11]

再假设我切到 Codex 视图,在本机仓库里启动“修复登录超时”。Codex 左侧历史中会出现一条任务记录。这里的 history 只是查找和重新打开 Codex 任务的界面入口,不是一种新的会话对象,也不能由“separate history”推出 OpenAI 为它单独建设了一套数据库。

这条本地任务真正运行时,Desktop 通过本机 App Server 控制 Agent runtime。App Server 把一条 Codex 对话称为 Thread;用户每发起一次请求,对应一个 Turn,消息、命令和文件修改则是 Item。[8] 因此,对同一条本地 Codex 任务,可以从两个层面看:用户在 Codex history 里看到一个可重新打开的任务,runtime 内部则用 Thread、Turn 和 Item 继续它。手机通过 Remote 打开这条任务时,访问的仍是原 host 上的状态,不会把它变成 ChatGPT Cloud Work conversation。

把产品入口与运行模式交叉来看,这几种对象的边界会清楚一些。

用户看到的对象 历史入口 Agent runtime 主要状态位置 跨端连续性 与 App Server Thread 的关系
Work conversation · Cloud ChatGPT 会话列表 托管云环境 ChatGPT 云端 Cloud sync 未公开
Work conversation · Local ChatGPT 会话列表 当前电脑 当前 host Remote 未公开
Codex task · Local / Worktree / connected host Codex history 所选 host 所选 host Remote / Handoff 本地 runtime 使用 Thread
Codex task · Cloud Codex history 云端 sandbox Codex 云端 协议未公开 是否复用 Thread schema 未公开

表里的 history 只是用户查找和重新打开任务的入口,任务选择的运行模式才决定 Agent runtime 和主要状态放在哪里。Cloud Work conversation 明确使用云端状态,并在 Web、Mobile 和 Desktop 之间同步;Local Work 与本地 Codex task 仍以执行 host 为中心,其他设备通过 Remote 访问,Codex task 还可以用 Handoff 更换执行 host。[6][10][11]

App Server Thread 放在最后一列,因为它属于 runtime 协议层。官方把 Thread 定义为用户与 Codex agent 的一条 conversation,由 Turn 和 Item 组成;它不是第三种用户会话。[8] 至于 Cloud Work conversation 与云端 Codex task 是否复用底层数据库、增量投递、冲突处理协议或 Thread schema,公开资料没有说明。

4.2 Remote 对本地会话的访问

Remote 采用另一条路径。手机通过用于转发控制消息的 secure relay 连接 host,发送 prompt、approval 和 follow-up;host 提供聊天、仓库、Shell、本机凭据、浏览器和其他扩展工具。[6]

因此,Remote 的多端体验更接近远程访问。Local thread 的 rollout 和 repo 仍在 host。手机得到消息视图和控制能力,没有得到一份可脱离 host 继续运行的本地环境。Host 休眠、断网或退出 Desktop 后,Remote 也会停止。

这解释了一个表面矛盾:官方一边说 local Work conversations stay on your computer,一边又允许手机继续本地聊天。会话数据以 host 为中心,secure relay 让其他授权设备访问它;产品不需要先把整个工作区同步到云端。

4.3 Handoff 的显式迁移

假设我白天在笔记本 Host A 上启动一个本地 Codex 任务,晚上希望改用常开的工作站 Host B 继续。两个 host 已经保存了同一个 Git 仓库后,我可以在 Desktop 的聊天底部把运行位置从 Host A 切换到 Host B,再确认目标 branch 并执行 Handoff。Codex 会中断仍在生成的响应,在 Host B 创建或复用 worktree,把 chat 与当前 Git state 转过去,然后将这条聊天的后续执行位置切到 Host B。[6]

迁移完成后,新的 Agent loop、Shell 和文件访问都由 Host B 提供,后续执行不再依赖 Host A。这一点和 Remote 明显不同:Remote 期间任务始终在 Host A,控制端只是在远程操作它;Handoff 完成后,Host B 成了新的执行 host。从产品语义看,它也不同于 Cloud sync:A、B 不是同时打开同一份云端权威会话,chat 与 Git state 会在用户确认后从 A 定向转到 B。官方没有公开这一步底层使用的传输与持久化协议。目前 Handoff 只支持本地计算机与 connected remote host 之间移动,不支持把任务交给 Codex cloud。[6]

它是一次显式迁移,不承担后台持续复制。官方只写了 chat 和 Git state,没有把 local memory 列入 Handoff 范围。项目规则如果已经提交到 AGENTS.md,可以跟 Git 到目标 host;Handoff 后的 local memory 召回应以目标 host 的 store 为准,这是根据 memory 的 host scope 做出的推断,不是 Handoff 文档直接披露的行为。

4.4 流式推送与历史补齐的双链路

前三节回答状态在哪里、怎样跨设备继续;这一节回答消息怎样到达 Client。它不是第四种连续性,而是 Cloud sync 与 Remote 都要处理的交付问题。为了让用户打开会话时先看到完整历史,任务运行时又能立即看到文字增量、工具进度和 approval,常见实现会拆成两条链路。

  1. 历史同步从持久化状态中读取 conversation、Turn 和 Item,并用 cursor 分页。它负责首次打开、向前翻页和断线后的补齐。
  2. 流式推送通过 WebSocket、SSE 或事件网关发送增量消息、工具进度和状态变化。它追求低延迟,不应成为唯一的持久化真相。

难点在两条链路的接缝。一种常见做法是让历史响应带回 cursor C,Client 合并历史后只接收 C 之后的事件;重连时携带最后确认的 event ID 或 sequence。推送链路还可能重试,Client 需要按 event 或 item ID 去重。Slack 的公开 API 就把实时 Events API 与分页读取 conversations.history 分开;WHATWG 的 SSE 规范则用 Last-Event-ID 支持断线重连。[12][13][14]

App Server 的公开协议也能看到这种分工:thread/readthread/turns/listthread/items/list 读取已保存的历史,turn/*item/* notification 传递运行中的增量。[8] 这只能证明本地公开协议的形状;ChatGPT 与 Codex cloud 是否使用同一套事件日志、cursor 和推送网关,官方没有披露。

5. 多端记忆的四层状态

讨论 memory 前,先用四个读者问题区分对象。

读者期望 实际对象 默认作用域
继续刚才的任务 Thread transcript 同一个 chat
新聊天记得本机使用习惯 Local Memory 当前 Codex host
ChatGPT 在不同端记得账号偏好 ChatGPT Memory 账号或 workspace
每次都必须执行项目规则 AGENTS.md / 项目文档 Git 仓库或目录层级

5.1 Thread transcript

Thread 保存用户消息、Agent 消息、命令、工具结果和文件变化。它是本地 App Server 中 Resume 与 Remote 操作的会话单位,让同一条聊天知道前面做过什么。云端任务也有 conversation/task state,但公开资料没有说明它是否复用本地 Thread schema。

对话过长时,runtime 可能压缩较早历史,以放进模型当前可用的上下文。当前本地 rollout 仍可以保留更完整的事件,模型下一轮收到的可能只是压缩结果。因此,落盘的 Thread history 与 model context 不能完全画等号。

5.2 Local Memory

Local Memory 从符合条件的本机历史聊天中后台提取可复用信息。它默认关闭;开启后会跳过仍在活跃或过短的会话,对生成字段做 secret redaction,并在会话空闲后更新,不保证聊天一结束就写入。[15]

官方把主文件放在 ~/.codex/memories/,内容包括 summaries、durable entries、recent inputs 和 supporting evidence。Desktop、CLI 和 IDE 使用所连接 Codex host 的 local memory store。[15]

当前机器的 memories_*.sqlite 结构与“后台抽取,再整合”的流程一致,但数据库目前没有可验证的生成结果。我只能把它当作 pipeline 形状的本地证据,不能据此声称 Codex 使用了某种固定 embedding 或检索算法。字段细节留在实验记录里。

5.3 ChatGPT Memory

官方明确区分两套 memory:ChatGPT 云端产品使用 ChatGPT Memory,本地 Codex clients 使用独立的 local memory store 和控制项。前者服从账号与 workspace 的 memory 设置,不读取本地 Codex memory。[15]

公开资料没有描述两套 memory 的自动双向同步,也没有披露 ChatGPT Memory 怎样存储、索引、合并和更新。Codex Cloud 执行容器的 12 小时 cache 也不是用户 memory:cache 复用的是预装依赖和环境状态,不代表 Agent 记住了上一条聊天。[7]

从产品边界看,分开有现实理由。Local Memory 可能带有仓库路径、本机工具、个人命令习惯和未提交任务的上下文。默认汇入云端账号 memory 后,用户删除一条记忆时,怎样从原始记录、派生结果和其他副本中一致删除,会和企业隔离、可解释性一起变得复杂。代价是换 host 后没有天然一致的个人编码记忆。

5.4 AGENTS.md

必须稳定生效的内容应该写进 AGENTS.md 或仓库文档。Codex 会读取全局文件,以及从仓库根到当前工作目录之间的分层规则;更接近当前目录的指令后应用。[16]

它和 memory 的差别很简单:memory 是后台生成、概率性使用的召回层;AGENTS.md 是显式、可审查、可随 Git 版本化的输入。编译命令、测试要求、安全边界和团队约定都属于后者。项目切换 Local、Worktree、SSH 或 Cloud 时,只要代码状态包含这些文件,规则就能跟着执行环境移动。

6. 架构判断与公开边界

回到开头的四个问题,我现在的理解是:Codex 的多端架构围绕执行 host 和状态归属展开。

Local 与 Worktree 的 Agent loop 在本机;Worktree 只隔离 Git 工作区。SSH 和 Remote 把客户端连接到另一台 host;仓库、工具、sandbox 和 local memory 仍由那台 host 提供。Cloud 在隔离容器中运行 Agent loop,服务端托管会话和任务状态。

消息连续性随状态中心选择机制。Cloud Work conversation 使用官方明确的云端会话同步,Remote 通过 relay 访问 host,Handoff 显式迁移 chat 与 Git state;Codex 专用 history 的同步协议仍未公开。它们提供相似的 UI 体验,数据复制范围并不相同。

Memory 也沿着同一边界拆开。Thread 解决当前任务连续性,Local Memory 服务当前 host,ChatGPT Memory 服务云端账号或 workspace,AGENTS.md 服务可版本化的项目规则。当前没有证据支持一套横跨所有端的 Codex memory 总线。

OpenAI 当前公布的开源组件清单包含 App Server、CLI、SDK、Skills、Plugins 和通用云环境;清单没有列出 Desktop 完整实现和 Codex cloud 后端。[17] 因此,下面几项我暂时无法确认:

  • Cloud conversation 的数据库、队列和冲突处理协议。
  • ChatGPT Memory 怎样索引、合并和更新。
  • Local Memory 未来是否提供加密的跨 host 迁移。
  • Desktop 后续版本是否继续使用当前 Electron/Chromium 与独立 App Server 的进程布局。

我认为目前把 Local 和 Cloud 分开是一个合理选择。本地任务把 Agent loop、状态、文件和工具都留在用户自己的 host,读取仓库、调用本机凭据和启动工具都很直接,也不需要为每个本地任务长期占用云端 sandbox。代价同样明确:host 一旦关机、断网或退出 Desktop,Remote 就会停止。从另一台设备看,聊天历史、执行进度和本地制品都被挡在这台离线机器后面。[6]

另一条路径是更彻底的存算分离。Conversation、任务进度和制品索引进入独立的云端状态服务,Agent loop 由云端控制面维护,sandbox 按需拉起;用户的电脑只作为一个带权限边界的 tool endpoint,负责提供本地文件、凭据、浏览器和桌面应用。这样即使电脑离线,Web、Mobile 和 Desktop 仍然能看到已有消息、进度与云端制品;需要访问本机文件的步骤可以暂停,等 tool endpoint 重新上线。Cloud Work 已经表现出这种连续性,但公开资料不足以证明 Codex 的全部入口采用了这套实现。[10]

这套架构把可用性问题转成了云端成本问题。Sandbox 保持时间越短,空闲计算越少,但恢复任务时就要重新准备环境,从对象存储拉取制品和代码;sandbox 保持时间越长,恢复更快,闲置成本也更高。再加上制品存储、依赖缓存、网络流量,以及本机 tool endpoint 的鉴权、审计和断线恢复,账单和系统复杂度都会上去。这里没有银弹,全是 tradeoff。当前方案选择本机能力、隐私边界和较低的云端成本,彻底存算分离选择跨端可见性与任务连续性,本质上只是决定由用户承担 host 在线约束,还是由服务端承担更多基础设施成本。

7. 参考资料

[1] CNNIC,第 57 次《中国互联网络发展状况统计报告》

[2] QuestMobile,2026 年 AI 应用市场发展半年报

[3] IDC,企业 Agent 如何落地:COMPASS 七维方法论与 MarketGlance 选型参考

[4] OpenAI, Codex environments

[5] OpenAI, Worktrees

[6] OpenAI, Remote connections

[7] OpenAI, Cloud environments

[8] OpenAI, Codex App Server

[9] OpenAI, Permissions

[10] OpenAI, Use ChatGPT

[11] OpenAI, What’s new in ChatGPT for work

[12] Slack, The Events API

[13] Slack, conversations.history

[14] WHATWG, Server-sent events

[15] OpenAI, Memories

[16] OpenAI, AGENTS.md

[17] OpenAI, Open source

Logo

葡萄城是专业的软件开发技术和低代码平台提供商,聚焦软件开发技术,以“赋能开发者”为使命,致力于通过表格控件、低代码和BI等各类软件开发工具和服务,一站式满足开发者需求,帮助企业提升开发效率并创新开发模式。

更多推荐