OpenAI最近发布了关于Codex App Server的详细架构描述。这种双向协议将Codex编码代理的核心逻辑与其各种客户端界面分离开来。如今,通过这一统一的、稳定的API,App Server为所有的Codex应用提供了支持,包括命令行工具、VS Code扩展程序、网页应用、macOS桌面应用,以及JetBrains和Apple Xcode等第三方集成环境。
这篇由OpenAI工程师Celia Chen撰写的文章,属于一个系列报道的一部分,该系列专门介绍了开源Codex CLI的内部架构。正如Chen所指出的,其中的核心挑战在于:代理之间的交互方式与简单的请求/响应机制有着本质上的区别:
用户的某个请求往往会引发一系列结构化的操作流程,客户端需要准确地记录下这些步骤:用户的输入、代理的处理过程,以及在此过程中产生的各种结果。

Codex App Server的内部架构:stdio读取器与Codex消息处理器会将客户端的JSON-RPC请求转换为Codex的核心操作指令,同时会将内部事件转换成适合用户界面显示的通知信息(来源:此处)
为了实现这一功能,OpenAI设计了三种对话模型基础单元。Item是输入或输出的原子单位,它具有明确的生命周期:从“开始”到可选的“增量更新”阶段,最终结束于“完成”。这种单元可以代表用户的消息、代理发出的指令、工具的执行结果、审批请求,或者文件差异对比信息等。Turn则用于汇总由某个具体操作任务所产生的所有步骤,这些操作通常是由用户的输入触发的。Thread则是用来承载持续进行的对话会话的容器,它支持会话的创建、恢复、分叉以及存档功能,并能保留所有的事件记录,因此客户端在重新连接时可以保持之前的对话状态不变。
该协议还支持服务器主动发起的请求。当代理在执行某个命令之前需要获得批准时,服务器会向客户端发送请求,并暂停当前的对话流程,直到收到“允许”或“拒绝”的回复为止。通信过程中使用的是JSON-RPC协议,数据通过stdio接口以JSONL格式进行传输。OpenAI设计这套协议时充分考虑了向后兼容性,因此旧版本的客户端也可以与新版本的服务器正常通信。
值得注意的是,在最终确定这一设计方案之前,OpenAI曾尝试过使用模型上下文协议,但后来放弃了这一方案。陈解释说,在开发VS Code扩展时,团队最初尝试将Codex作为MCP服务器来使用,但“要想以适合VS Code的方式实现MCP协议的功能,其实非常困难”。对于集成开发环境来说,一些更复杂的交互功能(比如差异对比、审批流程以及线程状态的持久化保存)所需的机制,并无法与MCP协议所基于的工具导向模型很好地对应起来。虽然OpenAI仍然支持将Codex作为MCP服务器用于简单的工作流程中,但对于需要高度集成化的场景,他们推荐使用应用服务器来实现这些功能。

该图展示了工具执行过程中的协议消息流,其中包含了可选的审批环节。服务器会暂停当前操作,并向客户端发送请求;客户端必须回复“允许”或“拒绝”,才能让代理继续执行后续操作。更多信息
这篇文章介绍了客户端在部署App Server时所采用的三种方式。像VS Code扩展程序和桌面应用程序这样的本地客户端,会将特定于平台的二进制文件打包在一起,作为子进程运行,并保持双向标准输入输出通道的开放状态;而像Xcode这样的合作伙伴,则通过让客户端版本保持稳定,同时引用更新版本的App Server二进制文件,从而实现服务器端功能的升级,而无需等待客户端的重新发布。
Codex Web运行时采用了另一种不同的方式:工作进程会创建一个容器,在其中启动App Server,而浏览器则通过HTTP协议和服务器发送的事件进行通信——这种方式使得浏览器的用户界面保持轻量级。同时,对于那些需要长时间运行的任务来说,服务器仍然是这些任务的核心处理节点。
App Server的发展历程与整个行业为标准化代理程序与编辑器之间的交互所做出的努力是同步的。Agent Client Protocol就是这样一个例子。这一协议最初由Zed Industries提出,现在也得到了JetBrains的支持。与OpenAI的App Server这种专门为Codex平台设计的协议不同,ACP旨在成为一种通用标准,使得任何编码代理程序都能与任何编辑器进行连接。这其实与十年前Language Server Protocol为语言工具标准化所起的作用非常相似。事实上,Codex CLI本身也被列为兼容ACP的代理程序之一。这些不同方法的共存,反映了整个行业仍在努力确定代理程序集成所需的最佳抽象层次——OpenAI也承认,这个领域正在“迅速发展”。
Codex App Server的所有源代码都可以在open-source Codex CLI仓库中找到,而相关协议文档中也提供了TypeScript和JSON Schema格式的模板生成工具,这些工具可以帮助使用任何语言的客户端进行绑定开发。